1
First arm pullreq of 4.2...
1
First arm pullreq for 7.1. The bulk of this is the qemu_split_irq
2
removal.
3
4
I have enough stuff in my to-review queue that I expect to do another
5
pullreq early next week, but 31 patches is enough to not hang on to.
2
6
3
thanks
7
thanks
4
-- PMM
8
-- PMM
5
9
6
The following changes since commit 27608c7c66bd923eb5e5faab80e795408cbe2b51:
10
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
7
11
8
Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20190814a' into staging (2019-08-16 12:00:18 +0100)
12
Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700)
9
13
10
are available in the Git repository at:
14
are available in the Git repository at:
11
15
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190816
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220421
13
17
14
for you to fetch changes up to 664b7e3b97d6376f3329986c465b3782458b0f8b:
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
15
19
16
target/arm: Use tcg_gen_extrh_i64_i32 to extract the high word (2019-08-16 14:02:53 +0100)
20
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs (2022-04-21 11:37:05 +0100)
17
21
18
----------------------------------------------------------------
22
----------------------------------------------------------------
19
target-arm queue:
23
target-arm queue:
20
* target/arm: generate a custom MIDR for -cpu max
24
* hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
21
* hw/misc/zynq_slcr: refactor to use standard register definition
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
22
* Set ENET_BD_BDU in I.MX FEC controller
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
23
* target/arm: Fix routing of singlestep exceptions
27
* xlnx-zynqmp: Connect 4 TTC timers
24
* refactor a32/t32 decoder handling of PC
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
25
* minor optimisations/cleanups of some a32/t32 codegen
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
26
* target/arm/cpu64: Ensure kvm really supports aarch64=off
30
* stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
27
* target/arm/cpu: Ensure we can use the pmu with kvm
31
* hw/core/irq: remove unused 'qemu_irq_split' function
28
* target/arm: Minor cleanups preparatory to KVM SVE support
32
* npcm7xx: use symbolic constants for PWRON STRAP bit fields
33
* virt: document impact of gic-version on max CPUs
29
34
30
----------------------------------------------------------------
35
----------------------------------------------------------------
31
Aaron Hill (1):
36
Edgar E. Iglesias (6):
32
Set ENET_BD_BDU in I.MX FEC controller
37
timer: cadence_ttc: Break out header file to allow embedding
38
hw/arm/xlnx-zynqmp: Connect 4 TTC timers
39
hw/arm: versal: Create an APU CPU Cluster
40
hw/arm: versal: Add the Cortex-R5Fs
41
hw/misc: Add a model of the Xilinx Versal CRL
42
hw/arm: versal: Connect the CRL
33
43
34
Alex Bennée (1):
44
Hao Wu (2):
35
target/arm: generate a custom MIDR for -cpu max
45
hw/misc: Add PWRON STRAP bit fields in GCR module
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
36
47
37
Andrew Jones (6):
48
Heinrich Schuchardt (1):
38
target/arm/cpu64: Ensure kvm really supports aarch64=off
49
hw/arm/virt: impact of gic-version on max CPUs
39
target/arm/cpu: Ensure we can use the pmu with kvm
40
target/arm/helper: zcr: Add build bug next to value range assumption
41
target/arm/cpu: Use div-round-up to determine predicate register array size
42
target/arm/kvm64: Fix error returns
43
target/arm/kvm64: Move the get/put of fpsimd registers out
44
50
45
Damien Hedde (1):
51
Peter Maydell (19):
46
hw/misc/zynq_slcr: use standard register definition
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
53
hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device
54
hw/intc/exynos4210_gic: Remove unused TYPE_EXYNOS4210_IRQ_GATE
55
hw/arm/exynos4210: Put a9mpcore device into state struct
56
hw/arm/exynos4210: Drop int_gic_irq[] from Exynos4210Irq struct
57
hw/arm/exynos4210: Coalesce board_irqs and irq_table
58
hw/arm/exynos4210: Fix code style nit in combiner_grp_to_gic_id[]
59
hw/arm/exynos4210: Move exynos4210_init_board_irqs() into exynos4210.c
60
hw/arm/exynos4210: Put external GIC into state struct
61
hw/arm/exynos4210: Drop ext_gic_irq[] from Exynos4210Irq struct
62
hw/arm/exynos4210: Move exynos4210_combiner_get_gpioin() into exynos4210.c
63
hw/arm/exynos4210: Delete unused macro definitions
64
hw/arm/exynos4210: Use TYPE_SPLIT_IRQ in exynos4210_init_board_irqs()
65
hw/arm/exynos4210: Fill in irq_table[] for internal-combiner-only IRQ lines
66
hw/arm/exynos4210: Connect MCT_G0 and MCT_G1 to both combiners
67
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
68
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
69
hw/arm/exynos4210: Put combiners into state struct
70
hw/arm/exynos4210: Drop Exynos4210Irq struct
47
71
48
Peter Maydell (2):
72
Zongyuan Li (3):
49
target/arm: Factor out 'generate singlestep exception' function
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
50
target/arm: Fix routing of singlestep exceptions
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
75
hw/core/irq: remove unused 'qemu_irq_split' function
51
76
52
Richard Henderson (18):
77
docs/system/arm/virt.rst | 4 +-
53
target/arm: Pass in pc to thumb_insn_is_16bit
78
include/hw/arm/exynos4210.h | 50 ++--
54
target/arm: Introduce pc_curr
79
include/hw/arm/xlnx-versal.h | 16 ++
55
target/arm: Introduce read_pc
80
include/hw/arm/xlnx-zynqmp.h | 4 +
56
target/arm: Introduce add_reg_for_lit
81
include/hw/intc/exynos4210_combiner.h | 57 +++++
57
target/arm: Remove redundant s->pc & ~1
82
include/hw/intc/exynos4210_gic.h | 43 ++++
58
target/arm: Replace s->pc with s->base.pc_next
83
include/hw/irq.h | 5 -
59
target/arm: Replace offset with pc in gen_exception_insn
84
include/hw/misc/npcm7xx_gcr.h | 30 +++
60
target/arm: Replace offset with pc in gen_exception_internal_insn
85
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++++
61
target/arm: Remove offset argument to gen_exception_bkpt_insn
86
include/hw/timer/cadence_ttc.h | 54 +++++
62
target/arm: Use unallocated_encoding for aarch32
87
hw/arm/exynos4210.c | 430 ++++++++++++++++++++++++++++++----
63
target/arm: Remove helper_double_saturate
88
hw/arm/npcm7xx_boards.c | 24 +-
64
target/arm: Use tcg_gen_extract_i32 for shifter_out_im
89
hw/arm/realview.c | 33 ++-
65
target/arm: Use tcg_gen_deposit_i32 for PKHBT, PKHTB
90
hw/arm/stellaris.c | 15 +-
66
target/arm: Remove redundant shift tests
91
hw/arm/virt.c | 7 +
67
target/arm: Use ror32 instead of open-coding the operation
92
hw/arm/xlnx-versal-virt.c | 6 +-
68
target/arm: Use tcg_gen_rotri_i32 for gen_swap_half
93
hw/arm/xlnx-versal.c | 99 +++++++-
69
target/arm: Simplify SMMLA, SMMLAR, SMMLS, SMMLSR
94
hw/arm/xlnx-zynqmp.c | 22 ++
70
target/arm: Use tcg_gen_extrh_i64_i32 to extract the high word
95
hw/core/irq.c | 15 --
71
96
hw/intc/exynos4210_combiner.c | 108 +--------
72
target/arm/cpu.h | 13 +-
97
hw/intc/exynos4210_gic.c | 344 +--------------------------
73
target/arm/helper.h | 1 -
98
hw/misc/xlnx-versal-crl.c | 421 +++++++++++++++++++++++++++++++++
74
target/arm/kvm_arm.h | 28 ++
99
hw/timer/cadence_ttc.c | 32 +--
75
target/arm/translate-a64.h | 4 +-
100
MAINTAINERS | 2 +-
76
target/arm/translate.h | 39 ++-
101
hw/misc/meson.build | 1 +
77
hw/misc/zynq_slcr.c | 450 ++++++++++++++++----------------
102
25 files changed, 1457 insertions(+), 600 deletions(-)
78
hw/net/imx_fec.c | 4 +
103
create mode 100644 include/hw/intc/exynos4210_combiner.h
79
target/arm/cpu.c | 30 ++-
104
create mode 100644 include/hw/intc/exynos4210_gic.h
80
target/arm/cpu64.c | 31 ++-
105
create mode 100644 include/hw/misc/xlnx-versal-crl.h
81
target/arm/helper.c | 7 +
106
create mode 100644 include/hw/timer/cadence_ttc.h
82
target/arm/kvm.c | 7 +
107
create mode 100644 hw/misc/xlnx-versal-crl.c
83
target/arm/kvm64.c | 161 +++++++-----
84
target/arm/op_helper.c | 15 --
85
target/arm/translate-a64.c | 130 ++++------
86
target/arm/translate-vfp.inc.c | 45 +---
87
target/arm/translate.c | 572 +++++++++++++++++------------------------
88
16 files changed, 771 insertions(+), 766 deletions(-)
89
diff view generated by jsdifflib
1
When generating an architectural single-step exception we were
1
It's not possible to provide the guest with the Security extensions
2
routing it to the "default exception level", which is to say
2
(TrustZone) when using KVM or HVF, because the hardware
3
the same exception level we execute at except that EL0 exceptions
3
virtualization extensions don't permit running EL3 guest code.
4
go to EL1. This is incorrect because the debug exception level
4
However, we weren't checking for this combination, with the result
5
can be configured by the guest for situations such as single
5
that QEMU would assert if you tried it:
6
stepping of EL0 and EL1 code by EL2.
7
6
8
We have to track the target debug exception level in the TB
7
$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none
9
flags, because it is dependent on CPU state like HCR_EL2.TGE
8
Unexpected error in object_property_find_err() at ../../qom/object.c:1304:
10
and MDCR_EL2.TDE. (That we were previously calling the
9
qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found
11
arm_debug_target_el() function to determine dc->ss_same_el
10
Aborted
12
is itself a bug, though one that would only have manifested
13
as incorrect syndrome information.) Since we are out of TB
14
flag bits unless we want to expand into the cs_base field,
15
we share some bits with the M-profile only HANDLER and
16
STACKCHECK bits, since only A-profile has this singlestep.
17
11
18
Fixes: https://bugs.launchpad.net/qemu/+bug/1838913
12
Check for this combination of options and report an error, in the
13
same way we already do for attempts to give a KVM or HVF guest the
14
Virtualization or MTE extensions. Now we will report:
15
16
qemu-system-aarch64: mach-virt: KVM does not support providing Security extensions (TrustZone) to the guest CPU
17
18
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/961
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Tested-by: Alex Bennée <alex.bennee@linaro.org>
21
Message-id: 20220404155301.566542-1-peter.maydell@linaro.org
22
Message-id: 20190805130952.4415-3-peter.maydell@linaro.org
23
---
22
---
24
target/arm/cpu.h | 5 +++++
23
hw/arm/virt.c | 7 +++++++
25
target/arm/translate.h | 15 +++++++++++----
24
1 file changed, 7 insertions(+)
26
target/arm/helper.c | 6 ++++++
27
target/arm/translate-a64.c | 2 +-
28
target/arm/translate.c | 4 +++-
29
5 files changed, 26 insertions(+), 6 deletions(-)
30
25
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
32
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
28
--- a/hw/arm/virt.c
34
+++ b/target/arm/cpu.h
29
+++ b/hw/arm/virt.c
35
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1)
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
36
/* Target EL if we take a floating-point-disabled exception */
31
exit(1);
37
FIELD(TBFLAG_ANY, FPEXC_EL, 24, 2)
38
FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
39
+/*
40
+ * For A-profile only, target EL for debug exceptions.
41
+ * Note that this overlaps with the M-profile-only HANDLER and STACKCHECK bits.
42
+ */
43
+FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 21, 2)
44
45
/* Bit usage when in AArch32 state: */
46
FIELD(TBFLAG_A32, THUMB, 0, 1)
47
diff --git a/target/arm/translate.h b/target/arm/translate.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/translate.h
50
+++ b/target/arm/translate.h
51
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
52
uint32_t svc_imm;
53
int aarch64;
54
int current_el;
55
+ /* Debug target exception level for single-step exceptions */
56
+ int debug_target_el;
57
GHashTable *cp_regs;
58
uint64_t features; /* CPU features bits */
59
/* Because unallocated encodings generate different exception syndrome
60
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
61
* ie A64 LDX*, LDAX*, A32/T32 LDREX*, LDAEX*.
62
*/
63
bool is_ldex;
64
- /* True if a single-step exception will be taken to the current EL */
65
- bool ss_same_el;
66
/* True if v8.3-PAuth is active. */
67
bool pauth_active;
68
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
69
@@ -XXX,XX +XXX,XX @@ static inline void gen_exception(int excp, uint32_t syndrome,
70
/* Generate an architectural singlestep exception */
71
static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
72
{
73
- gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, isv, ex),
74
- default_exception_el(s));
75
+ bool same_el = (s->debug_target_el == s->current_el);
76
+
77
+ /*
78
+ * If singlestep is targeting a lower EL than the current one,
79
+ * then s->ss_active must be false and we can never get here.
80
+ */
81
+ assert(s->debug_target_el >= s->current_el);
82
+
83
+ gen_exception(EXCP_UDEF, syn_swstep(same_el, isv, ex), s->debug_target_el);
84
}
85
86
/*
87
diff --git a/target/arm/helper.c b/target/arm/helper.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/helper.c
90
+++ b/target/arm/helper.c
91
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
92
}
93
}
32
}
94
33
95
+ if (!arm_feature(env, ARM_FEATURE_M)) {
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
96
+ int target_el = arm_debug_target_el(env);
35
+ error_report("mach-virt: %s does not support providing "
97
+
36
+ "Security extensions (TrustZone) to the guest CPU",
98
+ flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL, target_el);
37
+ kvm_enabled() ? "KVM" : "HVF");
38
+ exit(1);
99
+ }
39
+ }
100
+
40
+
101
*pflags = flags;
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
102
*cs_base = 0;
42
error_report("mach-virt: %s does not support providing "
103
}
43
"Virtualization extensions to the guest CPU",
104
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/translate-a64.c
107
+++ b/target/arm/translate-a64.c
108
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
109
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
110
dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
111
dc->is_ldex = false;
112
- dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
113
+ dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
114
115
/* Bound the number of insns to execute to those left on the page. */
116
bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
117
diff --git a/target/arm/translate.c b/target/arm/translate.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/translate.c
120
+++ b/target/arm/translate.c
121
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
122
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
123
dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
124
dc->is_ldex = false;
125
- dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
126
+ if (!arm_feature(env, ARM_FEATURE_M)) {
127
+ dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
128
+ }
129
130
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
131
132
--
44
--
133
2.20.1
45
2.25.1
134
135
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Rotate is the more compact and obvious way to swap 16-bit
3
Break out header file to allow embedding of the the TTC.
4
elements of a 32-bit word.
5
4
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
7
Message-id: 20190808202616.13782-6-richard.henderson@linaro.org
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Message-id: 20220331222017.2914409-2-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/translate.c | 6 +-----
12
include/hw/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++
12
1 file changed, 1 insertion(+), 5 deletions(-)
13
hw/timer/cadence_ttc.c | 32 ++------------------
14
2 files changed, 56 insertions(+), 30 deletions(-)
15
create mode 100644 include/hw/timer/cadence_ttc.h
13
16
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/include/hw/timer/cadence_ttc.h b/include/hw/timer/cadence_ttc.h
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
15
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
79
--- a/hw/timer/cadence_ttc.c
17
+++ b/target/arm/translate.c
80
+++ b/hw/timer/cadence_ttc.c
18
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
81
@@ -XXX,XX +XXX,XX @@
19
/* Swap low and high halfwords. */
82
#include "qemu/timer.h"
20
static void gen_swap_half(TCGv_i32 var)
83
#include "qom/object.h"
84
85
+#include "hw/timer/cadence_ttc.h"
86
+
87
#ifdef CADENCE_TTC_ERR_DEBUG
88
#define DB_PRINT(...) do { \
89
fprintf(stderr, ": %s: ", __func__); \
90
@@ -XXX,XX +XXX,XX @@
91
#define CLOCK_CTRL_PS_EN 0x00000001
92
#define CLOCK_CTRL_PS_V 0x0000001e
93
94
-typedef struct {
95
- QEMUTimer *timer;
96
- int freq;
97
-
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)
21
{
125
{
22
- TCGv_i32 tmp = tcg_temp_new_i32();
126
qemu_set_irq(s->irq, !!(s->reg_intr & s->reg_intr_en));
23
- tcg_gen_shri_i32(tmp, var, 16);
24
- tcg_gen_shli_i32(var, var, 16);
25
- tcg_gen_or_i32(var, var, tmp);
26
- tcg_temp_free_i32(tmp);
27
+ tcg_gen_rotri_i32(var, var, 16);
28
}
29
30
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
31
--
127
--
32
2.20.1
128
2.25.1
33
34
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
We first convert the pmu property from a static property to one with
3
Connect the 4 TTC timers on the ZynqMP.
4
its own accessors. Then we use the set accessor to check if the PMU is
5
supported when using KVM. Indeed a 32-bit KVM host does not support
6
the PMU, so this check will catch an attempt to use it at property-set
7
time.
8
4
9
Signed-off-by: Andrew Jones <drjones@redhat.com>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Message-id: 20220331222017.2914409-3-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
target/arm/kvm_arm.h | 14 ++++++++++++++
12
include/hw/arm/xlnx-zynqmp.h | 4 ++++
14
target/arm/cpu.c | 30 +++++++++++++++++++++++++-----
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
15
target/arm/kvm.c | 7 +++++++
14
2 files changed, 26 insertions(+)
16
3 files changed, 46 insertions(+), 5 deletions(-)
17
15
18
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/kvm_arm.h
18
--- a/include/hw/arm/xlnx-zynqmp.h
21
+++ b/target/arm/kvm_arm.h
19
+++ b/include/hw/arm/xlnx-zynqmp.h
22
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/or-irq.h"
22
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
23
#include "hw/misc/xlnx-zynqmp-crf.h"
24
+#include "hw/timer/cadence_ttc.h"
25
26
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
27
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
29
#define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
30
XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
31
32
+#define XLNX_ZYNQMP_NUM_TTC 4
33
+
34
/*
35
* Unimplemented mmio regions needed to boot some images.
23
*/
36
*/
24
bool kvm_arm_aarch32_supported(CPUState *cs);
37
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
25
38
qemu_or_irq qspi_irq_orgate;
26
+/**
39
XlnxZynqMPAPUCtrl apu_ctrl;
27
+ * bool kvm_arm_pmu_supported:
40
XlnxZynqMPCRF crf;
28
+ * @cs: CPUState
41
+ CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
29
+ *
42
30
+ * Returns: true if the KVM VCPU can enable its PMU
43
char *boot_cpu;
31
+ * and false otherwise.
44
ARMCPU *boot_cpu_ptr;
32
+ */
45
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
33
+bool kvm_arm_pmu_supported(CPUState *cs);
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/xlnx-zynqmp.c
48
+++ b/hw/arm/xlnx-zynqmp.c
49
@@ -XXX,XX +XXX,XX @@
50
#define APU_ADDR 0xfd5c0000
51
#define APU_IRQ 153
52
53
+#define TTC0_ADDR 0xFF110000
54
+#define TTC0_IRQ 36
34
+
55
+
35
/**
56
#define IPI_ADDR 0xFF300000
36
* kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the
57
#define IPI_IRQ 64
37
* IPA address space supported by KVM
58
38
@@ -XXX,XX +XXX,XX @@ static inline bool kvm_arm_aarch32_supported(CPUState *cs)
59
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, qemu_irq *gic)
39
return false;
60
sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
40
}
61
}
41
62
42
+static inline bool kvm_arm_pmu_supported(CPUState *cs)
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
43
+{
64
+{
44
+ return false;
65
+ SysBusDevice *sbd;
66
+ int i, irq;
67
+
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
70
+ TYPE_CADENCE_TTC);
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
72
+
73
+ sysbus_realize(sbd, &error_fatal);
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
75
+ for (irq = 0; irq < 3; irq++) {
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
77
+ }
78
+ }
45
+}
79
+}
46
+
80
+
47
static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
48
{
82
{
49
return -ENOENT;
83
static const struct UnimpInfo {
50
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
51
index XXXXXXX..XXXXXXX 100644
85
xlnx_zynqmp_create_efuse(s, gic_spi);
52
--- a/target/arm/cpu.c
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
53
+++ b/target/arm/cpu.c
87
xlnx_zynqmp_create_crf(s, gic_spi);
54
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_has_el3_property =
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
55
static Property arm_cpu_cfgend_property =
89
xlnx_zynqmp_create_unimp_mmio(s);
56
DEFINE_PROP_BOOL("cfgend", ARMCPU, cfgend, false);
90
57
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
58
-/* use property name "pmu" to match other archs and virt tools */
59
-static Property arm_cpu_has_pmu_property =
60
- DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true);
61
-
62
static Property arm_cpu_has_vfp_property =
63
DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true);
64
65
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_pmsav7_dregion_property =
66
pmsav7_dregion,
67
qdev_prop_uint32, uint32_t);
68
69
+static bool arm_get_pmu(Object *obj, Error **errp)
70
+{
71
+ ARMCPU *cpu = ARM_CPU(obj);
72
+
73
+ return cpu->has_pmu;
74
+}
75
+
76
+static void arm_set_pmu(Object *obj, bool value, Error **errp)
77
+{
78
+ ARMCPU *cpu = ARM_CPU(obj);
79
+
80
+ if (value) {
81
+ if (kvm_enabled() && !kvm_arm_pmu_supported(CPU(cpu))) {
82
+ error_setg(errp, "'pmu' feature not supported by KVM on this host");
83
+ return;
84
+ }
85
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
86
+ } else {
87
+ unset_feature(&cpu->env, ARM_FEATURE_PMU);
88
+ }
89
+ cpu->has_pmu = value;
90
+}
91
+
92
static void arm_get_init_svtor(Object *obj, Visitor *v, const char *name,
93
void *opaque, Error **errp)
94
{
95
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
96
}
97
98
if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) {
99
- qdev_property_add_static(DEVICE(obj), &arm_cpu_has_pmu_property,
100
+ cpu->has_pmu = true;
101
+ object_property_add_bool(obj, "pmu", arm_get_pmu, arm_set_pmu,
102
&error_abort);
103
}
104
105
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/kvm.c
108
+++ b/target/arm/kvm.c
109
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
110
env->features = arm_host_cpu_features.features;
111
}
112
113
+bool kvm_arm_pmu_supported(CPUState *cpu)
114
+{
115
+ KVMState *s = KVM_STATE(current_machine->accelerator);
116
+
117
+ return kvm_check_extension(s, KVM_CAP_ARM_PMU_V3);
118
+}
119
+
120
int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
121
{
122
KVMState *s = KVM_STATE(ms->accelerator);
123
--
92
--
124
2.20.1
93
2.25.1
125
126
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Extract is a compact combination of shift + and.
3
Create an APU CPU Cluster. This is in preparation to add the RPU.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Message-id: 20190808202616.13782-2-richard.henderson@linaro.org
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
target/arm/translate.c | 9 +--------
10
include/hw/arm/xlnx-versal.h | 2 ++
11
1 file changed, 1 insertion(+), 8 deletions(-)
11
hw/arm/xlnx-versal.c | 9 ++++++++-
12
2 files changed, 10 insertions(+), 1 deletion(-)
12
13
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
16
--- a/include/hw/arm/xlnx-versal.h
16
+++ b/target/arm/translate.c
17
+++ b/include/hw/arm/xlnx-versal.h
17
@@ -XXX,XX +XXX,XX @@ static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
18
@@ -XXX,XX +XXX,XX @@
18
19
19
static void shifter_out_im(TCGv_i32 var, int shift)
20
#include "hw/sysbus.h"
21
#include "hw/arm/boot.h"
22
+#include "hw/cpu/cluster.h"
23
#include "hw/or-irq.h"
24
#include "hw/sd/sdhci.h"
25
#include "hw/intc/arm_gicv3.h"
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
27
struct {
28
struct {
29
MemoryRegion mr;
30
+ CPUClusterState cluster;
31
ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
32
GICv3State gic;
33
} apu;
34
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/xlnx-versal.c
37
+++ b/hw/arm/xlnx-versal.c
38
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
20
{
39
{
21
- if (shift == 0) {
40
int i;
22
- tcg_gen_andi_i32(cpu_CF, var, 1);
41
23
- } else {
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
24
- tcg_gen_shri_i32(cpu_CF, var, shift);
43
+ TYPE_CPU_CLUSTER);
25
- if (shift != 31) {
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
26
- tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
45
+
27
- }
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
28
- }
47
Object *obj;
29
+ tcg_gen_extract_i32(cpu_CF, var, shift, 1);
48
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
52
XLNX_VERSAL_ACPU_TYPE);
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
54
if (i) {
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
56
&error_abort);
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
58
}
59
+
60
+ qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
30
}
61
}
31
62
32
/* Shift by immediate. Includes special handling for shift == 0. */
63
static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
33
--
64
--
34
2.20.1
65
2.25.1
35
36
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Promote this function from aarch64 to fully general use.
3
Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit)
4
Use it to unify the code sequences for generating illegal
4
subsystem.
5
opcode exceptions.
6
5
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com
10
Message-id: 20190807045335.1361-11-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/translate-a64.h | 2 --
11
include/hw/arm/xlnx-versal.h | 10 ++++++++++
14
target/arm/translate.h | 2 ++
12
hw/arm/xlnx-versal-virt.c | 6 +++---
15
target/arm/translate-a64.c | 7 -------
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
16
target/arm/translate-vfp.inc.c | 3 +--
14
3 files changed, 49 insertions(+), 3 deletions(-)
17
target/arm/translate.c | 22 ++++++++++++----------
18
5 files changed, 15 insertions(+), 21 deletions(-)
19
15
20
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/translate-a64.h
18
--- a/include/hw/arm/xlnx-versal.h
23
+++ b/target/arm/translate-a64.h
19
+++ b/include/hw/arm/xlnx-versal.h
24
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
25
#ifndef TARGET_ARM_TRANSLATE_A64_H
21
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
26
#define TARGET_ARM_TRANSLATE_A64_H
22
27
23
#define XLNX_VERSAL_NR_ACPUS 2
28
-void unallocated_encoding(DisasContext *s);
24
+#define XLNX_VERSAL_NR_RCPUS 2
29
-
25
#define XLNX_VERSAL_NR_UARTS 2
30
#define unsupported_encoding(s, insn) \
26
#define XLNX_VERSAL_NR_GEMS 2
31
do { \
27
#define XLNX_VERSAL_NR_ADMAS 8
32
qemu_log_mask(LOG_UNIMP, \
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
33
diff --git a/target/arm/translate.h b/target/arm/translate.h
29
VersalUsb2 usb;
30
} iou;
31
32
+ /* Real-time Processing Unit. */
33
+ struct {
34
+ MemoryRegion mr;
35
+ MemoryRegion mr_ps_alias;
36
+
37
+ CPUClusterState cluster;
38
+ ARMCPU cpu[XLNX_VERSAL_NR_RCPUS];
39
+ } rpu;
40
+
41
struct {
42
qemu_or_irq irq_orgate;
43
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
44
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
34
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate.h
46
--- a/hw/arm/xlnx-versal-virt.c
36
+++ b/target/arm/translate.h
47
+++ b/hw/arm/xlnx-versal-virt.c
37
@@ -XXX,XX +XXX,XX @@ typedef struct DisasCompare {
48
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
38
bool value_global;
49
39
} DisasCompare;
50
mc->desc = "Xilinx Versal Virtual development board";
40
51
mc->init = versal_virt_init;
41
+void unallocated_encoding(DisasContext *s);
52
- mc->min_cpus = XLNX_VERSAL_NR_ACPUS;
42
+
53
- mc->max_cpus = XLNX_VERSAL_NR_ACPUS;
43
/* Share the TCG temporaries common between 32 and 64 bit modes. */
54
- mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
44
extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
55
+ mc->min_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
45
extern TCGv_i64 cpu_exclusive_addr;
56
+ mc->max_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
46
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
57
+ mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
58
mc->no_cdrom = true;
59
mc->default_ram_id = "ddr";
60
}
61
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
47
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate-a64.c
63
--- a/hw/arm/xlnx-versal.c
49
+++ b/target/arm/translate-a64.c
64
+++ b/hw/arm/xlnx-versal.c
50
@@ -XXX,XX +XXX,XX @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
65
@@ -XXX,XX +XXX,XX @@
66
#include "hw/sysbus.h"
67
68
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
69
+#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
70
#define GEM_REVISION 0x40070106
71
72
#define VERSAL_NUM_PMC_APB_IRQS 3
73
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
51
}
74
}
52
}
75
}
53
76
54
-void unallocated_encoding(DisasContext *s)
77
+static void versal_create_rpu_cpus(Versal *s)
55
-{
56
- /* Unallocated and reserved encodings are uncategorized */
57
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
58
- default_exception_el(s));
59
-}
60
-
61
static void init_tmp_a64_array(DisasContext *s)
62
{
63
#ifdef CONFIG_DEBUG_TCG
64
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate-vfp.inc.c
67
+++ b/target/arm/translate-vfp.inc.c
68
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
69
70
if (!s->vfp_enabled && !ignore_vfp_enabled) {
71
assert(!arm_dc_feature(s, ARM_FEATURE_M));
72
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
73
- default_exception_el(s));
74
+ unallocated_encoding(s);
75
return false;
76
}
77
78
diff --git a/target/arm/translate.c b/target/arm/translate.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/translate.c
81
+++ b/target/arm/translate.c
82
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
83
s->base.is_jmp = DISAS_NORETURN;
84
}
85
86
+void unallocated_encoding(DisasContext *s)
87
+{
78
+{
88
+ /* Unallocated and reserved encodings are uncategorized */
79
+ int i;
89
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
80
+
90
+ default_exception_el(s));
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
82
+ TYPE_CPU_CLUSTER);
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
84
+
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
86
+ Object *obj;
87
+
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
89
+ "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
90
+ XLNX_VERSAL_RCPU_TYPE);
91
+ obj = OBJECT(&s->lpd.rpu.cpu[i]);
92
+ object_property_set_bool(obj, "start-powered-off", true,
93
+ &error_abort);
94
+
95
+ object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
96
+ object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
97
+ &error_abort);
98
+ object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
99
+ &error_abort);
100
+ qdev_realize(DEVICE(obj), NULL, &error_fatal);
101
+ }
102
+
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
91
+}
104
+}
92
+
105
+
93
/* Force a TB lookup after an instruction that changes the CPU state. */
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
94
static inline void gen_lookup_tb(DisasContext *s)
95
{
107
{
96
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
108
int i;
97
return;
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
98
}
110
99
111
versal_create_apu_cpus(s);
100
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
112
versal_create_apu_gic(s, pic);
101
- default_exception_el(s));
113
+ versal_create_rpu_cpus(s);
102
+ unallocated_encoding(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);
103
}
123
}
104
124
105
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
125
static void versal_init(Object *obj)
106
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
107
}
127
Versal *s = XLNX_VERSAL(obj);
108
128
109
if (undef) {
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
110
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
111
- default_exception_el(s));
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
112
+ unallocated_encoding(s);
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
113
return;
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
117
break;
118
default:
119
illegal_op:
120
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
121
- default_exception_el(s));
122
+ unallocated_encoding(s);
123
break;
124
}
125
}
126
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
127
}
128
return;
129
illegal_op:
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
131
- default_exception_el(s));
132
+ unallocated_encoding(s);
133
}
134
}
134
135
135
static void disas_thumb_insn(DisasContext *s, uint32_t insn)
136
static Property versal_properties[] = {
136
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
137
return;
138
illegal_op:
139
undef:
140
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
141
- default_exception_el(s));
142
+ unallocated_encoding(s);
143
}
144
145
static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
146
--
137
--
147
2.20.1
138
2.25.1
148
149
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
The helper function is more documentary, and also already
3
Add a model of the Xilinx Versal CRL.
4
handles the case of rotate by zero.
5
4
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
7
Message-id: 20190808202616.13782-5-richard.henderson@linaro.org
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/translate.c | 7 ++-----
11
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++
12
1 file changed, 2 insertions(+), 5 deletions(-)
12
hw/misc/xlnx-versal-crl.c | 421 ++++++++++++++++++++++++++++++
13
hw/misc/meson.build | 1 +
14
3 files changed, 657 insertions(+)
15
create mode 100644 include/hw/misc/xlnx-versal-crl.h
16
create mode 100644 hw/misc/xlnx-versal-crl.c
13
17
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
19
new file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- /dev/null
22
+++ b/include/hw/misc/xlnx-versal-crl.h
23
@@ -XXX,XX +XXX,XX @@
24
+/*
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
26
+ *
27
+ * Copyright (c) 2022 Xilinx Inc.
28
+ * SPDX-License-Identifier: GPL-2.0-or-later
29
+ *
30
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
31
+ */
32
+#ifndef HW_MISC_XLNX_VERSAL_CRL_H
33
+#define HW_MISC_XLNX_VERSAL_CRL_H
34
+
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
+{
294
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
295
+ qemu_set_irq(s->irq, pending);
296
+}
297
+
298
+static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
299
+{
300
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
301
+ crl_update_irq(s);
302
+}
303
+
304
+static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
305
+{
306
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
307
+ uint32_t val = val64;
308
+
309
+ s->regs[R_IR_MASK] &= ~val;
310
+ crl_update_irq(s);
311
+ return 0;
312
+}
313
+
314
+static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
315
+{
316
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
317
+ uint32_t val = val64;
318
+
319
+ s->regs[R_IR_MASK] |= val;
320
+ crl_update_irq(s);
321
+ return 0;
322
+}
323
+
324
+static void crl_reset_dev(XlnxVersalCRL *s, DeviceState *dev,
325
+ bool rst_old, bool rst_new)
326
+{
327
+ device_cold_reset(dev);
328
+}
329
+
330
+static void crl_reset_cpu(XlnxVersalCRL *s, ARMCPU *armcpu,
331
+ bool rst_old, bool rst_new)
332
+{
333
+ if (rst_new) {
334
+ arm_set_cpu_off(armcpu->mp_affinity);
335
+ } else {
336
+ arm_set_cpu_on_and_reset(armcpu->mp_affinity);
337
+ }
338
+}
339
+
340
+#define REGFIELD_RESET(type, s, reg, f, new_val, dev) { \
341
+ bool old_f = ARRAY_FIELD_EX32((s)->regs, reg, f); \
342
+ bool new_f = FIELD_EX32(new_val, reg, f); \
343
+ \
344
+ /* Detect edges. */ \
345
+ if (dev && old_f != new_f) { \
346
+ crl_reset_ ## type(s, dev, old_f, new_f); \
347
+ } \
348
+}
349
+
350
+static uint64_t crl_rst_r5_prew(RegisterInfo *reg, uint64_t val64)
351
+{
352
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
353
+
354
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU0, val64, s->cfg.cpu_r5[0]);
355
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU1, val64, s->cfg.cpu_r5[1]);
356
+ return val64;
357
+}
358
+
359
+static uint64_t crl_rst_adma_prew(RegisterInfo *reg, uint64_t val64)
360
+{
361
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
362
+ int i;
363
+
364
+ /* A single register fans out to all ADMA reset inputs. */
365
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); i++) {
366
+ REGFIELD_RESET(dev, s, RST_ADMA, RESET, val64, s->cfg.adma[i]);
367
+ }
368
+ return val64;
369
+}
370
+
371
+static uint64_t crl_rst_uart0_prew(RegisterInfo *reg, uint64_t val64)
372
+{
373
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
374
+
375
+ REGFIELD_RESET(dev, s, RST_UART0, RESET, val64, s->cfg.uart[0]);
376
+ return val64;
377
+}
378
+
379
+static uint64_t crl_rst_uart1_prew(RegisterInfo *reg, uint64_t val64)
380
+{
381
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
382
+
383
+ REGFIELD_RESET(dev, s, RST_UART1, RESET, val64, s->cfg.uart[1]);
384
+ return val64;
385
+}
386
+
387
+static uint64_t crl_rst_gem0_prew(RegisterInfo *reg, uint64_t val64)
388
+{
389
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
390
+
391
+ REGFIELD_RESET(dev, s, RST_GEM0, RESET, val64, s->cfg.gem[0]);
392
+ return val64;
393
+}
394
+
395
+static uint64_t crl_rst_gem1_prew(RegisterInfo *reg, uint64_t val64)
396
+{
397
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
398
+
399
+ REGFIELD_RESET(dev, s, RST_GEM1, RESET, val64, s->cfg.gem[1]);
400
+ return val64;
401
+}
402
+
403
+static uint64_t crl_rst_usb_prew(RegisterInfo *reg, uint64_t val64)
404
+{
405
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
406
+
407
+ REGFIELD_RESET(dev, s, RST_USB0, RESET, val64, s->cfg.usb);
408
+ return val64;
409
+}
410
+
411
+static const RegisterAccessInfo crl_regs_info[] = {
412
+ { .name = "ERR_CTRL", .addr = A_ERR_CTRL,
413
+ },{ .name = "IR_STATUS", .addr = A_IR_STATUS,
414
+ .w1c = 0x1,
415
+ .post_write = crl_status_postw,
416
+ },{ .name = "IR_MASK", .addr = A_IR_MASK,
417
+ .reset = 0x1,
418
+ .ro = 0x1,
419
+ },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE,
420
+ .pre_write = crl_enable_prew,
421
+ },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE,
422
+ .pre_write = crl_disable_prew,
423
+ },{ .name = "WPROT", .addr = A_WPROT,
424
+ },{ .name = "PLL_CLK_OTHER_DMN", .addr = A_PLL_CLK_OTHER_DMN,
425
+ .reset = 0x1,
426
+ .rsvd = 0xe,
427
+ },{ .name = "RPLL_CTRL", .addr = A_RPLL_CTRL,
428
+ .reset = 0x24809,
429
+ .rsvd = 0xf88c00f6,
430
+ },{ .name = "RPLL_CFG", .addr = A_RPLL_CFG,
431
+ .reset = 0x2000000,
432
+ .rsvd = 0x1801210,
433
+ },{ .name = "RPLL_FRAC_CFG", .addr = A_RPLL_FRAC_CFG,
434
+ .rsvd = 0x7e330000,
435
+ },{ .name = "PLL_STATUS", .addr = A_PLL_STATUS,
436
+ .reset = R_PLL_STATUS_RPLL_STABLE_MASK |
437
+ R_PLL_STATUS_RPLL_LOCK_MASK,
438
+ .rsvd = 0xfa,
439
+ .ro = 0x5,
440
+ },{ .name = "RPLL_TO_XPD_CTRL", .addr = A_RPLL_TO_XPD_CTRL,
441
+ .reset = 0x2000100,
442
+ .rsvd = 0xfdfc00ff,
443
+ },{ .name = "LPD_TOP_SWITCH_CTRL", .addr = A_LPD_TOP_SWITCH_CTRL,
444
+ .reset = 0x6000300,
445
+ .rsvd = 0xf9fc00f8,
446
+ },{ .name = "LPD_LSBUS_CTRL", .addr = A_LPD_LSBUS_CTRL,
447
+ .reset = 0x2000800,
448
+ .rsvd = 0xfdfc00f8,
449
+ },{ .name = "CPU_R5_CTRL", .addr = A_CPU_R5_CTRL,
450
+ .reset = 0xe000300,
451
+ .rsvd = 0xe1fc00f8,
452
+ },{ .name = "IOU_SWITCH_CTRL", .addr = A_IOU_SWITCH_CTRL,
453
+ .reset = 0x2000500,
454
+ .rsvd = 0xfdfc00f8,
455
+ },{ .name = "GEM0_REF_CTRL", .addr = A_GEM0_REF_CTRL,
456
+ .reset = 0xe000a00,
457
+ .rsvd = 0xf1fc00f8,
458
+ },{ .name = "GEM1_REF_CTRL", .addr = A_GEM1_REF_CTRL,
459
+ .reset = 0xe000a00,
460
+ .rsvd = 0xf1fc00f8,
461
+ },{ .name = "GEM_TSU_REF_CTRL", .addr = A_GEM_TSU_REF_CTRL,
462
+ .reset = 0x300,
463
+ .rsvd = 0xfdfc00f8,
464
+ },{ .name = "USB0_BUS_REF_CTRL", .addr = A_USB0_BUS_REF_CTRL,
465
+ .reset = 0x2001900,
466
+ .rsvd = 0xfdfc00f8,
467
+ },{ .name = "UART0_REF_CTRL", .addr = A_UART0_REF_CTRL,
468
+ .reset = 0xc00,
469
+ .rsvd = 0xfdfc00f8,
470
+ },{ .name = "UART1_REF_CTRL", .addr = A_UART1_REF_CTRL,
471
+ .reset = 0xc00,
472
+ .rsvd = 0xfdfc00f8,
473
+ },{ .name = "SPI0_REF_CTRL", .addr = A_SPI0_REF_CTRL,
474
+ .reset = 0x600,
475
+ .rsvd = 0xfdfc00f8,
476
+ },{ .name = "SPI1_REF_CTRL", .addr = A_SPI1_REF_CTRL,
477
+ .reset = 0x600,
478
+ .rsvd = 0xfdfc00f8,
479
+ },{ .name = "CAN0_REF_CTRL", .addr = A_CAN0_REF_CTRL,
480
+ .reset = 0xc00,
481
+ .rsvd = 0xfdfc00f8,
482
+ },{ .name = "CAN1_REF_CTRL", .addr = A_CAN1_REF_CTRL,
483
+ .reset = 0xc00,
484
+ .rsvd = 0xfdfc00f8,
485
+ },{ .name = "I2C0_REF_CTRL", .addr = A_I2C0_REF_CTRL,
486
+ .reset = 0xc00,
487
+ .rsvd = 0xfdfc00f8,
488
+ },{ .name = "I2C1_REF_CTRL", .addr = A_I2C1_REF_CTRL,
489
+ .reset = 0xc00,
490
+ .rsvd = 0xfdfc00f8,
491
+ },{ .name = "DBG_LPD_CTRL", .addr = A_DBG_LPD_CTRL,
492
+ .reset = 0x300,
493
+ .rsvd = 0xfdfc00f8,
494
+ },{ .name = "TIMESTAMP_REF_CTRL", .addr = A_TIMESTAMP_REF_CTRL,
495
+ .reset = 0x2000c00,
496
+ .rsvd = 0xfdfc00f8,
497
+ },{ .name = "CRL_SAFETY_CHK", .addr = A_CRL_SAFETY_CHK,
498
+ },{ .name = "PSM_REF_CTRL", .addr = A_PSM_REF_CTRL,
499
+ .reset = 0xf04,
500
+ .rsvd = 0xfffc00f8,
501
+ },{ .name = "DBG_TSTMP_CTRL", .addr = A_DBG_TSTMP_CTRL,
502
+ .reset = 0x300,
503
+ .rsvd = 0xfdfc00f8,
504
+ },{ .name = "CPM_TOPSW_REF_CTRL", .addr = A_CPM_TOPSW_REF_CTRL,
505
+ .reset = 0x300,
506
+ .rsvd = 0xfdfc00f8,
507
+ },{ .name = "USB3_DUAL_REF_CTRL", .addr = A_USB3_DUAL_REF_CTRL,
508
+ .reset = 0x3c00,
509
+ .rsvd = 0xfdfc00f8,
510
+ },{ .name = "RST_CPU_R5", .addr = A_RST_CPU_R5,
511
+ .reset = 0x17,
512
+ .rsvd = 0x8,
513
+ .pre_write = crl_rst_r5_prew,
514
+ },{ .name = "RST_ADMA", .addr = A_RST_ADMA,
515
+ .reset = 0x1,
516
+ .pre_write = crl_rst_adma_prew,
517
+ },{ .name = "RST_GEM0", .addr = A_RST_GEM0,
518
+ .reset = 0x1,
519
+ .pre_write = crl_rst_gem0_prew,
520
+ },{ .name = "RST_GEM1", .addr = A_RST_GEM1,
521
+ .reset = 0x1,
522
+ .pre_write = crl_rst_gem1_prew,
523
+ },{ .name = "RST_SPARE", .addr = A_RST_SPARE,
524
+ .reset = 0x1,
525
+ },{ .name = "RST_USB0", .addr = A_RST_USB0,
526
+ .reset = 0x1,
527
+ .pre_write = crl_rst_usb_prew,
528
+ },{ .name = "RST_UART0", .addr = A_RST_UART0,
529
+ .reset = 0x1,
530
+ .pre_write = crl_rst_uart0_prew,
531
+ },{ .name = "RST_UART1", .addr = A_RST_UART1,
532
+ .reset = 0x1,
533
+ .pre_write = crl_rst_uart1_prew,
534
+ },{ .name = "RST_SPI0", .addr = A_RST_SPI0,
535
+ .reset = 0x1,
536
+ },{ .name = "RST_SPI1", .addr = A_RST_SPI1,
537
+ .reset = 0x1,
538
+ },{ .name = "RST_CAN0", .addr = A_RST_CAN0,
539
+ .reset = 0x1,
540
+ },{ .name = "RST_CAN1", .addr = A_RST_CAN1,
541
+ .reset = 0x1,
542
+ },{ .name = "RST_I2C0", .addr = A_RST_I2C0,
543
+ .reset = 0x1,
544
+ },{ .name = "RST_I2C1", .addr = A_RST_I2C1,
545
+ .reset = 0x1,
546
+ },{ .name = "RST_DBG_LPD", .addr = A_RST_DBG_LPD,
547
+ .reset = 0x33,
548
+ .rsvd = 0xcc,
549
+ },{ .name = "RST_GPIO", .addr = A_RST_GPIO,
550
+ .reset = 0x1,
551
+ },{ .name = "RST_TTC", .addr = A_RST_TTC,
552
+ .reset = 0xf,
553
+ },{ .name = "RST_TIMESTAMP", .addr = A_RST_TIMESTAMP,
554
+ .reset = 0x1,
555
+ },{ .name = "RST_SWDT", .addr = A_RST_SWDT,
556
+ .reset = 0x1,
557
+ },{ .name = "RST_OCM", .addr = A_RST_OCM,
558
+ },{ .name = "RST_IPI", .addr = A_RST_IPI,
559
+ },{ .name = "RST_FPD", .addr = A_RST_FPD,
560
+ .reset = 0x3,
561
+ },{ .name = "PSM_RST_MODE", .addr = A_PSM_RST_MODE,
562
+ .reset = 0x1,
563
+ .rsvd = 0xf8,
564
+ }
565
+};
566
+
567
+static void crl_reset_enter(Object *obj, ResetType type)
568
+{
569
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
570
+ unsigned int i;
571
+
572
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
573
+ register_reset(&s->regs_info[i]);
574
+ }
575
+}
576
+
577
+static void crl_reset_hold(Object *obj)
578
+{
579
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
580
+
581
+ crl_update_irq(s);
582
+}
583
+
584
+static const MemoryRegionOps crl_ops = {
585
+ .read = register_read_memory,
586
+ .write = register_write_memory,
587
+ .endianness = DEVICE_LITTLE_ENDIAN,
588
+ .valid = {
589
+ .min_access_size = 4,
590
+ .max_access_size = 4,
591
+ },
592
+};
593
+
594
+static void crl_init(Object *obj)
595
+{
596
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
597
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
598
+ int i;
599
+
600
+ s->reg_array =
601
+ register_init_block32(DEVICE(obj), crl_regs_info,
602
+ ARRAY_SIZE(crl_regs_info),
603
+ s->regs_info, s->regs,
604
+ &crl_ops,
605
+ XLNX_VERSAL_CRL_ERR_DEBUG,
606
+ CRL_R_MAX * 4);
607
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
608
+ sysbus_init_irq(sbd, &s->irq);
609
+
610
+ for (i = 0; i < ARRAY_SIZE(s->cfg.cpu_r5); ++i) {
611
+ object_property_add_link(obj, "cpu_r5[*]", TYPE_ARM_CPU,
612
+ (Object **)&s->cfg.cpu_r5[i],
613
+ qdev_prop_allow_set_link_before_realize,
614
+ OBJ_PROP_LINK_STRONG);
615
+ }
616
+
617
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); ++i) {
618
+ object_property_add_link(obj, "adma[*]", TYPE_DEVICE,
619
+ (Object **)&s->cfg.adma[i],
620
+ qdev_prop_allow_set_link_before_realize,
621
+ OBJ_PROP_LINK_STRONG);
622
+ }
623
+
624
+ for (i = 0; i < ARRAY_SIZE(s->cfg.uart); ++i) {
625
+ object_property_add_link(obj, "uart[*]", TYPE_DEVICE,
626
+ (Object **)&s->cfg.uart[i],
627
+ qdev_prop_allow_set_link_before_realize,
628
+ OBJ_PROP_LINK_STRONG);
629
+ }
630
+
631
+ for (i = 0; i < ARRAY_SIZE(s->cfg.gem); ++i) {
632
+ object_property_add_link(obj, "gem[*]", TYPE_DEVICE,
633
+ (Object **)&s->cfg.gem[i],
634
+ qdev_prop_allow_set_link_before_realize,
635
+ OBJ_PROP_LINK_STRONG);
636
+ }
637
+
638
+ object_property_add_link(obj, "usb", TYPE_DEVICE,
639
+ (Object **)&s->cfg.gem[i],
640
+ qdev_prop_allow_set_link_before_realize,
641
+ OBJ_PROP_LINK_STRONG);
642
+}
643
+
644
+static void crl_finalize(Object *obj)
645
+{
646
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
647
+ register_finalize_block(s->reg_array);
648
+}
649
+
650
+static const VMStateDescription vmstate_crl = {
651
+ .name = TYPE_XLNX_VERSAL_CRL,
652
+ .version_id = 1,
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
15
index XXXXXXX..XXXXXXX 100644
687
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
688
--- a/hw/misc/meson.build
17
+++ b/target/arm/translate.c
689
+++ b/hw/misc/meson.build
18
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
690
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
19
/* CPSR = immediate */
691
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
20
val = insn & 0xff;
692
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-crf.c'))
21
shift = ((insn >> 8) & 0xf) * 2;
693
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-apu-ctrl.c'))
22
- if (shift)
694
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
23
- val = (val >> shift) | (val << (32 - shift));
695
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
24
+ val = ror32(val, shift);
696
'xlnx-versal-xramc.c',
25
i = ((insn & (1 << 22)) != 0);
697
'xlnx-versal-pmc-iou-slcr.c',
26
if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
27
i, val)) {
28
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
29
/* immediate operand */
30
val = insn & 0xff;
31
shift = ((insn >> 8) & 0xf) * 2;
32
- if (shift) {
33
- val = (val >> shift) | (val << (32 - shift));
34
- }
35
+ val = ror32(val, shift);
36
tmp2 = tcg_temp_new_i32();
37
tcg_gen_movi_i32(tmp2, val);
38
if (logic_cc && shift) {
39
--
698
--
40
2.20.1
699
2.25.1
41
42
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
The offset is variable depending on the instruction set, whereas
3
Connect the CRL (Clock Reset LPD) to the Versal SoC.
4
we have stored values for the current pc and the next pc. Passing
5
in the actual value is clearer in intent.
6
4
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
10
Message-id: 20190807045335.1361-8-richard.henderson@linaro.org
8
Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/translate-a64.c | 25 ++++++++++++++-----------
11
include/hw/arm/xlnx-versal.h | 4 +++
14
target/arm/translate-vfp.inc.c | 6 +++---
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
15
target/arm/translate.c | 31 ++++++++++++++++---------------
13
2 files changed, 56 insertions(+), 2 deletions(-)
16
3 files changed, 33 insertions(+), 29 deletions(-)
17
14
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a64.c
17
--- a/include/hw/arm/xlnx-versal.h
21
+++ b/target/arm/translate-a64.c
18
+++ b/include/hw/arm/xlnx-versal.h
22
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
19
@@ -XXX,XX +XXX,XX @@
23
s->base.is_jmp = DISAS_NORETURN;
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]);
24
}
50
}
25
51
26
-static void gen_exception_insn(DisasContext *s, int offset, int excp,
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
27
+static void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
53
+{
28
uint32_t syndrome, uint32_t target_el)
54
+ SysBusDevice *sbd;
29
{
55
+ int i;
30
- gen_a64_set_pc_im(s->base.pc_next - offset);
56
+
31
+ gen_a64_set_pc_im(pc);
57
+ object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
32
gen_exception(excp, syndrome, target_el);
58
+ TYPE_XLNX_VERSAL_CRL);
33
s->base.is_jmp = DISAS_NORETURN;
59
+ sbd = SYS_BUS_DEVICE(&s->lpd.crl);
34
}
60
+
35
@@ -XXX,XX +XXX,XX @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
61
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
36
void unallocated_encoding(DisasContext *s)
62
+ g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
37
{
63
+
38
/* Unallocated and reserved encodings are uncategorized */
64
+ object_property_set_link(OBJECT(&s->lpd.crl),
39
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
65
+ name, OBJECT(&s->lpd.rpu.cpu[i]),
40
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
66
+ &error_abort);
41
default_exception_el(s));
67
+ }
42
}
68
+
43
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
44
@@ -XXX,XX +XXX,XX @@ static inline bool fp_access_check(DisasContext *s)
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
45
return true;
71
+
46
}
72
+ object_property_set_link(OBJECT(&s->lpd.crl),
47
73
+ name, OBJECT(&s->lpd.iou.gem[i]),
48
- gen_exception_insn(s, 4, EXCP_UDEF, syn_fp_access_trap(1, 0xe, false),
74
+ &error_abort);
49
- s->fp_excp_el);
75
+ }
50
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
76
+
51
+ syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
77
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
52
return false;
78
+ g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
53
}
79
+
54
80
+ object_property_set_link(OBJECT(&s->lpd.crl),
55
@@ -XXX,XX +XXX,XX @@ static inline bool fp_access_check(DisasContext *s)
81
+ name, OBJECT(&s->lpd.iou.adma[i]),
56
bool sve_access_check(DisasContext *s)
82
+ &error_abort);
57
{
83
+ }
58
if (s->sve_excp_el) {
84
+
59
- gen_exception_insn(s, 4, EXCP_UDEF, syn_sve_access_trap(),
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
60
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_sve_access_trap(),
86
+ g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
61
s->sve_excp_el);
87
+
62
return false;
88
+ object_property_set_link(OBJECT(&s->lpd.crl),
63
}
89
+ name, OBJECT(&s->lpd.iou.uart[i]),
64
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
90
+ &error_abort);
65
switch (op2_ll) {
91
+ }
66
case 1: /* SVC */
92
+
67
gen_ss_advance(s);
93
+ object_property_set_link(OBJECT(&s->lpd.crl),
68
- gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16),
94
+ "usb", OBJECT(&s->lpd.iou.usb),
69
- default_exception_el(s));
95
+ &error_abort);
70
+ gen_exception_insn(s, s->base.pc_next, EXCP_SWI,
96
+
71
+ syn_aa64_svc(imm16), default_exception_el(s));
97
+ sysbus_realize(sbd, &error_fatal);
72
break;
98
+ memory_region_add_subregion(&s->mr_ps, MM_CRL,
73
case 2: /* HVC */
99
+ sysbus_mmio_get_region(sbd, 0));
74
if (s->current_el == 0) {
100
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
75
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
101
+}
76
gen_a64_set_pc_im(s->pc_curr);
102
+
77
gen_helper_pre_hvc(cpu_env);
103
/* This takes the board allocated linear DDR memory and creates aliases
78
gen_ss_advance(s);
104
* for each split DDR range/aperture on the Versal address map.
79
- gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
105
*/
80
+ gen_exception_insn(s, s->base.pc_next, EXCP_HVC,
106
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
81
+ syn_aa64_hvc(imm16), 2);
107
82
break;
108
versal_unimp_area(s, "psm", &s->mr_ps,
83
case 3: /* SMC */
109
MM_PSM_START, MM_PSM_END - MM_PSM_START);
84
if (s->current_el == 0) {
110
- versal_unimp_area(s, "crl", &s->mr_ps,
85
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
111
- MM_CRL, MM_CRL_SIZE);
86
gen_helper_pre_smc(cpu_env, tmp);
112
versal_unimp_area(s, "crf", &s->mr_ps,
87
tcg_temp_free_i32(tmp);
113
MM_FPD_CRF, MM_FPD_CRF_SIZE);
88
gen_ss_advance(s);
114
versal_unimp_area(s, "apu", &s->mr_ps,
89
- gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_smc(imm16), 3);
115
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
90
+ gen_exception_insn(s, s->base.pc_next, EXCP_SMC,
116
versal_create_efuse(s, pic);
91
+ syn_aa64_smc(imm16), 3);
117
versal_create_pmc_iou_slcr(s, pic);
92
break;
118
versal_create_ospi(s, pic);
93
default:
119
+ versal_create_crl(s, pic);
94
unallocated_encoding(s);
120
versal_map_ddr(s);
95
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
121
versal_unimp(s);
96
if (s->btype != 0
97
&& s->guarded_page
98
&& !btype_destination_ok(insn, s->bt, s->btype)) {
99
- gen_exception_insn(s, 4, EXCP_UDEF, syn_btitrap(s->btype),
100
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
101
+ syn_btitrap(s->btype),
102
default_exception_el(s));
103
return;
104
}
105
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/translate-vfp.inc.c
108
+++ b/target/arm/translate-vfp.inc.c
109
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
110
{
111
if (s->fp_excp_el) {
112
if (arm_dc_feature(s, ARM_FEATURE_M)) {
113
- gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
114
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
115
s->fp_excp_el);
116
} else {
117
- gen_exception_insn(s, 4, EXCP_UDEF,
118
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
119
syn_fp_access_trap(1, 0xe, false),
120
s->fp_excp_el);
121
}
122
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
123
124
if (!s->vfp_enabled && !ignore_vfp_enabled) {
125
assert(!arm_dc_feature(s, ARM_FEATURE_M));
126
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
127
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
128
default_exception_el(s));
129
return false;
130
}
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/translate.c
134
+++ b/target/arm/translate.c
135
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
136
s->base.is_jmp = DISAS_NORETURN;
137
}
138
139
-static void gen_exception_insn(DisasContext *s, int offset, int excp,
140
+static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
141
int syn, uint32_t target_el)
142
{
143
gen_set_condexec(s);
144
- gen_set_pc_im(s, s->base.pc_next - offset);
145
+ gen_set_pc_im(s, pc);
146
gen_exception(excp, syn, target_el);
147
s->base.is_jmp = DISAS_NORETURN;
148
}
149
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
150
return;
151
}
152
153
- gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
154
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
155
default_exception_el(s));
156
}
157
158
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
159
160
undef:
161
/* If we get here then some access check did not pass */
162
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
163
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
164
+ syn_uncategorized(), exc_target);
165
return false;
166
}
167
168
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
169
* for attempts to execute invalid vfp/neon encodings with FP disabled.
170
*/
171
if (s->fp_excp_el) {
172
- gen_exception_insn(s, 4, EXCP_UDEF,
173
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
174
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
175
return 0;
176
}
177
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
178
* for attempts to execute invalid vfp/neon encodings with FP disabled.
179
*/
180
if (s->fp_excp_el) {
181
- gen_exception_insn(s, 4, EXCP_UDEF,
182
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
183
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
184
return 0;
185
}
186
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
187
}
188
189
if (s->fp_excp_el) {
190
- gen_exception_insn(s, 4, EXCP_UDEF,
191
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
192
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
193
return 0;
194
}
195
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
196
off_rm = vfp_reg_offset(0, rm);
197
}
198
if (s->fp_excp_el) {
199
- gen_exception_insn(s, 4, EXCP_UDEF,
200
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
201
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
202
return 0;
203
}
204
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
205
* For the UNPREDICTABLE cases we choose to UNDEF.
206
*/
207
if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
208
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
209
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
210
return;
211
}
212
213
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
214
}
215
216
if (undef) {
217
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
218
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
219
default_exception_el(s));
220
return;
221
}
222
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
223
* UsageFault exception.
224
*/
225
if (arm_dc_feature(s, ARM_FEATURE_M)) {
226
- gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
227
+ gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
228
default_exception_el(s));
229
return;
230
}
231
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
232
break;
233
default:
234
illegal_op:
235
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
236
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
237
default_exception_el(s));
238
break;
239
}
240
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
241
}
242
243
/* All other insns: NOCP */
244
- gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
245
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
246
default_exception_el(s));
247
break;
248
}
249
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
250
}
251
return;
252
illegal_op:
253
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
254
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
255
default_exception_el(s));
256
}
257
258
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
259
return;
260
illegal_op:
261
undef:
262
- gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
263
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
264
default_exception_el(s));
265
}
266
122
267
--
123
--
268
2.20.1
124
2.25.1
269
270
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
The Exynos4210 SoC device currently uses a custom device
2
"exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ
3
line. We have a standard TYPE_OR_IRQ device for this now, so use
4
that instead.
2
5
3
A couple return -EINVAL's forgot their '-'s.
6
(This is a migration compatibility break, but that is OK for this
7
machine type.)
4
8
5
Signed-off-by: Andrew Jones <drjones@redhat.com>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20220404154658.565020-2-peter.maydell@linaro.org
9
---
12
---
10
target/arm/kvm64.c | 4 ++--
13
include/hw/arm/exynos4210.h | 1 +
11
1 file changed, 2 insertions(+), 2 deletions(-)
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
15
2 files changed, 17 insertions(+), 15 deletions(-)
12
16
13
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/kvm64.c
19
--- a/include/hw/arm/exynos4210.h
16
+++ b/target/arm/kvm64.c
20
+++ b/include/hw/arm/exynos4210.h
17
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
21
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
18
write_cpustate_to_list(cpu, true);
22
MemoryRegion bootreg_mem;
19
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
20
if (!write_list_to_kvmstate(cpu, level)) {
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
21
- return EINVAL;
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
22
+ return -EINVAL;
26
};
27
28
#define TYPE_EXYNOS4210_SOC "exynos4210"
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
{
35
Exynos4210State *s = EXYNOS4210_SOC(socdev);
36
MemoryRegion *system_mem = get_system_memory();
37
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
38
SysBusDevice *busdev;
39
DeviceState *dev, *uart[4], *pl330[3];
40
int i, n;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
42
43
/* IRQ Gate */
44
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
45
- dev = qdev_new("exynos4210.irq_gate");
46
- qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
47
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
48
- /* Get IRQ Gate input in gate_irq */
49
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
50
- gate_irq[i][n] = qdev_get_gpio_in(dev, n);
51
- }
52
- busdev = SYS_BUS_DEVICE(dev);
53
-
54
- /* Connect IRQ Gate output to CPU's IRQ line */
55
- sysbus_connect_irq(busdev, 0,
56
- qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
57
+ DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
58
+ object_property_set_int(OBJECT(orgate), "num-lines",
59
+ EXYNOS4210_IRQ_GATE_NINPUTS,
60
+ &error_abort);
61
+ qdev_realize(orgate, NULL, &error_abort);
62
+ qdev_connect_gpio_out(orgate, 0,
63
+ qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
23
}
64
}
24
65
25
kvm_arm_sync_mpstate_to_kvm(cpu);
66
/* Private memory region and Internal GIC */
26
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
67
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
68
sysbus_realize_and_unref(busdev, &error_fatal);
69
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
70
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
71
- sysbus_connect_irq(busdev, n, gate_irq[n][0]);
72
+ sysbus_connect_irq(busdev, n,
73
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
27
}
74
}
28
75
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
29
if (!write_kvmstate_to_list(cpu)) {
76
s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
30
- return EINVAL;
77
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
31
+ return -EINVAL;
78
/* Map Distributer interface */
79
sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
80
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
81
- sysbus_connect_irq(busdev, n, gate_irq[n][1]);
82
+ sysbus_connect_irq(busdev, n,
83
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
32
}
84
}
33
/* Note that it's OK to have registers which aren't in CPUState,
85
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
34
* so we can ignore a failure return here.
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)
35
--
99
--
36
2.20.1
100
2.25.1
37
38
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
Now we have removed the only use of TYPE_EXYNOS4210_IRQ_GATE we can
2
delete the device entirely.
2
3
3
If -cpu <cpu>,aarch64=off is used then KVM must also be used, and it
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
and the host must support running the vcpu in 32-bit mode. Also, if
5
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
-cpu <cpu>,aarch64=on is used, then it doesn't matter if kvm is
6
Message-id: 20220404154658.565020-3-peter.maydell@linaro.org
6
enabled or not.
7
---
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
9
1 file changed, 107 deletions(-)
7
10
8
Signed-off-by: Andrew Jones <drjones@redhat.com>
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/kvm_arm.h | 14 ++++++++++++++
13
target/arm/cpu64.c | 12 ++++++------
14
target/arm/kvm64.c | 9 +++++++++
15
3 files changed, 29 insertions(+), 6 deletions(-)
16
17
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/kvm_arm.h
13
--- a/hw/intc/exynos4210_gic.c
20
+++ b/target/arm/kvm_arm.h
14
+++ b/hw/intc/exynos4210_gic.c
21
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
22
*/
23
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
24
25
+/**
26
+ * kvm_arm_aarch32_supported:
27
+ * @cs: CPUState
28
+ *
29
+ * Returns: true if the KVM VCPU can enable AArch32 mode
30
+ * and false otherwise.
31
+ */
32
+bool kvm_arm_aarch32_supported(CPUState *cs);
33
+
34
/**
35
* kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the
36
* IPA address space supported by KVM
37
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
38
cpu->host_cpu_probe_failed = true;
39
}
16
}
40
17
41
+static inline bool kvm_arm_aarch32_supported(CPUState *cs)
18
type_init(exynos4210_gic_register_types)
42
+{
19
-
43
+ return false;
20
-/* IRQ OR Gate struct.
44
+}
21
- *
45
+
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
46
static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
47
{
24
- * gpio inputs.
48
return -ENOENT;
25
- */
49
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
26
-
50
index XXXXXXX..XXXXXXX 100644
27
-#define TYPE_EXYNOS4210_IRQ_GATE "exynos4210.irq_gate"
51
--- a/target/arm/cpu64.c
28
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210IRQGateState, EXYNOS4210_IRQ_GATE)
52
+++ b/target/arm/cpu64.c
29
-
53
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
30
-struct Exynos4210IRQGateState {
54
* restriction allows us to avoid fixing up functionality that assumes a
31
- SysBusDevice parent_obj;
55
* uniform execution state like do_interrupt.
32
-
56
*/
33
- uint32_t n_in; /* inputs amount */
57
- if (!kvm_enabled()) {
34
- uint32_t *level; /* input levels */
58
- error_setg(errp, "'aarch64' feature cannot be disabled "
35
- qemu_irq out; /* output IRQ */
59
- "unless KVM is enabled");
36
-};
60
- return;
37
-
38
-static Property exynos4210_irq_gate_properties[] = {
39
- DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
40
- DEFINE_PROP_END_OF_LIST(),
41
-};
42
-
43
-static const VMStateDescription vmstate_exynos4210_irq_gate = {
44
- .name = "exynos4210.irq_gate",
45
- .version_id = 2,
46
- .minimum_version_id = 2,
47
- .fields = (VMStateField[]) {
48
- VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, n_in),
49
- VMSTATE_END_OF_LIST()
50
- }
51
-};
52
-
53
-/* Process a change in IRQ input. */
54
-static void exynos4210_irq_gate_handler(void *opaque, int irq, int level)
55
-{
56
- Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)opaque;
57
- uint32_t i;
58
-
59
- assert(irq < s->n_in);
60
-
61
- s->level[irq] = level;
62
-
63
- for (i = 0; i < s->n_in; i++) {
64
- if (s->level[i] >= 1) {
65
- qemu_irq_raise(s->out);
66
- return;
67
- }
61
- }
68
- }
62
-
69
-
63
if (value == false) {
70
- qemu_irq_lower(s->out);
64
+ if (!kvm_enabled() || !kvm_arm_aarch32_supported(CPU(cpu))) {
71
-}
65
+ error_setg(errp, "'aarch64' feature cannot be disabled "
72
-
66
+ "unless KVM is enabled and 32-bit EL1 "
73
-static void exynos4210_irq_gate_reset(DeviceState *d)
67
+ "is supported");
74
-{
68
+ return;
75
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(d);
69
+ }
76
-
70
unset_feature(&cpu->env, ARM_FEATURE_AARCH64);
77
- memset(s->level, 0, s->n_in * sizeof(*s->level));
71
} else {
78
-}
72
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
79
-
73
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
80
-/*
74
index XXXXXXX..XXXXXXX 100644
81
- * IRQ Gate initialization.
75
--- a/target/arm/kvm64.c
82
- */
76
+++ b/target/arm/kvm64.c
83
-static void exynos4210_irq_gate_init(Object *obj)
77
@@ -XXX,XX +XXX,XX @@
84
-{
78
#include "exec/gdbstub.h"
85
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(obj);
79
#include "sysemu/sysemu.h"
86
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
80
#include "sysemu/kvm.h"
87
-
81
+#include "sysemu/kvm_int.h"
88
- sysbus_init_irq(sbd, &s->out);
82
#include "kvm_arm.h"
89
-}
83
+#include "hw/boards.h"
90
-
84
#include "internals.h"
91
-static void exynos4210_irq_gate_realize(DeviceState *dev, Error **errp)
85
92
-{
86
static bool have_guest_debug;
93
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(dev);
87
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
94
-
88
return true;
95
- /* Allocate general purpose input signals and connect a handler to each of
89
}
96
- * them */
90
97
- qdev_init_gpio_in(dev, exynos4210_irq_gate_handler, s->n_in);
91
+bool kvm_arm_aarch32_supported(CPUState *cpu)
98
-
92
+{
99
- s->level = g_malloc0(s->n_in * sizeof(*s->level));
93
+ KVMState *s = KVM_STATE(current_machine->accelerator);
100
-}
94
+
101
-
95
+ return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT);
102
-static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
96
+}
103
-{
97
+
104
- DeviceClass *dc = DEVICE_CLASS(klass);
98
#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
105
-
99
106
- dc->reset = exynos4210_irq_gate_reset;
100
int kvm_arch_init_vcpu(CPUState *cs)
107
- dc->vmsd = &vmstate_exynos4210_irq_gate;
108
- device_class_set_props(dc, exynos4210_irq_gate_properties);
109
- dc->realize = exynos4210_irq_gate_realize;
110
-}
111
-
112
-static const TypeInfo exynos4210_irq_gate_info = {
113
- .name = TYPE_EXYNOS4210_IRQ_GATE,
114
- .parent = TYPE_SYS_BUS_DEVICE,
115
- .instance_size = sizeof(Exynos4210IRQGateState),
116
- .instance_init = exynos4210_irq_gate_init,
117
- .class_init = exynos4210_irq_gate_class_init,
118
-};
119
-
120
-static void exynos4210_irq_gate_register_types(void)
121
-{
122
- type_register_static(&exynos4210_irq_gate_info);
123
-}
124
-
125
-type_init(exynos4210_irq_gate_register_types)
101
--
126
--
102
2.20.1
127
2.25.1
103
104
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The exynos4210 SoC mostly creates its child devices as if it were
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.
2
6
3
Provide a common routine for the places that require ALIGN(PC, 4)
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
as the base address as opposed to plain PC. The two are always
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
the same for A32, but the difference is meaningful for thumb mode.
9
Message-id: 20220404154658.565020-4-peter.maydell@linaro.org
10
---
11
include/hw/arm/exynos4210.h | 2 ++
12
hw/arm/exynos4210.c | 11 ++++++-----
13
2 files changed, 8 insertions(+), 5 deletions(-)
6
14
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20190807045335.1361-5-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate-vfp.inc.c | 38 ++------
14
target/arm/translate.c | 166 +++++++++++++++------------------
15
2 files changed, 82 insertions(+), 122 deletions(-)
16
17
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-vfp.inc.c
17
--- a/include/hw/arm/exynos4210.h
20
+++ b/target/arm/translate-vfp.inc.c
18
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
19
@@ -XXX,XX +XXX,XX @@
22
offset = -offset;
20
21
#include "hw/or-irq.h"
22
#include "hw/sysbus.h"
23
+#include "hw/cpu/a9mpcore.h"
24
#include "target/arm/cpu-qom.h"
25
#include "qom/object.h"
26
27
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
28
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
29
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
30
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
31
+ A9MPPrivState a9mpcore;
32
};
33
34
#define TYPE_EXYNOS4210_SOC "exynos4210"
35
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/arm/exynos4210.c
38
+++ b/hw/arm/exynos4210.c
39
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
23
}
40
}
24
41
25
- if (s->thumb && a->rn == 15) {
42
/* Private memory region and Internal GIC */
26
- /* This is actually UNPREDICTABLE */
43
- dev = qdev_new(TYPE_A9MPCORE_PRIV);
27
- addr = tcg_temp_new_i32();
44
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
28
- tcg_gen_movi_i32(addr, s->pc & ~2);
45
- busdev = SYS_BUS_DEVICE(dev);
29
- } else {
46
- sysbus_realize_and_unref(busdev, &error_fatal);
30
- addr = load_reg(s, a->rn);
47
+ qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
31
- }
48
+ busdev = SYS_BUS_DEVICE(&s->a9mpcore);
32
- tcg_gen_addi_i32(addr, addr, offset);
49
+ sysbus_realize(busdev, &error_fatal);
33
+ /* For thumb, use of PC is UNPREDICTABLE. */
50
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
34
+ addr = add_reg_for_lit(s, a->rn, offset);
51
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
35
tmp = tcg_temp_new_i32();
52
sysbus_connect_irq(busdev, n,
36
if (a->l) {
53
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
37
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
39
offset = -offset;
40
}
54
}
41
55
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
42
- if (s->thumb && a->rn == 15) {
56
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
43
- /* This is actually UNPREDICTABLE */
57
+ s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
44
- addr = tcg_temp_new_i32();
45
- tcg_gen_movi_i32(addr, s->pc & ~2);
46
- } else {
47
- addr = load_reg(s, a->rn);
48
- }
49
- tcg_gen_addi_i32(addr, addr, offset);
50
+ /* For thumb, use of PC is UNPREDICTABLE. */
51
+ addr = add_reg_for_lit(s, a->rn, offset);
52
tmp = tcg_temp_new_i64();
53
if (a->l) {
54
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
56
return true;
57
}
58
}
58
59
59
- if (s->thumb && a->rn == 15) {
60
/* Cache controller */
60
- /* This is actually UNPREDICTABLE */
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
61
- addr = tcg_temp_new_i32();
62
g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
62
- tcg_gen_movi_i32(addr, s->pc & ~2);
63
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
63
- } else {
64
- addr = load_reg(s, a->rn);
65
- }
66
+ /* For thumb, use of PC is UNPREDICTABLE. */
67
+ addr = add_reg_for_lit(s, a->rn, 0);
68
if (a->p) {
69
/* pre-decrement */
70
tcg_gen_addi_i32(addr, addr, -(a->imm << 2));
71
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
72
return true;
73
}
64
}
74
65
+
75
- if (s->thumb && a->rn == 15) {
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
76
- /* This is actually UNPREDICTABLE */
77
- addr = tcg_temp_new_i32();
78
- tcg_gen_movi_i32(addr, s->pc & ~2);
79
- } else {
80
- addr = load_reg(s, a->rn);
81
- }
82
+ /* For thumb, use of PC is UNPREDICTABLE. */
83
+ addr = add_reg_for_lit(s, a->rn, 0);
84
if (a->p) {
85
/* pre-decrement */
86
tcg_gen_addi_i32(addr, addr, -(a->imm << 2));
87
diff --git a/target/arm/translate.c b/target/arm/translate.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/translate.c
90
+++ b/target/arm/translate.c
91
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg)
92
return tmp;
93
}
67
}
94
68
95
+/*
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
96
+ * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
97
+ * This is used for load/store for which use of PC implies (literal),
98
+ * or ADD that implies ADR.
99
+ */
100
+static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
101
+{
102
+ TCGv_i32 tmp = tcg_temp_new_i32();
103
+
104
+ if (reg == 15) {
105
+ tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
106
+ } else {
107
+ tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
108
+ }
109
+ return tmp;
110
+}
111
+
112
/* Set a CPU register. The source must be a temporary and will be
113
marked as dead. */
114
static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
115
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
116
*/
117
bool wback = extract32(insn, 21, 1);
118
119
- if (rn == 15) {
120
- if (insn & (1 << 21)) {
121
- /* UNPREDICTABLE */
122
- goto illegal_op;
123
- }
124
- addr = tcg_temp_new_i32();
125
- tcg_gen_movi_i32(addr, s->pc & ~3);
126
- } else {
127
- addr = load_reg(s, rn);
128
+ if (rn == 15 && (insn & (1 << 21))) {
129
+ /* UNPREDICTABLE */
130
+ goto illegal_op;
131
}
132
+
133
+ addr = add_reg_for_lit(s, rn, 0);
134
offset = (insn & 0xff) * 4;
135
if ((insn & (1 << 23)) == 0) {
136
offset = -offset;
137
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
138
store_reg(s, rd, tmp);
139
} else {
140
/* Add/sub 12-bit immediate. */
141
- if (rn == 15) {
142
- offset = s->pc & ~(uint32_t)3;
143
- if (insn & (1 << 23))
144
- offset -= imm;
145
- else
146
- offset += imm;
147
- tmp = tcg_temp_new_i32();
148
- tcg_gen_movi_i32(tmp, offset);
149
- store_reg(s, rd, tmp);
150
+ if (insn & (1 << 23)) {
151
+ imm = -imm;
152
+ }
153
+ tmp = add_reg_for_lit(s, rn, imm);
154
+ if (rn == 13 && rd == 13) {
155
+ /* ADD SP, SP, imm or SUB SP, SP, imm */
156
+ store_sp_checked(s, tmp);
157
} else {
158
- tmp = load_reg(s, rn);
159
- if (insn & (1 << 23))
160
- tcg_gen_subi_i32(tmp, tmp, imm);
161
- else
162
- tcg_gen_addi_i32(tmp, tmp, imm);
163
- if (rn == 13 && rd == 13) {
164
- /* ADD SP, SP, imm or SUB SP, SP, imm */
165
- store_sp_checked(s, tmp);
166
- } else {
167
- store_reg(s, rd, tmp);
168
- }
169
+ store_reg(s, rd, tmp);
170
}
171
}
172
}
173
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
174
}
175
}
176
memidx = get_mem_index(s);
177
- if (rn == 15) {
178
- addr = tcg_temp_new_i32();
179
- /* PC relative. */
180
- /* s->pc has already been incremented by 4. */
181
- imm = s->pc & 0xfffffffc;
182
- if (insn & (1 << 23))
183
- imm += insn & 0xfff;
184
- else
185
- imm -= insn & 0xfff;
186
- tcg_gen_movi_i32(addr, imm);
187
+ imm = insn & 0xfff;
188
+ if (insn & (1 << 23)) {
189
+ /* PC relative or Positive offset. */
190
+ addr = add_reg_for_lit(s, rn, imm);
191
+ } else if (rn == 15) {
192
+ /* PC relative with negative offset. */
193
+ addr = add_reg_for_lit(s, rn, -imm);
194
} else {
195
addr = load_reg(s, rn);
196
- if (insn & (1 << 23)) {
197
- /* Positive offset. */
198
- imm = insn & 0xfff;
199
- tcg_gen_addi_i32(addr, addr, imm);
200
- } else {
201
- imm = insn & 0xff;
202
- switch ((insn >> 8) & 0xf) {
203
- case 0x0: /* Shifted Register. */
204
- shift = (insn >> 4) & 0xf;
205
- if (shift > 3) {
206
- tcg_temp_free_i32(addr);
207
- goto illegal_op;
208
- }
209
- tmp = load_reg(s, rm);
210
- if (shift)
211
- tcg_gen_shli_i32(tmp, tmp, shift);
212
- tcg_gen_add_i32(addr, addr, tmp);
213
- tcg_temp_free_i32(tmp);
214
- break;
215
- case 0xc: /* Negative offset. */
216
- tcg_gen_addi_i32(addr, addr, -imm);
217
- break;
218
- case 0xe: /* User privilege. */
219
- tcg_gen_addi_i32(addr, addr, imm);
220
- memidx = get_a32_user_mem_index(s);
221
- break;
222
- case 0x9: /* Post-decrement. */
223
- imm = -imm;
224
- /* Fall through. */
225
- case 0xb: /* Post-increment. */
226
- postinc = 1;
227
- writeback = 1;
228
- break;
229
- case 0xd: /* Pre-decrement. */
230
- imm = -imm;
231
- /* Fall through. */
232
- case 0xf: /* Pre-increment. */
233
- writeback = 1;
234
- break;
235
- default:
236
+ imm = insn & 0xff;
237
+ switch ((insn >> 8) & 0xf) {
238
+ case 0x0: /* Shifted Register. */
239
+ shift = (insn >> 4) & 0xf;
240
+ if (shift > 3) {
241
tcg_temp_free_i32(addr);
242
goto illegal_op;
243
}
244
+ tmp = load_reg(s, rm);
245
+ if (shift) {
246
+ tcg_gen_shli_i32(tmp, tmp, shift);
247
+ }
248
+ tcg_gen_add_i32(addr, addr, tmp);
249
+ tcg_temp_free_i32(tmp);
250
+ break;
251
+ case 0xc: /* Negative offset. */
252
+ tcg_gen_addi_i32(addr, addr, -imm);
253
+ break;
254
+ case 0xe: /* User privilege. */
255
+ tcg_gen_addi_i32(addr, addr, imm);
256
+ memidx = get_a32_user_mem_index(s);
257
+ break;
258
+ case 0x9: /* Post-decrement. */
259
+ imm = -imm;
260
+ /* Fall through. */
261
+ case 0xb: /* Post-increment. */
262
+ postinc = 1;
263
+ writeback = 1;
264
+ break;
265
+ case 0xd: /* Pre-decrement. */
266
+ imm = -imm;
267
+ /* Fall through. */
268
+ case 0xf: /* Pre-increment. */
269
+ writeback = 1;
270
+ break;
271
+ default:
272
+ tcg_temp_free_i32(addr);
273
+ goto illegal_op;
274
}
275
}
276
277
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
278
if (insn & (1 << 11)) {
279
rd = (insn >> 8) & 7;
280
/* load pc-relative. Bit 1 of PC is ignored. */
281
- val = read_pc(s) + ((insn & 0xff) * 4);
282
- val &= ~(uint32_t)2;
283
- addr = tcg_temp_new_i32();
284
- tcg_gen_movi_i32(addr, val);
285
+ addr = add_reg_for_lit(s, 15, (insn & 0xff) * 4);
286
tmp = tcg_temp_new_i32();
287
gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
288
rd | ISSIs16Bit);
289
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
290
* - Add PC/SP (immediate)
291
*/
292
rd = (insn >> 8) & 7;
293
- if (insn & (1 << 11)) {
294
- /* SP */
295
- tmp = load_reg(s, 13);
296
- } else {
297
- /* PC. bit 1 is ignored. */
298
- tmp = tcg_temp_new_i32();
299
- tcg_gen_movi_i32(tmp, read_pc(s) & ~(uint32_t)2);
300
- }
301
val = (insn & 0xff) * 4;
302
- tcg_gen_addi_i32(tmp, tmp, val);
303
+ tmp = add_reg_for_lit(s, insn & (1 << 11) ? 13 : 15, val);
304
store_reg(s, rd, tmp);
305
break;
306
307
--
70
--
308
2.20.1
71
2.25.1
309
310
diff view generated by jsdifflib
New 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.
1
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-5-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 -
14
hw/arm/exynos4210.c | 6 ++----
15
2 files changed, 2 insertions(+), 5 deletions(-)
16
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@
22
typedef struct Exynos4210Irq {
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
25
- qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
26
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
27
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
28
} Exynos4210Irq;
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
sysbus_connect_irq(busdev, n,
35
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
36
}
37
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
38
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
39
- }
40
41
/* Cache controller */
42
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
43
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
44
busdev = SYS_BUS_DEVICE(dev);
45
sysbus_realize_and_unref(busdev, &error_fatal);
46
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
47
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
48
+ sysbus_connect_irq(busdev, n,
49
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
50
}
51
exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
52
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
53
--
54
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The exynos4210 code currently has two very similar arrays of IRQs:
2
2
3
We must update s->base.pc_next when we return from the translate_insn
3
* board_irqs is a field of the Exynos4210Irq struct which is filled
4
hook to the main translator loop. By incrementing s->base.pc_next
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
5
immediately after reading the insn word, "pc_next" contains the address
5
for each IRQ the board/SoC can assert
6
of the next instruction throughout translation.
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
7
10
8
All remaining uses of s->pc are referencing the address of the next insn,
11
The extra indirection through irq_table is unnecessary, so coalesce
9
so this is now a simple global replacement. Remove the "s->pc" field.
12
these into a single irq_table[] array as a direct field in
13
Exynos4210State which exynos4210_init_board_irqs() fills in.
10
14
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Message-id: 20190807045335.1361-7-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20220404154658.565020-6-peter.maydell@linaro.org
16
---
18
---
17
target/arm/translate.h | 1 -
19
include/hw/arm/exynos4210.h | 8 ++------
18
target/arm/translate-a64.c | 51 +++++++++---------
20
hw/arm/exynos4210.c | 6 +-----
19
target/arm/translate.c | 103 ++++++++++++++++++-------------------
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
20
3 files changed, 72 insertions(+), 83 deletions(-)
22
3 files changed, 11 insertions(+), 35 deletions(-)
21
23
22
diff --git a/target/arm/translate.h b/target/arm/translate.h
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
23
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate.h
26
--- a/include/hw/arm/exynos4210.h
25
+++ b/target/arm/translate.h
27
+++ b/include/hw/arm/exynos4210.h
26
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
27
DisasContextBase base;
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
28
const ARMISARegisters *isar;
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
29
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
30
- target_ulong pc;
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
31
/* The address of the current instruction being translated. */
33
} Exynos4210Irq;
32
target_ulong pc_curr;
34
33
target_ulong page_start;
35
struct Exynos4210State {
34
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
36
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
37
/*< public >*/
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
39
Exynos4210Irq irqs;
40
- qemu_irq *irq_table;
41
+ qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
42
43
MemoryRegion chipid_mem;
44
MemoryRegion iram_mem;
45
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
46
void exynos4210_write_secondary(ARMCPU *cpu,
47
const struct arm_boot_info *info);
48
49
-/* Initialize exynos4210 IRQ subsystem stub */
50
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
51
-
52
/* Initialize board IRQs.
53
* These IRQs contain splitted Int/External Combiner and External Gic IRQs */
54
-void exynos4210_init_board_irqs(Exynos4210Irq *s);
55
+void exynos4210_init_board_irqs(Exynos4210State *s);
56
57
/* Get IRQ number from exynos4210 IRQ subsystem stub.
58
* To identify IRQ source use internal combiner group and bit number
59
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
35
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-a64.c
61
--- a/hw/arm/exynos4210.c
37
+++ b/target/arm/translate-a64.c
62
+++ b/hw/arm/exynos4210.c
38
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal(int excp)
63
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
39
64
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
40
static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
65
}
66
67
- /*** IRQs ***/
68
-
69
- s->irq_table = exynos4210_init_irq(&s->irqs);
70
-
71
/* IRQ Gate */
72
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
73
DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
74
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
75
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
76
77
/* Initialize board IRQs. */
78
- exynos4210_init_board_irqs(&s->irqs);
79
+ exynos4210_init_board_irqs(s);
80
81
/*** Memory ***/
82
83
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/intc/exynos4210_gic.c
86
+++ b/hw/intc/exynos4210_gic.c
87
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
88
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
89
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
90
91
-static void exynos4210_irq_handler(void *opaque, int irq, int level)
92
-{
93
- Exynos4210Irq *s = (Exynos4210Irq *)opaque;
94
-
95
- /* Bypass */
96
- qemu_set_irq(s->board_irqs[irq], level);
97
-}
98
-
99
-/*
100
- * Initialize exynos4210 IRQ subsystem stub.
101
- */
102
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *s)
103
-{
104
- return qemu_allocate_irqs(exynos4210_irq_handler, s,
105
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ);
106
-}
107
-
108
/*
109
* Initialize board IRQs.
110
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
111
*/
112
-void exynos4210_init_board_irqs(Exynos4210Irq *s)
113
+void exynos4210_init_board_irqs(Exynos4210State *s)
41
{
114
{
42
- gen_a64_set_pc_im(s->pc - offset);
115
uint32_t grp, bit, irq_id, n;
43
+ gen_a64_set_pc_im(s->base.pc_next - offset);
116
+ Exynos4210Irq *is = &s->irqs;
44
gen_exception_internal(excp);
117
45
s->base.is_jmp = DISAS_NORETURN;
118
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
46
}
119
irq_id = 0;
47
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
120
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
48
static void gen_exception_insn(DisasContext *s, int offset, int excp,
121
irq_id = EXT_GIC_ID_MCT_G1;
49
uint32_t syndrome, uint32_t target_el)
50
{
51
- gen_a64_set_pc_im(s->pc - offset);
52
+ gen_a64_set_pc_im(s->base.pc_next - offset);
53
gen_exception(excp, syndrome, target_el);
54
s->base.is_jmp = DISAS_NORETURN;
55
}
56
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset,
57
{
58
TCGv_i32 tcg_syn;
59
60
- gen_a64_set_pc_im(s->pc - offset);
61
+ gen_a64_set_pc_im(s->base.pc_next - offset);
62
tcg_syn = tcg_const_i32(syndrome);
63
gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
64
tcg_temp_free_i32(tcg_syn);
65
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
66
67
if (insn & (1U << 31)) {
68
/* BL Branch with link */
69
- tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
70
+ tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
71
}
72
73
/* B Branch / BL Branch with link */
74
@@ -XXX,XX +XXX,XX @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
75
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
76
tcg_cmp, 0, label_match);
77
78
- gen_goto_tb(s, 0, s->pc);
79
+ gen_goto_tb(s, 0, s->base.pc_next);
80
gen_set_label(label_match);
81
gen_goto_tb(s, 1, addr);
82
}
83
@@ -XXX,XX +XXX,XX @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
84
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
85
tcg_cmp, 0, label_match);
86
tcg_temp_free_i64(tcg_cmp);
87
- gen_goto_tb(s, 0, s->pc);
88
+ gen_goto_tb(s, 0, s->base.pc_next);
89
gen_set_label(label_match);
90
gen_goto_tb(s, 1, addr);
91
}
92
@@ -XXX,XX +XXX,XX @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
93
/* genuinely conditional branches */
94
TCGLabel *label_match = gen_new_label();
95
arm_gen_test_cc(cond, label_match);
96
- gen_goto_tb(s, 0, s->pc);
97
+ gen_goto_tb(s, 0, s->base.pc_next);
98
gen_set_label(label_match);
99
gen_goto_tb(s, 1, addr);
100
} else {
101
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
102
* any pending interrupts immediately.
103
*/
104
reset_btype(s);
105
- gen_goto_tb(s, 0, s->pc);
106
+ gen_goto_tb(s, 0, s->base.pc_next);
107
return;
108
109
case 7: /* SB */
110
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
111
* MB and end the TB instead.
112
*/
113
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
114
- gen_goto_tb(s, 0, s->pc);
115
+ gen_goto_tb(s, 0, s->base.pc_next);
116
return;
117
118
default:
119
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
120
gen_a64_set_pc(s, dst);
121
/* BLR also needs to load return address */
122
if (opc == 1) {
123
- tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
124
+ tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
125
}
122
}
126
break;
123
if (irq_id) {
127
124
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
128
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
125
- s->ext_gic_irq[irq_id-32]);
129
gen_a64_set_pc(s, dst);
126
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
130
/* BLRAA also needs to load return address */
127
+ is->ext_gic_irq[irq_id - 32]);
131
if (opc == 9) {
128
} else {
132
- tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
129
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
133
+ tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
130
- s->ext_combiner_irq[n]);
134
}
131
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
135
break;
132
+ is->ext_combiner_irq[n]);
136
137
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
138
{
139
uint32_t insn;
140
141
- s->pc_curr = s->pc;
142
- insn = arm_ldl_code(env, s->pc, s->sctlr_b);
143
+ s->pc_curr = s->base.pc_next;
144
+ insn = arm_ldl_code(env, s->base.pc_next, s->sctlr_b);
145
s->insn = insn;
146
- s->pc += 4;
147
+ s->base.pc_next += 4;
148
149
s->fp_access_checked = false;
150
151
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
152
int bound, core_mmu_idx;
153
154
dc->isar = &arm_cpu->isar;
155
- dc->pc = dc->base.pc_first;
156
dc->condjmp = 0;
157
158
dc->aarch64 = 1;
159
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
160
{
161
DisasContext *dc = container_of(dcbase, DisasContext, base);
162
163
- tcg_gen_insn_start(dc->pc, 0, 0);
164
+ tcg_gen_insn_start(dc->base.pc_next, 0, 0);
165
dc->insn_start = tcg_last_op();
166
}
167
168
@@ -XXX,XX +XXX,XX @@ static bool aarch64_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
169
DisasContext *dc = container_of(dcbase, DisasContext, base);
170
171
if (bp->flags & BP_CPU) {
172
- gen_a64_set_pc_im(dc->pc);
173
+ gen_a64_set_pc_im(dc->base.pc_next);
174
gen_helper_check_breakpoints(cpu_env);
175
/* End the TB early; it likely won't be executed */
176
dc->base.is_jmp = DISAS_TOO_MANY;
177
@@ -XXX,XX +XXX,XX @@ static bool aarch64_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
178
to for it to be properly cleared -- thus we
179
increment the PC here so that the logic setting
180
tb->size below does the right thing. */
181
- dc->pc += 4;
182
+ dc->base.pc_next += 4;
183
dc->base.is_jmp = DISAS_NORETURN;
184
}
185
186
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
187
disas_a64_insn(env, dc);
188
}
189
190
- dc->base.pc_next = dc->pc;
191
translator_loop_temp_check(&dc->base);
192
}
193
194
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
195
*/
196
switch (dc->base.is_jmp) {
197
default:
198
- gen_a64_set_pc_im(dc->pc);
199
+ gen_a64_set_pc_im(dc->base.pc_next);
200
/* fall through */
201
case DISAS_EXIT:
202
case DISAS_JUMP:
203
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
204
switch (dc->base.is_jmp) {
205
case DISAS_NEXT:
206
case DISAS_TOO_MANY:
207
- gen_goto_tb(dc, 1, dc->pc);
208
+ gen_goto_tb(dc, 1, dc->base.pc_next);
209
break;
210
default:
211
case DISAS_UPDATE:
212
- gen_a64_set_pc_im(dc->pc);
213
+ gen_a64_set_pc_im(dc->base.pc_next);
214
/* fall through */
215
case DISAS_EXIT:
216
tcg_gen_exit_tb(NULL, 0);
217
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
218
case DISAS_SWI:
219
break;
220
case DISAS_WFE:
221
- gen_a64_set_pc_im(dc->pc);
222
+ gen_a64_set_pc_im(dc->base.pc_next);
223
gen_helper_wfe(cpu_env);
224
break;
225
case DISAS_YIELD:
226
- gen_a64_set_pc_im(dc->pc);
227
+ gen_a64_set_pc_im(dc->base.pc_next);
228
gen_helper_yield(cpu_env);
229
break;
230
case DISAS_WFI:
231
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
232
*/
233
TCGv_i32 tmp = tcg_const_i32(4);
234
235
- gen_a64_set_pc_im(dc->pc);
236
+ gen_a64_set_pc_im(dc->base.pc_next);
237
gen_helper_wfi(cpu_env, tmp);
238
tcg_temp_free_i32(tmp);
239
/* The helper doesn't necessarily throw an exception, but we
240
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
241
}
242
}
133
}
243
}
134
}
244
-
135
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
245
- /* Functions above can change dc->pc, so re-align db->pc_next */
136
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
246
- dc->base.pc_next = dc->pc;
137
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
247
}
138
248
139
if (irq_id) {
249
static void aarch64_tr_disas_log(const DisasContextBase *dcbase,
140
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
250
diff --git a/target/arm/translate.c b/target/arm/translate.c
141
- s->ext_gic_irq[irq_id-32]);
251
index XXXXXXX..XXXXXXX 100644
142
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
252
--- a/target/arm/translate.c
143
+ is->ext_gic_irq[irq_id - 32]);
253
+++ b/target/arm/translate.c
254
@@ -XXX,XX +XXX,XX @@ static inline void gen_blxns(DisasContext *s, int rm)
255
* We do however need to set the PC, because the blxns helper reads it.
256
* The blxns helper may throw an exception.
257
*/
258
- gen_set_pc_im(s, s->pc);
259
+ gen_set_pc_im(s, s->base.pc_next);
260
gen_helper_v7m_blxns(cpu_env, var);
261
tcg_temp_free_i32(var);
262
s->base.is_jmp = DISAS_EXIT;
263
@@ -XXX,XX +XXX,XX @@ static inline void gen_hvc(DisasContext *s, int imm16)
264
* for single stepping.)
265
*/
266
s->svc_imm = imm16;
267
- gen_set_pc_im(s, s->pc);
268
+ gen_set_pc_im(s, s->base.pc_next);
269
s->base.is_jmp = DISAS_HVC;
270
}
271
272
@@ -XXX,XX +XXX,XX @@ static inline void gen_smc(DisasContext *s)
273
tmp = tcg_const_i32(syn_aa32_smc());
274
gen_helper_pre_smc(cpu_env, tmp);
275
tcg_temp_free_i32(tmp);
276
- gen_set_pc_im(s, s->pc);
277
+ gen_set_pc_im(s, s->base.pc_next);
278
s->base.is_jmp = DISAS_SMC;
279
}
280
281
static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
282
{
283
gen_set_condexec(s);
284
- gen_set_pc_im(s, s->pc - offset);
285
+ gen_set_pc_im(s, s->base.pc_next - offset);
286
gen_exception_internal(excp);
287
s->base.is_jmp = DISAS_NORETURN;
288
}
289
@@ -XXX,XX +XXX,XX @@ static void gen_exception_insn(DisasContext *s, int offset, int excp,
290
int syn, uint32_t target_el)
291
{
292
gen_set_condexec(s);
293
- gen_set_pc_im(s, s->pc - offset);
294
+ gen_set_pc_im(s, s->base.pc_next - offset);
295
gen_exception(excp, syn, target_el);
296
s->base.is_jmp = DISAS_NORETURN;
297
}
298
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
299
TCGv_i32 tcg_syn;
300
301
gen_set_condexec(s);
302
- gen_set_pc_im(s, s->pc - offset);
303
+ gen_set_pc_im(s, s->base.pc_next - offset);
304
tcg_syn = tcg_const_i32(syn);
305
gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
306
tcg_temp_free_i32(tcg_syn);
307
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
308
/* Force a TB lookup after an instruction that changes the CPU state. */
309
static inline void gen_lookup_tb(DisasContext *s)
310
{
311
- tcg_gen_movi_i32(cpu_R[15], s->pc);
312
+ tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
313
s->base.is_jmp = DISAS_EXIT;
314
}
315
316
@@ -XXX,XX +XXX,XX @@ static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
317
{
318
#ifndef CONFIG_USER_ONLY
319
return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
320
- ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
321
+ ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
322
#else
323
return true;
324
#endif
325
@@ -XXX,XX +XXX,XX @@ static void gen_nop_hint(DisasContext *s, int val)
326
*/
327
case 1: /* yield */
328
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
329
- gen_set_pc_im(s, s->pc);
330
+ gen_set_pc_im(s, s->base.pc_next);
331
s->base.is_jmp = DISAS_YIELD;
332
}
333
break;
334
case 3: /* wfi */
335
- gen_set_pc_im(s, s->pc);
336
+ gen_set_pc_im(s, s->base.pc_next);
337
s->base.is_jmp = DISAS_WFI;
338
break;
339
case 2: /* wfe */
340
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
341
- gen_set_pc_im(s, s->pc);
342
+ gen_set_pc_im(s, s->base.pc_next);
343
s->base.is_jmp = DISAS_WFE;
344
}
345
break;
346
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
347
if (isread) {
348
return 1;
349
}
350
- gen_set_pc_im(s, s->pc);
351
+ gen_set_pc_im(s, s->base.pc_next);
352
s->base.is_jmp = DISAS_WFI;
353
return 0;
354
default:
355
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
356
* self-modifying code correctly and also to take
357
* any pending interrupts immediately.
358
*/
359
- gen_goto_tb(s, 0, s->pc);
360
+ gen_goto_tb(s, 0, s->base.pc_next);
361
return;
362
case 7: /* sb */
363
if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
364
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
365
* for TCG; MB and end the TB instead.
366
*/
367
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
368
- gen_goto_tb(s, 0, s->pc);
369
+ gen_goto_tb(s, 0, s->base.pc_next);
370
return;
371
default:
372
goto illegal_op;
373
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
374
int32_t offset;
375
376
tmp = tcg_temp_new_i32();
377
- tcg_gen_movi_i32(tmp, s->pc);
378
+ tcg_gen_movi_i32(tmp, s->base.pc_next);
379
store_reg(s, 14, tmp);
380
/* Sign-extend the 24-bit offset */
381
offset = (((int32_t)insn) << 8) >> 8;
382
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
383
/* branch link/exchange thumb (blx) */
384
tmp = load_reg(s, rm);
385
tmp2 = tcg_temp_new_i32();
386
- tcg_gen_movi_i32(tmp2, s->pc);
387
+ tcg_gen_movi_i32(tmp2, s->base.pc_next);
388
store_reg(s, 14, tmp2);
389
gen_bx(s, tmp);
390
break;
391
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
392
/* branch (and link) */
393
if (insn & (1 << 24)) {
394
tmp = tcg_temp_new_i32();
395
- tcg_gen_movi_i32(tmp, s->pc);
396
+ tcg_gen_movi_i32(tmp, s->base.pc_next);
397
store_reg(s, 14, tmp);
398
}
399
offset = sextract32(insn << 2, 0, 26);
400
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
401
break;
402
case 0xf:
403
/* swi */
404
- gen_set_pc_im(s, s->pc);
405
+ gen_set_pc_im(s, s->base.pc_next);
406
s->svc_imm = extract32(insn, 0, 24);
407
s->base.is_jmp = DISAS_SWI;
408
break;
409
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
410
411
if (insn & (1 << 14)) {
412
/* Branch and link. */
413
- tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
414
+ tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
415
}
416
417
offset += read_pc(s);
418
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
419
* and also to take any pending interrupts
420
* immediately.
421
*/
422
- gen_goto_tb(s, 0, s->pc);
423
+ gen_goto_tb(s, 0, s->base.pc_next);
424
break;
425
case 7: /* sb */
426
if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
427
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
428
* for TCG; MB and end the TB instead.
429
*/
430
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
431
- gen_goto_tb(s, 0, s->pc);
432
+ gen_goto_tb(s, 0, s->base.pc_next);
433
break;
434
default:
435
goto illegal_op;
436
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
437
/* BLX/BX */
438
tmp = load_reg(s, rm);
439
if (link) {
440
- val = (uint32_t)s->pc | 1;
441
+ val = (uint32_t)s->base.pc_next | 1;
442
tmp2 = tcg_temp_new_i32();
443
tcg_gen_movi_i32(tmp2, val);
444
store_reg(s, 14, tmp2);
445
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
446
447
if (cond == 0xf) {
448
/* swi */
449
- gen_set_pc_im(s, s->pc);
450
+ gen_set_pc_im(s, s->base.pc_next);
451
s->svc_imm = extract32(insn, 0, 8);
452
s->base.is_jmp = DISAS_SWI;
453
break;
454
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
455
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
456
457
tmp2 = tcg_temp_new_i32();
458
- tcg_gen_movi_i32(tmp2, s->pc | 1);
459
+ tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
460
store_reg(s, 14, tmp2);
461
gen_bx(s, tmp);
462
break;
463
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
464
tcg_gen_addi_i32(tmp, tmp, offset);
465
466
tmp2 = tcg_temp_new_i32();
467
- tcg_gen_movi_i32(tmp2, s->pc | 1);
468
+ tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
469
store_reg(s, 14, tmp2);
470
gen_bx(s, tmp);
471
} else {
472
@@ -XXX,XX +XXX,XX @@ undef:
473
474
static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
475
{
476
- /* Return true if the insn at dc->pc might cross a page boundary.
477
+ /* Return true if the insn at dc->base.pc_next might cross a page boundary.
478
* (False positives are OK, false negatives are not.)
479
* We know this is a Thumb insn, and our caller ensures we are
480
- * only called if dc->pc is less than 4 bytes from the page
481
+ * only called if dc->base.pc_next is less than 4 bytes from the page
482
* boundary, so we cross the page if the first 16 bits indicate
483
* that this is a 32 bit insn.
484
*/
485
- uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
486
+ uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
487
488
- return !thumb_insn_is_16bit(s, s->pc, insn);
489
+ return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
490
}
491
492
static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
493
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
494
uint32_t condexec, core_mmu_idx;
495
496
dc->isar = &cpu->isar;
497
- dc->pc = dc->base.pc_first;
498
dc->condjmp = 0;
499
500
dc->aarch64 = 0;
501
@@ -XXX,XX +XXX,XX @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
502
{
503
DisasContext *dc = container_of(dcbase, DisasContext, base);
504
505
- tcg_gen_insn_start(dc->pc,
506
+ tcg_gen_insn_start(dc->base.pc_next,
507
(dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
508
0);
509
dc->insn_start = tcg_last_op();
510
@@ -XXX,XX +XXX,XX @@ static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
511
512
if (bp->flags & BP_CPU) {
513
gen_set_condexec(dc);
514
- gen_set_pc_im(dc, dc->pc);
515
+ gen_set_pc_im(dc, dc->base.pc_next);
516
gen_helper_check_breakpoints(cpu_env);
517
/* End the TB early; it's likely not going to be executed */
518
dc->base.is_jmp = DISAS_TOO_MANY;
519
@@ -XXX,XX +XXX,XX @@ static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
520
tb->size below does the right thing. */
521
/* TODO: Advance PC by correct instruction length to
522
* avoid disassembler error messages */
523
- dc->pc += 2;
524
+ dc->base.pc_next += 2;
525
dc->base.is_jmp = DISAS_NORETURN;
526
}
527
528
@@ -XXX,XX +XXX,XX @@ static bool arm_pre_translate_insn(DisasContext *dc)
529
{
530
#ifdef CONFIG_USER_ONLY
531
/* Intercept jump to the magic kernel page. */
532
- if (dc->pc >= 0xffff0000) {
533
+ if (dc->base.pc_next >= 0xffff0000) {
534
/* We always get here via a jump, so know we are not in a
535
conditional execution block. */
536
gen_exception_internal(EXCP_KERNEL_TRAP);
537
@@ -XXX,XX +XXX,XX @@ static void arm_post_translate_insn(DisasContext *dc)
538
gen_set_label(dc->condlabel);
539
dc->condjmp = 0;
540
}
541
- dc->base.pc_next = dc->pc;
542
translator_loop_temp_check(&dc->base);
543
}
544
545
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
546
return;
547
}
548
549
- dc->pc_curr = dc->pc;
550
- insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
551
+ dc->pc_curr = dc->base.pc_next;
552
+ insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
553
dc->insn = insn;
554
- dc->pc += 4;
555
+ dc->base.pc_next += 4;
556
disas_arm_insn(dc, insn);
557
558
arm_post_translate_insn(dc);
559
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
560
return;
561
}
562
563
- dc->pc_curr = dc->pc;
564
- insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
565
- is_16bit = thumb_insn_is_16bit(dc, dc->pc, insn);
566
- dc->pc += 2;
567
+ dc->pc_curr = dc->base.pc_next;
568
+ insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
569
+ is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
570
+ dc->base.pc_next += 2;
571
if (!is_16bit) {
572
- uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
573
+ uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
574
575
insn = insn << 16 | insn2;
576
- dc->pc += 2;
577
+ dc->base.pc_next += 2;
578
}
579
dc->insn = insn;
580
581
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
582
* but isn't very efficient).
583
*/
584
if (dc->base.is_jmp == DISAS_NEXT
585
- && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
586
- || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
587
+ && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
588
+ || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
589
&& insn_crosses_page(env, dc)))) {
590
dc->base.is_jmp = DISAS_TOO_MANY;
591
}
592
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
593
case DISAS_NEXT:
594
case DISAS_TOO_MANY:
595
case DISAS_UPDATE:
596
- gen_set_pc_im(dc, dc->pc);
597
+ gen_set_pc_im(dc, dc->base.pc_next);
598
/* fall through */
599
default:
600
/* FIXME: Single stepping a WFI insn will not halt the CPU. */
601
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
602
switch(dc->base.is_jmp) {
603
case DISAS_NEXT:
604
case DISAS_TOO_MANY:
605
- gen_goto_tb(dc, 1, dc->pc);
606
+ gen_goto_tb(dc, 1, dc->base.pc_next);
607
break;
608
case DISAS_JUMP:
609
gen_goto_ptr();
610
break;
611
case DISAS_UPDATE:
612
- gen_set_pc_im(dc, dc->pc);
613
+ gen_set_pc_im(dc, dc->base.pc_next);
614
/* fall through */
615
default:
616
/* indicate that the hash table must be used to find the next TB */
617
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
618
gen_set_label(dc->condlabel);
619
gen_set_condexec(dc);
620
if (unlikely(is_singlestepping(dc))) {
621
- gen_set_pc_im(dc, dc->pc);
622
+ gen_set_pc_im(dc, dc->base.pc_next);
623
gen_singlestep_exception(dc);
624
} else {
625
- gen_goto_tb(dc, 1, dc->pc);
626
+ gen_goto_tb(dc, 1, dc->base.pc_next);
627
}
144
}
628
}
145
}
629
-
630
- /* Functions above can change dc->pc, so re-align db->pc_next */
631
- dc->base.pc_next = dc->pc;
632
}
146
}
633
634
static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
635
--
147
--
636
2.20.1
148
2.25.1
637
638
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
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.
2
5
3
Unless we're guaranteed to always increase ARM_MAX_VQ by a multiple of
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
four, then we should use DIV_ROUND_UP to ensure we get an appropriate
5
array size.
6
7
Signed-off-by: Andrew Jones <drjones@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220404154658.565020-7-peter.maydell@linaro.org
10
---
9
---
11
target/arm/cpu.h | 2 +-
10
hw/intc/exynos4210_gic.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
13
12
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
15
--- a/hw/intc/exynos4210_gic.c
17
+++ b/target/arm/cpu.h
16
+++ b/hw/intc/exynos4210_gic.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVectorReg {
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
19
#ifdef TARGET_AARCH64
18
*/
20
/* In AArch32 mode, predicate registers do not exist at all. */
19
21
typedef struct ARMPredicateReg {
20
static const uint32_t
22
- uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
21
-combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
23
+ uint64_t p[DIV_ROUND_UP(2 * ARM_MAX_VQ, 8)] QEMU_ALIGNED(16);
22
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
24
} ARMPredicateReg;
23
/* int combiner groups 16-19 */
25
24
{ }, { }, { }, { },
26
/* In AArch32 mode, PAC keys do not exist at all. */
25
/* int combiner group 20 */
27
--
26
--
28
2.20.1
27
2.25.1
29
30
diff view generated by jsdifflib
1
Factor out code to 'generate a singlestep exception', which is
1
The function exynos4210_init_board_irqs() currently lives in
2
currently repeated in four places.
2
exynos4210_gic.c, but it isn't really part of the exynos4210.gic
3
3
device -- it is a function that implements (some of) the wiring up of
4
To do this we need to also pull the identical copies of the
4
interrupts between the SoC's GIC and combiner components. This means
5
gen-exception() function out of translate-a64.c and translate.c
5
it fits better in exynos4210.c, which is the SoC-level code. Move it
6
into translate.h.
6
there. Similarly, exynos4210_git_irq() is used almost only in the
7
7
SoC-level code, so move it too.
8
(There is a bug in the code: we're taking the exception to the wrong
9
target EL. This will be simpler to fix if there's only one place to
10
do it.)
11
8
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
15
Message-id: 20190805130952.4415-2-peter.maydell@linaro.org
16
---
12
---
17
target/arm/translate.h | 23 +++++++++++++++++++++++
13
include/hw/arm/exynos4210.h | 4 -
18
target/arm/translate-a64.c | 19 ++-----------------
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
19
target/arm/translate.c | 20 ++------------------
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
20
3 files changed, 27 insertions(+), 35 deletions(-)
16
3 files changed, 202 insertions(+), 208 deletions(-)
21
17
22
diff --git a/target/arm/translate.h b/target/arm/translate.h
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
23
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate.h
20
--- a/include/hw/arm/exynos4210.h
25
+++ b/target/arm/translate.h
21
+++ b/include/hw/arm/exynos4210.h
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
23
void exynos4210_write_secondary(ARMCPU *cpu,
24
const struct arm_boot_info *info);
25
26
-/* Initialize board IRQs.
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
29
-
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
31
* To identify IRQ source use internal combiner group and bit number
32
* grp - group number
33
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/exynos4210.c
36
+++ b/hw/arm/exynos4210.c
26
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
27
#define TARGET_ARM_TRANSLATE_H
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
28
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
29
#include "exec/translator.h"
40
30
+#include "internals.h"
41
+enum ExtGicId {
31
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
32
43
+ EXT_GIC_ID_PDMA0,
33
/* internal defines */
44
+ EXT_GIC_ID_PDMA1,
34
@@ -XXX,XX +XXX,XX @@ static inline void gen_ss_advance(DisasContext *s)
45
+ EXT_GIC_ID_TIMER0,
35
}
46
+ EXT_GIC_ID_TIMER1,
36
}
47
+ EXT_GIC_ID_TIMER2,
37
48
+ EXT_GIC_ID_TIMER3,
38
+static inline void gen_exception(int excp, uint32_t syndrome,
49
+ EXT_GIC_ID_TIMER4,
39
+ uint32_t target_el)
50
+ EXT_GIC_ID_MCT_L0,
51
+ EXT_GIC_ID_WDT,
52
+ EXT_GIC_ID_RTC_ALARM,
53
+ EXT_GIC_ID_RTC_TIC,
54
+ EXT_GIC_ID_GPIO_XB,
55
+ EXT_GIC_ID_GPIO_XA,
56
+ EXT_GIC_ID_MCT_L1,
57
+ EXT_GIC_ID_IEM_APC,
58
+ EXT_GIC_ID_IEM_IEC,
59
+ EXT_GIC_ID_NFC,
60
+ EXT_GIC_ID_UART0,
61
+ EXT_GIC_ID_UART1,
62
+ EXT_GIC_ID_UART2,
63
+ EXT_GIC_ID_UART3,
64
+ EXT_GIC_ID_UART4,
65
+ EXT_GIC_ID_MCT_G0,
66
+ EXT_GIC_ID_I2C0,
67
+ EXT_GIC_ID_I2C1,
68
+ EXT_GIC_ID_I2C2,
69
+ EXT_GIC_ID_I2C3,
70
+ EXT_GIC_ID_I2C4,
71
+ EXT_GIC_ID_I2C5,
72
+ EXT_GIC_ID_I2C6,
73
+ EXT_GIC_ID_I2C7,
74
+ EXT_GIC_ID_SPI0,
75
+ EXT_GIC_ID_SPI1,
76
+ EXT_GIC_ID_SPI2,
77
+ EXT_GIC_ID_MCT_G1,
78
+ EXT_GIC_ID_USB_HOST,
79
+ EXT_GIC_ID_USB_DEVICE,
80
+ EXT_GIC_ID_MODEMIF,
81
+ EXT_GIC_ID_HSMMC0,
82
+ EXT_GIC_ID_HSMMC1,
83
+ EXT_GIC_ID_HSMMC2,
84
+ EXT_GIC_ID_HSMMC3,
85
+ EXT_GIC_ID_SDMMC,
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
90
+ EXT_GIC_ID_ONENAND_AUDI,
91
+ EXT_GIC_ID_ROTATOR,
92
+ EXT_GIC_ID_FIMC0,
93
+ EXT_GIC_ID_FIMC1,
94
+ EXT_GIC_ID_FIMC2,
95
+ EXT_GIC_ID_FIMC3,
96
+ EXT_GIC_ID_JPEG,
97
+ EXT_GIC_ID_2D,
98
+ EXT_GIC_ID_PCIe,
99
+ EXT_GIC_ID_MIXER,
100
+ EXT_GIC_ID_HDMI,
101
+ EXT_GIC_ID_HDMI_I2C,
102
+ EXT_GIC_ID_MFC,
103
+ EXT_GIC_ID_TVENC,
104
+};
105
+
106
+enum ExtInt {
107
+ EXT_GIC_ID_EXTINT0 = 48,
108
+ EXT_GIC_ID_EXTINT1,
109
+ EXT_GIC_ID_EXTINT2,
110
+ EXT_GIC_ID_EXTINT3,
111
+ EXT_GIC_ID_EXTINT4,
112
+ EXT_GIC_ID_EXTINT5,
113
+ EXT_GIC_ID_EXTINT6,
114
+ EXT_GIC_ID_EXTINT7,
115
+ EXT_GIC_ID_EXTINT8,
116
+ EXT_GIC_ID_EXTINT9,
117
+ EXT_GIC_ID_EXTINT10,
118
+ EXT_GIC_ID_EXTINT11,
119
+ EXT_GIC_ID_EXTINT12,
120
+ EXT_GIC_ID_EXTINT13,
121
+ EXT_GIC_ID_EXTINT14,
122
+ EXT_GIC_ID_EXTINT15
123
+};
124
+
125
+/*
126
+ * External GIC sources which are not from External Interrupt Combiner or
127
+ * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
128
+ * which is INTG16 in Internal Interrupt Combiner.
129
+ */
130
+
131
+static const uint32_t
132
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
133
+ /* int combiner groups 16-19 */
134
+ { }, { }, { }, { },
135
+ /* int combiner group 20 */
136
+ { 0, EXT_GIC_ID_MDMA_LCD0 },
137
+ /* int combiner group 21 */
138
+ { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
139
+ /* int combiner group 22 */
140
+ { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
141
+ EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
142
+ /* int combiner group 23 */
143
+ { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
144
+ /* int combiner group 24 */
145
+ { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
146
+ /* int combiner group 25 */
147
+ { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
148
+ /* int combiner group 26 */
149
+ { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
150
+ EXT_GIC_ID_UART4 },
151
+ /* int combiner group 27 */
152
+ { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
153
+ EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
154
+ EXT_GIC_ID_I2C7 },
155
+ /* int combiner group 28 */
156
+ { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
157
+ /* int combiner group 29 */
158
+ { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
159
+ EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
160
+ /* int combiner group 30 */
161
+ { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
162
+ /* int combiner group 31 */
163
+ { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
164
+ /* int combiner group 32 */
165
+ { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
166
+ /* int combiner group 33 */
167
+ { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
168
+ /* int combiner group 34 */
169
+ { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
170
+ /* int combiner group 35 */
171
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
172
+ /* int combiner group 36 */
173
+ { EXT_GIC_ID_MIXER },
174
+ /* int combiner group 37 */
175
+ { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
176
+ EXT_GIC_ID_EXTINT7 },
177
+ /* groups 38-50 */
178
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
179
+ /* int combiner group 51 */
180
+ { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
181
+ /* group 52 */
182
+ { },
183
+ /* int combiner group 53 */
184
+ { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
185
+ /* groups 54-63 */
186
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
187
+};
188
+
189
+/*
190
+ * Initialize board IRQs.
191
+ * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
192
+ */
193
+static void exynos4210_init_board_irqs(Exynos4210State *s)
40
+{
194
+{
41
+ TCGv_i32 tcg_excp = tcg_const_i32(excp);
195
+ uint32_t grp, bit, irq_id, n;
42
+ TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
196
+ Exynos4210Irq *is = &s->irqs;
43
+ TCGv_i32 tcg_el = tcg_const_i32(target_el);
197
+
44
+
198
+ for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
45
+ gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
199
+ irq_id = 0;
46
+ tcg_syn, tcg_el);
200
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
47
+
201
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
48
+ tcg_temp_free_i32(tcg_el);
202
+ /* MCT_G0 is passed to External GIC */
49
+ tcg_temp_free_i32(tcg_syn);
203
+ irq_id = EXT_GIC_ID_MCT_G0;
50
+ tcg_temp_free_i32(tcg_excp);
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
+ }
51
+}
230
+}
52
+
231
+
53
+/* Generate an architectural singlestep exception */
232
+/*
54
+static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
233
+ * Get IRQ number from exynos4210 IRQ subsystem stub.
234
+ * To identify IRQ source use internal combiner group and bit number
235
+ * grp - group number
236
+ * bit - bit number inside group
237
+ */
238
+uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
55
+{
239
+{
56
+ gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, isv, ex),
240
+ return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
57
+ default_exception_el(s));
58
+}
241
+}
59
+
242
+
60
/*
243
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
61
* Given a VFP floating point constant encoded into an 8 bit immediate in an
244
0x09, 0x00, 0x00, 0x00 };
62
* instruction, expand it to the actual constant value of the specified
245
63
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
246
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
64
index XXXXXXX..XXXXXXX 100644
247
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate-a64.c
248
--- a/hw/intc/exynos4210_gic.c
66
+++ b/target/arm/translate-a64.c
249
+++ b/hw/intc/exynos4210_gic.c
67
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal(int excp)
250
@@ -XXX,XX +XXX,XX @@
68
tcg_temp_free_i32(tcg_excp);
251
#include "hw/arm/exynos4210.h"
69
}
252
#include "qom/object.h"
70
253
71
-static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
254
-enum ExtGicId {
255
- EXT_GIC_ID_MDMA_LCD0 = 66,
256
- EXT_GIC_ID_PDMA0,
257
- EXT_GIC_ID_PDMA1,
258
- EXT_GIC_ID_TIMER0,
259
- EXT_GIC_ID_TIMER1,
260
- EXT_GIC_ID_TIMER2,
261
- EXT_GIC_ID_TIMER3,
262
- EXT_GIC_ID_TIMER4,
263
- EXT_GIC_ID_MCT_L0,
264
- EXT_GIC_ID_WDT,
265
- EXT_GIC_ID_RTC_ALARM,
266
- EXT_GIC_ID_RTC_TIC,
267
- EXT_GIC_ID_GPIO_XB,
268
- EXT_GIC_ID_GPIO_XA,
269
- EXT_GIC_ID_MCT_L1,
270
- EXT_GIC_ID_IEM_APC,
271
- EXT_GIC_ID_IEM_IEC,
272
- EXT_GIC_ID_NFC,
273
- EXT_GIC_ID_UART0,
274
- EXT_GIC_ID_UART1,
275
- EXT_GIC_ID_UART2,
276
- EXT_GIC_ID_UART3,
277
- EXT_GIC_ID_UART4,
278
- EXT_GIC_ID_MCT_G0,
279
- EXT_GIC_ID_I2C0,
280
- EXT_GIC_ID_I2C1,
281
- EXT_GIC_ID_I2C2,
282
- EXT_GIC_ID_I2C3,
283
- EXT_GIC_ID_I2C4,
284
- EXT_GIC_ID_I2C5,
285
- EXT_GIC_ID_I2C6,
286
- EXT_GIC_ID_I2C7,
287
- EXT_GIC_ID_SPI0,
288
- EXT_GIC_ID_SPI1,
289
- EXT_GIC_ID_SPI2,
290
- EXT_GIC_ID_MCT_G1,
291
- EXT_GIC_ID_USB_HOST,
292
- EXT_GIC_ID_USB_DEVICE,
293
- EXT_GIC_ID_MODEMIF,
294
- EXT_GIC_ID_HSMMC0,
295
- EXT_GIC_ID_HSMMC1,
296
- EXT_GIC_ID_HSMMC2,
297
- EXT_GIC_ID_HSMMC3,
298
- EXT_GIC_ID_SDMMC,
299
- EXT_GIC_ID_MIPI_CSI_4LANE,
300
- EXT_GIC_ID_MIPI_DSI_4LANE,
301
- EXT_GIC_ID_MIPI_CSI_2LANE,
302
- EXT_GIC_ID_MIPI_DSI_2LANE,
303
- EXT_GIC_ID_ONENAND_AUDI,
304
- EXT_GIC_ID_ROTATOR,
305
- EXT_GIC_ID_FIMC0,
306
- EXT_GIC_ID_FIMC1,
307
- EXT_GIC_ID_FIMC2,
308
- EXT_GIC_ID_FIMC3,
309
- EXT_GIC_ID_JPEG,
310
- EXT_GIC_ID_2D,
311
- EXT_GIC_ID_PCIe,
312
- EXT_GIC_ID_MIXER,
313
- EXT_GIC_ID_HDMI,
314
- EXT_GIC_ID_HDMI_I2C,
315
- EXT_GIC_ID_MFC,
316
- EXT_GIC_ID_TVENC,
317
-};
318
-
319
-enum ExtInt {
320
- EXT_GIC_ID_EXTINT0 = 48,
321
- EXT_GIC_ID_EXTINT1,
322
- EXT_GIC_ID_EXTINT2,
323
- EXT_GIC_ID_EXTINT3,
324
- EXT_GIC_ID_EXTINT4,
325
- EXT_GIC_ID_EXTINT5,
326
- EXT_GIC_ID_EXTINT6,
327
- EXT_GIC_ID_EXTINT7,
328
- EXT_GIC_ID_EXTINT8,
329
- EXT_GIC_ID_EXTINT9,
330
- EXT_GIC_ID_EXTINT10,
331
- EXT_GIC_ID_EXTINT11,
332
- EXT_GIC_ID_EXTINT12,
333
- EXT_GIC_ID_EXTINT13,
334
- EXT_GIC_ID_EXTINT14,
335
- EXT_GIC_ID_EXTINT15
336
-};
337
-
338
-/*
339
- * External GIC sources which are not from External Interrupt Combiner or
340
- * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
341
- * which is INTG16 in Internal Interrupt Combiner.
342
- */
343
-
344
-static const uint32_t
345
-combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
346
- /* int combiner groups 16-19 */
347
- { }, { }, { }, { },
348
- /* int combiner group 20 */
349
- { 0, EXT_GIC_ID_MDMA_LCD0 },
350
- /* int combiner group 21 */
351
- { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
352
- /* int combiner group 22 */
353
- { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
354
- EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
355
- /* int combiner group 23 */
356
- { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
357
- /* int combiner group 24 */
358
- { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
359
- /* int combiner group 25 */
360
- { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
361
- /* int combiner group 26 */
362
- { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
363
- EXT_GIC_ID_UART4 },
364
- /* int combiner group 27 */
365
- { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
366
- EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
367
- EXT_GIC_ID_I2C7 },
368
- /* int combiner group 28 */
369
- { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
370
- /* int combiner group 29 */
371
- { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
372
- EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
373
- /* int combiner group 30 */
374
- { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
375
- /* int combiner group 31 */
376
- { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
377
- /* int combiner group 32 */
378
- { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
379
- /* int combiner group 33 */
380
- { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
381
- /* int combiner group 34 */
382
- { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
383
- /* int combiner group 35 */
384
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
385
- /* int combiner group 36 */
386
- { EXT_GIC_ID_MIXER },
387
- /* int combiner group 37 */
388
- { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
389
- EXT_GIC_ID_EXTINT7 },
390
- /* groups 38-50 */
391
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
392
- /* int combiner group 51 */
393
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
394
- /* group 52 */
395
- { },
396
- /* int combiner group 53 */
397
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
398
- /* groups 54-63 */
399
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
400
-};
401
-
402
#define EXYNOS4210_GIC_NIRQ 160
403
404
#define EXYNOS4210_EXT_GIC_CPU_REGION_SIZE 0x10000
405
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
406
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
407
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
408
409
-/*
410
- * Initialize board IRQs.
411
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
412
- */
413
-void exynos4210_init_board_irqs(Exynos4210State *s)
72
-{
414
-{
73
- TCGv_i32 tcg_excp = tcg_const_i32(excp);
415
- uint32_t grp, bit, irq_id, n;
74
- TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
416
- Exynos4210Irq *is = &s->irqs;
75
- TCGv_i32 tcg_el = tcg_const_i32(target_el);
417
-
76
-
418
- for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
77
- gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
419
- irq_id = 0;
78
- tcg_syn, tcg_el);
420
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
79
- tcg_temp_free_i32(tcg_el);
421
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
80
- tcg_temp_free_i32(tcg_syn);
422
- /* MCT_G0 is passed to External GIC */
81
- tcg_temp_free_i32(tcg_excp);
423
- irq_id = EXT_GIC_ID_MCT_G0;
424
- }
425
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
426
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
427
- /* MCT_G1 is passed to External and GIC */
428
- irq_id = EXT_GIC_ID_MCT_G1;
429
- }
430
- if (irq_id) {
431
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
432
- is->ext_gic_irq[irq_id - 32]);
433
- } else {
434
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
435
- is->ext_combiner_irq[n]);
436
- }
437
- }
438
- for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
439
- /* these IDs are passed to Internal Combiner and External GIC */
440
- grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
441
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
442
- irq_id = combiner_grp_to_gic_id[grp -
443
- EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
444
-
445
- if (irq_id) {
446
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
447
- is->ext_gic_irq[irq_id - 32]);
448
- }
449
- }
82
-}
450
-}
83
-
451
-
84
static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
452
-/*
85
{
453
- * Get IRQ number from exynos4210 IRQ subsystem stub.
86
gen_a64_set_pc_im(s->pc - offset);
454
- * To identify IRQ source use internal combiner group and bit number
87
@@ -XXX,XX +XXX,XX @@ static void gen_step_complete_exception(DisasContext *s)
455
- * grp - group number
88
* of the exception, and our syndrome information is always correct.
456
- * bit - bit number inside group
89
*/
457
- */
90
gen_ss_advance(s);
458
-uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
91
- gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
92
- default_exception_el(s));
93
+ gen_swstep_exception(s, 1, s->is_ldex);
94
s->base.is_jmp = DISAS_NORETURN;
95
}
96
97
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
98
* bits should be zero.
99
*/
100
assert(dc->base.num_insns == 1);
101
- gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
102
- default_exception_el(dc));
103
+ gen_swstep_exception(dc, 0, 0);
104
dc->base.is_jmp = DISAS_NORETURN;
105
} else {
106
disas_a64_insn(env, dc);
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal(int excp)
112
tcg_temp_free_i32(tcg_excp);
113
}
114
115
-static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
116
-{
459
-{
117
- TCGv_i32 tcg_excp = tcg_const_i32(excp);
460
- return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
118
- TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
119
- TCGv_i32 tcg_el = tcg_const_i32(target_el);
120
-
121
- gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
122
- tcg_syn, tcg_el);
123
-
124
- tcg_temp_free_i32(tcg_el);
125
- tcg_temp_free_i32(tcg_syn);
126
- tcg_temp_free_i32(tcg_excp);
127
-}
461
-}
128
-
462
-
129
static void gen_step_complete_exception(DisasContext *s)
463
-/********* GIC part *********/
130
{
464
-
131
/* We just completed step of an insn. Move from Active-not-pending
465
#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
132
@@ -XXX,XX +XXX,XX @@ static void gen_step_complete_exception(DisasContext *s)
466
OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
133
* of the exception, and our syndrome information is always correct.
467
134
*/
135
gen_ss_advance(s);
136
- gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
137
- default_exception_el(s));
138
+ gen_swstep_exception(s, 1, s->is_ldex);
139
s->base.is_jmp = DISAS_NORETURN;
140
}
141
142
@@ -XXX,XX +XXX,XX @@ static bool arm_pre_translate_insn(DisasContext *dc)
143
* bits should be zero.
144
*/
145
assert(dc->base.num_insns == 1);
146
- gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
147
- default_exception_el(dc));
148
+ gen_swstep_exception(dc, 0, 0);
149
dc->base.is_jmp = DISAS_NORETURN;
150
return true;
151
}
152
--
468
--
153
2.20.1
469
2.25.1
154
155
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Switch the creation of the external GIC to the new-style "embedded in
2
state struct" approach, so we can easily refer to the object
3
elsewhere during realize.
2
4
3
Unlike the other more generic gen_exception{,_internal}_insn
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
interfaces, breakpoints always refer to the current instruction.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-9-peter.maydell@linaro.org
8
---
9
include/hw/arm/exynos4210.h | 2 ++
10
include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++
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
5
16
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190807045335.1361-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 7 +++----
13
target/arm/translate.c | 8 ++++----
14
2 files changed, 7 insertions(+), 8 deletions(-)
15
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
19
--- a/include/hw/arm/exynos4210.h
19
+++ b/target/arm/translate-a64.c
20
+++ b/include/hw/arm/exynos4210.h
20
@@ -XXX,XX +XXX,XX @@ static void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
21
@@ -XXX,XX +XXX,XX @@
21
s->base.is_jmp = DISAS_NORETURN;
22
#include "hw/or-irq.h"
23
#include "hw/sysbus.h"
24
#include "hw/cpu/a9mpcore.h"
25
+#include "hw/intc/exynos4210_gic.h"
26
#include "target/arm/cpu-qom.h"
27
#include "qom/object.h"
28
29
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
30
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
31
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
32
A9MPPrivState a9mpcore;
33
+ Exynos4210GicState ext_gic;
34
};
35
36
#define TYPE_EXYNOS4210_SOC "exynos4210"
37
diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_gic.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Samsung exynos4210 GIC implementation. Based on hw/arm_gic.c
45
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
59
+ * See the GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+#ifndef HW_INTC_EXYNOS4210_GIC_H
65
+#define HW_INTC_EXYNOS4210_GIC_H
66
+
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
}
107
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
108
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
109
+ s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
110
}
111
112
/* Internal Interrupt Combiner */
113
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
114
}
115
116
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
117
+ object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
22
}
118
}
23
119
24
-static void gen_exception_bkpt_insn(DisasContext *s, int offset,
120
static void exynos4210_class_init(ObjectClass *klass, void *data)
25
- uint32_t syndrome)
121
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
26
+static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syndrome)
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)
27
{
152
{
28
TCGv_i32 tcg_syn;
153
Exynos4210GicState *s = (Exynos4210GicState *)opaque;
29
154
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
30
- gen_a64_set_pc_im(s->base.pc_next - offset);
155
* enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
31
+ gen_a64_set_pc_im(s->pc_curr);
156
* doesn't figure this out, otherwise and gives spurious warnings.
32
tcg_syn = tcg_const_i32(syndrome);
157
*/
33
gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
158
- assert(n <= EXYNOS4210_NCPUS);
34
tcg_temp_free_i32(tcg_syn);
159
+ assert(n <= EXYNOS4210_GIC_NCPUS);
35
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
160
for (i = 0; i < n; i++) {
36
break;
161
/* Map CPU interface per SMP Core */
37
}
162
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
38
/* BRK */
163
diff --git a/MAINTAINERS b/MAINTAINERS
39
- gen_exception_bkpt_insn(s, 4, syn_aa64_bkpt(imm16));
40
+ gen_exception_bkpt_insn(s, syn_aa64_bkpt(imm16));
41
break;
42
case 2:
43
if (op2_ll != 0) {
44
diff --git a/target/arm/translate.c b/target/arm/translate.c
45
index XXXXXXX..XXXXXXX 100644
164
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/translate.c
165
--- a/MAINTAINERS
47
+++ b/target/arm/translate.c
166
+++ b/MAINTAINERS
48
@@ -XXX,XX +XXX,XX @@ static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
167
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
49
s->base.is_jmp = DISAS_NORETURN;
168
L: qemu-arm@nongnu.org
50
}
169
S: Odd Fixes
51
170
F: hw/*/exynos*
52
-static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
171
-F: include/hw/arm/exynos4210.h
53
+static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
172
+F: include/hw/*/exynos*
54
{
173
55
TCGv_i32 tcg_syn;
174
Calxeda Highbank
56
175
M: Rob Herring <robh@kernel.org>
57
gen_set_condexec(s);
58
- gen_set_pc_im(s, s->base.pc_next - offset);
59
+ gen_set_pc_im(s, s->pc_curr);
60
tcg_syn = tcg_const_i32(syn);
61
gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
62
tcg_temp_free_i32(tcg_syn);
63
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
64
case 1:
65
/* bkpt */
66
ARCH(5);
67
- gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
68
+ gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm16, false));
69
break;
70
case 2:
71
/* Hypervisor call (v7) */
72
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
73
{
74
int imm8 = extract32(insn, 0, 8);
75
ARCH(5);
76
- gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
77
+ gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm8, true));
78
break;
79
}
80
81
--
176
--
82
2.20.1
177
2.25.1
83
84
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
2
8
3
This function is used in two different contexts, and it will be
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
clearer if the function is given the address to which it applies.
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(-)
5
16
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190807045335.1361-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate.c | 14 +++++++-------
13
1 file changed, 7 insertions(+), 7 deletions(-)
14
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
19
--- a/include/hw/arm/exynos4210.h
18
+++ b/target/arm/translate.c
20
+++ b/include/hw/arm/exynos4210.h
19
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
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
}
20
}
59
}
21
}
60
}
22
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
23
-static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
62
sysbus_connect_irq(busdev, n,
24
+static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
63
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
25
{
26
- /* Return true if this is a 16 bit instruction. We must be precise
27
- * about this (matching the decode). We assume that s->pc still
28
- * points to the first 16 bits of the insn.
29
+ /*
30
+ * Return true if this is a 16 bit instruction. We must be precise
31
+ * about this (matching the decode).
32
*/
33
if ((insn >> 11) < 0x1d) {
34
/* Definitely a 16-bit instruction */
35
@@ -XXX,XX +XXX,XX @@ static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
36
return false;
37
}
64
}
38
65
- for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
39
- if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
66
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
40
+ if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
67
- }
41
/* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
68
42
* is not on the next page; we merge this into a 32-bit
69
/* Internal Interrupt Combiner */
43
* insn.
70
dev = qdev_new("exynos4210.combiner");
44
@@ -XXX,XX +XXX,XX @@ static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
45
*/
72
busdev = SYS_BUS_DEVICE(dev);
46
uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
73
sysbus_realize_and_unref(busdev, &error_fatal);
47
74
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
48
- return !thumb_insn_is_16bit(s, insn);
75
- sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
49
+ return !thumb_insn_is_16bit(s, s->pc, insn);
76
+ sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
50
}
51
52
static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
53
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
54
}
77
}
55
78
exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
56
insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
79
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
57
- is_16bit = thumb_insn_is_16bit(dc, insn);
58
+ is_16bit = thumb_insn_is_16bit(dc, dc->pc, insn);
59
dc->pc += 2;
60
if (!is_16bit) {
61
uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
62
--
80
--
63
2.20.1
81
2.25.1
64
65
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The function exynos4210_combiner_get_gpioin() currently lives in
2
exynos4210_combiner.c, but it isn't really part of the combiner
3
device itself -- it is a function that implements the wiring up of
4
some interrupt sources to multiple combiner inputs. Move it to live
5
with the other SoC-level code in exynos4210.c, along with a few
6
macros previously defined in exynos4210.h which are now used only
7
in exynos4210.c.
2
8
3
The offset is variable depending on the instruction set.
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Passing in the actual value is clearer in intent.
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-11-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 11 -----
14
hw/arm/exynos4210.c | 82 +++++++++++++++++++++++++++++++++++
15
hw/intc/exynos4210_combiner.c | 77 --------------------------------
16
3 files changed, 82 insertions(+), 88 deletions(-)
5
17
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190807045335.1361-9-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 8 ++++----
13
target/arm/translate.c | 8 ++++----
14
2 files changed, 8 insertions(+), 8 deletions(-)
15
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
20
--- a/include/hw/arm/exynos4210.h
19
+++ b/target/arm/translate-a64.c
21
+++ b/include/hw/arm/exynos4210.h
20
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal(int excp)
22
@@ -XXX,XX +XXX,XX @@
21
tcg_temp_free_i32(tcg_excp);
23
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
24
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
25
26
-#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
27
-#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
28
-#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
29
- ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
30
-
31
/* IRQs number for external and internal GIC */
32
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
33
#define EXYNOS4210_INT_GIC_NIRQ 64
34
@@ -XXX,XX +XXX,XX @@ void exynos4210_write_secondary(ARMCPU *cpu,
35
* bit - bit number inside group */
36
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
37
38
-/*
39
- * Get Combiner input GPIO into irqs structure
40
- */
41
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
42
- int ext);
43
-
44
/*
45
* exynos4210 UART
46
*/
47
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/exynos4210.c
50
+++ b/hw/arm/exynos4210.c
51
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
52
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
53
};
54
55
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
56
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
57
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
58
+ ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
59
+
60
/*
61
* Initialize board IRQs.
62
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
63
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
64
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
22
}
65
}
23
66
24
-static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
67
+/*
25
+static void gen_exception_internal_insn(DisasContext *s, uint64_t pc, int excp)
68
+ * Get Combiner input GPIO into irqs structure
69
+ */
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
71
+ DeviceState *dev, int ext)
72
+{
73
+ int n;
74
+ int bit;
75
+ int max;
76
+ qemu_irq *irq;
77
+
78
+ max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
79
+ EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
80
+ irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
81
+
82
+ /*
83
+ * Some IRQs of Int/External Combiner are going to two Combiners groups,
84
+ * so let split them.
85
+ */
86
+ for (n = 0; n < max; n++) {
87
+
88
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
89
+
90
+ switch (n) {
91
+ /* MDNIE_LCD1 INTG1 */
92
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
93
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
94
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
95
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
96
+ continue;
97
+
98
+ /* TMU INTG3 */
99
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
100
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
101
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
102
+ continue;
103
+
104
+ /* LCD1 INTG12 */
105
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
106
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
107
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
108
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
109
+ continue;
110
+
111
+ /* Multi-Core Timer INTG12 */
112
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
113
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
114
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
115
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
116
+ continue;
117
+
118
+ /* Multi-Core Timer INTG35 */
119
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
120
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
121
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
122
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
123
+ continue;
124
+
125
+ /* Multi-Core Timer INTG51 */
126
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
127
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
128
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
129
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
130
+ continue;
131
+
132
+ /* Multi-Core Timer INTG53 */
133
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
134
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
135
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
136
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
137
+ continue;
138
+ }
139
+
140
+ irq[n] = qdev_get_gpio_in(dev, n);
141
+ }
142
+}
143
+
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
145
0x09, 0x00, 0x00, 0x00 };
146
147
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/hw/intc/exynos4210_combiner.c
150
+++ b/hw/intc/exynos4210_combiner.c
151
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_exynos4210_combiner = {
152
}
153
};
154
155
-/*
156
- * Get Combiner input GPIO into irqs structure
157
- */
158
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
159
- int ext)
160
-{
161
- int n;
162
- int bit;
163
- int max;
164
- qemu_irq *irq;
165
-
166
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
167
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
168
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
169
-
170
- /*
171
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
172
- * so let split them.
173
- */
174
- for (n = 0; n < max; n++) {
175
-
176
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
177
-
178
- switch (n) {
179
- /* MDNIE_LCD1 INTG1 */
180
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
181
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
182
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
183
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
184
- continue;
185
-
186
- /* TMU INTG3 */
187
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
188
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
189
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
190
- continue;
191
-
192
- /* LCD1 INTG12 */
193
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
194
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
195
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
196
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
197
- continue;
198
-
199
- /* Multi-Core Timer INTG12 */
200
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
201
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
202
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
203
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
204
- continue;
205
-
206
- /* Multi-Core Timer INTG35 */
207
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
208
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
209
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
210
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
211
- continue;
212
-
213
- /* Multi-Core Timer INTG51 */
214
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
215
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
216
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
217
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
218
- continue;
219
-
220
- /* Multi-Core Timer INTG53 */
221
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
222
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
223
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
224
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
225
- continue;
226
- }
227
-
228
- irq[n] = qdev_get_gpio_in(dev, n);
229
- }
230
-}
231
-
232
static uint64_t
233
exynos4210_combiner_read(void *opaque, hwaddr offset, unsigned size)
26
{
234
{
27
- gen_a64_set_pc_im(s->base.pc_next - offset);
28
+ gen_a64_set_pc_im(pc);
29
gen_exception_internal(excp);
30
s->base.is_jmp = DISAS_NORETURN;
31
}
32
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
33
break;
34
}
35
#endif
36
- gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
37
+ gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
38
} else {
39
unsupported_encoding(s, insn);
40
}
41
@@ -XXX,XX +XXX,XX @@ static bool aarch64_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
42
/* End the TB early; it likely won't be executed */
43
dc->base.is_jmp = DISAS_TOO_MANY;
44
} else {
45
- gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
46
+ gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
47
/* The address covered by the breakpoint must be
48
included in [tb->pc, tb->pc + tb->size) in order
49
to for it to be properly cleared -- thus we
50
diff --git a/target/arm/translate.c b/target/arm/translate.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate.c
53
+++ b/target/arm/translate.c
54
@@ -XXX,XX +XXX,XX @@ static inline void gen_smc(DisasContext *s)
55
s->base.is_jmp = DISAS_SMC;
56
}
57
58
-static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
59
+static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
60
{
61
gen_set_condexec(s);
62
- gen_set_pc_im(s, s->base.pc_next - offset);
63
+ gen_set_pc_im(s, pc);
64
gen_exception_internal(excp);
65
s->base.is_jmp = DISAS_NORETURN;
66
}
67
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
68
s->current_el != 0 &&
69
#endif
70
(imm == (s->thumb ? 0x3c : 0xf000))) {
71
- gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
72
+ gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
73
return;
74
}
75
76
@@ -XXX,XX +XXX,XX @@ static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
77
/* End the TB early; it's likely not going to be executed */
78
dc->base.is_jmp = DISAS_TOO_MANY;
79
} else {
80
- gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
81
+ gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
82
/* The address covered by the breakpoint must be
83
included in [tb->pc, tb->pc + tb->size) in order
84
to for it to be properly cleared -- thus we
85
--
235
--
86
2.20.1
236
2.25.1
87
88
diff view generated by jsdifflib
New patch
1
Delete a couple of #defines which are never used.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220404154658.565020-12-peter.maydell@linaro.org
6
---
7
include/hw/arm/exynos4210.h | 4 ----
8
1 file changed, 4 deletions(-)
9
10
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/include/hw/arm/exynos4210.h
13
+++ b/include/hw/arm/exynos4210.h
14
@@ -XXX,XX +XXX,XX @@
15
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
16
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
17
18
-/* IRQs number for external and internal GIC */
19
-#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
20
-#define EXYNOS4210_INT_GIC_NIRQ 64
21
-
22
#define EXYNOS4210_I2C_NUMBER 9
23
24
#define EXYNOS4210_NUM_DMA 3
25
--
26
2.25.1
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
2
instead of qemu_irq_split().
2
3
3
Replace the zynq_slcr registers enum and macros using the
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
hw/registerfields.h macros.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
7
---
8
include/hw/arm/exynos4210.h | 9 ++++++++
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
10
2 files changed, 42 insertions(+), 8 deletions(-)
5
11
6
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
12
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20190729145654.14644-30-damien.hedde@greensocs.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/misc/zynq_slcr.c | 450 ++++++++++++++++++++++----------------------
13
1 file changed, 225 insertions(+), 225 deletions(-)
14
15
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/zynq_slcr.c
14
--- a/include/hw/arm/exynos4210.h
18
+++ b/hw/misc/zynq_slcr.c
15
+++ b/include/hw/arm/exynos4210.h
19
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
20
#include "sysemu/sysemu.h"
17
#include "hw/sysbus.h"
21
#include "qemu/log.h"
18
#include "hw/cpu/a9mpcore.h"
22
#include "qemu/module.h"
19
#include "hw/intc/exynos4210_gic.h"
23
+#include "hw/registerfields.h"
20
+#include "hw/core/split-irq.h"
24
21
#include "target/arm/cpu-qom.h"
25
#ifndef ZYNQ_SLCR_ERR_DEBUG
22
#include "qom/object.h"
26
#define ZYNQ_SLCR_ERR_DEBUG 0
23
27
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
28
#define XILINX_LOCK_KEY 0x767b
25
29
#define XILINX_UNLOCK_KEY 0xdf0d
26
#define EXYNOS4210_NUM_DMA 3
30
27
31
-#define R_PSS_RST_CTRL_SOFT_RST 0x1
28
+/*
32
+REG32(SCL, 0x000)
29
+ * We need one splitter for every external combiner input, plus
33
+REG32(LOCK, 0x004)
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
34
+REG32(UNLOCK, 0x008)
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
35
+REG32(LOCKSTA, 0x00c)
32
+ */
36
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
37
-enum {
34
+
38
- SCL = 0x000 / 4,
35
typedef struct Exynos4210Irq {
39
- LOCK,
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
40
- UNLOCK,
37
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
41
- LOCKSTA,
38
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
42
+REG32(ARM_PLL_CTRL, 0x100)
39
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
43
+REG32(DDR_PLL_CTRL, 0x104)
40
A9MPPrivState a9mpcore;
44
+REG32(IO_PLL_CTRL, 0x108)
41
Exynos4210GicState ext_gic;
45
+REG32(PLL_STATUS, 0x10c)
42
+ SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
46
+REG32(ARM_PLL_CFG, 0x110)
43
};
47
+REG32(DDR_PLL_CFG, 0x114)
44
48
+REG32(IO_PLL_CFG, 0x118)
45
#define TYPE_EXYNOS4210_SOC "exynos4210"
49
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
50
- ARM_PLL_CTRL = 0x100 / 4,
47
index XXXXXXX..XXXXXXX 100644
51
- DDR_PLL_CTRL,
48
--- a/hw/arm/exynos4210.c
52
- IO_PLL_CTRL,
49
+++ b/hw/arm/exynos4210.c
53
- PLL_STATUS,
50
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
54
- ARM_PLL_CFG,
51
uint32_t grp, bit, irq_id, n;
55
- DDR_PLL_CFG,
52
Exynos4210Irq *is = &s->irqs;
56
- IO_PLL_CFG,
53
DeviceState *extgicdev = DEVICE(&s->ext_gic);
57
-
54
+ int splitcount = 0;
58
- ARM_CLK_CTRL = 0x120 / 4,
55
+ DeviceState *splitter;
59
- DDR_CLK_CTRL,
56
60
- DCI_CLK_CTRL,
57
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
61
- APER_CLK_CTRL,
58
irq_id = 0;
62
- USB0_CLK_CTRL,
59
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
63
- USB1_CLK_CTRL,
60
/* MCT_G1 is passed to External and GIC */
64
- GEM0_RCLK_CTRL,
61
irq_id = EXT_GIC_ID_MCT_G1;
65
- GEM1_RCLK_CTRL,
62
}
66
- GEM0_CLK_CTRL,
63
+
67
- GEM1_CLK_CTRL,
64
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
68
- SMC_CLK_CTRL,
65
+ splitter = DEVICE(&s->splitter[splitcount]);
69
- LQSPI_CLK_CTRL,
66
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
70
- SDIO_CLK_CTRL,
67
+ qdev_realize(splitter, NULL, &error_abort);
71
- UART_CLK_CTRL,
68
+ splitcount++;
72
- SPI_CLK_CTRL,
69
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
73
- CAN_CLK_CTRL,
70
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
74
- CAN_MIOCLK_CTRL,
71
if (irq_id) {
75
- DBG_CLK_CTRL,
72
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
76
- PCAP_CLK_CTRL,
73
- qdev_get_gpio_in(extgicdev,
77
- TOPSW_CLK_CTRL,
74
- irq_id - 32));
78
+REG32(ARM_CLK_CTRL, 0x120)
75
+ qdev_connect_gpio_out(splitter, 1,
79
+REG32(DDR_CLK_CTRL, 0x124)
76
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
80
+REG32(DCI_CLK_CTRL, 0x128)
77
} else {
81
+REG32(APER_CLK_CTRL, 0x12c)
78
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
82
+REG32(USB0_CLK_CTRL, 0x130)
79
- is->ext_combiner_irq[n]);
83
+REG32(USB1_CLK_CTRL, 0x134)
80
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
84
+REG32(GEM0_RCLK_CTRL, 0x138)
81
}
85
+REG32(GEM1_RCLK_CTRL, 0x13c)
86
+REG32(GEM0_CLK_CTRL, 0x140)
87
+REG32(GEM1_CLK_CTRL, 0x144)
88
+REG32(SMC_CLK_CTRL, 0x148)
89
+REG32(LQSPI_CLK_CTRL, 0x14c)
90
+REG32(SDIO_CLK_CTRL, 0x150)
91
+REG32(UART_CLK_CTRL, 0x154)
92
+REG32(SPI_CLK_CTRL, 0x158)
93
+REG32(CAN_CLK_CTRL, 0x15c)
94
+REG32(CAN_MIOCLK_CTRL, 0x160)
95
+REG32(DBG_CLK_CTRL, 0x164)
96
+REG32(PCAP_CLK_CTRL, 0x168)
97
+REG32(TOPSW_CLK_CTRL, 0x16c)
98
99
#define FPGA_CTRL_REGS(n, start) \
100
- FPGA ## n ## _CLK_CTRL = (start) / 4, \
101
- FPGA ## n ## _THR_CTRL, \
102
- FPGA ## n ## _THR_CNT, \
103
- FPGA ## n ## _THR_STA,
104
- FPGA_CTRL_REGS(0, 0x170)
105
- FPGA_CTRL_REGS(1, 0x180)
106
- FPGA_CTRL_REGS(2, 0x190)
107
- FPGA_CTRL_REGS(3, 0x1a0)
108
+ REG32(FPGA ## n ## _CLK_CTRL, (start)) \
109
+ REG32(FPGA ## n ## _THR_CTRL, (start) + 0x4)\
110
+ REG32(FPGA ## n ## _THR_CNT, (start) + 0x8)\
111
+ REG32(FPGA ## n ## _THR_STA, (start) + 0xc)
112
+FPGA_CTRL_REGS(0, 0x170)
113
+FPGA_CTRL_REGS(1, 0x180)
114
+FPGA_CTRL_REGS(2, 0x190)
115
+FPGA_CTRL_REGS(3, 0x1a0)
116
117
- BANDGAP_TRIP = 0x1b8 / 4,
118
- PLL_PREDIVISOR = 0x1c0 / 4,
119
- CLK_621_TRUE,
120
+REG32(BANDGAP_TRIP, 0x1b8)
121
+REG32(PLL_PREDIVISOR, 0x1c0)
122
+REG32(CLK_621_TRUE, 0x1c4)
123
124
- PSS_RST_CTRL = 0x200 / 4,
125
- DDR_RST_CTRL,
126
- TOPSW_RESET_CTRL,
127
- DMAC_RST_CTRL,
128
- USB_RST_CTRL,
129
- GEM_RST_CTRL,
130
- SDIO_RST_CTRL,
131
- SPI_RST_CTRL,
132
- CAN_RST_CTRL,
133
- I2C_RST_CTRL,
134
- UART_RST_CTRL,
135
- GPIO_RST_CTRL,
136
- LQSPI_RST_CTRL,
137
- SMC_RST_CTRL,
138
- OCM_RST_CTRL,
139
- FPGA_RST_CTRL = 0x240 / 4,
140
- A9_CPU_RST_CTRL,
141
+REG32(PSS_RST_CTRL, 0x200)
142
+ FIELD(PSS_RST_CTRL, SOFT_RST, 0, 1)
143
+REG32(DDR_RST_CTRL, 0x204)
144
+REG32(TOPSW_RESET_CTRL, 0x208)
145
+REG32(DMAC_RST_CTRL, 0x20c)
146
+REG32(USB_RST_CTRL, 0x210)
147
+REG32(GEM_RST_CTRL, 0x214)
148
+REG32(SDIO_RST_CTRL, 0x218)
149
+REG32(SPI_RST_CTRL, 0x21c)
150
+REG32(CAN_RST_CTRL, 0x220)
151
+REG32(I2C_RST_CTRL, 0x224)
152
+REG32(UART_RST_CTRL, 0x228)
153
+REG32(GPIO_RST_CTRL, 0x22c)
154
+REG32(LQSPI_RST_CTRL, 0x230)
155
+REG32(SMC_RST_CTRL, 0x234)
156
+REG32(OCM_RST_CTRL, 0x238)
157
+REG32(FPGA_RST_CTRL, 0x240)
158
+REG32(A9_CPU_RST_CTRL, 0x244)
159
160
- RS_AWDT_CTRL = 0x24c / 4,
161
- RST_REASON,
162
+REG32(RS_AWDT_CTRL, 0x24c)
163
+REG32(RST_REASON, 0x250)
164
165
- REBOOT_STATUS = 0x258 / 4,
166
- BOOT_MODE,
167
+REG32(REBOOT_STATUS, 0x258)
168
+REG32(BOOT_MODE, 0x25c)
169
170
- APU_CTRL = 0x300 / 4,
171
- WDT_CLK_SEL,
172
+REG32(APU_CTRL, 0x300)
173
+REG32(WDT_CLK_SEL, 0x304)
174
175
- TZ_DMA_NS = 0x440 / 4,
176
- TZ_DMA_IRQ_NS,
177
- TZ_DMA_PERIPH_NS,
178
+REG32(TZ_DMA_NS, 0x440)
179
+REG32(TZ_DMA_IRQ_NS, 0x444)
180
+REG32(TZ_DMA_PERIPH_NS, 0x448)
181
182
- PSS_IDCODE = 0x530 / 4,
183
+REG32(PSS_IDCODE, 0x530)
184
185
- DDR_URGENT = 0x600 / 4,
186
- DDR_CAL_START = 0x60c / 4,
187
- DDR_REF_START = 0x614 / 4,
188
- DDR_CMD_STA,
189
- DDR_URGENT_SEL,
190
- DDR_DFI_STATUS,
191
+REG32(DDR_URGENT, 0x600)
192
+REG32(DDR_CAL_START, 0x60c)
193
+REG32(DDR_REF_START, 0x614)
194
+REG32(DDR_CMD_STA, 0x618)
195
+REG32(DDR_URGENT_SEL, 0x61c)
196
+REG32(DDR_DFI_STATUS, 0x620)
197
198
- MIO = 0x700 / 4,
199
+REG32(MIO, 0x700)
200
#define MIO_LENGTH 54
201
202
- MIO_LOOPBACK = 0x804 / 4,
203
- MIO_MST_TRI0,
204
- MIO_MST_TRI1,
205
+REG32(MIO_LOOPBACK, 0x804)
206
+REG32(MIO_MST_TRI0, 0x808)
207
+REG32(MIO_MST_TRI1, 0x80c)
208
209
- SD0_WP_CD_SEL = 0x830 / 4,
210
- SD1_WP_CD_SEL,
211
+REG32(SD0_WP_CD_SEL, 0x830)
212
+REG32(SD1_WP_CD_SEL, 0x834)
213
214
- LVL_SHFTR_EN = 0x900 / 4,
215
- OCM_CFG = 0x910 / 4,
216
+REG32(LVL_SHFTR_EN, 0x900)
217
+REG32(OCM_CFG, 0x910)
218
219
- CPU_RAM = 0xa00 / 4,
220
+REG32(CPU_RAM, 0xa00)
221
222
- IOU = 0xa30 / 4,
223
+REG32(IOU, 0xa30)
224
225
- DMAC_RAM = 0xa50 / 4,
226
+REG32(DMAC_RAM, 0xa50)
227
228
- AFI0 = 0xa60 / 4,
229
- AFI1 = AFI0 + 3,
230
- AFI2 = AFI1 + 3,
231
- AFI3 = AFI2 + 3,
232
+REG32(AFI0, 0xa60)
233
+REG32(AFI1, 0xa6c)
234
+REG32(AFI2, 0xa78)
235
+REG32(AFI3, 0xa84)
236
#define AFI_LENGTH 3
237
238
- OCM = 0xa90 / 4,
239
+REG32(OCM, 0xa90)
240
241
- DEVCI_RAM = 0xaa0 / 4,
242
+REG32(DEVCI_RAM, 0xaa0)
243
244
- CSG_RAM = 0xab0 / 4,
245
+REG32(CSG_RAM, 0xab0)
246
247
- GPIOB_CTRL = 0xb00 / 4,
248
- GPIOB_CFG_CMOS18,
249
- GPIOB_CFG_CMOS25,
250
- GPIOB_CFG_CMOS33,
251
- GPIOB_CFG_HSTL = 0xb14 / 4,
252
- GPIOB_DRVR_BIAS_CTRL,
253
+REG32(GPIOB_CTRL, 0xb00)
254
+REG32(GPIOB_CFG_CMOS18, 0xb04)
255
+REG32(GPIOB_CFG_CMOS25, 0xb08)
256
+REG32(GPIOB_CFG_CMOS33, 0xb0c)
257
+REG32(GPIOB_CFG_HSTL, 0xb14)
258
+REG32(GPIOB_DRVR_BIAS_CTRL, 0xb18)
259
260
- DDRIOB = 0xb40 / 4,
261
+REG32(DDRIOB, 0xb40)
262
#define DDRIOB_LENGTH 14
263
-};
264
265
#define ZYNQ_SLCR_MMIO_SIZE 0x1000
266
#define ZYNQ_SLCR_NUM_REGS (ZYNQ_SLCR_MMIO_SIZE / 4)
267
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_reset(DeviceState *d)
268
269
DB_PRINT("RESET\n");
270
271
- s->regs[LOCKSTA] = 1;
272
+ s->regs[R_LOCKSTA] = 1;
273
/* 0x100 - 0x11C */
274
- s->regs[ARM_PLL_CTRL] = 0x0001A008;
275
- s->regs[DDR_PLL_CTRL] = 0x0001A008;
276
- s->regs[IO_PLL_CTRL] = 0x0001A008;
277
- s->regs[PLL_STATUS] = 0x0000003F;
278
- s->regs[ARM_PLL_CFG] = 0x00014000;
279
- s->regs[DDR_PLL_CFG] = 0x00014000;
280
- s->regs[IO_PLL_CFG] = 0x00014000;
281
+ s->regs[R_ARM_PLL_CTRL] = 0x0001A008;
282
+ s->regs[R_DDR_PLL_CTRL] = 0x0001A008;
283
+ s->regs[R_IO_PLL_CTRL] = 0x0001A008;
284
+ s->regs[R_PLL_STATUS] = 0x0000003F;
285
+ s->regs[R_ARM_PLL_CFG] = 0x00014000;
286
+ s->regs[R_DDR_PLL_CFG] = 0x00014000;
287
+ s->regs[R_IO_PLL_CFG] = 0x00014000;
288
289
/* 0x120 - 0x16C */
290
- s->regs[ARM_CLK_CTRL] = 0x1F000400;
291
- s->regs[DDR_CLK_CTRL] = 0x18400003;
292
- s->regs[DCI_CLK_CTRL] = 0x01E03201;
293
- s->regs[APER_CLK_CTRL] = 0x01FFCCCD;
294
- s->regs[USB0_CLK_CTRL] = s->regs[USB1_CLK_CTRL] = 0x00101941;
295
- s->regs[GEM0_RCLK_CTRL] = s->regs[GEM1_RCLK_CTRL] = 0x00000001;
296
- s->regs[GEM0_CLK_CTRL] = s->regs[GEM1_CLK_CTRL] = 0x00003C01;
297
- s->regs[SMC_CLK_CTRL] = 0x00003C01;
298
- s->regs[LQSPI_CLK_CTRL] = 0x00002821;
299
- s->regs[SDIO_CLK_CTRL] = 0x00001E03;
300
- s->regs[UART_CLK_CTRL] = 0x00003F03;
301
- s->regs[SPI_CLK_CTRL] = 0x00003F03;
302
- s->regs[CAN_CLK_CTRL] = 0x00501903;
303
- s->regs[DBG_CLK_CTRL] = 0x00000F03;
304
- s->regs[PCAP_CLK_CTRL] = 0x00000F01;
305
+ s->regs[R_ARM_CLK_CTRL] = 0x1F000400;
306
+ s->regs[R_DDR_CLK_CTRL] = 0x18400003;
307
+ s->regs[R_DCI_CLK_CTRL] = 0x01E03201;
308
+ s->regs[R_APER_CLK_CTRL] = 0x01FFCCCD;
309
+ s->regs[R_USB0_CLK_CTRL] = s->regs[R_USB1_CLK_CTRL] = 0x00101941;
310
+ s->regs[R_GEM0_RCLK_CTRL] = s->regs[R_GEM1_RCLK_CTRL] = 0x00000001;
311
+ s->regs[R_GEM0_CLK_CTRL] = s->regs[R_GEM1_CLK_CTRL] = 0x00003C01;
312
+ s->regs[R_SMC_CLK_CTRL] = 0x00003C01;
313
+ s->regs[R_LQSPI_CLK_CTRL] = 0x00002821;
314
+ s->regs[R_SDIO_CLK_CTRL] = 0x00001E03;
315
+ s->regs[R_UART_CLK_CTRL] = 0x00003F03;
316
+ s->regs[R_SPI_CLK_CTRL] = 0x00003F03;
317
+ s->regs[R_CAN_CLK_CTRL] = 0x00501903;
318
+ s->regs[R_DBG_CLK_CTRL] = 0x00000F03;
319
+ s->regs[R_PCAP_CLK_CTRL] = 0x00000F01;
320
321
/* 0x170 - 0x1AC */
322
- s->regs[FPGA0_CLK_CTRL] = s->regs[FPGA1_CLK_CTRL] = s->regs[FPGA2_CLK_CTRL]
323
- = s->regs[FPGA3_CLK_CTRL] = 0x00101800;
324
- s->regs[FPGA0_THR_STA] = s->regs[FPGA1_THR_STA] = s->regs[FPGA2_THR_STA]
325
- = s->regs[FPGA3_THR_STA] = 0x00010000;
326
+ s->regs[R_FPGA0_CLK_CTRL] = s->regs[R_FPGA1_CLK_CTRL]
327
+ = s->regs[R_FPGA2_CLK_CTRL]
328
+ = s->regs[R_FPGA3_CLK_CTRL] = 0x00101800;
329
+ s->regs[R_FPGA0_THR_STA] = s->regs[R_FPGA1_THR_STA]
330
+ = s->regs[R_FPGA2_THR_STA]
331
+ = s->regs[R_FPGA3_THR_STA] = 0x00010000;
332
333
/* 0x1B0 - 0x1D8 */
334
- s->regs[BANDGAP_TRIP] = 0x0000001F;
335
- s->regs[PLL_PREDIVISOR] = 0x00000001;
336
- s->regs[CLK_621_TRUE] = 0x00000001;
337
+ s->regs[R_BANDGAP_TRIP] = 0x0000001F;
338
+ s->regs[R_PLL_PREDIVISOR] = 0x00000001;
339
+ s->regs[R_CLK_621_TRUE] = 0x00000001;
340
341
/* 0x200 - 0x25C */
342
- s->regs[FPGA_RST_CTRL] = 0x01F33F0F;
343
- s->regs[RST_REASON] = 0x00000040;
344
+ s->regs[R_FPGA_RST_CTRL] = 0x01F33F0F;
345
+ s->regs[R_RST_REASON] = 0x00000040;
346
347
- s->regs[BOOT_MODE] = 0x00000001;
348
+ s->regs[R_BOOT_MODE] = 0x00000001;
349
350
/* 0x700 - 0x7D4 */
351
for (i = 0; i < 54; i++) {
352
- s->regs[MIO + i] = 0x00001601;
353
+ s->regs[R_MIO + i] = 0x00001601;
354
}
82
}
355
for (i = 2; i <= 8; i++) {
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
356
- s->regs[MIO + i] = 0x00000601;
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
357
+ s->regs[R_MIO + i] = 0x00000601;
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
86
87
if (irq_id) {
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
89
- qdev_get_gpio_in(extgicdev,
90
- irq_id - 32));
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
92
+ splitter = DEVICE(&s->splitter[splitcount]);
93
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
94
+ qdev_realize(splitter, NULL, &error_abort);
95
+ splitcount++;
96
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
97
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
98
+ qdev_connect_gpio_out(splitter, 1,
99
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
100
}
358
}
101
}
359
102
+ /*
360
- s->regs[MIO_MST_TRI0] = s->regs[MIO_MST_TRI1] = 0xFFFFFFFF;
103
+ * We check this here to avoid a more obscure assert later when
361
+ s->regs[R_MIO_MST_TRI0] = s->regs[R_MIO_MST_TRI1] = 0xFFFFFFFF;
104
+ * qdev_assert_realized_properly() checks that we realized every
362
105
+ * child object we initialized.
363
- s->regs[CPU_RAM + 0] = s->regs[CPU_RAM + 1] = s->regs[CPU_RAM + 3]
106
+ */
364
- = s->regs[CPU_RAM + 4] = s->regs[CPU_RAM + 7]
107
+ assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
365
- = 0x00010101;
366
- s->regs[CPU_RAM + 2] = s->regs[CPU_RAM + 5] = 0x01010101;
367
- s->regs[CPU_RAM + 6] = 0x00000001;
368
+ s->regs[R_CPU_RAM + 0] = s->regs[R_CPU_RAM + 1] = s->regs[R_CPU_RAM + 3]
369
+ = s->regs[R_CPU_RAM + 4] = s->regs[R_CPU_RAM + 7]
370
+ = 0x00010101;
371
+ s->regs[R_CPU_RAM + 2] = s->regs[R_CPU_RAM + 5] = 0x01010101;
372
+ s->regs[R_CPU_RAM + 6] = 0x00000001;
373
374
- s->regs[IOU + 0] = s->regs[IOU + 1] = s->regs[IOU + 2] = s->regs[IOU + 3]
375
- = 0x09090909;
376
- s->regs[IOU + 4] = s->regs[IOU + 5] = 0x00090909;
377
- s->regs[IOU + 6] = 0x00000909;
378
+ s->regs[R_IOU + 0] = s->regs[R_IOU + 1] = s->regs[R_IOU + 2]
379
+ = s->regs[R_IOU + 3] = 0x09090909;
380
+ s->regs[R_IOU + 4] = s->regs[R_IOU + 5] = 0x00090909;
381
+ s->regs[R_IOU + 6] = 0x00000909;
382
383
- s->regs[DMAC_RAM] = 0x00000009;
384
+ s->regs[R_DMAC_RAM] = 0x00000009;
385
386
- s->regs[AFI0 + 0] = s->regs[AFI0 + 1] = 0x09090909;
387
- s->regs[AFI1 + 0] = s->regs[AFI1 + 1] = 0x09090909;
388
- s->regs[AFI2 + 0] = s->regs[AFI2 + 1] = 0x09090909;
389
- s->regs[AFI3 + 0] = s->regs[AFI3 + 1] = 0x09090909;
390
- s->regs[AFI0 + 2] = s->regs[AFI1 + 2] = s->regs[AFI2 + 2]
391
- = s->regs[AFI3 + 2] = 0x00000909;
392
+ s->regs[R_AFI0 + 0] = s->regs[R_AFI0 + 1] = 0x09090909;
393
+ s->regs[R_AFI1 + 0] = s->regs[R_AFI1 + 1] = 0x09090909;
394
+ s->regs[R_AFI2 + 0] = s->regs[R_AFI2 + 1] = 0x09090909;
395
+ s->regs[R_AFI3 + 0] = s->regs[R_AFI3 + 1] = 0x09090909;
396
+ s->regs[R_AFI0 + 2] = s->regs[R_AFI1 + 2] = s->regs[R_AFI2 + 2]
397
+ = s->regs[R_AFI3 + 2] = 0x00000909;
398
399
- s->regs[OCM + 0] = 0x01010101;
400
- s->regs[OCM + 1] = s->regs[OCM + 2] = 0x09090909;
401
+ s->regs[R_OCM + 0] = 0x01010101;
402
+ s->regs[R_OCM + 1] = s->regs[R_OCM + 2] = 0x09090909;
403
404
- s->regs[DEVCI_RAM] = 0x00000909;
405
- s->regs[CSG_RAM] = 0x00000001;
406
+ s->regs[R_DEVCI_RAM] = 0x00000909;
407
+ s->regs[R_CSG_RAM] = 0x00000001;
408
409
- s->regs[DDRIOB + 0] = s->regs[DDRIOB + 1] = s->regs[DDRIOB + 2]
410
- = s->regs[DDRIOB + 3] = 0x00000e00;
411
- s->regs[DDRIOB + 4] = s->regs[DDRIOB + 5] = s->regs[DDRIOB + 6]
412
- = 0x00000e00;
413
- s->regs[DDRIOB + 12] = 0x00000021;
414
+ s->regs[R_DDRIOB + 0] = s->regs[R_DDRIOB + 1] = s->regs[R_DDRIOB + 2]
415
+ = s->regs[R_DDRIOB + 3] = 0x00000e00;
416
+ s->regs[R_DDRIOB + 4] = s->regs[R_DDRIOB + 5] = s->regs[R_DDRIOB + 6]
417
+ = 0x00000e00;
418
+ s->regs[R_DDRIOB + 12] = 0x00000021;
419
}
108
}
420
109
421
110
/*
422
static bool zynq_slcr_check_offset(hwaddr offset, bool rnw)
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
423
{
112
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
424
switch (offset) {
425
- case LOCK:
426
- case UNLOCK:
427
- case DDR_CAL_START:
428
- case DDR_REF_START:
429
+ case R_LOCK:
430
+ case R_UNLOCK:
431
+ case R_DDR_CAL_START:
432
+ case R_DDR_REF_START:
433
return !rnw; /* Write only */
434
- case LOCKSTA:
435
- case FPGA0_THR_STA:
436
- case FPGA1_THR_STA:
437
- case FPGA2_THR_STA:
438
- case FPGA3_THR_STA:
439
- case BOOT_MODE:
440
- case PSS_IDCODE:
441
- case DDR_CMD_STA:
442
- case DDR_DFI_STATUS:
443
- case PLL_STATUS:
444
+ case R_LOCKSTA:
445
+ case R_FPGA0_THR_STA:
446
+ case R_FPGA1_THR_STA:
447
+ case R_FPGA2_THR_STA:
448
+ case R_FPGA3_THR_STA:
449
+ case R_BOOT_MODE:
450
+ case R_PSS_IDCODE:
451
+ case R_DDR_CMD_STA:
452
+ case R_DDR_DFI_STATUS:
453
+ case R_PLL_STATUS:
454
return rnw;/* read only */
455
- case SCL:
456
- case ARM_PLL_CTRL ... IO_PLL_CTRL:
457
- case ARM_PLL_CFG ... IO_PLL_CFG:
458
- case ARM_CLK_CTRL ... TOPSW_CLK_CTRL:
459
- case FPGA0_CLK_CTRL ... FPGA0_THR_CNT:
460
- case FPGA1_CLK_CTRL ... FPGA1_THR_CNT:
461
- case FPGA2_CLK_CTRL ... FPGA2_THR_CNT:
462
- case FPGA3_CLK_CTRL ... FPGA3_THR_CNT:
463
- case BANDGAP_TRIP:
464
- case PLL_PREDIVISOR:
465
- case CLK_621_TRUE:
466
- case PSS_RST_CTRL ... A9_CPU_RST_CTRL:
467
- case RS_AWDT_CTRL:
468
- case RST_REASON:
469
- case REBOOT_STATUS:
470
- case APU_CTRL:
471
- case WDT_CLK_SEL:
472
- case TZ_DMA_NS ... TZ_DMA_PERIPH_NS:
473
- case DDR_URGENT:
474
- case DDR_URGENT_SEL:
475
- case MIO ... MIO + MIO_LENGTH - 1:
476
- case MIO_LOOPBACK ... MIO_MST_TRI1:
477
- case SD0_WP_CD_SEL:
478
- case SD1_WP_CD_SEL:
479
- case LVL_SHFTR_EN:
480
- case OCM_CFG:
481
- case CPU_RAM:
482
- case IOU:
483
- case DMAC_RAM:
484
- case AFI0 ... AFI3 + AFI_LENGTH - 1:
485
- case OCM:
486
- case DEVCI_RAM:
487
- case CSG_RAM:
488
- case GPIOB_CTRL ... GPIOB_CFG_CMOS33:
489
- case GPIOB_CFG_HSTL:
490
- case GPIOB_DRVR_BIAS_CTRL:
491
- case DDRIOB ... DDRIOB + DDRIOB_LENGTH - 1:
492
+ case R_SCL:
493
+ case R_ARM_PLL_CTRL ... R_IO_PLL_CTRL:
494
+ case R_ARM_PLL_CFG ... R_IO_PLL_CFG:
495
+ case R_ARM_CLK_CTRL ... R_TOPSW_CLK_CTRL:
496
+ case R_FPGA0_CLK_CTRL ... R_FPGA0_THR_CNT:
497
+ case R_FPGA1_CLK_CTRL ... R_FPGA1_THR_CNT:
498
+ case R_FPGA2_CLK_CTRL ... R_FPGA2_THR_CNT:
499
+ case R_FPGA3_CLK_CTRL ... R_FPGA3_THR_CNT:
500
+ case R_BANDGAP_TRIP:
501
+ case R_PLL_PREDIVISOR:
502
+ case R_CLK_621_TRUE:
503
+ case R_PSS_RST_CTRL ... R_A9_CPU_RST_CTRL:
504
+ case R_RS_AWDT_CTRL:
505
+ case R_RST_REASON:
506
+ case R_REBOOT_STATUS:
507
+ case R_APU_CTRL:
508
+ case R_WDT_CLK_SEL:
509
+ case R_TZ_DMA_NS ... R_TZ_DMA_PERIPH_NS:
510
+ case R_DDR_URGENT:
511
+ case R_DDR_URGENT_SEL:
512
+ case R_MIO ... R_MIO + MIO_LENGTH - 1:
513
+ case R_MIO_LOOPBACK ... R_MIO_MST_TRI1:
514
+ case R_SD0_WP_CD_SEL:
515
+ case R_SD1_WP_CD_SEL:
516
+ case R_LVL_SHFTR_EN:
517
+ case R_OCM_CFG:
518
+ case R_CPU_RAM:
519
+ case R_IOU:
520
+ case R_DMAC_RAM:
521
+ case R_AFI0 ... R_AFI3 + AFI_LENGTH - 1:
522
+ case R_OCM:
523
+ case R_DEVCI_RAM:
524
+ case R_CSG_RAM:
525
+ case R_GPIOB_CTRL ... R_GPIOB_CFG_CMOS33:
526
+ case R_GPIOB_CFG_HSTL:
527
+ case R_GPIOB_DRVR_BIAS_CTRL:
528
+ case R_DDRIOB ... R_DDRIOB + DDRIOB_LENGTH - 1:
529
return true;
530
default:
531
return false;
532
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_write(void *opaque, hwaddr offset,
533
}
113
}
534
114
535
switch (offset) {
115
+ for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
536
- case SCL:
116
+ g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
537
- s->regs[SCL] = val & 0x1;
117
+ object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
538
+ case R_SCL:
118
+ }
539
+ s->regs[R_SCL] = val & 0x1;
119
+
540
return;
120
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
541
- case LOCK:
121
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
542
+ case R_LOCK:
122
}
543
if ((val & 0xFFFF) == XILINX_LOCK_KEY) {
544
DB_PRINT("XILINX LOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
545
(unsigned)val & 0xFFFF);
546
- s->regs[LOCKSTA] = 1;
547
+ s->regs[R_LOCKSTA] = 1;
548
} else {
549
DB_PRINT("WRONG XILINX LOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
550
(int)offset, (unsigned)val & 0xFFFF);
551
}
552
return;
553
- case UNLOCK:
554
+ case R_UNLOCK:
555
if ((val & 0xFFFF) == XILINX_UNLOCK_KEY) {
556
DB_PRINT("XILINX UNLOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
557
(unsigned)val & 0xFFFF);
558
- s->regs[LOCKSTA] = 0;
559
+ s->regs[R_LOCKSTA] = 0;
560
} else {
561
DB_PRINT("WRONG XILINX UNLOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
562
(int)offset, (unsigned)val & 0xFFFF);
563
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_write(void *opaque, hwaddr offset,
564
return;
565
}
566
567
- if (s->regs[LOCKSTA]) {
568
+ if (s->regs[R_LOCKSTA]) {
569
qemu_log_mask(LOG_GUEST_ERROR,
570
"SCLR registers are locked. Unlock them first\n");
571
return;
572
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_write(void *opaque, hwaddr offset,
573
s->regs[offset] = val;
574
575
switch (offset) {
576
- case PSS_RST_CTRL:
577
- if (val & R_PSS_RST_CTRL_SOFT_RST) {
578
+ case R_PSS_RST_CTRL:
579
+ if (FIELD_EX32(val, PSS_RST_CTRL, SOFT_RST)) {
580
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
581
}
582
break;
583
--
123
--
584
2.20.1
124
2.25.1
585
586
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
2
are in a range that applies to the internal combiner only creates a
3
splitter for those interrupts which go to both the internal combiner
4
and to the external GIC, but it does nothing at all for the
5
interrupts which don't go to the external GIC, leaving the
6
irq_table[] array element empty for those. (This will result in
7
those interrupts simply being lost, not in a QEMU crash.)
2
8
3
The current implementation of ZCR_ELx matches the architecture, only
9
I don't have a reliable datasheet for this SoC, but since we do wire
4
implementing the lower four bits, with the rest RAZ/WI. This puts
10
up one interrupt line in this category (the HDMI I2C device on
5
a strict limit on ARM_MAX_VQ of 16. Make sure we don't let ARM_MAX_VQ
11
interrupt 16,1), this seems like it must be a bug in the existing
6
grow without a corresponding update here.
12
QEMU code. Fill in the irq_table[] entries where we're not splitting
13
the IRQ to both the internal combiner and the external GIC with the
14
IRQ line of the internal combiner. (That is, these IRQ lines go to
15
just one device, not multiple.)
7
16
8
Suggested-by: Dave Martin <Dave.Martin@arm.com>
17
This bug didn't have any visible guest effects because the only
9
Signed-off-by: Andrew Jones <drjones@redhat.com>
18
implemented device that was affected was the HDMI I2C controller,
19
and we never connect any I2C devices to that bus.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
23
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
24
---
14
target/arm/helper.c | 1 +
25
hw/arm/exynos4210.c | 2 ++
15
1 file changed, 1 insertion(+)
26
1 file changed, 2 insertions(+)
16
27
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
18
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
30
--- a/hw/arm/exynos4210.c
20
+++ b/target/arm/helper.c
31
+++ b/hw/arm/exynos4210.c
21
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
32
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
22
int new_len;
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
23
34
qdev_connect_gpio_out(splitter, 1,
24
/* Bits other than [3:0] are RAZ/WI. */
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
25
+ QEMU_BUILD_BUG_ON(ARM_MAX_VQ > 16);
36
+ } else {
26
raw_write(env, ri, value & 0xf);
37
+ s->irq_table[n] = is->int_combiner_irq[n];
27
38
}
39
}
28
/*
40
/*
29
--
41
--
30
2.20.1
42
2.25.1
31
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Currently for the interrupts MCT_G0 and MCT_G1 which are
2
the only ones in the input range of the external combiner
3
and which are also wired to the external GIC, we connect
4
them only to the internal combiner and the external GIC.
5
This seems likely to be a bug, as all other interrupts
6
which are in the input range of both combiners are
7
connected to both combiners. (The fact that the code in
8
exynos4210_combiner_get_gpioin() is also trying to wire
9
up these inputs on both combiners also suggests this.)
2
10
3
The immediate shift generator functions already test for,
11
Wire these interrupts up to both combiners, like the rest.
4
and eliminate, the case of a shift by zero.
5
12
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190808202616.13782-4-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-15-peter.maydell@linaro.org
10
---
16
---
11
target/arm/translate.c | 19 +++++++------------
17
hw/arm/exynos4210.c | 7 +++----
12
1 file changed, 7 insertions(+), 12 deletions(-)
18
1 file changed, 3 insertions(+), 4 deletions(-)
13
19
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
22
--- a/hw/arm/exynos4210.c
17
+++ b/target/arm/translate.c
23
+++ b/hw/arm/exynos4210.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
19
shift = (insn >> 10) & 3;
25
20
/* ??? In many cases it's not necessary to do a
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
21
rotate, a shift is sufficient. */
27
splitter = DEVICE(&s->splitter[splitcount]);
22
- if (shift != 0)
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
23
- tcg_gen_rotri_i32(tmp, tmp, shift * 8);
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
24
+ tcg_gen_rotri_i32(tmp, tmp, shift * 8);
30
qdev_realize(splitter, NULL, &error_abort);
25
op1 = (insn >> 20) & 7;
31
splitcount++;
26
switch (op1) {
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
27
case 0: gen_sxtb16(tmp); break;
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
28
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
29
shift = (insn >> 4) & 3;
35
if (irq_id) {
30
/* ??? In many cases it's not necessary to do a
36
- qdev_connect_gpio_out(splitter, 1,
31
rotate, a shift is sufficient. */
37
+ qdev_connect_gpio_out(splitter, 2,
32
- if (shift != 0)
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
33
- tcg_gen_rotri_i32(tmp, tmp, shift * 8);
39
- } else {
34
+ tcg_gen_rotri_i32(tmp, tmp, shift * 8);
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
35
op = (insn >> 20) & 7;
41
}
36
switch (op) {
42
}
37
case 0: gen_sxth(tmp); break;
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
38
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
39
case 7:
40
goto illegal_op;
41
default: /* Saturate. */
42
- if (shift) {
43
- if (op & 1)
44
- tcg_gen_sari_i32(tmp, tmp, shift);
45
- else
46
- tcg_gen_shli_i32(tmp, tmp, shift);
47
+ if (op & 1) {
48
+ tcg_gen_sari_i32(tmp, tmp, shift);
49
+ } else {
50
+ tcg_gen_shli_i32(tmp, tmp, shift);
51
}
52
tmp2 = tcg_const_i32(imm);
53
if (op & 4) {
54
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
55
goto illegal_op;
56
}
57
tmp = load_reg(s, rm);
58
- if (shift) {
59
- tcg_gen_shli_i32(tmp, tmp, shift);
60
- }
61
+ tcg_gen_shli_i32(tmp, tmp, shift);
62
tcg_gen_add_i32(addr, addr, tmp);
63
tcg_temp_free_i32(tmp);
64
break;
65
--
44
--
66
2.20.1
45
2.25.1
67
68
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
3
connect multiple IRQs up to the same external GIC input, which
4
is not permitted. We do the same thing in the code in
5
exynos4210_init_board_irqs() because the conditionals selecting
6
an irq_id in the first loop match multiple interrupt IDs.
2
7
3
Add a new field to retain the address of the instruction currently
8
Overall we do this for interrupt IDs
4
being translated. The 32-bit uses are all within subroutines used
9
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
5
by a32 and t32. This will become less obvious when t16 support is
10
and
6
merged with a32+t32, and having a clear definition will help.
11
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
7
12
8
Convert aarch64 as well for consistency. Note that there is one
13
These correspond to the cases for the multi-core timer that we are
9
instance of a pre-assert fprintf that used the wrong value for the
14
wiring up to multiple inputs on the combiner in
10
address of the current instruction.
15
exynos4210_combiner_get_gpioin(). That code already deals with all
16
these interrupt IDs being the same input source, so we don't need to
17
connect the external GIC interrupt for any of them except the first
18
(1, 4) and (1, 5). Remove the array entries and conditionals which
19
were incorrectly causing us to wire up extra lines.
11
20
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
21
This bug didn't cause any visible effects, because we only connect
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
up a device to the "primary" ID values (1, 4) and (1, 5), so the
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
23
extra lines would never be set to a level.
15
Message-id: 20190807045335.1361-3-richard.henderson@linaro.org
24
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
17
---
28
---
18
target/arm/translate-a64.h | 2 +-
29
include/hw/arm/exynos4210.h | 2 +-
19
target/arm/translate.h | 2 ++
30
hw/arm/exynos4210.c | 12 +++++-------
20
target/arm/translate-a64.c | 21 +++++++++++----------
31
2 files changed, 6 insertions(+), 8 deletions(-)
21
target/arm/translate.c | 14 ++++++++------
22
4 files changed, 22 insertions(+), 17 deletions(-)
23
32
24
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
33
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
25
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-a64.h
35
--- a/include/hw/arm/exynos4210.h
27
+++ b/target/arm/translate-a64.h
36
+++ b/include/hw/arm/exynos4210.h
28
@@ -XXX,XX +XXX,XX @@ void unallocated_encoding(DisasContext *s);
37
@@ -XXX,XX +XXX,XX @@
29
qemu_log_mask(LOG_UNIMP, \
38
* one for every non-zero entry in combiner_grp_to_gic_id[].
30
"%s:%d: unsupported instruction encoding 0x%08x " \
39
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
31
"at pc=%016" PRIx64 "\n", \
40
*/
32
- __FILE__, __LINE__, insn, s->pc - 4); \
41
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
33
+ __FILE__, __LINE__, insn, s->pc_curr); \
42
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
34
unallocated_encoding(s); \
43
35
} while (0)
44
typedef struct Exynos4210Irq {
36
45
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
37
diff --git a/target/arm/translate.h b/target/arm/translate.h
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
38
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate.h
48
--- a/hw/arm/exynos4210.c
40
+++ b/target/arm/translate.h
49
+++ b/hw/arm/exynos4210.c
41
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
50
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
42
const ARMISARegisters *isar;
51
/* int combiner group 34 */
43
52
{ EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
44
target_ulong pc;
53
/* int combiner group 35 */
45
+ /* The address of the current instruction being translated. */
54
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
46
+ target_ulong pc_curr;
55
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
47
target_ulong page_start;
56
/* int combiner group 36 */
48
uint32_t insn;
57
{ EXT_GIC_ID_MIXER },
49
/* Nonzero if this instruction has been conditionally skipped. */
58
/* int combiner group 37 */
50
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
59
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
51
index XXXXXXX..XXXXXXX 100644
60
/* groups 38-50 */
52
--- a/target/arm/translate-a64.c
61
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
53
+++ b/target/arm/translate-a64.c
62
/* int combiner group 51 */
54
@@ -XXX,XX +XXX,XX @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
63
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
55
*/
64
+ { EXT_GIC_ID_MCT_L0 },
56
static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
65
/* group 52 */
57
{
66
{ },
58
- uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
67
/* int combiner group 53 */
59
+ uint64_t addr = s->pc_curr + sextract32(insn, 0, 26) * 4;
68
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
60
69
+ { EXT_GIC_ID_WDT },
61
if (insn & (1U << 31)) {
70
/* groups 54-63 */
62
/* BL Branch with link */
71
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
63
@@ -XXX,XX +XXX,XX @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
72
};
64
sf = extract32(insn, 31, 1);
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
65
op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
74
66
rt = extract32(insn, 0, 5);
75
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
67
- addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
76
irq_id = 0;
68
+ addr = s->pc_curr + sextract32(insn, 5, 19) * 4;
77
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
69
78
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
70
tcg_cmp = read_cpu_reg(s, rt, sf);
79
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
71
label_match = gen_new_label();
80
/* MCT_G0 is passed to External GIC */
72
@@ -XXX,XX +XXX,XX @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
81
irq_id = EXT_GIC_ID_MCT_G0;
73
82
}
74
bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
83
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
75
op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
84
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
76
- addr = s->pc + sextract32(insn, 5, 14) * 4 - 4;
85
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
77
+ addr = s->pc_curr + sextract32(insn, 5, 14) * 4;
86
/* MCT_G1 is passed to External and GIC */
78
rt = extract32(insn, 0, 5);
87
irq_id = EXT_GIC_ID_MCT_G1;
79
88
}
80
tcg_cmp = tcg_temp_new_i64();
81
@@ -XXX,XX +XXX,XX @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
82
unallocated_encoding(s);
83
return;
84
}
85
- addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
86
+ addr = s->pc_curr + sextract32(insn, 5, 19) * 4;
87
cond = extract32(insn, 0, 4);
88
89
reset_btype(s);
90
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
91
TCGv_i32 tcg_syn, tcg_isread;
92
uint32_t syndrome;
93
94
- gen_a64_set_pc_im(s->pc - 4);
95
+ gen_a64_set_pc_im(s->pc_curr);
96
tmpptr = tcg_const_ptr(ri);
97
syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
98
tcg_syn = tcg_const_i32(syndrome);
99
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
100
/* The pre HVC helper handles cases when HVC gets trapped
101
* as an undefined insn by runtime configuration.
102
*/
103
- gen_a64_set_pc_im(s->pc - 4);
104
+ gen_a64_set_pc_im(s->pc_curr);
105
gen_helper_pre_hvc(cpu_env);
106
gen_ss_advance(s);
107
gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
108
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
109
unallocated_encoding(s);
110
break;
111
}
112
- gen_a64_set_pc_im(s->pc - 4);
113
+ gen_a64_set_pc_im(s->pc_curr);
114
tmp = tcg_const_i32(syn_aa64_smc(imm16));
115
gen_helper_pre_smc(cpu_env, tmp);
116
tcg_temp_free_i32(tmp);
117
@@ -XXX,XX +XXX,XX @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
118
119
tcg_rt = cpu_reg(s, rt);
120
121
- clean_addr = tcg_const_i64((s->pc - 4) + imm);
122
+ clean_addr = tcg_const_i64(s->pc_curr + imm);
123
if (is_vector) {
124
do_fp_ld(s, rt, clean_addr, size);
125
} else {
126
@@ -XXX,XX +XXX,XX @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
127
offset = sextract64(insn, 5, 19);
128
offset = offset << 2 | extract32(insn, 29, 2);
129
rd = extract32(insn, 0, 5);
130
- base = s->pc - 4;
131
+ base = s->pc_curr;
132
133
if (page) {
134
/* ADRP (page based) */
135
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
136
break;
137
default:
138
fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
139
- __func__, insn, fpopcode, s->pc);
140
+ __func__, insn, fpopcode, s->pc_curr);
141
g_assert_not_reached();
142
}
143
144
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
145
{
146
uint32_t insn;
147
148
+ s->pc_curr = s->pc;
149
insn = arm_ldl_code(env, s->pc, s->sctlr_b);
150
s->insn = insn;
151
s->pc += 4;
152
diff --git a/target/arm/translate.c b/target/arm/translate.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/translate.c
155
+++ b/target/arm/translate.c
156
@@ -XXX,XX +XXX,XX @@ static inline void gen_hvc(DisasContext *s, int imm16)
157
* as an undefined insn by runtime configuration (ie before
158
* the insn really executes).
159
*/
160
- gen_set_pc_im(s, s->pc - 4);
161
+ gen_set_pc_im(s, s->pc_curr);
162
gen_helper_pre_hvc(cpu_env);
163
/* Otherwise we will treat this as a real exception which
164
* happens after execution of the insn. (The distinction matters
165
@@ -XXX,XX +XXX,XX @@ static inline void gen_smc(DisasContext *s)
166
*/
167
TCGv_i32 tmp;
168
169
- gen_set_pc_im(s, s->pc - 4);
170
+ gen_set_pc_im(s, s->pc_curr);
171
tmp = tcg_const_i32(syn_aa32_smc());
172
gen_helper_pre_smc(cpu_env, tmp);
173
tcg_temp_free_i32(tmp);
174
@@ -XXX,XX +XXX,XX @@ static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
175
176
/* Sync state because msr_banked() can raise exceptions */
177
gen_set_condexec(s);
178
- gen_set_pc_im(s, s->pc - 4);
179
+ gen_set_pc_im(s, s->pc_curr);
180
tcg_reg = load_reg(s, rn);
181
tcg_tgtmode = tcg_const_i32(tgtmode);
182
tcg_regno = tcg_const_i32(regno);
183
@@ -XXX,XX +XXX,XX @@ static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
184
185
/* Sync state because mrs_banked() can raise exceptions */
186
gen_set_condexec(s);
187
- gen_set_pc_im(s, s->pc - 4);
188
+ gen_set_pc_im(s, s->pc_curr);
189
tcg_reg = tcg_temp_new_i32();
190
tcg_tgtmode = tcg_const_i32(tgtmode);
191
tcg_regno = tcg_const_i32(regno);
192
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
193
}
194
195
gen_set_condexec(s);
196
- gen_set_pc_im(s, s->pc - 4);
197
+ gen_set_pc_im(s, s->pc_curr);
198
tmpptr = tcg_const_ptr(ri);
199
tcg_syn = tcg_const_i32(syndrome);
200
tcg_isread = tcg_const_i32(isread);
201
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
202
tmp = tcg_const_i32(mode);
203
/* get_r13_banked() will raise an exception if called from System mode */
204
gen_set_condexec(s);
205
- gen_set_pc_im(s, s->pc - 4);
206
+ gen_set_pc_im(s, s->pc_curr);
207
gen_helper_get_r13_banked(addr, cpu_env, tmp);
208
tcg_temp_free_i32(tmp);
209
switch (amode) {
210
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
211
return;
212
}
213
214
+ dc->pc_curr = dc->pc;
215
insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
216
dc->insn = insn;
217
dc->pc += 4;
218
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
219
return;
220
}
221
222
+ dc->pc_curr = dc->pc;
223
insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
224
is_16bit = thumb_insn_is_16bit(dc, dc->pc, insn);
225
dc->pc += 2;
226
--
89
--
227
2.20.1
90
2.25.1
228
229
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
At this point, the function exynos4210_init_board_irqs() splits input
2
2
IRQ lines to connect them to the input combiner, output combiner and
3
Move the getting/putting of the fpsimd registers out of
3
external GIC. The function exynos4210_combiner_get_gpioin() splits
4
kvm_arch_get/put_registers() into their own helper functions
4
some of the combiner input lines further to connect them to multiple
5
to prepare for alternatively getting/putting SVE registers.
5
different inputs on the combiner.
6
6
7
No functional change.
7
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
8
8
configurable number of outputs, we can do all this in one place, by
9
Signed-off-by: Andrew Jones <drjones@redhat.com>
9
making exynos4210_init_board_irqs() add extra outputs to the splitter
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
device when it must be connected to more than one input on each
11
combiner.
12
13
We do this with a new data structure, the combinermap, which is an
14
array each of whose elements is a list of the interrupt IDs on the
15
combiner which must be tied together. As we loop through each
16
interrupt ID, if we find that it is the first one in one of these
17
lists, we configure the splitter device with eonugh extra outputs and
18
wire them up to the other interrupt IDs in the list.
19
20
Conveniently, for all the cases where this is necessary, the
21
lowest-numbered interrupt ID in each group is in the range of the
22
external combiner, so we only need to code for this in the first of
23
the two loops in exynos4210_init_board_irqs().
24
25
The old code in exynos4210_combiner_get_gpioin() which is being
26
deleted here had several problems which don't exist in the new code
27
in its handling of the multi-core timer interrupts:
28
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
29
exist; these should have been 4 ... 7
30
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
31
multiple times as the input of several different splitters,
32
which isn't allowed
33
(3) in an apparent cut-and-paste error, the cases for all the
34
multi-core timer inputs used "bit + 4" even though the
35
bit range for the case was (intended to be) 4 ... 7, which
36
meant it was looking at non-existent bits 8 ... 11.
37
None of these exist in the new code.
38
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
40
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
41
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
13
---
42
---
14
target/arm/kvm64.c | 148 +++++++++++++++++++++++++++------------------
43
include/hw/arm/exynos4210.h | 6 +-
15
1 file changed, 88 insertions(+), 60 deletions(-)
44
hw/arm/exynos4210.c | 178 +++++++++++++++++++++++-------------
16
45
2 files changed, 119 insertions(+), 65 deletions(-)
17
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
46
47
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/kvm64.c
49
--- a/include/hw/arm/exynos4210.h
20
+++ b/target/arm/kvm64.c
50
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@ int kvm_arm_cpreg_level(uint64_t regidx)
51
@@ -XXX,XX +XXX,XX @@
22
#define AARCH64_SIMD_CTRL_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U32 | \
52
23
KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
53
/*
24
54
* We need one splitter for every external combiner input, plus
25
+static int kvm_arch_put_fpsimd(CPUState *cs)
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
74
+/*
75
+ * Some interrupt lines go to multiple combiner inputs.
76
+ * This data structure defines those: each array element is
77
+ * a list of combiner inputs which are connected together;
78
+ * the one with the smallest interrupt ID value must be first.
79
+ * As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
80
+ * wired to anything so we can use 0 as a terminator.
81
+ */
82
+#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
83
+#define IRQNONE 0
84
+
85
+#define COMBINERMAP_SIZE 16
86
+
87
+static const int combinermap[COMBINERMAP_SIZE][6] = {
88
+ /* MDNIE_LCD1 */
89
+ { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
90
+ { IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
91
+ { IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
92
+ { IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
93
+ /* TMU */
94
+ { IRQNO(2, 4), IRQNO(3, 4), IRQNONE },
95
+ { IRQNO(2, 5), IRQNO(3, 5), IRQNONE },
96
+ { IRQNO(2, 6), IRQNO(3, 6), IRQNONE },
97
+ { IRQNO(2, 7), IRQNO(3, 7), IRQNONE },
98
+ /* LCD1 */
99
+ { IRQNO(11, 4), IRQNO(12, 0), IRQNONE },
100
+ { IRQNO(11, 5), IRQNO(12, 1), IRQNONE },
101
+ { IRQNO(11, 6), IRQNO(12, 2), IRQNONE },
102
+ { IRQNO(11, 7), IRQNO(12, 3), IRQNONE },
103
+ /* Multi-core timer */
104
+ { IRQNO(1, 4), IRQNO(12, 4), IRQNO(35, 4), IRQNO(51, 4), IRQNO(53, 4), IRQNONE },
105
+ { IRQNO(1, 5), IRQNO(12, 5), IRQNO(35, 5), IRQNO(51, 5), IRQNO(53, 5), IRQNONE },
106
+ { IRQNO(1, 6), IRQNO(12, 6), IRQNO(35, 6), IRQNO(51, 6), IRQNO(53, 6), IRQNONE },
107
+ { IRQNO(1, 7), IRQNO(12, 7), IRQNO(35, 7), IRQNO(51, 7), IRQNO(53, 7), IRQNONE },
108
+};
109
+
110
+#undef IRQNO
111
+
112
+static const int *combinermap_entry(int irq)
26
+{
113
+{
27
+ ARMCPU *cpu = ARM_CPU(cs);
114
+ /*
28
+ CPUARMState *env = &cpu->env;
115
+ * If the interrupt number passed in is the first entry in some
29
+ struct kvm_one_reg reg;
116
+ * line of the combinermap, return a pointer to that line;
30
+ uint32_t fpr;
117
+ * otherwise return NULL.
31
+ int i, ret;
118
+ */
32
+
119
+ int i;
33
+ for (i = 0; i < 32; i++) {
120
+ for (i = 0; i < COMBINERMAP_SIZE; i++) {
34
+ uint64_t *q = aa64_vfp_qreg(env, i);
121
+ if (combinermap[i][0] == irq) {
35
+#ifdef HOST_WORDS_BIGENDIAN
122
+ return combinermap[i];
36
+ uint64_t fp_val[2] = { q[1], q[0] };
37
+ reg.addr = (uintptr_t)fp_val;
38
+#else
39
+ reg.addr = (uintptr_t)q;
40
+#endif
41
+ reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
42
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
43
+ if (ret) {
44
+ return ret;
45
+ }
123
+ }
46
+ }
124
+ }
47
+
125
+ return NULL;
48
+ reg.addr = (uintptr_t)(&fpr);
126
+}
49
+ fpr = vfp_get_fpsr(env);
127
+
50
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
128
+static int mapline_size(const int *mapline)
51
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
129
+{
52
+ if (ret) {
130
+ /* Return number of entries in this mapline in total */
53
+ return ret;
131
+ int i = 0;
132
+
133
+ if (!mapline) {
134
+ /* Not in the map? IRQ goes to exactly one combiner input */
135
+ return 1;
54
+ }
136
+ }
55
+
137
+ while (*mapline != IRQNONE) {
56
+ reg.addr = (uintptr_t)(&fpr);
138
+ mapline++;
57
+ fpr = vfp_get_fpcr(env);
139
+ i++;
58
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
59
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
60
+ if (ret) {
61
+ return ret;
62
+ }
140
+ }
63
+
141
+ return i;
64
+ return 0;
65
+}
142
+}
66
+
143
+
67
int kvm_arch_put_registers(CPUState *cs, int level)
144
/*
68
{
145
* Initialize board IRQs.
69
struct kvm_one_reg reg;
146
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
70
- uint32_t fpr;
147
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
71
uint64_t val;
148
DeviceState *extgicdev = DEVICE(&s->ext_gic);
72
- int i;
149
int splitcount = 0;
73
- int ret;
150
DeviceState *splitter;
74
+ int i, ret;
151
+ const int *mapline;
75
unsigned int el;
152
+ int numlines, splitin, in;
76
153
77
ARMCPU *cpu = ARM_CPU(cs);
154
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
78
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
155
irq_id = 0;
156
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
157
irq_id = EXT_GIC_ID_MCT_G1;
158
}
159
160
+ if (s->irq_table[n]) {
161
+ /*
162
+ * This must be some non-first entry in a combinermap line,
163
+ * and we've already filled it in.
164
+ */
165
+ continue;
166
+ }
167
+ mapline = combinermap_entry(n);
168
+ /*
169
+ * We need to connect the IRQ to multiple inputs on both combiners
170
+ * and possibly also to the external GIC.
171
+ */
172
+ numlines = 2 * mapline_size(mapline);
173
+ if (irq_id) {
174
+ numlines++;
175
+ }
176
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
177
splitter = DEVICE(&s->splitter[splitcount]);
178
- qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
179
+ qdev_prop_set_uint16(splitter, "num-lines", numlines);
180
qdev_realize(splitter, NULL, &error_abort);
181
splitcount++;
182
- s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
183
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
184
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
185
+
186
+ in = n;
187
+ splitin = 0;
188
+ for (;;) {
189
+ s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
190
+ qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
191
+ qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
192
+ splitin += 2;
193
+ if (!mapline) {
194
+ break;
195
+ }
196
+ mapline++;
197
+ in = *mapline;
198
+ if (in == IRQNONE) {
199
+ break;
200
+ }
201
+ }
202
if (irq_id) {
203
- qdev_connect_gpio_out(splitter, 2,
204
+ qdev_connect_gpio_out(splitter, splitin,
205
qdev_get_gpio_in(extgicdev, irq_id - 32));
79
}
206
}
80
}
207
}
81
208
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
82
- /* Advanced SIMD and FP registers. */
209
irq_id = combiner_grp_to_gic_id[grp -
83
- for (i = 0; i < 32; i++) {
210
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
84
- uint64_t *q = aa64_vfp_qreg(env, i);
211
85
-#ifdef HOST_WORDS_BIGENDIAN
212
+ if (s->irq_table[n]) {
86
- uint64_t fp_val[2] = { q[1], q[0] };
213
+ /*
87
- reg.addr = (uintptr_t)fp_val;
214
+ * This must be some non-first entry in a combinermap line,
88
-#else
215
+ * and we've already filled it in.
89
- reg.addr = (uintptr_t)q;
216
+ */
90
-#endif
217
+ continue;
91
- reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
218
+ }
92
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
219
+
93
- if (ret) {
220
if (irq_id) {
94
- return ret;
221
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
222
splitter = DEVICE(&s->splitter[splitcount]);
223
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
224
DeviceState *dev, int ext)
225
{
226
int n;
227
- int bit;
228
int max;
229
qemu_irq *irq;
230
231
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
232
EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
233
irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
234
235
- /*
236
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
237
- * so let split them.
238
- */
239
for (n = 0; n < max; n++) {
240
-
241
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
242
-
243
- switch (n) {
244
- /* MDNIE_LCD1 INTG1 */
245
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
246
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
247
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
248
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
249
- continue;
250
-
251
- /* TMU INTG3 */
252
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
253
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
254
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
255
- continue;
256
-
257
- /* LCD1 INTG12 */
258
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
259
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
260
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
261
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
262
- continue;
263
-
264
- /* Multi-Core Timer INTG12 */
265
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
266
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
267
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
268
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
269
- continue;
270
-
271
- /* Multi-Core Timer INTG35 */
272
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
273
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
274
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
275
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
276
- continue;
277
-
278
- /* Multi-Core Timer INTG51 */
279
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
280
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
281
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
282
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
283
- continue;
284
-
285
- /* Multi-Core Timer INTG53 */
286
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
287
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
288
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
289
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
290
- continue;
95
- }
291
- }
96
- }
292
-
97
-
293
irq[n] = qdev_get_gpio_in(dev, n);
98
- reg.addr = (uintptr_t)(&fpr);
99
- fpr = vfp_get_fpsr(env);
100
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
101
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
102
- if (ret) {
103
- return ret;
104
- }
105
-
106
- fpr = vfp_get_fpcr(env);
107
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
108
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
109
+ ret = kvm_arch_put_fpsimd(cs);
110
if (ret) {
111
return ret;
112
}
294
}
113
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
114
return ret;
115
}
295
}
116
117
+static int kvm_arch_get_fpsimd(CPUState *cs)
118
+{
119
+ ARMCPU *cpu = ARM_CPU(cs);
120
+ CPUARMState *env = &cpu->env;
121
+ struct kvm_one_reg reg;
122
+ uint32_t fpr;
123
+ int i, ret;
124
+
125
+ for (i = 0; i < 32; i++) {
126
+ uint64_t *q = aa64_vfp_qreg(env, i);
127
+ reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
128
+ reg.addr = (uintptr_t)q;
129
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
130
+ if (ret) {
131
+ return ret;
132
+ } else {
133
+#ifdef HOST_WORDS_BIGENDIAN
134
+ uint64_t t;
135
+ t = q[0], q[0] = q[1], q[1] = t;
136
+#endif
137
+ }
138
+ }
139
+
140
+ reg.addr = (uintptr_t)(&fpr);
141
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
142
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
143
+ if (ret) {
144
+ return ret;
145
+ }
146
+ vfp_set_fpsr(env, fpr);
147
+
148
+ reg.addr = (uintptr_t)(&fpr);
149
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
150
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
151
+ if (ret) {
152
+ return ret;
153
+ }
154
+ vfp_set_fpcr(env, fpr);
155
+
156
+ return 0;
157
+}
158
+
159
int kvm_arch_get_registers(CPUState *cs)
160
{
161
struct kvm_one_reg reg;
162
uint64_t val;
163
- uint32_t fpr;
164
unsigned int el;
165
- int i;
166
- int ret;
167
+ int i, ret;
168
169
ARMCPU *cpu = ARM_CPU(cs);
170
CPUARMState *env = &cpu->env;
171
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
172
env->spsr = env->banked_spsr[i];
173
}
174
175
- /* Advanced SIMD and FP registers */
176
- for (i = 0; i < 32; i++) {
177
- uint64_t *q = aa64_vfp_qreg(env, i);
178
- reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
179
- reg.addr = (uintptr_t)q;
180
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
181
- if (ret) {
182
- return ret;
183
- } else {
184
-#ifdef HOST_WORDS_BIGENDIAN
185
- uint64_t t;
186
- t = q[0], q[0] = q[1], q[1] = t;
187
-#endif
188
- }
189
- }
190
-
191
- reg.addr = (uintptr_t)(&fpr);
192
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
193
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
194
+ ret = kvm_arch_get_fpsimd(cs);
195
if (ret) {
196
return ret;
197
}
198
- vfp_set_fpsr(env, fpr);
199
-
200
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
201
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
202
- if (ret) {
203
- return ret;
204
- }
205
- vfp_set_fpcr(env, fpr);
206
207
ret = kvm_get_vcpu_events(cpu);
208
if (ret) {
209
--
296
--
210
2.20.1
297
2.25.1
211
212
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Switch the creation of the combiner devices to the new-style
2
"embedded in state struct" approach, so we can easily refer
3
to the object elsewhere during realize.
2
4
3
The thumb bit has already been removed from s->pc, and is always even.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-18-peter.maydell@linaro.org
8
---
9
include/hw/arm/exynos4210.h | 3 ++
10
include/hw/intc/exynos4210_combiner.h | 57 +++++++++++++++++++++++++++
11
hw/arm/exynos4210.c | 20 +++++-----
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
4
15
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190807045335.1361-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate.c | 10 +++++-----
12
1 file changed, 5 insertions(+), 5 deletions(-)
13
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
18
--- a/include/hw/arm/exynos4210.h
17
+++ b/target/arm/translate.c
19
+++ b/include/hw/arm/exynos4210.h
18
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
20
@@ -XXX,XX +XXX,XX @@
19
/* Force a TB lookup after an instruction that changes the CPU state. */
21
#include "hw/sysbus.h"
20
static inline void gen_lookup_tb(DisasContext *s)
22
#include "hw/cpu/a9mpcore.h"
21
{
23
#include "hw/intc/exynos4210_gic.h"
22
- tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
24
+#include "hw/intc/exynos4210_combiner.h"
23
+ tcg_gen_movi_i32(cpu_R[15], s->pc);
25
#include "hw/core/split-irq.h"
24
s->base.is_jmp = DISAS_EXIT;
26
#include "target/arm/cpu-qom.h"
27
#include "qom/object.h"
28
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
29
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
30
A9MPPrivState a9mpcore;
31
Exynos4210GicState ext_gic;
32
+ Exynos4210CombinerState int_combiner;
33
+ Exynos4210CombinerState ext_combiner;
34
SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
35
};
36
37
diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_combiner.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Samsung exynos4210 Interrupt Combiner
45
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
59
+ * See the GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+
65
+#ifndef HW_INTC_EXYNOS4210_COMBINER
66
+#define HW_INTC_EXYNOS4210_COMBINER
67
+
68
+#include "hw/sysbus.h"
69
+
70
+/*
71
+ * State for each output signal of internal combiner
72
+ */
73
+typedef struct CombinerGroupState {
74
+ uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
75
+ uint8_t src_pending; /* Pending source interrupts before masking */
76
+} CombinerGroupState;
77
+
78
+#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
79
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
80
+
81
+/* Number of groups and total number of interrupts for the internal combiner */
82
+#define IIC_NGRP 64
83
+#define IIC_NIRQ (IIC_NGRP * 8)
84
+#define IIC_REGSET_SIZE 0x41
85
+
86
+struct Exynos4210CombinerState {
87
+ SysBusDevice parent_obj;
88
+
89
+ MemoryRegion iomem;
90
+
91
+ struct CombinerGroupState group[IIC_NGRP];
92
+ uint32_t reg_set[IIC_REGSET_SIZE];
93
+ uint32_t icipsr[2];
94
+ uint32_t external; /* 1 means that this combiner is external */
95
+
96
+ qemu_irq output_irq[IIC_NGRP];
97
+};
98
+
99
+#endif
100
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/arm/exynos4210.c
103
+++ b/hw/arm/exynos4210.c
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
}
106
107
/* Internal Interrupt Combiner */
108
- dev = qdev_new("exynos4210.combiner");
109
- busdev = SYS_BUS_DEVICE(dev);
110
- sysbus_realize_and_unref(busdev, &error_fatal);
111
+ busdev = SYS_BUS_DEVICE(&s->int_combiner);
112
+ sysbus_realize(busdev, &error_fatal);
113
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
114
sysbus_connect_irq(busdev, n,
115
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
116
}
117
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
118
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
119
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
120
121
/* External Interrupt Combiner */
122
- dev = qdev_new("exynos4210.combiner");
123
- qdev_prop_set_uint32(dev, "external", 1);
124
- busdev = SYS_BUS_DEVICE(dev);
125
- sysbus_realize_and_unref(busdev, &error_fatal);
126
+ qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
127
+ busdev = SYS_BUS_DEVICE(&s->ext_combiner);
128
+ sysbus_realize(busdev, &error_fatal);
129
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
130
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
131
}
132
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
133
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
134
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
135
136
/* Initialize board IRQs. */
137
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
138
139
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
140
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
141
+ object_initialize_child(obj, "int-combiner", &s->int_combiner,
142
+ TYPE_EXYNOS4210_COMBINER);
143
+ object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
144
+ TYPE_EXYNOS4210_COMBINER);
25
}
145
}
26
146
27
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
147
static void exynos4210_class_init(ObjectClass *klass, void *data)
28
* self-modifying code correctly and also to take
148
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
29
* any pending interrupts immediately.
149
index XXXXXXX..XXXXXXX 100644
30
*/
150
--- a/hw/intc/exynos4210_combiner.c
31
- gen_goto_tb(s, 0, s->pc & ~1);
151
+++ b/hw/intc/exynos4210_combiner.c
32
+ gen_goto_tb(s, 0, s->pc);
152
@@ -XXX,XX +XXX,XX @@
33
return;
153
#include "hw/sysbus.h"
34
case 7: /* sb */
154
#include "migration/vmstate.h"
35
if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
155
#include "qemu/module.h"
36
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
156
-
37
* for TCG; MB and end the TB instead.
157
+#include "hw/intc/exynos4210_combiner.h"
38
*/
158
#include "hw/arm/exynos4210.h"
39
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
159
#include "hw/hw.h"
40
- gen_goto_tb(s, 0, s->pc & ~1);
160
#include "hw/irq.h"
41
+ gen_goto_tb(s, 0, s->pc);
161
@@ -XXX,XX +XXX,XX @@
42
return;
162
#define DPRINTF(fmt, ...) do {} while (0)
43
default:
163
#endif
44
goto illegal_op;
164
45
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
165
-#define IIC_NGRP 64 /* Internal Interrupt Combiner
46
* and also to take any pending interrupts
166
- Groups number */
47
* immediately.
167
-#define IIC_NIRQ (IIC_NGRP * 8)/* Internal Interrupt Combiner
48
*/
168
- Interrupts number */
49
- gen_goto_tb(s, 0, s->pc & ~1);
169
#define IIC_REGION_SIZE 0x108 /* Size of memory mapped region */
50
+ gen_goto_tb(s, 0, s->pc);
170
-#define IIC_REGSET_SIZE 0x41
51
break;
171
-
52
case 7: /* sb */
172
-/*
53
if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
173
- * State for each output signal of internal combiner
54
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
174
- */
55
* for TCG; MB and end the TB instead.
175
-typedef struct CombinerGroupState {
56
*/
176
- uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
57
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
177
- uint8_t src_pending; /* Pending source interrupts before masking */
58
- gen_goto_tb(s, 0, s->pc & ~1);
178
-} CombinerGroupState;
59
+ gen_goto_tb(s, 0, s->pc);
179
-
60
break;
180
-#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
61
default:
181
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
62
goto illegal_op;
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",
63
--
198
--
64
2.20.1
199
2.25.1
65
66
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The only time we use the int_combiner_irq[] and ext_combiner_irq[]
2
arrays in the Exynos4210Irq struct is during realize of the SoC -- we
3
initialize them with the input IRQs of the combiner devices, and then
4
connect those to outputs of other devices in
5
exynos4210_init_board_irqs(). Now that the combiner objects are
6
easily accessible as s->int_combiner and s->ext_combiner we can make
7
the connections directly from one device to the other without going
8
via these arrays.
2
9
3
Replace x = double_saturate(y) with x = add_saturate(y, y).
10
Since these are the only two remaining elements of Exynos4210Irq,
4
There is no need for a separate more specialized helper.
11
we can remove that struct entirely.
5
12
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190807045335.1361-12-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
11
---
16
---
12
target/arm/helper.h | 1 -
17
include/hw/arm/exynos4210.h | 6 ------
13
target/arm/op_helper.c | 15 ---------------
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
14
target/arm/translate.c | 4 ++--
19
2 files changed, 8 insertions(+), 32 deletions(-)
15
3 files changed, 2 insertions(+), 18 deletions(-)
16
20
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.h
23
--- a/include/hw/arm/exynos4210.h
20
+++ b/target/arm/helper.h
24
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(add_saturate, i32, env, i32, i32)
25
@@ -XXX,XX +XXX,XX @@
22
DEF_HELPER_3(sub_saturate, i32, env, i32, i32)
26
*/
23
DEF_HELPER_3(add_usaturate, i32, env, i32, i32)
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
24
DEF_HELPER_3(sub_usaturate, i32, env, i32, i32)
28
25
-DEF_HELPER_2(double_saturate, i32, env, s32)
29
-typedef struct Exynos4210Irq {
26
DEF_HELPER_FLAGS_2(sdiv, TCG_CALL_NO_RWG_SE, s32, s32, s32)
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
27
DEF_HELPER_FLAGS_2(udiv, TCG_CALL_NO_RWG_SE, i32, i32, i32)
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
28
DEF_HELPER_FLAGS_1(rbit, TCG_CALL_NO_RWG_SE, i32, i32)
32
-} Exynos4210Irq;
29
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
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
30
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/op_helper.c
45
--- a/hw/arm/exynos4210.c
32
+++ b/target/arm/op_helper.c
46
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
34
return res;
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
}
84
/*
85
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
86
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
35
}
87
}
36
88
37
-uint32_t HELPER(double_saturate)(CPUARMState *env, int32_t val)
89
-/*
90
- * Get Combiner input GPIO into irqs structure
91
- */
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
93
- DeviceState *dev, int ext)
38
-{
94
-{
39
- uint32_t res;
95
- int n;
40
- if (val >= 0x40000000) {
96
- int max;
41
- res = ~SIGNBIT;
97
- qemu_irq *irq;
42
- env->QF = 1;
98
-
43
- } else if (val <= (int32_t)0xc0000000) {
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
44
- res = SIGNBIT;
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
45
- env->QF = 1;
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
46
- } else {
102
-
47
- res = val << 1;
103
- for (n = 0; n < max; n++) {
104
- irq[n] = qdev_get_gpio_in(dev, n);
48
- }
105
- }
49
- return res;
50
-}
106
-}
51
-
107
-
52
uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
53
{
109
0x09, 0x00, 0x00, 0x00 };
54
uint32_t res = a + b;
110
55
diff --git a/target/arm/translate.c b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
56
index XXXXXXX..XXXXXXX 100644
112
sysbus_connect_irq(busdev, n,
57
--- a/target/arm/translate.c
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
58
+++ b/target/arm/translate.c
114
}
59
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
115
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
60
tmp = load_reg(s, rm);
116
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
61
tmp2 = load_reg(s, rn);
117
62
if (op1 & 2)
118
/* External Interrupt Combiner */
63
- gen_helper_double_saturate(tmp2, cpu_env, tmp2);
119
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
64
+ gen_helper_add_saturate(tmp2, cpu_env, tmp2, tmp2);
120
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
65
if (op1 & 1)
121
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
66
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
122
}
67
else
123
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
68
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
124
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
69
tmp = load_reg(s, rn);
125
70
tmp2 = load_reg(s, rm);
126
/* Initialize board IRQs. */
71
if (op & 1)
72
- gen_helper_double_saturate(tmp, cpu_env, tmp);
73
+ gen_helper_add_saturate(tmp, cpu_env, tmp, tmp);
74
if (op & 2)
75
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
76
else
77
--
127
--
78
2.20.1
128
2.25.1
79
80
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
We currently have 3 different ways of computing the architectural
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
value of "PC" as seen in the ARM ARM.
5
6
The value of s->pc has been incremented past the current insn,
7
but that is all. Thus for a32, PC = s->pc + 4; for t32, PC = s->pc;
8
for t16, PC = s->pc + 2. These differing computations make it
9
impossible at present to unify the various code paths.
10
11
With the newly introduced s->pc_curr, we can compute the correct
12
value for all cases, using the formula given in the ARM ARM.
13
14
This changes the behaviour for load_reg() and load_reg_var()
15
when called with reg==15 from a 32-bit Thumb instruction:
16
previously they would have returned the incorrect value
17
of pc_curr + 6, and now they will return the architecturally
18
correct value of PC, which is pc_curr + 4. This will not
19
affect well-behaved guest software, because all of the places
20
we call these functions from T32 code are instructions where
21
using r15 is UNPREDICTABLE. Using the architectural PC value
22
here is more consistent with the T16 and A32 behaviour.
23
24
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
27
Message-id: 20190807045335.1361-4-richard.henderson@linaro.org
28
[PMM: added commit message note about UNPREDICTABLE T32 cases]
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
---
7
---
31
target/arm/translate.c | 59 ++++++++++++++++--------------------------
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
32
1 file changed, 23 insertions(+), 36 deletions(-)
9
1 file changed, 24 insertions(+), 9 deletions(-)
33
10
34
diff --git a/target/arm/translate.c b/target/arm/translate.c
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
35
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate.c
13
--- a/hw/arm/realview.c
37
+++ b/target/arm/translate.c
14
+++ b/hw/arm/realview.c
38
@@ -XXX,XX +XXX,XX @@ static inline void store_cpu_offset(TCGv_i32 var, int offset)
15
@@ -XXX,XX +XXX,XX @@
39
#define store_cpu_field(var, name) \
16
#include "hw/sysbus.h"
40
store_cpu_offset(var, offsetof(CPUARMState, name))
17
#include "hw/arm/boot.h"
41
18
#include "hw/arm/primecell.h"
42
+/* The architectural value of PC. */
19
+#include "hw/core/split-irq.h"
43
+static uint32_t read_pc(DisasContext *s)
20
#include "hw/net/lan9118.h"
44
+{
21
#include "hw/net/smc91c111.h"
45
+ return s->pc_curr + (s->thumb ? 4 : 8);
22
#include "hw/pci/pci.h"
23
+#include "hw/qdev-core.h"
24
#include "net/net.h"
25
#include "sysemu/sysemu.h"
26
#include "hw/boards.h"
27
@@ -XXX,XX +XXX,XX @@ static const int realview_board_id[] = {
28
0x76d
29
};
30
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
32
+ qemu_irq out1, qemu_irq out2) {
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
34
+
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
36
+
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
38
+
39
+ qdev_connect_gpio_out(splitter, 0, out1);
40
+ qdev_connect_gpio_out(splitter, 1, out2);
41
+ qdev_connect_gpio_out_named(src, outname, 0,
42
+ qdev_get_gpio_in(splitter, 0));
46
+}
43
+}
47
+
44
+
48
/* Set a variable to the value of a CPU register. */
45
static void realview_init(MachineState *machine,
49
static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
46
enum realview_board_type board_type)
50
{
47
{
51
if (reg == 15) {
48
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
52
- uint32_t addr;
49
DeviceState *dev, *sysctl, *gpio2, *pl041;
53
- /* normally, since we updated PC, we need only to add one insn */
50
SysBusDevice *busdev;
54
- if (s->thumb)
51
qemu_irq pic[64];
55
- addr = (long)s->pc + 2;
52
- qemu_irq mmc_irq[2];
56
- else
53
PCIBus *pci_bus = NULL;
57
- addr = (long)s->pc + 4;
54
NICInfo *nd;
58
- tcg_gen_movi_i32(var, addr);
55
DriveInfo *dinfo;
59
+ tcg_gen_movi_i32(var, read_pc(s));
56
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
60
} else {
57
* and the PL061 has them the other way about. Also the card
61
tcg_gen_mov_i32(var, cpu_R[reg]);
58
* detect line is inverted.
62
}
59
*/
63
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
60
- mmc_irq[0] = qemu_irq_split(
64
/* branch link and change to thumb (blx <offset>) */
61
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
65
int32_t offset;
62
- qdev_get_gpio_in(gpio2, 1));
66
63
- mmc_irq[1] = qemu_irq_split(
67
- val = (uint32_t)s->pc;
64
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
68
tmp = tcg_temp_new_i32();
65
- qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
69
- tcg_gen_movi_i32(tmp, val);
66
- qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
70
+ tcg_gen_movi_i32(tmp, s->pc);
67
- qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_irq[1]);
71
store_reg(s, 14, tmp);
68
+ split_irq_from_named(dev, "card-read-only",
72
/* Sign-extend the 24-bit offset */
69
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
73
offset = (((int32_t)insn) << 8) >> 8;
70
+ qdev_get_gpio_in(gpio2, 1));
74
+ val = read_pc(s);
71
+
75
/* offset * 4 + bit24 * 2 + (thumb bit) */
72
+ split_irq_from_named(dev, "card-inserted",
76
val += (offset << 2) | ((insn >> 23) & 2) | 1;
73
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
77
- /* pipeline offset */
74
+ qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
78
- val += 4;
75
+
79
/* protected by ARCH(5); above, near the start of uncond block */
76
dinfo = drive_get(IF_SD, 0, 0);
80
gen_bx_im(s, val);
77
if (dinfo) {
81
return;
78
DeviceState *card;
82
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
83
} else {
84
/* store */
85
if (i == 15) {
86
- /* special case: r15 = PC + 8 */
87
- val = (long)s->pc + 4;
88
tmp = tcg_temp_new_i32();
89
- tcg_gen_movi_i32(tmp, val);
90
+ tcg_gen_movi_i32(tmp, read_pc(s));
91
} else if (user) {
92
tmp = tcg_temp_new_i32();
93
tmp2 = tcg_const_i32(i);
94
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
95
int32_t offset;
96
97
/* branch (and link) */
98
- val = (int32_t)s->pc;
99
if (insn & (1 << 24)) {
100
tmp = tcg_temp_new_i32();
101
- tcg_gen_movi_i32(tmp, val);
102
+ tcg_gen_movi_i32(tmp, s->pc);
103
store_reg(s, 14, tmp);
104
}
105
offset = sextract32(insn << 2, 0, 26);
106
- val += offset + 4;
107
- gen_jmp(s, val);
108
+ gen_jmp(s, read_pc(s) + offset);
109
}
110
break;
111
case 0xc:
112
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
113
tcg_temp_free_i32(addr);
114
} else if ((insn & (7 << 5)) == 0) {
115
/* Table Branch. */
116
- if (rn == 15) {
117
- addr = tcg_temp_new_i32();
118
- tcg_gen_movi_i32(addr, s->pc);
119
- } else {
120
- addr = load_reg(s, rn);
121
- }
122
+ addr = load_reg(s, rn);
123
tmp = load_reg(s, rm);
124
tcg_gen_add_i32(addr, addr, tmp);
125
if (insn & (1 << 4)) {
126
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
127
}
128
tcg_temp_free_i32(addr);
129
tcg_gen_shli_i32(tmp, tmp, 1);
130
- tcg_gen_addi_i32(tmp, tmp, s->pc);
131
+ tcg_gen_addi_i32(tmp, tmp, read_pc(s));
132
store_reg(s, 15, tmp);
133
} else {
134
bool is_lasr = false;
135
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
136
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
137
}
138
139
- offset += s->pc;
140
+ offset += read_pc(s);
141
if (insn & (1 << 12)) {
142
/* b/bl */
143
gen_jmp(s, offset);
144
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
145
offset |= (insn & (1 << 11)) << 8;
146
147
/* jump to the offset */
148
- gen_jmp(s, s->pc + offset);
149
+ gen_jmp(s, read_pc(s) + offset);
150
}
151
} else {
152
/*
153
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
154
if (insn & (1 << 11)) {
155
rd = (insn >> 8) & 7;
156
/* load pc-relative. Bit 1 of PC is ignored. */
157
- val = s->pc + 2 + ((insn & 0xff) * 4);
158
+ val = read_pc(s) + ((insn & 0xff) * 4);
159
val &= ~(uint32_t)2;
160
addr = tcg_temp_new_i32();
161
tcg_gen_movi_i32(addr, val);
162
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
163
} else {
164
/* PC. bit 1 is ignored. */
165
tmp = tcg_temp_new_i32();
166
- tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
167
+ tcg_gen_movi_i32(tmp, read_pc(s) & ~(uint32_t)2);
168
}
169
val = (insn & 0xff) * 4;
170
tcg_gen_addi_i32(tmp, tmp, val);
171
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
172
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
173
tcg_temp_free_i32(tmp);
174
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
175
- val = (uint32_t)s->pc + 2;
176
- val += offset;
177
- gen_jmp(s, val);
178
+ gen_jmp(s, read_pc(s) + offset);
179
break;
180
181
case 15: /* IT, nop-hint. */
182
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
183
arm_skip_unless(s, cond);
184
185
/* jump to the offset */
186
- val = (uint32_t)s->pc + 2;
187
+ val = read_pc(s);
188
offset = ((int32_t)insn << 24) >> 24;
189
val += offset << 1;
190
gen_jmp(s, val);
191
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
192
break;
193
}
194
/* unconditional branch */
195
- val = (uint32_t)s->pc;
196
+ val = read_pc(s);
197
offset = ((int32_t)insn << 21) >> 21;
198
- val += (offset << 1) + 2;
199
+ val += offset << 1;
200
gen_jmp(s, val);
201
break;
202
203
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
204
/* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
205
uint32_t uoffset = ((int32_t)insn << 21) >> 9;
206
207
- tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
208
+ tcg_gen_movi_i32(cpu_R[14], read_pc(s) + uoffset);
209
}
210
break;
211
}
212
--
79
--
213
2.20.1
80
2.25.1
214
215
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
While most features are now detected by probing the ID_* registers
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
kernels can (and do) use MIDR_EL1 for working out of they have to
5
apply errata. This can trip up warnings in the kernel as it tries to
6
work out if it should apply workarounds to features that don't
7
actually exist in the reported CPU type.
8
9
Avoid this problem by synthesising our own MIDR value.
10
11
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
14
Message-id: 20190726113950.7499-1-alex.bennee@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
7
---
17
target/arm/cpu.h | 6 ++++++
8
hw/arm/stellaris.c | 15 +++++++++++++--
18
target/arm/cpu64.c | 19 +++++++++++++++++++
9
1 file changed, 13 insertions(+), 2 deletions(-)
19
2 files changed, 25 insertions(+)
20
10
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
22
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
13
--- a/hw/arm/stellaris.c
24
+++ b/target/arm/cpu.h
14
+++ b/hw/arm/stellaris.c
25
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_FPCCR, ASPEN, 31, 1)
15
@@ -XXX,XX +XXX,XX @@
26
/*
16
27
* System register ID fields.
17
#include "qemu/osdep.h"
28
*/
18
#include "qapi/error.h"
29
+FIELD(MIDR_EL1, REVISION, 0, 4)
19
+#include "hw/core/split-irq.h"
30
+FIELD(MIDR_EL1, PARTNUM, 4, 12)
20
#include "hw/sysbus.h"
31
+FIELD(MIDR_EL1, ARCHITECTURE, 16, 4)
21
#include "hw/sd/sd.h"
32
+FIELD(MIDR_EL1, VARIANT, 20, 4)
22
#include "hw/ssi/ssi.h"
33
+FIELD(MIDR_EL1, IMPLEMENTER, 24, 8)
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
24
DeviceState *ssddev;
25
DriveInfo *dinfo;
26
DeviceState *carddev;
27
+ DeviceState *gpio_d_splitter;
28
BlockBackend *blk;
29
30
/*
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
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),
34
+
37
+
35
FIELD(ID_ISAR0, SWAP, 0, 4)
38
+ gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
36
FIELD(ID_ISAR0, BITCOUNT, 4, 4)
39
+ qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
37
FIELD(ID_ISAR0, BITFIELD, 8, 4)
40
+ qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
38
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
41
+ qdev_connect_gpio_out(
39
index XXXXXXX..XXXXXXX 100644
42
+ gpio_d_splitter, 0,
40
--- a/target/arm/cpu64.c
43
+ qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0));
41
+++ b/target/arm/cpu64.c
44
+ qdev_connect_gpio_out(
42
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
45
+ gpio_d_splitter, 1,
43
uint32_t u;
46
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
44
aarch64_a57_initfn(obj);
47
+ gpio_out[GPIO_D][0] = qdev_get_gpio_in(gpio_d_splitter, 0);
45
46
+ /*
47
+ * Reset MIDR so the guest doesn't mistake our 'max' CPU type for a real
48
+ * one and try to apply errata workarounds or use impdef features we
49
+ * don't provide.
50
+ * An IMPLEMENTER field of 0 means "reserved for software use";
51
+ * ARCHITECTURE must be 0xf indicating "v7 or later, check ID registers
52
+ * to see which features are present";
53
+ * the VARIANT, PARTNUM and REVISION fields are all implementation
54
+ * defined and we choose to define PARTNUM just in case guest
55
+ * code needs to distinguish this QEMU CPU from other software
56
+ * implementations, though this shouldn't be needed.
57
+ */
58
+ t = FIELD_DP64(0, MIDR_EL1, IMPLEMENTER, 0);
59
+ t = FIELD_DP64(t, MIDR_EL1, ARCHITECTURE, 0xf);
60
+ t = FIELD_DP64(t, MIDR_EL1, PARTNUM, 'Q');
61
+ t = FIELD_DP64(t, MIDR_EL1, VARIANT, 0);
62
+ t = FIELD_DP64(t, MIDR_EL1, REVISION, 0);
63
+ cpu->midr = t;
64
+
48
+
65
t = cpu->isar.id_aa64isar0;
49
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
66
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */
50
67
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);
51
/* Make sure the select pin is high. */
68
--
52
--
69
2.20.1
53
2.25.1
70
71
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
All of the inputs to these instructions are 32-bits. Rather than
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
extend each input to 64-bits and then extract the high 32-bits of
5
the output, use tcg_gen_muls2_i32 and other 32-bit generator functions.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190808202616.13782-7-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/translate.c | 72 +++++++++++++++---------------------------
9
include/hw/irq.h | 5 -----
13
1 file changed, 26 insertions(+), 46 deletions(-)
10
hw/core/irq.c | 15 ---------------
11
2 files changed, 20 deletions(-)
14
12
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
15
--- a/include/hw/irq.h
18
+++ b/target/arm/translate.c
16
+++ b/include/hw/irq.h
19
@@ -XXX,XX +XXX,XX @@ static void gen_revsh(TCGv_i32 var)
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
20
tcg_gen_ext16s_i32(var, var);
18
/* Returns a new IRQ with opposite polarity. */
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);
21
}
35
}
22
36
23
-/* Return (b << 32) + a. Mark inputs as dead */
37
-static void qemu_splitirq(void *opaque, int line, int level)
24
-static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
25
-{
38
-{
26
- TCGv_i64 tmp64 = tcg_temp_new_i64();
39
- struct IRQState **irq = opaque;
27
-
40
- irq[0]->handler(irq[0]->opaque, irq[0]->n, level);
28
- tcg_gen_extu_i32_i64(tmp64, b);
41
- irq[1]->handler(irq[1]->opaque, irq[1]->n, level);
29
- tcg_temp_free_i32(b);
30
- tcg_gen_shli_i64(tmp64, tmp64, 32);
31
- tcg_gen_add_i64(a, tmp64, a);
32
-
33
- tcg_temp_free_i64(tmp64);
34
- return a;
35
-}
42
-}
36
-
43
-
37
-/* Return (b << 32) - a. Mark inputs as dead. */
44
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
38
-static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
39
-{
45
-{
40
- TCGv_i64 tmp64 = tcg_temp_new_i64();
46
- qemu_irq *s = g_new0(qemu_irq, 2);
41
-
47
- s[0] = irq1;
42
- tcg_gen_extu_i32_i64(tmp64, b);
48
- s[1] = irq2;
43
- tcg_temp_free_i32(b);
49
- return qemu_allocate_irq(qemu_splitirq, s, 0);
44
- tcg_gen_shli_i64(tmp64, tmp64, 32);
45
- tcg_gen_sub_i64(a, tmp64, a);
46
-
47
- tcg_temp_free_i64(tmp64);
48
- return a;
49
-}
50
-}
50
-
51
-
51
/* 32x32->64 multiply. Marks inputs as dead. */
52
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
52
static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
53
{
53
{
54
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
54
int i;
55
(SMMUL, SMMLA, SMMLS) */
56
tmp = load_reg(s, rm);
57
tmp2 = load_reg(s, rs);
58
- tmp64 = gen_muls_i64_i32(tmp, tmp2);
59
+ tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
60
61
if (rd != 15) {
62
- tmp = load_reg(s, rd);
63
+ tmp3 = load_reg(s, rd);
64
if (insn & (1 << 6)) {
65
- tmp64 = gen_subq_msw(tmp64, tmp);
66
+ tcg_gen_sub_i32(tmp, tmp, tmp3);
67
} else {
68
- tmp64 = gen_addq_msw(tmp64, tmp);
69
+ tcg_gen_add_i32(tmp, tmp, tmp3);
70
}
71
+ tcg_temp_free_i32(tmp3);
72
}
73
if (insn & (1 << 5)) {
74
- tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
75
+ /*
76
+ * Adding 0x80000000 to the 64-bit quantity
77
+ * means that we have carry in to the high
78
+ * word when the low word has the high bit set.
79
+ */
80
+ tcg_gen_shri_i32(tmp2, tmp2, 31);
81
+ tcg_gen_add_i32(tmp, tmp, tmp2);
82
}
83
- tcg_gen_shri_i64(tmp64, tmp64, 32);
84
- tmp = tcg_temp_new_i32();
85
- tcg_gen_extrl_i64_i32(tmp, tmp64);
86
- tcg_temp_free_i64(tmp64);
87
+ tcg_temp_free_i32(tmp2);
88
store_reg(s, rn, tmp);
89
break;
90
case 0:
91
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
92
}
93
break;
94
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
95
- tmp64 = gen_muls_i64_i32(tmp, tmp2);
96
+ tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
97
if (rs != 15) {
98
- tmp = load_reg(s, rs);
99
+ tmp3 = load_reg(s, rs);
100
if (insn & (1 << 20)) {
101
- tmp64 = gen_addq_msw(tmp64, tmp);
102
+ tcg_gen_add_i32(tmp, tmp, tmp3);
103
} else {
104
- tmp64 = gen_subq_msw(tmp64, tmp);
105
+ tcg_gen_sub_i32(tmp, tmp, tmp3);
106
}
107
+ tcg_temp_free_i32(tmp3);
108
}
109
if (insn & (1 << 4)) {
110
- tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
111
+ /*
112
+ * Adding 0x80000000 to the 64-bit quantity
113
+ * means that we have carry in to the high
114
+ * word when the low word has the high bit set.
115
+ */
116
+ tcg_gen_shri_i32(tmp2, tmp2, 31);
117
+ tcg_gen_add_i32(tmp, tmp, tmp2);
118
}
119
- tcg_gen_shri_i64(tmp64, tmp64, 32);
120
- tmp = tcg_temp_new_i32();
121
- tcg_gen_extrl_i64_i32(tmp, tmp64);
122
- tcg_temp_free_i64(tmp64);
123
+ tcg_temp_free_i32(tmp2);
124
break;
125
case 7: /* Unsigned sum of absolute differences. */
126
gen_helper_usad8(tmp, tmp, tmp2);
127
--
55
--
128
2.20.1
56
2.25.1
129
130
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
2
2
3
Use deposit as the composit operation to merge the
3
Describe that the gic-version influences the maximum number of CPUs.
4
bits from the two inputs.
5
4
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
7
Message-id: 20190808202616.13782-3-richard.henderson@linaro.org
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
7
[PMM: minor punctuation tweaks]
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@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
target/arm/translate.c | 26 ++++++++++----------------
11
docs/system/arm/virt.rst | 4 ++--
12
1 file changed, 10 insertions(+), 16 deletions(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
13
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
16
--- a/docs/system/arm/virt.rst
17
+++ b/target/arm/translate.c
17
+++ b/docs/system/arm/virt.rst
18
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
18
@@ -XXX,XX +XXX,XX @@ gic-version
19
shift = (insn >> 7) & 0x1f;
19
Valid values are:
20
if (insn & (1 << 6)) {
20
21
/* pkhtb */
21
``2``
22
- if (shift == 0)
22
- GICv2
23
+ if (shift == 0) {
23
+ GICv2. Note that this limits the number of CPUs to 8.
24
shift = 31;
24
``3``
25
+ }
25
- GICv3
26
tcg_gen_sari_i32(tmp2, tmp2, shift);
26
+ GICv3. This allows up to 512 CPUs.
27
- tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
27
``host``
28
- tcg_gen_ext16u_i32(tmp2, tmp2);
28
Use the same GIC version the host provides, when using KVM
29
+ tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
29
``max``
30
} else {
31
/* pkhbt */
32
- if (shift)
33
- tcg_gen_shli_i32(tmp2, tmp2, shift);
34
- tcg_gen_ext16u_i32(tmp, tmp);
35
- tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
36
+ tcg_gen_shli_i32(tmp2, tmp2, shift);
37
+ tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
38
}
39
- tcg_gen_or_i32(tmp, tmp, tmp2);
40
tcg_temp_free_i32(tmp2);
41
store_reg(s, rd, tmp);
42
} else if ((insn & 0x00200020) == 0x00200000) {
43
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
44
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
45
if (insn & (1 << 5)) {
46
/* pkhtb */
47
- if (shift == 0)
48
+ if (shift == 0) {
49
shift = 31;
50
+ }
51
tcg_gen_sari_i32(tmp2, tmp2, shift);
52
- tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
53
- tcg_gen_ext16u_i32(tmp2, tmp2);
54
+ tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
55
} else {
56
/* pkhbt */
57
- if (shift)
58
- tcg_gen_shli_i32(tmp2, tmp2, shift);
59
- tcg_gen_ext16u_i32(tmp, tmp);
60
- tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
61
+ tcg_gen_shli_i32(tmp2, tmp2, shift);
62
+ tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
63
}
64
- tcg_gen_or_i32(tmp, tmp, tmp2);
65
tcg_temp_free_i32(tmp2);
66
store_reg(s, rd, tmp);
67
} else {
68
--
30
--
69
2.20.1
31
2.25.1
70
71
diff view generated by jsdifflib
1
From: Aaron Hill <aa1ronham@gmail.com>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
This commit properly sets the ENET_BD_BDU flag once the emulated FEC controller
3
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
4
has finished processing the last descriptor. This is done for both transmit
4
the PWRON STRAP fields in their corresponding module for NPCM7XX.
5
and receive descriptors.
6
5
7
This allows the QNX 7.0.0 BSP for the Sabrelite board (which can be
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
8
found at http://blackberry.qnx.com/en/developers/bsp) to properly
7
Reviewed-by: Patrick Venture <venture@google.com>
9
control the FEC. Without this patch, the BSP ethernet driver will never
8
Message-id: 20220411165842.3912945-2-wuhaotsh@google.com
10
re-use FEC descriptors, as the unset ENET_BD_BDU flag will cause
11
it to believe that the descriptors are still in use by the NIC.
12
13
Note that Linux does not appear to use this field at all, and is
14
unaffected by this patch.
15
16
Without this patch, QNX will think that the NIC is still processing its
17
transaction descriptors, and won't send any more data over the network.
18
19
For reference:
20
21
On page 1192 of the I.MX 6DQ reference manual revision (Rev. 5, 06/2018),
22
which can be found at https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/i.mx-applications-processors/i.mx-6-processors/i.mx-6quad-processors-high-performance-3d-graphics-hd-video-arm-cortex-a9-core:i.MX6Q?&tab=Documentation_Tab&linkline=Application-Note
23
24
the 'BDU' field is described as follows for the 'Enhanced transmit
25
buffer descriptor':
26
27
'Last buffer descriptor update done. Indicates that the last BD data has been updated by
28
uDMA. This field is written by the user (=0) and uDMA (=1).'
29
30
The same description is used for the receive buffer descriptor.
31
32
Signed-off-by: Aaron Hill <aa1ronham@gmail.com>
33
Message-id: 20190805142417.10433-1-aaron.hill@alertinnovation.com
34
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
---
11
---
37
hw/net/imx_fec.c | 4 ++++
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
38
1 file changed, 4 insertions(+)
13
1 file changed, 30 insertions(+)
39
14
40
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
41
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/net/imx_fec.c
17
--- a/include/hw/misc/npcm7xx_gcr.h
43
+++ b/hw/net/imx_fec.c
18
+++ b/include/hw/misc/npcm7xx_gcr.h
44
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
19
@@ -XXX,XX +XXX,XX @@
45
if (bd.option & ENET_BD_TX_INT) {
20
#include "exec/memory.h"
46
s->regs[ENET_EIR] |= int_txf;
21
#include "hw/sysbus.h"
47
}
22
48
+ /* Indicate that we've updated the last buffer descriptor. */
23
+/*
49
+ bd.last_buffer = ENET_BD_BDU;
24
+ * NPCM7XX PWRON STRAP bit fields
50
}
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
51
if (bd.option & ENET_BD_TX_INT) {
26
+ * 11: System flash attached to BMC
52
s->regs[ENET_EIR] |= int_txb;
27
+ * 10: BSP alternative pins.
53
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
28
+ * 9:8: Flash UART command route enabled.
54
/* Last buffer in frame. */
29
+ * 7: Security enabled.
55
bd.flags |= flags | ENET_BD_L;
30
+ * 6: HI-Z state control.
56
FEC_PRINTF("rx frame flags %04x\n", bd.flags);
31
+ * 5: ECC disabled.
57
+ /* Indicate that we've updated the last buffer descriptor. */
32
+ * 4: Reserved
58
+ bd.last_buffer = ENET_BD_BDU;
33
+ * 3: JTAG2 enabled.
59
if (bd.option & ENET_BD_RX_INT) {
34
+ * 2:0: CPU and DRAM clock frequency.
60
s->regs[ENET_EIR] |= ENET_INT_RXF;
35
+ */
61
}
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.
62
--
56
--
63
2.20.1
57
2.25.1
64
65
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
Separate shift + extract low will result in one extra insn
3
This patch uses the defined fields to describe PWRON STRAPs for
4
for hosts like RISC-V, MIPS, and Sparc.
4
better readability.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
7
Message-id: 20190808202616.13782-8-richard.henderson@linaro.org
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Message-id: 20220411165842.3912945-3-wuhaotsh@google.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@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
target/arm/translate.c | 18 ++++++------------
12
hw/arm/npcm7xx_boards.c | 24 +++++++++++++++++++-----
12
1 file changed, 6 insertions(+), 12 deletions(-)
13
1 file changed, 19 insertions(+), 5 deletions(-)
13
14
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
17
--- a/hw/arm/npcm7xx_boards.c
17
+++ b/target/arm/translate.c
18
+++ b/hw/arm/npcm7xx_boards.c
18
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@
19
if (insn & ARM_CP_RW_BIT) { /* TMRRC */
20
#include "sysemu/sysemu.h"
20
iwmmxt_load_reg(cpu_V0, wrd);
21
#include "sysemu/block-backend.h"
21
tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
22
22
- tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
23
- tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
24
+ tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
25
} else { /* TMCRR */
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
26
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
27
-#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
27
iwmmxt_store_reg(cpu_V0, wrd);
28
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT ( \
28
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
29
+ NPCM7XX_PWRON_STRAP_SPI0F18 | \
29
if (insn & ARM_CP_RW_BIT) { /* MRA */
30
+ NPCM7XX_PWRON_STRAP_SFAB | \
30
iwmmxt_load_reg(cpu_V0, acc);
31
+ NPCM7XX_PWRON_STRAP_BSPA | \
31
tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
32
+ NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) | \
32
- tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
33
+ NPCM7XX_PWRON_STRAP_SECEN | \
33
- tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
34
+ NPCM7XX_PWRON_STRAP_HIZ | \
34
+ tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
35
+ NPCM7XX_PWRON_STRAP_ECC | \
35
tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
36
+ NPCM7XX_PWRON_STRAP_RESERVE1 | \
36
} else { /* MAR */
37
+ NPCM7XX_PWRON_STRAP_J2EN | \
37
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
38
+ NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))
38
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
39
+
39
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
40
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
40
break;
41
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_J2EN)
41
case 2:
42
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
42
- tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
43
+#define QUANTA_GBS_POWER_ON_STRAPS ( \
43
- tcg_gen_extrl_i64_i32(tmp, cpu_V0);
44
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_SFAB)
44
+ tcg_gen_extrh_i64_i32(tmp, cpu_V0);
45
+#define KUDO_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
45
break;
46
+#define MORI_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
46
default: abort();
47
47
}
48
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
48
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
49
break;
50
case 2:
51
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
52
- tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
53
- tcg_gen_extrl_i64_i32(tmp, cpu_V0);
54
+ tcg_gen_extrh_i64_i32(tmp, cpu_V0);
55
break;
56
default: abort();
57
}
58
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
59
tmp = tcg_temp_new_i32();
60
tcg_gen_extrl_i64_i32(tmp, tmp64);
61
store_reg(s, rt, tmp);
62
- tcg_gen_shri_i64(tmp64, tmp64, 32);
63
tmp = tcg_temp_new_i32();
64
- tcg_gen_extrl_i64_i32(tmp, tmp64);
65
+ tcg_gen_extrh_i64_i32(tmp, tmp64);
66
tcg_temp_free_i64(tmp64);
67
store_reg(s, rt2, tmp);
68
} else {
69
@@ -XXX,XX +XXX,XX @@ static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
70
tcg_gen_extrl_i64_i32(tmp, val);
71
store_reg(s, rlow, tmp);
72
tmp = tcg_temp_new_i32();
73
- tcg_gen_shri_i64(val, val, 32);
74
- tcg_gen_extrl_i64_i32(tmp, val);
75
+ tcg_gen_extrh_i64_i32(tmp, val);
76
store_reg(s, rhigh, tmp);
77
}
78
49
79
--
50
--
80
2.20.1
51
2.25.1
81
82
diff view generated by jsdifflib