1
Most of this is the Neon decodetree patches, followed by Edgar's versal cleanups.
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
10
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
6
11
7
The following changes since commit 2ef486e76d64436be90f7359a3071fb2a56ce835:
12
Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700)
8
9
Merge remote-tracking branch 'remotes/marcel/tags/rdma-pull-request' into staging (2020-05-03 14:12:56 +0100)
10
13
11
are available in the Git repository at:
14
are available in the Git repository at:
12
15
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200504
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220421
14
17
15
for you to fetch changes up to 9aefc6cf9b73f66062d2f914a0136756e7a28211:
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
16
19
17
target/arm: Move gen_ function typedefs to translate.h (2020-05-04 12:59:26 +0100)
20
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs (2022-04-21 11:37:05 +0100)
18
21
19
----------------------------------------------------------------
22
----------------------------------------------------------------
20
target-arm queue:
23
target-arm queue:
21
* Start of conversion of Neon insns to decodetree
24
* hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
22
* versal board: support SD and RTC
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
23
* Implement ARMv8.2-TTS2UXN
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
24
* Make VQDMULL undefined when U=1
27
* xlnx-zynqmp: Connect 4 TTC timers
25
* Some minor code cleanups
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
30
* stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
31
* hw/core/irq: remove unused 'qemu_irq_split' function
32
* npcm7xx: use symbolic constants for PWRON STRAP bit fields
33
* virt: document impact of gic-version on max CPUs
26
34
27
----------------------------------------------------------------
35
----------------------------------------------------------------
28
Edgar E. Iglesias (11):
36
Edgar E. Iglesias (6):
29
hw/arm: versal: Remove inclusion of arm_gicv3_common.h
37
timer: cadence_ttc: Break out header file to allow embedding
30
hw/arm: versal: Move misplaced comment
38
hw/arm/xlnx-zynqmp: Connect 4 TTC timers
31
hw/arm: versal-virt: Fix typo xlnx-ve -> xlnx-versal
39
hw/arm: versal: Create an APU CPU Cluster
32
hw/arm: versal: Embed the UARTs into the SoC type
40
hw/arm: versal: Add the Cortex-R5Fs
33
hw/arm: versal: Embed the GEMs into the SoC type
41
hw/misc: Add a model of the Xilinx Versal CRL
34
hw/arm: versal: Embed the ADMAs into the SoC type
42
hw/arm: versal: Connect the CRL
35
hw/arm: versal: Embed the APUs into the SoC type
36
hw/arm: versal: Add support for SD
37
hw/arm: versal: Add support for the RTC
38
hw/arm: versal-virt: Add support for SD
39
hw/arm: versal-virt: Add support for the RTC
40
43
41
Fredrik Strupe (1):
44
Hao Wu (2):
42
target/arm: Make VQDMULL undefined when U=1
45
hw/misc: Add PWRON STRAP bit fields in GCR module
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
43
47
44
Peter Maydell (25):
48
Heinrich Schuchardt (1):
45
target/arm: Don't use a TLB for ARMMMUIdx_Stage2
49
hw/arm/virt: impact of gic-version on max CPUs
46
target/arm: Use enum constant in get_phys_addr_lpae() call
47
target/arm: Add new 's1_is_el0' argument to get_phys_addr_lpae()
48
target/arm: Implement ARMv8.2-TTS2UXN
49
target/arm: Use correct variable for setting 'max' cpu's ID_AA64DFR0
50
target/arm/translate-vfp.inc.c: Remove duplicate simd_r32 check
51
target/arm: Don't allow Thumb Neon insns without FEATURE_NEON
52
target/arm: Add stubs for AArch32 Neon decodetree
53
target/arm: Convert VCMLA (vector) to decodetree
54
target/arm: Convert VCADD (vector) to decodetree
55
target/arm: Convert V[US]DOT (vector) to decodetree
56
target/arm: Convert VFM[AS]L (vector) to decodetree
57
target/arm: Convert VCMLA (scalar) to decodetree
58
target/arm: Convert V[US]DOT (scalar) to decodetree
59
target/arm: Convert VFM[AS]L (scalar) to decodetree
60
target/arm: Convert Neon load/store multiple structures to decodetree
61
target/arm: Convert Neon 'load single structure to all lanes' to decodetree
62
target/arm: Convert Neon 'load/store single structure' to decodetree
63
target/arm: Convert Neon 3-reg-same VADD/VSUB to decodetree
64
target/arm: Convert Neon 3-reg-same logic ops to decodetree
65
target/arm: Convert Neon 3-reg-same VMAX/VMIN to decodetree
66
target/arm: Convert Neon 3-reg-same comparisons to decodetree
67
target/arm: Convert Neon 3-reg-same VQADD/VQSUB to decodetree
68
target/arm: Convert Neon 3-reg-same VMUL, VMLA, VMLS, VSHL to decodetree
69
target/arm: Move gen_ function typedefs to translate.h
70
50
71
Philippe Mathieu-Daudé (2):
51
Peter Maydell (19):
72
hw/arm/mps2-tz: Use TYPE_IOTKIT instead of hardcoded string
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
73
target/arm: Use uint64_t for midr field in CPU state struct
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
74
71
75
include/hw/arm/xlnx-versal.h | 31 +-
72
Zongyuan Li (3):
76
target/arm/cpu-param.h | 2 +-
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
77
target/arm/cpu.h | 38 ++-
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
78
target/arm/translate-a64.h | 9 -
75
hw/core/irq: remove unused 'qemu_irq_split' function
79
target/arm/translate.h | 26 ++
80
target/arm/neon-dp.decode | 86 +++++
81
target/arm/neon-ls.decode | 52 +++
82
target/arm/neon-shared.decode | 66 ++++
83
hw/arm/mps2-tz.c | 2 +-
84
hw/arm/xlnx-versal-virt.c | 74 ++++-
85
hw/arm/xlnx-versal.c | 115 +++++--
86
target/arm/cpu.c | 3 +-
87
target/arm/cpu64.c | 8 +-
88
target/arm/helper.c | 183 ++++------
89
target/arm/translate-a64.c | 17 -
90
target/arm/translate-neon.inc.c | 714 +++++++++++++++++++++++++++++++++++++++
91
target/arm/translate-vfp.inc.c | 6 -
92
target/arm/translate.c | 716 +++-------------------------------------
93
target/arm/Makefile.objs | 18 +
94
19 files changed, 1302 insertions(+), 864 deletions(-)
95
create mode 100644 target/arm/neon-dp.decode
96
create mode 100644 target/arm/neon-ls.decode
97
create mode 100644 target/arm/neon-shared.decode
98
create mode 100644 target/arm/translate-neon.inc.c
99
76
77
docs/system/arm/virt.rst | 4 +-
78
include/hw/arm/exynos4210.h | 50 ++--
79
include/hw/arm/xlnx-versal.h | 16 ++
80
include/hw/arm/xlnx-zynqmp.h | 4 +
81
include/hw/intc/exynos4210_combiner.h | 57 +++++
82
include/hw/intc/exynos4210_gic.h | 43 ++++
83
include/hw/irq.h | 5 -
84
include/hw/misc/npcm7xx_gcr.h | 30 +++
85
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++++
86
include/hw/timer/cadence_ttc.h | 54 +++++
87
hw/arm/exynos4210.c | 430 ++++++++++++++++++++++++++++++----
88
hw/arm/npcm7xx_boards.c | 24 +-
89
hw/arm/realview.c | 33 ++-
90
hw/arm/stellaris.c | 15 +-
91
hw/arm/virt.c | 7 +
92
hw/arm/xlnx-versal-virt.c | 6 +-
93
hw/arm/xlnx-versal.c | 99 +++++++-
94
hw/arm/xlnx-zynqmp.c | 22 ++
95
hw/core/irq.c | 15 --
96
hw/intc/exynos4210_combiner.c | 108 +--------
97
hw/intc/exynos4210_gic.c | 344 +--------------------------
98
hw/misc/xlnx-versal-crl.c | 421 +++++++++++++++++++++++++++++++++
99
hw/timer/cadence_ttc.c | 32 +--
100
MAINTAINERS | 2 +-
101
hw/misc/meson.build | 1 +
102
25 files changed, 1457 insertions(+), 600 deletions(-)
103
create mode 100644 include/hw/intc/exynos4210_combiner.h
104
create mode 100644 include/hw/intc/exynos4210_gic.h
105
create mode 100644 include/hw/misc/xlnx-versal-crl.h
106
create mode 100644 include/hw/timer/cadence_ttc.h
107
create mode 100644 hw/misc/xlnx-versal-crl.c
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VMAX and VMIN insns to decodetree.
1
It's not possible to provide the guest with the Security extensions
2
(TrustZone) when using KVM or HVF, because the hardware
3
virtualization extensions don't permit running EL3 guest code.
4
However, we weren't checking for this combination, with the result
5
that QEMU would assert if you tried it:
2
6
7
$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none
8
Unexpected error in object_property_find_err() at ../../qom/object.c:1304:
9
qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found
10
Aborted
11
12
Check for this combination of options and report an error, in the
13
same way we already do for attempts to give a KVM or HVF guest the
14
Virtualization or MTE extensions. Now we will report:
15
16
qemu-system-aarch64: mach-virt: KVM does not support providing Security extensions (TrustZone) to the guest CPU
17
18
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/961
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-17-peter.maydell@linaro.org
21
Message-id: 20220404155301.566542-1-peter.maydell@linaro.org
6
---
22
---
7
target/arm/neon-dp.decode | 5 +++++
23
hw/arm/virt.c | 7 +++++++
8
target/arm/translate-neon.inc.c | 14 ++++++++++++++
24
1 file changed, 7 insertions(+)
9
target/arm/translate.c | 21 ++-------------------
10
3 files changed, 21 insertions(+), 19 deletions(-)
11
25
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
26
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
13
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
28
--- a/hw/arm/virt.c
15
+++ b/target/arm/neon-dp.decode
29
+++ b/hw/arm/virt.c
16
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
17
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
31
exit(1);
18
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
32
}
19
33
20
+VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
21
+VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
35
+ error_report("mach-virt: %s does not support providing "
22
+VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
36
+ "Security extensions (TrustZone) to the guest CPU",
23
+VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
37
+ kvm_enabled() ? "KVM" : "HVF");
24
+
38
+ exit(1);
25
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
26
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
30
+++ b/target/arm/translate-neon.inc.c
31
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VEOR, tcg_gen_gvec_xor)
32
DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
33
DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
34
DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
35
+
36
+#define DO_3SAME_NO_SZ_3(INSN, FUNC) \
37
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
38
+ { \
39
+ if (a->size == 3) { \
40
+ return false; \
41
+ } \
42
+ return do_3same(s, a, FUNC); \
43
+ }
39
+ }
44
+
40
+
45
+DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
46
+DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
42
error_report("mach-virt: %s does not support providing "
47
+DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
43
"Virtualization extensions to the guest CPU",
48
+DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/translate.c
52
+++ b/target/arm/translate.c
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
54
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
55
return 0;
56
57
- case NEON_3R_VMAX:
58
- if (u) {
59
- tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
60
- vec_size, vec_size);
61
- } else {
62
- tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
63
- vec_size, vec_size);
64
- }
65
- return 0;
66
- case NEON_3R_VMIN:
67
- if (u) {
68
- tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
69
- vec_size, vec_size);
70
- } else {
71
- tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
72
- vec_size, vec_size);
73
- }
74
- return 0;
75
-
76
case NEON_3R_VSHL:
77
/* Note the operation is vshl vd,vm,vn */
78
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
79
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
80
81
case NEON_3R_VADD_VSUB:
82
case NEON_3R_LOGIC:
83
+ case NEON_3R_VMAX:
84
+ case NEON_3R_VMIN:
85
/* Already handled by decodetree */
86
return 1;
87
}
88
--
44
--
89
2.20.1
45
2.25.1
90
91
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Embed the ADMAs into the SoC type.
3
Break out header file to allow embedding of the the TTC.
4
4
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
10
Message-id: 20200427181649.26851-7-edgar.iglesias@gmail.com
9
Message-id: 20220331222017.2914409-2-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
include/hw/arm/xlnx-versal.h | 3 ++-
12
include/hw/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++
14
hw/arm/xlnx-versal.c | 14 +++++++-------
13
hw/timer/cadence_ttc.c | 32 ++------------------
15
2 files changed, 9 insertions(+), 8 deletions(-)
14
2 files changed, 56 insertions(+), 30 deletions(-)
15
create mode 100644 include/hw/timer/cadence_ttc.h
16
16
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
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
18
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
79
--- a/hw/timer/cadence_ttc.c
20
+++ b/include/hw/arm/xlnx-versal.h
80
+++ b/hw/timer/cadence_ttc.c
21
@@ -XXX,XX +XXX,XX @@
81
@@ -XXX,XX +XXX,XX @@
22
#include "hw/arm/boot.h"
82
#include "qemu/timer.h"
23
#include "hw/intc/arm_gicv3.h"
83
#include "qom/object.h"
24
#include "hw/char/pl011.h"
84
25
+#include "hw/dma/xlnx-zdma.h"
85
+#include "hw/timer/cadence_ttc.h"
26
#include "hw/net/cadence_gem.h"
86
+
27
87
#ifdef CADENCE_TTC_ERR_DEBUG
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
88
#define DB_PRINT(...) do { \
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
89
fprintf(stderr, ": %s: ", __func__); \
30
struct {
90
@@ -XXX,XX +XXX,XX @@
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
91
#define CLOCK_CTRL_PS_EN 0x00000001
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
92
#define CLOCK_CTRL_PS_V 0x0000001e
33
- SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
93
34
+ XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
94
-typedef struct {
35
} iou;
95
- QEMUTimer *timer;
36
} lpd;
96
- int freq;
37
97
-
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
98
- uint32_t reg_clock;
39
index XXXXXXX..XXXXXXX 100644
99
- uint32_t reg_count;
40
--- a/hw/arm/xlnx-versal.c
100
- uint32_t reg_value;
41
+++ b/hw/arm/xlnx-versal.c
101
- uint16_t reg_interval;
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
102
- uint16_t reg_match[3];
43
DeviceState *dev;
103
- uint32_t reg_intr;
44
MemoryRegion *mr;
104
- uint32_t reg_intr_en;
45
105
- uint32_t reg_event_ctrl;
46
- dev = qdev_create(NULL, "xlnx.zdma");
106
- uint32_t reg_event;
47
- s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
107
-
48
- object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
108
- uint64_t cpu_time;
49
- &error_abort);
109
- unsigned int cpu_time_valid;
50
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
110
-
51
+ sysbus_init_child_obj(OBJECT(s), name,
111
- qemu_irq irq;
52
+ &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]),
112
-} CadenceTimerState;
53
+ TYPE_XLNX_ZDMA);
113
-
54
+ dev = DEVICE(&s->lpd.iou.adma[i]);
114
-#define TYPE_CADENCE_TTC "cadence_ttc"
55
+ object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort);
115
-OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
56
qdev_init_nofail(dev);
116
-
57
117
-struct CadenceTTCState {
58
- mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
118
- SysBusDevice parent_obj;
59
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
119
-
60
memory_region_add_subregion(&s->mr_ps,
120
- MemoryRegion iomem;
61
MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
121
- CadenceTimerState timer[3];
62
122
-};
63
- sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
123
-
64
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
124
static void cadence_timer_update(CadenceTimerState *s)
65
g_free(name);
125
{
66
}
126
qemu_set_irq(s->irq, !!(s->reg_intr & s->reg_intr_en));
67
}
68
--
127
--
69
2.20.1
128
2.25.1
70
71
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Add support for SD.
3
Connect the 4 TTC timers on the ZynqMP.
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Message-id: 20200427181649.26851-11-edgar.iglesias@gmail.com
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Message-id: 20220331222017.2914409-3-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
hw/arm/xlnx-versal-virt.c | 46 +++++++++++++++++++++++++++++++++++++++
12
include/hw/arm/xlnx-zynqmp.h | 4 ++++
12
1 file changed, 46 insertions(+)
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
14
2 files changed, 26 insertions(+)
13
15
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
18
--- a/include/hw/arm/xlnx-zynqmp.h
17
+++ b/hw/arm/xlnx-versal-virt.c
19
+++ b/include/hw/arm/xlnx-zynqmp.h
18
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
19
#include "hw/arm/sysbus-fdt.h"
21
#include "hw/or-irq.h"
20
#include "hw/arm/fdt.h"
22
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
21
#include "cpu.h"
23
#include "hw/misc/xlnx-zynqmp-crf.h"
22
+#include "hw/qdev-properties.h"
24
+#include "hw/timer/cadence_ttc.h"
23
#include "hw/arm/xlnx-versal.h"
25
24
26
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
25
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
27
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
26
@@ -XXX,XX +XXX,XX @@ static void fdt_add_zdma_nodes(VersalVirt *s)
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
27
}
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.
36
*/
37
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
38
qemu_or_irq qspi_irq_orgate;
39
XlnxZynqMPAPUCtrl apu_ctrl;
40
XlnxZynqMPCRF crf;
41
+ CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
42
43
char *boot_cpu;
44
ARMCPU *boot_cpu_ptr;
45
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/xlnx-zynqmp.c
48
+++ b/hw/arm/xlnx-zynqmp.c
49
@@ -XXX,XX +XXX,XX @@
50
#define APU_ADDR 0xfd5c0000
51
#define APU_IRQ 153
52
53
+#define TTC0_ADDR 0xFF110000
54
+#define TTC0_IRQ 36
55
+
56
#define IPI_ADDR 0xFF300000
57
#define IPI_IRQ 64
58
59
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, qemu_irq *gic)
60
sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
28
}
61
}
29
62
30
+static void fdt_add_sd_nodes(VersalVirt *s)
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
31
+{
64
+{
32
+ const char clocknames[] = "clk_xin\0clk_ahb";
65
+ SysBusDevice *sbd;
33
+ const char compat[] = "arasan,sdhci-8.9a";
66
+ int i, irq;
34
+ int i;
35
+
67
+
36
+ for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
37
+ uint64_t addr = MM_PMC_SD0 + MM_PMC_SD0_SIZE * i;
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
38
+ char *name = g_strdup_printf("/sdhci@%" PRIx64, addr);
70
+ TYPE_CADENCE_TTC);
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
39
+
72
+
40
+ qemu_fdt_add_subnode(s->fdt, name);
73
+ sysbus_realize(sbd, &error_fatal);
41
+
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
42
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
75
+ for (irq = 0; irq < 3; irq++) {
43
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
44
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
77
+ }
45
+ clocknames, sizeof(clocknames));
46
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
47
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_SD0_IRQ_0 + i * 2,
48
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
49
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
50
+ 2, addr, 2, MM_PMC_SD0_SIZE);
51
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
52
+ g_free(name);
53
+ }
78
+ }
54
+}
79
+}
55
+
80
+
56
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
57
{
82
{
58
Error *err = NULL;
83
static const struct UnimpInfo {
59
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
60
}
85
xlnx_zynqmp_create_efuse(s, gic_spi);
61
}
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
62
87
xlnx_zynqmp_create_crf(s, gic_spi);
63
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
64
+{
89
xlnx_zynqmp_create_unimp_mmio(s);
65
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
90
66
+ DeviceState *card;
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
67
+
68
+ card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
69
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
70
+ &error_fatal);
71
+ qdev_prop_set_drive(card, "drive", blk, &error_fatal);
72
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
73
+}
74
+
75
static void versal_virt_init(MachineState *machine)
76
{
77
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
78
int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
79
+ int i;
80
81
/*
82
* If the user provides an Operating System to be loaded, we expect them
83
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
84
fdt_add_gic_nodes(s);
85
fdt_add_timer_nodes(s);
86
fdt_add_zdma_nodes(s);
87
+ fdt_add_sd_nodes(s);
88
fdt_add_cpu_nodes(s, psci_conduit);
89
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
90
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
91
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
92
memory_region_add_subregion_overlap(get_system_memory(),
93
0, &s->soc.fpd.apu.mr, 0);
94
95
+ /* Plugin SD cards. */
96
+ for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
97
+ sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
98
+ }
99
+
100
s->binfo.ram_size = machine->ram_size;
101
s->binfo.loader_start = 0x0;
102
s->binfo.get_dtb = versal_virt_get_dtb;
103
--
92
--
104
2.20.1
93
2.25.1
105
106
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Embed the APUs into the SoC type.
3
Create an APU CPU Cluster. This is in preparation to add the RPU.
4
4
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-8-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
9
---
13
include/hw/arm/xlnx-versal.h | 2 +-
10
include/hw/arm/xlnx-versal.h | 2 ++
14
hw/arm/xlnx-versal-virt.c | 4 ++--
11
hw/arm/xlnx-versal.c | 9 ++++++++-
15
hw/arm/xlnx-versal.c | 19 +++++--------------
12
2 files changed, 10 insertions(+), 1 deletion(-)
16
3 files changed, 8 insertions(+), 17 deletions(-)
17
13
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/xlnx-versal.h
16
--- a/include/hw/arm/xlnx-versal.h
21
+++ b/include/hw/arm/xlnx-versal.h
17
+++ b/include/hw/arm/xlnx-versal.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
18
@@ -XXX,XX +XXX,XX @@
19
20
#include "hw/sysbus.h"
21
#include "hw/arm/boot.h"
22
+#include "hw/cpu/cluster.h"
23
#include "hw/or-irq.h"
24
#include "hw/sd/sdhci.h"
25
#include "hw/intc/arm_gicv3.h"
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
23
struct {
27
struct {
24
struct {
28
struct {
25
MemoryRegion mr;
29
MemoryRegion mr;
26
- ARMCPU *cpu[XLNX_VERSAL_NR_ACPUS];
30
+ CPUClusterState cluster;
27
+ ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
31
ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
28
GICv3State gic;
32
GICv3State gic;
29
} apu;
33
} apu;
30
} fpd;
31
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/xlnx-versal-virt.c
34
+++ b/hw/arm/xlnx-versal-virt.c
35
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
36
s->binfo.get_dtb = versal_virt_get_dtb;
37
s->binfo.modify_dtb = versal_virt_modify_dtb;
38
if (machine->kernel_filename) {
39
- arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo);
40
+ arm_load_kernel(&s->soc.fpd.apu.cpu[0], machine, &s->binfo);
41
} else {
42
- AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
43
+ AddressSpace *as = arm_boot_address_space(&s->soc.fpd.apu.cpu[0],
44
&s->binfo);
45
/* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
46
* Offset things by 4K. */
47
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
34
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
48
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/xlnx-versal.c
36
--- a/hw/arm/xlnx-versal.c
50
+++ b/hw/arm/xlnx-versal.c
37
+++ b/hw/arm/xlnx-versal.c
51
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
38
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
52
39
{
40
int i;
41
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
43
+ TYPE_CPU_CLUSTER);
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
45
+
53
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
54
Object *obj;
47
Object *obj;
55
- char *name;
48
56
-
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
57
- obj = object_new(XLNX_VERSAL_ACPU_TYPE);
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
58
- if (!obj) {
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
59
- error_report("Unable to create apu.cpu[%d] of type %s",
52
XLNX_VERSAL_ACPU_TYPE);
60
- i, XLNX_VERSAL_ACPU_TYPE);
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
61
- exit(EXIT_FAILURE);
62
- }
63
-
64
- name = g_strdup_printf("apu-cpu[%d]", i);
65
- object_property_add_child(OBJECT(s), name, obj, &error_fatal);
66
- g_free(name);
67
68
+ object_initialize_child(OBJECT(s), "apu-cpu[*]",
69
+ &s->fpd.apu.cpu[i], sizeof(s->fpd.apu.cpu[i]),
70
+ XLNX_VERSAL_ACPU_TYPE, &error_abort, NULL);
71
+ obj = OBJECT(&s->fpd.apu.cpu[i]);
72
object_property_set_int(obj, s->cfg.psci_conduit,
73
"psci-conduit", &error_abort);
74
if (i) {
54
if (i) {
75
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
76
object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory",
77
&error_abort);
56
&error_abort);
78
object_property_set_bool(obj, true, "realized", &error_fatal);
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
79
- s->fpd.apu.cpu[i] = ARM_CPU(obj);
80
}
58
}
59
+
60
+ qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
81
}
61
}
82
62
83
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
63
static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
84
}
85
86
for (i = 0; i < nr_apu_cpus; i++) {
87
- DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
88
+ DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
89
int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
90
qemu_irq maint_irq;
91
int ti;
92
--
64
--
93
2.20.1
65
2.25.1
94
95
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Add support for SD.
3
Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit)
4
subsystem.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-9-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
include/hw/arm/xlnx-versal.h | 12 ++++++++++++
11
include/hw/arm/xlnx-versal.h | 10 ++++++++++
13
hw/arm/xlnx-versal.c | 31 +++++++++++++++++++++++++++++++
12
hw/arm/xlnx-versal-virt.c | 6 +++---
14
2 files changed, 43 insertions(+)
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
14
3 files changed, 49 insertions(+), 3 deletions(-)
15
15
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
18
--- a/include/hw/arm/xlnx-versal.h
19
+++ b/include/hw/arm/xlnx-versal.h
19
+++ b/include/hw/arm/xlnx-versal.h
20
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
21
21
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
22
#include "hw/sysbus.h"
22
23
#include "hw/arm/boot.h"
23
#define XLNX_VERSAL_NR_ACPUS 2
24
+#include "hw/sd/sdhci.h"
24
+#define XLNX_VERSAL_NR_RCPUS 2
25
#include "hw/intc/arm_gicv3.h"
26
#include "hw/char/pl011.h"
27
#include "hw/dma/xlnx-zdma.h"
28
@@ -XXX,XX +XXX,XX @@
29
#define XLNX_VERSAL_NR_UARTS 2
25
#define XLNX_VERSAL_NR_UARTS 2
30
#define XLNX_VERSAL_NR_GEMS 2
26
#define XLNX_VERSAL_NR_GEMS 2
31
#define XLNX_VERSAL_NR_ADMAS 8
27
#define XLNX_VERSAL_NR_ADMAS 8
32
+#define XLNX_VERSAL_NR_SDS 2
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
33
#define XLNX_VERSAL_NR_IRQS 192
29
VersalUsb2 usb;
34
35
typedef struct Versal {
36
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
37
} iou;
30
} iou;
38
} lpd;
31
39
32
+ /* Real-time Processing Unit. */
40
+ /* The Platform Management Controller subsystem. */
41
+ struct {
42
+ struct {
33
+ struct {
43
+ SDHCIState sd[XLNX_VERSAL_NR_SDS];
34
+ MemoryRegion mr;
44
+ } iou;
35
+ MemoryRegion mr_ps_alias;
45
+ } pmc;
46
+
36
+
47
struct {
37
+ CPUClusterState cluster;
48
MemoryRegion *mr_ddr;
38
+ ARMCPU cpu[XLNX_VERSAL_NR_RCPUS];
49
uint32_t psci_conduit;
39
+ } rpu;
50
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
40
+
51
#define VERSAL_GEM1_IRQ_0 58
41
struct {
52
#define VERSAL_GEM1_WAKE_IRQ_0 59
42
qemu_or_irq irq_orgate;
53
#define VERSAL_ADMA_IRQ_0 60
43
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
54
+#define VERSAL_SD0_IRQ_0 126
44
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
55
45
index XXXXXXX..XXXXXXX 100644
56
/* Architecturally reserved IRQs suitable for virtualization. */
46
--- a/hw/arm/xlnx-versal-virt.c
57
#define VERSAL_RSVD_IRQ_FIRST 111
47
+++ b/hw/arm/xlnx-versal-virt.c
58
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
48
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
59
#define MM_FPD_CRF 0xfd1a0000U
49
60
#define MM_FPD_CRF_SIZE 0x140000
50
mc->desc = "Xilinx Versal Virtual development board";
61
51
mc->init = versal_virt_init;
62
+#define MM_PMC_SD0 0xf1040000U
52
- mc->min_cpus = XLNX_VERSAL_NR_ACPUS;
63
+#define MM_PMC_SD0_SIZE 0x10000
53
- mc->max_cpus = XLNX_VERSAL_NR_ACPUS;
64
#define MM_PMC_CRP 0xf1260000U
54
- mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
65
#define MM_PMC_CRP_SIZE 0x10000
55
+ mc->min_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
66
#endif
56
+ mc->max_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
57
+ mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
58
mc->no_cdrom = true;
59
mc->default_ram_id = "ddr";
60
}
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
61
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
68
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/xlnx-versal.c
63
--- a/hw/arm/xlnx-versal.c
70
+++ b/hw/arm/xlnx-versal.c
64
+++ b/hw/arm/xlnx-versal.c
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
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)
72
}
74
}
73
}
75
}
74
76
75
+#define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */
77
+static void versal_create_rpu_cpus(Versal *s)
76
+static void versal_create_sds(Versal *s, qemu_irq *pic)
77
+{
78
+{
78
+ int i;
79
+ int i;
79
+
80
+
80
+ for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
81
+ DeviceState *dev;
82
+ TYPE_CPU_CLUSTER);
82
+ MemoryRegion *mr;
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
83
+
84
+
84
+ sysbus_init_child_obj(OBJECT(s), "sd[*]",
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
85
+ &s->pmc.iou.sd[i], sizeof(s->pmc.iou.sd[i]),
86
+ Object *obj;
86
+ TYPE_SYSBUS_SDHCI);
87
+ dev = DEVICE(&s->pmc.iou.sd[i]);
88
+
87
+
89
+ object_property_set_uint(OBJECT(dev),
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
90
+ 3, "sd-spec-version", &error_fatal);
89
+ "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
91
+ object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg",
90
+ XLNX_VERSAL_RCPU_TYPE);
92
+ &error_fatal);
91
+ obj = OBJECT(&s->lpd.rpu.cpu[i]);
93
+ object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal);
92
+ object_property_set_bool(obj, "start-powered-off", true,
94
+ qdev_init_nofail(dev);
93
+ &error_abort);
95
+
94
+
96
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
95
+ object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
97
+ memory_region_add_subregion(&s->mr_ps,
96
+ object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
98
+ MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
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
+ }
99
+
102
+
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
101
+ pic[VERSAL_SD0_IRQ_0 + i * 2]);
102
+ }
103
+}
104
+}
104
+
105
+
105
/* This takes the board allocated linear DDR memory and creates aliases
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
106
* for each split DDR range/aperture on the Versal address map.
107
{
107
*/
108
int i;
108
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
110
111
versal_create_apu_cpus(s);
112
versal_create_apu_gic(s, pic);
113
+ versal_create_rpu_cpus(s);
109
versal_create_uarts(s, pic);
114
versal_create_uarts(s, pic);
115
versal_create_usbs(s, pic);
110
versal_create_gems(s, pic);
116
versal_create_gems(s, pic);
111
versal_create_admas(s, pic);
117
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
112
+ versal_create_sds(s, pic);
118
113
versal_map_ddr(s);
119
memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0);
114
versal_unimp(s);
120
memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0);
115
121
+ memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0,
122
+ &s->lpd.rpu.mr_ps_alias, 0);
123
}
124
125
static void versal_init(Object *obj)
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
127
Versal *s = XLNX_VERSAL(obj);
128
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
134
}
135
136
static Property versal_properties[] = {
116
--
137
--
117
2.20.1
138
2.25.1
118
119
diff view generated by jsdifflib
1
Add the infrastructure for building and invoking a decodetree decoder
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
for the AArch32 Neon encodings. At the moment the new decoder covers
3
nothing, so we always fall back to the existing hand-written decode.
4
2
5
We follow the same pattern we did for the VFP decodetree conversion
3
Add a model of the Xilinx Versal CRL.
6
(commit 78e138bc1f672c145ef6ace74617d and following): code that deals
7
with Neon will be moving gradually out to translate-neon.vfp.inc,
8
which we #include into translate.c.
9
4
10
In order to share the decode files between A32 and T32, we
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
11
split Neon into 3 parts:
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
12
* data-processing
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
13
* load-store
8
Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com
14
* 'shared' encodings
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++
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
15
17
16
The first two groups of instructions have similar but not identical
18
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
17
A32 and T32 encodings, so we need to manually transform the T32
18
encoding into the A32 one before calling the decoder; the third group
19
covers the Neon instructions which are identical in A32 and T32.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
24
---
25
target/arm/neon-dp.decode | 29 ++++++++++++++++++++++++++
26
target/arm/neon-ls.decode | 29 ++++++++++++++++++++++++++
27
target/arm/neon-shared.decode | 27 +++++++++++++++++++++++++
28
target/arm/translate-neon.inc.c | 32 +++++++++++++++++++++++++++++
29
target/arm/translate.c | 36 +++++++++++++++++++++++++++++++--
30
target/arm/Makefile.objs | 18 +++++++++++++++++
31
6 files changed, 169 insertions(+), 2 deletions(-)
32
create mode 100644 target/arm/neon-dp.decode
33
create mode 100644 target/arm/neon-ls.decode
34
create mode 100644 target/arm/neon-shared.decode
35
create mode 100644 target/arm/translate-neon.inc.c
36
37
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
38
new file mode 100644
19
new file mode 100644
39
index XXXXXXX..XXXXXXX
20
index XXXXXXX..XXXXXXX
40
--- /dev/null
21
--- /dev/null
41
+++ b/target/arm/neon-dp.decode
22
+++ b/include/hw/misc/xlnx-versal-crl.h
42
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
43
+# AArch32 Neon data-processing instruction descriptions
24
+/*
44
+#
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
45
+# Copyright (c) 2020 Linaro, Ltd
26
+ *
46
+#
27
+ * Copyright (c) 2022 Xilinx Inc.
47
+# This library is free software; you can redistribute it and/or
28
+ * SPDX-License-Identifier: GPL-2.0-or-later
48
+# modify it under the terms of the GNU Lesser General Public
29
+ *
49
+# License as published by the Free Software Foundation; either
30
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
50
+# version 2 of the License, or (at your option) any later version.
31
+ */
51
+#
32
+#ifndef HW_MISC_XLNX_VERSAL_CRL_H
52
+# This library is distributed in the hope that it will be useful,
33
+#define HW_MISC_XLNX_VERSAL_CRL_H
53
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
34
+
54
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35
+#include "hw/sysbus.h"
55
+# Lesser General Public License for more details.
36
+#include "hw/register.h"
56
+#
37
+#include "target/arm/cpu.h"
57
+# You should have received a copy of the GNU Lesser General Public
38
+
58
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
39
+#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl"
59
+
40
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL)
60
+#
41
+
61
+# This file is processed by scripts/decodetree.py
42
+REG32(ERR_CTRL, 0x0)
62
+#
43
+ FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
63
+
44
+REG32(IR_STATUS, 0x4)
64
+# Encodings for Neon data processing instructions where the T32 encoding
45
+ FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1)
65
+# is a simple transformation of the A32 encoding.
46
+REG32(IR_MASK, 0x8)
66
+# More specifically, this file covers instructions where the A32 encoding is
47
+ FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1)
67
+# 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
48
+REG32(IR_ENABLE, 0xc)
68
+# and the T32 encoding is
49
+ FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1)
69
+# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
50
+REG32(IR_DISABLE, 0x10)
70
+# This file works on the A32 encoding only; calling code for T32 has to
51
+ FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1)
71
+# transform the insn into the A32 version first.
52
+REG32(WPROT, 0x1c)
72
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
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
73
new file mode 100644
260
new file mode 100644
74
index XXXXXXX..XXXXXXX
261
index XXXXXXX..XXXXXXX
75
--- /dev/null
262
--- /dev/null
76
+++ b/target/arm/neon-ls.decode
263
+++ b/hw/misc/xlnx-versal-crl.c
77
@@ -XXX,XX +XXX,XX @@
78
+# AArch32 Neon load/store instruction descriptions
79
+#
80
+# Copyright (c) 2020 Linaro, Ltd
81
+#
82
+# This library is free software; you can redistribute it and/or
83
+# modify it under the terms of the GNU Lesser General Public
84
+# License as published by the Free Software Foundation; either
85
+# version 2 of the License, or (at your option) any later version.
86
+#
87
+# This library is distributed in the hope that it will be useful,
88
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
89
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90
+# Lesser General Public License for more details.
91
+#
92
+# You should have received a copy of the GNU Lesser General Public
93
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
94
+
95
+#
96
+# This file is processed by scripts/decodetree.py
97
+#
98
+
99
+# Encodings for Neon load/store instructions where the T32 encoding
100
+# is a simple transformation of the A32 encoding.
101
+# More specifically, this file covers instructions where the A32 encoding is
102
+# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
103
+# and the T32 encoding is
104
+# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
105
+# This file works on the A32 encoding only; calling code for T32 has to
106
+# transform the insn into the A32 version first.
107
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/target/arm/neon-shared.decode
112
@@ -XXX,XX +XXX,XX @@
113
+# AArch32 Neon instruction descriptions
114
+#
115
+# Copyright (c) 2020 Linaro, Ltd
116
+#
117
+# This library is free software; you can redistribute it and/or
118
+# modify it under the terms of the GNU Lesser General Public
119
+# License as published by the Free Software Foundation; either
120
+# version 2 of the License, or (at your option) any later version.
121
+#
122
+# This library is distributed in the hope that it will be useful,
123
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
124
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
125
+# Lesser General Public License for more details.
126
+#
127
+# You should have received a copy of the GNU Lesser General Public
128
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
129
+
130
+#
131
+# This file is processed by scripts/decodetree.py
132
+#
133
+
134
+# Encodings for Neon instructions whose encoding is the same for
135
+# both A32 and T32.
136
+
137
+# More specifically, this covers:
138
+# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
139
+# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
140
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
141
new file mode 100644
142
index XXXXXXX..XXXXXXX
143
--- /dev/null
144
+++ b/target/arm/translate-neon.inc.c
145
@@ -XXX,XX +XXX,XX @@
264
@@ -XXX,XX +XXX,XX @@
146
+/*
265
+/*
147
+ * ARM translation: AArch32 Neon instructions
266
+ * QEMU model of the Clock-Reset-LPD (CRL).
148
+ *
267
+ *
149
+ * Copyright (c) 2003 Fabrice Bellard
268
+ * Copyright (c) 2022 Advanced Micro Devices, Inc.
150
+ * Copyright (c) 2005-2007 CodeSourcery
269
+ * SPDX-License-Identifier: GPL-2.0-or-later
151
+ * Copyright (c) 2007 OpenedHand, Ltd.
152
+ * Copyright (c) 2020 Linaro, Ltd.
153
+ *
270
+ *
154
+ * This library is free software; you can redistribute it and/or
271
+ * Written by Edgar E. Iglesias <edgar.iglesias@amd.com>
155
+ * modify it under the terms of the GNU Lesser General Public
156
+ * License as published by the Free Software Foundation; either
157
+ * version 2 of the License, or (at your option) any later version.
158
+ *
159
+ * This library is distributed in the hope that it will be useful,
160
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
161
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
162
+ * Lesser General Public License for more details.
163
+ *
164
+ * You should have received a copy of the GNU Lesser General Public
165
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
166
+ */
272
+ */
167
+
273
+
168
+/*
274
+#include "qemu/osdep.h"
169
+ * This file is intended to be included from translate.c; it uses
275
+#include "qapi/error.h"
170
+ * some macros and definitions provided by that file.
276
+#include "qemu/log.h"
171
+ * It might be possible to convert it to a standalone .c file eventually.
277
+#include "qemu/bitops.h"
172
+ */
278
+#include "migration/vmstate.h"
173
+
279
+#include "hw/qdev-properties.h"
174
+/* Include the generated Neon decoder */
280
+#include "hw/sysbus.h"
175
+#include "decode-neon-dp.inc.c"
281
+#include "hw/irq.h"
176
+#include "decode-neon-ls.inc.c"
282
+#include "hw/register.h"
177
+#include "decode-neon-shared.inc.c"
283
+#include "hw/resettable.h"
178
diff --git a/target/arm/translate.c b/target/arm/translate.c
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
179
index XXXXXXX..XXXXXXX 100644
687
index XXXXXXX..XXXXXXX 100644
180
--- a/target/arm/translate.c
688
--- a/hw/misc/meson.build
181
+++ b/target/arm/translate.c
689
+++ b/hw/misc/meson.build
182
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
690
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
183
691
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
184
#define ARM_CP_RW_BIT (1 << 20)
692
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-crf.c'))
185
693
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-apu-ctrl.c'))
186
-/* Include the VFP decoder */
694
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
187
+/* Include the VFP and Neon decoders */
695
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
188
#include "translate-vfp.inc.c"
696
'xlnx-versal-xramc.c',
189
+#include "translate-neon.inc.c"
697
'xlnx-versal-pmc-iou-slcr.c',
190
191
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
192
{
193
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
194
/* Unconditional instructions. */
195
/* TODO: Perhaps merge these into one decodetree output file. */
196
if (disas_a32_uncond(s, insn) ||
197
- disas_vfp_uncond(s, insn)) {
198
+ disas_vfp_uncond(s, insn) ||
199
+ disas_neon_dp(s, insn) ||
200
+ disas_neon_ls(s, insn) ||
201
+ disas_neon_shared(s, insn)) {
202
return;
203
}
204
/* fall back to legacy decoder */
205
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
206
ARCH(6T2);
207
}
208
209
+ if ((insn & 0xef000000) == 0xef000000) {
210
+ /*
211
+ * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
212
+ * transform into
213
+ * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
214
+ */
215
+ uint32_t a32_insn = (insn & 0xe2ffffff) |
216
+ ((insn & (1 << 28)) >> 4) | (1 << 28);
217
+
218
+ if (disas_neon_dp(s, a32_insn)) {
219
+ return;
220
+ }
221
+ }
222
+
223
+ if ((insn & 0xff100000) == 0xf9000000) {
224
+ /*
225
+ * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
226
+ * transform into
227
+ * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
228
+ */
229
+ uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
230
+
231
+ if (disas_neon_ls(s, a32_insn)) {
232
+ return;
233
+ }
234
+ }
235
+
236
/*
237
* TODO: Perhaps merge these into one decodetree output file.
238
* Note disas_vfp is written for a32 with cond field in the
239
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
240
*/
241
if (disas_t32(s, insn) ||
242
disas_vfp_uncond(s, insn) ||
243
+ disas_neon_shared(s, insn) ||
244
((insn >> 28) == 0xe && disas_vfp(s, insn))) {
245
return;
246
}
247
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
248
index XXXXXXX..XXXXXXX 100644
249
--- a/target/arm/Makefile.objs
250
+++ b/target/arm/Makefile.objs
251
@@ -XXX,XX +XXX,XX @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
252
     $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
253
     "GEN", $(TARGET_DIR)$@)
254
255
+target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
256
+    $(call quiet-command,\
257
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_shared -o $@ $<,\
258
+     "GEN", $(TARGET_DIR)$@)
259
+
260
+target/arm/decode-neon-dp.inc.c: $(SRC_PATH)/target/arm/neon-dp.decode $(DECODETREE)
261
+    $(call quiet-command,\
262
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_dp -o $@ $<,\
263
+     "GEN", $(TARGET_DIR)$@)
264
+
265
+target/arm/decode-neon-ls.inc.c: $(SRC_PATH)/target/arm/neon-ls.decode $(DECODETREE)
266
+    $(call quiet-command,\
267
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_ls -o $@ $<,\
268
+     "GEN", $(TARGET_DIR)$@)
269
+
270
target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE)
271
    $(call quiet-command,\
272
     $(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\
273
@@ -XXX,XX +XXX,XX @@ target/arm/decode-t16.inc.c: $(SRC_PATH)/target/arm/t16.decode $(DECODETREE)
274
     "GEN", $(TARGET_DIR)$@)
275
276
target/arm/translate-sve.o: target/arm/decode-sve.inc.c
277
+target/arm/translate.o: target/arm/decode-neon-shared.inc.c
278
+target/arm/translate.o: target/arm/decode-neon-dp.inc.c
279
+target/arm/translate.o: target/arm/decode-neon-ls.inc.c
280
target/arm/translate.o: target/arm/decode-vfp.inc.c
281
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
282
target/arm/translate.o: target/arm/decode-a32.inc.c
283
--
698
--
284
2.20.1
699
2.25.1
285
286
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
hw/arm: versal: Add support for the RTC.
3
Connect the CRL (Clock Reset LPD) to the Versal SoC.
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com
9
Message-id: 20200427181649.26851-10-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
include/hw/arm/xlnx-versal.h | 8 ++++++++
11
include/hw/arm/xlnx-versal.h | 4 +++
13
hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
14
2 files changed, 29 insertions(+)
13
2 files changed, 56 insertions(+), 2 deletions(-)
15
14
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
17
--- a/include/hw/arm/xlnx-versal.h
19
+++ b/include/hw/arm/xlnx-versal.h
18
+++ b/include/hw/arm/xlnx-versal.h
20
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
21
#include "hw/char/pl011.h"
20
#include "hw/nvram/xlnx-versal-efuse.h"
22
#include "hw/dma/xlnx-zdma.h"
21
#include "hw/ssi/xlnx-versal-ospi.h"
23
#include "hw/net/cadence_gem.h"
22
#include "hw/dma/xlnx_csu_dma.h"
24
+#include "hw/rtc/xlnx-zynqmp-rtc.h"
23
+#include "hw/misc/xlnx-versal-crl.h"
24
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
25
25
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
27
@@ -XXX,XX +XXX,XX @@ struct Versal {
28
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
28
qemu_or_irq irq_orgate;
29
struct {
29
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
30
} xram;
31
} iou;
32
+
31
+
33
+ XlnxZynqMPRTC rtc;
32
+ XlnxVersalCRL crl;
34
} pmc;
33
} lpd;
35
34
36
struct {
35
/* The Platform Management Controller subsystem. */
37
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
36
@@ -XXX,XX +XXX,XX @@ struct Versal {
38
#define VERSAL_GEM1_IRQ_0 58
37
#define VERSAL_TIMER_NS_EL1_IRQ 14
39
#define VERSAL_GEM1_WAKE_IRQ_0 59
38
#define VERSAL_TIMER_NS_EL2_IRQ 10
40
#define VERSAL_ADMA_IRQ_0 60
39
41
+#define VERSAL_RTC_APB_ERR_IRQ 121
40
+#define VERSAL_CRL_IRQ 10
42
#define VERSAL_SD0_IRQ_0 126
41
#define VERSAL_UART0_IRQ_0 18
43
+#define VERSAL_RTC_ALARM_IRQ 142
42
#define VERSAL_UART1_IRQ_0 19
44
+#define VERSAL_RTC_SECONDS_IRQ 143
43
#define VERSAL_USB0_IRQ_0 22
45
46
/* Architecturally reserved IRQs suitable for virtualization. */
47
#define VERSAL_RSVD_IRQ_FIRST 111
48
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
49
#define MM_PMC_SD0_SIZE 0x10000
50
#define MM_PMC_CRP 0xf1260000U
51
#define MM_PMC_CRP_SIZE 0x10000
52
+#define MM_PMC_RTC 0xf12a0000
53
+#define MM_PMC_RTC_SIZE 0x10000
54
#endif
55
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
44
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
56
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/xlnx-versal.c
46
--- a/hw/arm/xlnx-versal.c
58
+++ b/hw/arm/xlnx-versal.c
47
+++ b/hw/arm/xlnx-versal.c
59
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
48
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
60
}
49
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
61
}
50
}
62
51
63
+static void versal_create_rtc(Versal *s, qemu_irq *pic)
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
64
+{
53
+{
65
+ SysBusDevice *sbd;
54
+ SysBusDevice *sbd;
66
+ MemoryRegion *mr;
55
+ int i;
67
+
56
+
68
+ sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc),
57
+ object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
69
+ TYPE_XLNX_ZYNQMP_RTC);
58
+ TYPE_XLNX_VERSAL_CRL);
70
+ sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
59
+ sbd = SYS_BUS_DEVICE(&s->lpd.crl);
71
+ qdev_init_nofail(DEVICE(sbd));
72
+
60
+
73
+ mr = sysbus_mmio_get_region(sbd, 0);
61
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
74
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
62
+ g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
75
+
63
+
76
+ /*
64
+ object_property_set_link(OBJECT(&s->lpd.crl),
77
+ * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
65
+ name, OBJECT(&s->lpd.rpu.cpu[i]),
78
+ * supports them.
66
+ &error_abort);
79
+ */
67
+ }
80
+ sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
68
+
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
71
+
72
+ object_property_set_link(OBJECT(&s->lpd.crl),
73
+ name, OBJECT(&s->lpd.iou.gem[i]),
74
+ &error_abort);
75
+ }
76
+
77
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
78
+ g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
79
+
80
+ object_property_set_link(OBJECT(&s->lpd.crl),
81
+ name, OBJECT(&s->lpd.iou.adma[i]),
82
+ &error_abort);
83
+ }
84
+
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
86
+ g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
87
+
88
+ object_property_set_link(OBJECT(&s->lpd.crl),
89
+ name, OBJECT(&s->lpd.iou.uart[i]),
90
+ &error_abort);
91
+ }
92
+
93
+ object_property_set_link(OBJECT(&s->lpd.crl),
94
+ "usb", OBJECT(&s->lpd.iou.usb),
95
+ &error_abort);
96
+
97
+ sysbus_realize(sbd, &error_fatal);
98
+ memory_region_add_subregion(&s->mr_ps, MM_CRL,
99
+ sysbus_mmio_get_region(sbd, 0));
100
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
81
+}
101
+}
82
+
102
+
83
/* This takes the board allocated linear DDR memory and creates aliases
103
/* This takes the board allocated linear DDR memory and creates aliases
84
* for each split DDR range/aperture on the Versal address map.
104
* for each split DDR range/aperture on the Versal address map.
85
*/
105
*/
106
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
107
108
versal_unimp_area(s, "psm", &s->mr_ps,
109
MM_PSM_START, MM_PSM_END - MM_PSM_START);
110
- versal_unimp_area(s, "crl", &s->mr_ps,
111
- MM_CRL, MM_CRL_SIZE);
112
versal_unimp_area(s, "crf", &s->mr_ps,
113
MM_FPD_CRF, MM_FPD_CRF_SIZE);
114
versal_unimp_area(s, "apu", &s->mr_ps,
86
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
115
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
87
versal_create_gems(s, pic);
116
versal_create_efuse(s, pic);
88
versal_create_admas(s, pic);
117
versal_create_pmc_iou_slcr(s, pic);
89
versal_create_sds(s, pic);
118
versal_create_ospi(s, pic);
90
+ versal_create_rtc(s, pic);
119
+ versal_create_crl(s, pic);
91
versal_map_ddr(s);
120
versal_map_ddr(s);
92
versal_unimp(s);
121
versal_unimp(s);
93
122
94
--
123
--
95
2.20.1
124
2.25.1
96
97
diff view generated by jsdifflib
1
We're going to want at least some of the NeonGen* typedefs
1
The Exynos4210 SoC device currently uses a custom device
2
for the refactored 32-bit Neon decoder, so move them all
2
"exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ
3
to translate.h since it makes more sense to keep them in
3
line. We have a standard TYPE_OR_IRQ device for this now, so use
4
one group.
4
that instead.
5
6
(This is a migration compatibility break, but that is OK for this
7
machine type.)
5
8
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200430181003.21682-23-peter.maydell@linaro.org
11
Message-id: 20220404154658.565020-2-peter.maydell@linaro.org
9
---
12
---
10
target/arm/translate.h | 17 +++++++++++++++++
13
include/hw/arm/exynos4210.h | 1 +
11
target/arm/translate-a64.c | 17 -----------------
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
12
2 files changed, 17 insertions(+), 17 deletions(-)
15
2 files changed, 17 insertions(+), 15 deletions(-)
13
16
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
19
--- a/include/hw/arm/exynos4210.h
17
+++ b/target/arm/translate.h
20
+++ b/include/hw/arm/exynos4210.h
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
21
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
19
typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
22
MemoryRegion bootreg_mem;
20
uint32_t, uint32_t, uint32_t);
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
21
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
22
+/* Function prototype for gen_ functions for calling Neon helpers */
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
23
+typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
26
};
24
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
27
25
+typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
28
#define TYPE_EXYNOS4210_SOC "exynos4210"
26
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
27
+typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
30
index XXXXXXX..XXXXXXX 100644
28
+typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
31
--- a/hw/arm/exynos4210.c
29
+typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
32
+++ b/hw/arm/exynos4210.c
30
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
31
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
34
{
32
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
35
Exynos4210State *s = EXYNOS4210_SOC(socdev);
33
+typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
36
MemoryRegion *system_mem = get_system_memory();
34
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
37
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
35
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
38
SysBusDevice *busdev;
36
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
39
DeviceState *dev, *uart[4], *pl330[3];
37
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
40
int i, n;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
42
43
/* IRQ Gate */
44
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
45
- dev = qdev_new("exynos4210.irq_gate");
46
- qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
47
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
48
- /* Get IRQ Gate input in gate_irq */
49
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
50
- gate_irq[i][n] = qdev_get_gpio_in(dev, n);
51
- }
52
- busdev = SYS_BUS_DEVICE(dev);
53
-
54
- /* Connect IRQ Gate output to CPU's IRQ line */
55
- sysbus_connect_irq(busdev, 0,
56
- qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
57
+ DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
58
+ object_property_set_int(OBJECT(orgate), "num-lines",
59
+ EXYNOS4210_IRQ_GATE_NINPUTS,
60
+ &error_abort);
61
+ qdev_realize(orgate, NULL, &error_abort);
62
+ qdev_connect_gpio_out(orgate, 0,
63
+ qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
64
}
65
66
/* Private memory region and Internal GIC */
67
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
68
sysbus_realize_and_unref(busdev, &error_fatal);
69
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
70
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
71
- sysbus_connect_irq(busdev, n, gate_irq[n][0]);
72
+ sysbus_connect_irq(busdev, n,
73
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
74
}
75
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
76
s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
77
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
78
/* Map Distributer interface */
79
sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
80
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
81
- sysbus_connect_irq(busdev, n, gate_irq[n][1]);
82
+ sysbus_connect_irq(busdev, n,
83
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
84
}
85
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
86
s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
87
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
88
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
89
g_free(name);
90
}
38
+
91
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
92
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
40
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
93
+ g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
41
index XXXXXXX..XXXXXXX 100644
94
+ object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
42
--- a/target/arm/translate-a64.c
95
+ }
43
+++ b/target/arm/translate-a64.c
96
}
44
@@ -XXX,XX +XXX,XX @@ typedef struct AArch64DecodeTable {
97
45
AArch64DecodeFn *disas_fn;
98
static void exynos4210_class_init(ObjectClass *klass, void *data)
46
} AArch64DecodeTable;
47
48
-/* Function prototype for gen_ functions for calling Neon helpers */
49
-typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
50
-typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
51
-typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
52
-typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
53
-typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
54
-typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
55
-typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
56
-typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
57
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
58
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
59
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
60
-typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
61
-typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
62
-typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
63
-typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
64
-
65
/* initialize TCG globals. */
66
void a64_translate_init(void)
67
{
68
--
99
--
69
2.20.1
100
2.25.1
70
71
diff view generated by jsdifflib
1
We define ARMMMUIdx_Stage2 as being an MMU index which uses a QEMU
1
Now we have removed the only use of TYPE_EXYNOS4210_IRQ_GATE we can
2
TLB. However we never actually use the TLB -- all stage 2 lookups
2
delete the device entirely.
3
are done by direct calls to get_phys_addr_lpae() followed by a
4
physical address load via address_space_ld*().
5
6
Remove Stage2 from the list of ARM MMU indexes which correspond to
7
real core MMU indexes, and instead put it in the set of "NOTLB" ARM
8
MMU indexes.
9
10
This allows us to drop NB_MMU_MODES to 11. It also means we can
11
safely add support for the ARMv8.3-TTS2UXN extension, which adds
12
permission bits to the stage 2 descriptors which define execute
13
permission separatel for EL0 and EL1; supporting that while keeping
14
Stage2 in a QEMU TLB would require us to use separate TLBs for
15
"Stage2 for an EL0 access" and "Stage2 for an EL1 access", which is a
16
lot of extra complication given we aren't even using the QEMU TLB.
17
18
In the process of updating the comment on our MMU index use,
19
fix a couple of other minor errors:
20
* NS EL2 EL2&0 was missing from the list in the comment
21
* some text hadn't been updated from when we bumped NB_MMU_MODES
22
above 8
23
3
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20220404154658.565020-3-peter.maydell@linaro.org
27
Message-id: 20200330210400.11724-2-peter.maydell@linaro.org
28
---
7
---
29
target/arm/cpu-param.h | 2 +-
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
30
target/arm/cpu.h | 21 +++++---
9
1 file changed, 107 deletions(-)
31
target/arm/helper.c | 112 ++++-------------------------------------
32
3 files changed, 27 insertions(+), 108 deletions(-)
33
10
34
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
35
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu-param.h
13
--- a/hw/intc/exynos4210_gic.c
37
+++ b/target/arm/cpu-param.h
14
+++ b/hw/intc/exynos4210_gic.c
38
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
39
# define TARGET_PAGE_BITS_MIN 10
16
}
40
#endif
17
41
18
type_init(exynos4210_gic_register_types)
42
-#define NB_MMU_MODES 12
43
+#define NB_MMU_MODES 11
44
45
#endif
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.h
49
+++ b/target/arm/cpu.h
50
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
51
* handling via the TLB. The only way to do a stage 1 translation without
52
* the immediate stage 2 translation is via the ATS or AT system insns,
53
* which can be slow-pathed and always do a page table walk.
54
+ * The only use of stage 2 translations is either as part of an s1+2
55
+ * lookup or when loading the descriptors during a stage 1 page table walk,
56
+ * and in both those cases we don't use the TLB.
57
* 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
58
* translation regimes, because they map reasonably well to each other
59
* and they can't both be active at the same time.
60
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
61
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
62
* NS EL1 EL1&0 stage 1+2 +PAN
63
* NS EL0 EL2&0
64
+ * NS EL2 EL2&0
65
* NS EL2 EL2&0 +PAN
66
* NS EL2 (aka NS PL2)
67
* S EL0 EL1&0 (aka S PL0)
68
* S EL1 EL1&0 (not used if EL3 is 32 bit)
69
* S EL1 EL1&0 +PAN
70
* S EL3 (aka S PL1)
71
- * NS EL1&0 stage 2
72
*
73
- * for a total of 12 different mmu_idx.
74
+ * for a total of 11 different mmu_idx.
75
*
76
* R profile CPUs have an MPU, but can use the same set of MMU indexes
77
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
78
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
79
* are not quite the same -- different CPU types (most notably M profile
80
* vs A/R profile) would like to use MMU indexes with different semantics,
81
* but since we don't ever need to use all of those in a single CPU we
82
- * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
83
+ * can avoid having to set NB_MMU_MODES to "total number of A profile MMU
84
+ * modes + total number of M profile MMU modes". The lower bits of
85
* ARMMMUIdx are the core TLB mmu index, and the higher bits are always
86
* the same for any particular CPU.
87
* Variables of type ARMMUIdx are always full values, and the core
88
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
89
ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
90
ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
91
92
- ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A,
93
-
19
-
94
/*
20
-/* IRQ OR Gate struct.
95
* These are not allocated TLBs and are used only for AT system
21
- *
96
* instructions or for the first stage of an S12 page table walk.
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
97
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
98
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
24
- * gpio inputs.
99
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
25
- */
100
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
26
-
101
+ /*
27
-#define TYPE_EXYNOS4210_IRQ_GATE "exynos4210.irq_gate"
102
+ * Not allocated a TLB: used only for second stage of an S12 page
28
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210IRQGateState, EXYNOS4210_IRQ_GATE)
103
+ * table walk, or for descriptor loads during first stage of an S1
29
-
104
+ * page table walk. Note that if we ever want to have a TLB for this
30
-struct Exynos4210IRQGateState {
105
+ * then various TLB flush insns which currently are no-ops or flush
31
- SysBusDevice parent_obj;
106
+ * only stage 1 MMU indexes will need to change to flush stage 2.
32
-
107
+ */
33
- uint32_t n_in; /* inputs amount */
108
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
34
- uint32_t *level; /* input levels */
109
35
- qemu_irq out; /* output IRQ */
110
/*
36
-};
111
* M-profile.
37
-
112
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
38
-static Property exynos4210_irq_gate_properties[] = {
113
TO_CORE_BIT(SE10_1),
39
- DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
114
TO_CORE_BIT(SE10_1_PAN),
40
- DEFINE_PROP_END_OF_LIST(),
115
TO_CORE_BIT(SE3),
41
-};
116
- TO_CORE_BIT(Stage2),
42
-
117
43
-static const VMStateDescription vmstate_exynos4210_irq_gate = {
118
TO_CORE_BIT(MUser),
44
- .name = "exynos4210.irq_gate",
119
TO_CORE_BIT(MPriv),
45
- .version_id = 2,
120
diff --git a/target/arm/helper.c b/target/arm/helper.c
46
- .minimum_version_id = 2,
121
index XXXXXXX..XXXXXXX 100644
47
- .fields = (VMStateField[]) {
122
--- a/target/arm/helper.c
48
- VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, n_in),
123
+++ b/target/arm/helper.c
49
- VMSTATE_END_OF_LIST()
124
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
50
- }
125
tlb_flush_by_mmuidx(cs,
51
-};
126
ARMMMUIdxBit_E10_1 |
52
-
127
ARMMMUIdxBit_E10_1_PAN |
53
-/* Process a change in IRQ input. */
128
- ARMMMUIdxBit_E10_0 |
54
-static void exynos4210_irq_gate_handler(void *opaque, int irq, int level)
129
- ARMMMUIdxBit_Stage2);
130
+ ARMMMUIdxBit_E10_0);
131
}
132
133
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
134
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
135
tlb_flush_by_mmuidx_all_cpus_synced(cs,
136
ARMMMUIdxBit_E10_1 |
137
ARMMMUIdxBit_E10_1_PAN |
138
- ARMMMUIdxBit_E10_0 |
139
- ARMMMUIdxBit_Stage2);
140
+ ARMMMUIdxBit_E10_0);
141
}
142
143
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
144
- uint64_t value)
145
-{
55
-{
146
- /* Invalidate by IPA. This has to invalidate any structures that
56
- Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)opaque;
147
- * contain only stage 2 translation information, but does not need
57
- uint32_t i;
148
- * to apply to structures that contain combined stage 1 and stage 2
149
- * translation information.
150
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
151
- */
152
- CPUState *cs = env_cpu(env);
153
- uint64_t pageaddr;
154
-
58
-
155
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
59
- assert(irq < s->n_in);
156
- return;
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
- }
157
- }
68
- }
158
-
69
-
159
- pageaddr = sextract64(value << 12, 0, 40);
70
- qemu_irq_lower(s->out);
160
-
161
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
162
-}
71
-}
163
-
72
-
164
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
73
-static void exynos4210_irq_gate_reset(DeviceState *d)
165
- uint64_t value)
166
-{
74
-{
167
- CPUState *cs = env_cpu(env);
75
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(d);
168
- uint64_t pageaddr;
169
-
76
-
170
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
77
- memset(s->level, 0, s->n_in * sizeof(*s->level));
171
- return;
172
- }
173
-
174
- pageaddr = sextract64(value << 12, 0, 40);
175
-
176
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
177
- ARMMMUIdxBit_Stage2);
178
-}
179
180
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
uint64_t value)
182
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
tlb_flush_by_mmuidx(cs,
184
ARMMMUIdxBit_E10_1 |
185
ARMMMUIdxBit_E10_1_PAN |
186
- ARMMMUIdxBit_E10_0 |
187
- ARMMMUIdxBit_Stage2);
188
+ ARMMMUIdxBit_E10_0);
189
raw_write(env, ri, value);
190
}
191
}
192
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
193
return ARMMMUIdxBit_SE10_1 |
194
ARMMMUIdxBit_SE10_1_PAN |
195
ARMMMUIdxBit_SE10_0;
196
- } else if (arm_feature(env, ARM_FEATURE_EL2)) {
197
- return ARMMMUIdxBit_E10_1 |
198
- ARMMMUIdxBit_E10_1_PAN |
199
- ARMMMUIdxBit_E10_0 |
200
- ARMMMUIdxBit_Stage2;
201
} else {
202
return ARMMMUIdxBit_E10_1 |
203
ARMMMUIdxBit_E10_1_PAN |
204
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
205
ARMMMUIdxBit_SE3);
206
}
207
208
-static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
209
- uint64_t value)
210
-{
211
- /* Invalidate by IPA. This has to invalidate any structures that
212
- * contain only stage 2 translation information, but does not need
213
- * to apply to structures that contain combined stage 1 and stage 2
214
- * translation information.
215
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
216
- */
217
- ARMCPU *cpu = env_archcpu(env);
218
- CPUState *cs = CPU(cpu);
219
- uint64_t pageaddr;
220
-
221
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
222
- return;
223
- }
224
-
225
- pageaddr = sextract64(value << 12, 0, 48);
226
-
227
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
228
-}
78
-}
229
-
79
-
230
-static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
80
-/*
231
- uint64_t value)
81
- * IRQ Gate initialization.
82
- */
83
-static void exynos4210_irq_gate_init(Object *obj)
232
-{
84
-{
233
- CPUState *cs = env_cpu(env);
85
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(obj);
234
- uint64_t pageaddr;
86
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
235
-
87
-
236
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
88
- sysbus_init_irq(sbd, &s->out);
237
- return;
238
- }
239
-
240
- pageaddr = sextract64(value << 12, 0, 48);
241
-
242
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
243
- ARMMMUIdxBit_Stage2);
244
-}
89
-}
245
-
90
-
246
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
91
-static void exynos4210_irq_gate_realize(DeviceState *dev, Error **errp)
247
bool isread)
92
-{
248
{
93
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(dev);
249
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
94
-
250
.writefn = tlbi_aa64_vae1_write },
95
- /* Allocate general purpose input signals and connect a handler to each of
251
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
96
- * them */
252
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
97
- qdev_init_gpio_in(dev, exynos4210_irq_gate_handler, s->n_in);
253
- .access = PL2_W, .type = ARM_CP_NO_RAW,
98
-
254
- .writefn = tlbi_aa64_ipas2e1is_write },
99
- s->level = g_malloc0(s->n_in * sizeof(*s->level));
255
+ .access = PL2_W, .type = ARM_CP_NOP },
100
-}
256
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
101
-
257
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
102
-static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
258
- .access = PL2_W, .type = ARM_CP_NO_RAW,
103
-{
259
- .writefn = tlbi_aa64_ipas2e1is_write },
104
- DeviceClass *dc = DEVICE_CLASS(klass);
260
+ .access = PL2_W, .type = ARM_CP_NOP },
105
-
261
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
106
- dc->reset = exynos4210_irq_gate_reset;
262
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
107
- dc->vmsd = &vmstate_exynos4210_irq_gate;
263
.access = PL2_W, .type = ARM_CP_NO_RAW,
108
- device_class_set_props(dc, exynos4210_irq_gate_properties);
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
109
- dc->realize = exynos4210_irq_gate_realize;
265
.writefn = tlbi_aa64_alle1is_write },
110
-}
266
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
111
-
267
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
112
-static const TypeInfo exynos4210_irq_gate_info = {
268
- .access = PL2_W, .type = ARM_CP_NO_RAW,
113
- .name = TYPE_EXYNOS4210_IRQ_GATE,
269
- .writefn = tlbi_aa64_ipas2e1_write },
114
- .parent = TYPE_SYS_BUS_DEVICE,
270
+ .access = PL2_W, .type = ARM_CP_NOP },
115
- .instance_size = sizeof(Exynos4210IRQGateState),
271
{ .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
116
- .instance_init = exynos4210_irq_gate_init,
272
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
117
- .class_init = exynos4210_irq_gate_class_init,
273
- .access = PL2_W, .type = ARM_CP_NO_RAW,
118
-};
274
- .writefn = tlbi_aa64_ipas2e1_write },
119
-
275
+ .access = PL2_W, .type = ARM_CP_NOP },
120
-static void exynos4210_irq_gate_register_types(void)
276
{ .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
121
-{
277
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
122
- type_register_static(&exynos4210_irq_gate_info);
278
.access = PL2_W, .type = ARM_CP_NO_RAW,
123
-}
279
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
124
-
280
.writefn = tlbimva_hyp_is_write },
125
-type_init(exynos4210_irq_gate_register_types)
281
{ .name = "TLBIIPAS2",
282
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
283
- .type = ARM_CP_NO_RAW, .access = PL2_W,
284
- .writefn = tlbiipas2_write },
285
+ .type = ARM_CP_NOP, .access = PL2_W },
286
{ .name = "TLBIIPAS2IS",
287
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
288
- .type = ARM_CP_NO_RAW, .access = PL2_W,
289
- .writefn = tlbiipas2_is_write },
290
+ .type = ARM_CP_NOP, .access = PL2_W },
291
{ .name = "TLBIIPAS2L",
292
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
293
- .type = ARM_CP_NO_RAW, .access = PL2_W,
294
- .writefn = tlbiipas2_write },
295
+ .type = ARM_CP_NOP, .access = PL2_W },
296
{ .name = "TLBIIPAS2LIS",
297
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
298
- .type = ARM_CP_NO_RAW, .access = PL2_W,
299
- .writefn = tlbiipas2_is_write },
300
+ .type = ARM_CP_NOP, .access = PL2_W },
301
/* 32 bit cache operations */
302
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
303
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
304
--
126
--
305
2.20.1
127
2.25.1
306
307
diff view generated by jsdifflib
1
Convert the Neon "load single structure to all lanes" insns to
1
The exynos4210 SoC mostly creates its child devices as if it were
2
decodetree.
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.
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-13-peter.maydell@linaro.org
9
Message-id: 20220404154658.565020-4-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-ls.decode | 5 +++
11
include/hw/arm/exynos4210.h | 2 ++
9
target/arm/translate-neon.inc.c | 73 +++++++++++++++++++++++++++++++++
12
hw/arm/exynos4210.c | 11 ++++++-----
10
target/arm/translate.c | 55 +------------------------
13
2 files changed, 8 insertions(+), 5 deletions(-)
11
3 files changed, 80 insertions(+), 53 deletions(-)
12
14
13
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-ls.decode
17
--- a/include/hw/arm/exynos4210.h
16
+++ b/target/arm/neon-ls.decode
18
+++ b/include/hw/arm/exynos4210.h
17
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
18
20
19
VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
21
#include "hw/or-irq.h"
20
vd=%vd_dp
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)
40
}
41
42
/* Private memory region and Internal GIC */
43
- dev = qdev_new(TYPE_A9MPCORE_PRIV);
44
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
45
- busdev = SYS_BUS_DEVICE(dev);
46
- sysbus_realize_and_unref(busdev, &error_fatal);
47
+ qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
48
+ busdev = SYS_BUS_DEVICE(&s->a9mpcore);
49
+ sysbus_realize(busdev, &error_fatal);
50
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
51
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
52
sysbus_connect_irq(busdev, n,
53
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
54
}
55
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
56
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
57
+ s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
58
}
59
60
/* Cache controller */
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
62
g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
63
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
64
}
21
+
65
+
22
+# Neon load single element to all lanes
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
23
+
24
+VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
25
+ vd=%vd_dp
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate-neon.inc.c
29
+++ b/target/arm/translate-neon.inc.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
31
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
32
return true;
33
}
67
}
34
+
68
35
+static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
36
+{
37
+ /* Neon load single structure to all lanes */
38
+ int reg, stride, vec_size;
39
+ int vd = a->vd;
40
+ int size = a->size;
41
+ int nregs = a->n + 1;
42
+ TCGv_i32 addr, tmp;
43
+
44
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
45
+ return false;
46
+ }
47
+
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
49
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if (size == 3) {
54
+ if (nregs != 4 || a->a == 0) {
55
+ return false;
56
+ }
57
+ /* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
58
+ size = 2;
59
+ }
60
+ if (nregs == 1 && a->a == 1 && size == 0) {
61
+ return false;
62
+ }
63
+ if (nregs == 3 && a->a == 1) {
64
+ return false;
65
+ }
66
+
67
+ if (!vfp_access_check(s)) {
68
+ return true;
69
+ }
70
+
71
+ /*
72
+ * VLD1 to all lanes: T bit indicates how many Dregs to write.
73
+ * VLD2/3/4 to all lanes: T bit indicates register stride.
74
+ */
75
+ stride = a->t ? 2 : 1;
76
+ vec_size = nregs == 1 ? stride * 8 : 8;
77
+
78
+ tmp = tcg_temp_new_i32();
79
+ addr = tcg_temp_new_i32();
80
+ load_reg_var(s, addr, a->rn);
81
+ for (reg = 0; reg < nregs; reg++) {
82
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
83
+ s->be_data | size);
84
+ if ((vd & 1) && vec_size == 16) {
85
+ /*
86
+ * We cannot write 16 bytes at once because the
87
+ * destination is unaligned.
88
+ */
89
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
90
+ 8, 8, tmp);
91
+ tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
92
+ neon_reg_offset(vd, 0), 8, 8);
93
+ } else {
94
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
95
+ vec_size, vec_size, tmp);
96
+ }
97
+ tcg_gen_addi_i32(addr, addr, 1 << size);
98
+ vd += stride;
99
+ }
100
+ tcg_temp_free_i32(tmp);
101
+ tcg_temp_free_i32(addr);
102
+
103
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
104
+
105
+ return true;
106
+}
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 int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
112
int size;
113
int reg;
114
int load;
115
- int vec_size;
116
TCGv_i32 addr;
117
TCGv_i32 tmp;
118
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
120
} else {
121
size = (insn >> 10) & 3;
122
if (size == 3) {
123
- /* Load single element to all lanes. */
124
- int a = (insn >> 4) & 1;
125
- if (!load) {
126
- return 1;
127
- }
128
- size = (insn >> 6) & 3;
129
- nregs = ((insn >> 8) & 3) + 1;
130
-
131
- if (size == 3) {
132
- if (nregs != 4 || a == 0) {
133
- return 1;
134
- }
135
- /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
136
- size = 2;
137
- }
138
- if (nregs == 1 && a == 1 && size == 0) {
139
- return 1;
140
- }
141
- if (nregs == 3 && a == 1) {
142
- return 1;
143
- }
144
- addr = tcg_temp_new_i32();
145
- load_reg_var(s, addr, rn);
146
-
147
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
148
- * VLD2/3/4 to all lanes: bit 5 indicates register stride.
149
- */
150
- stride = (insn & (1 << 5)) ? 2 : 1;
151
- vec_size = nregs == 1 ? stride * 8 : 8;
152
-
153
- tmp = tcg_temp_new_i32();
154
- for (reg = 0; reg < nregs; reg++) {
155
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
156
- s->be_data | size);
157
- if ((rd & 1) && vec_size == 16) {
158
- /* We cannot write 16 bytes at once because the
159
- * destination is unaligned.
160
- */
161
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
162
- 8, 8, tmp);
163
- tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
164
- neon_reg_offset(rd, 0), 8, 8);
165
- } else {
166
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
167
- vec_size, vec_size, tmp);
168
- }
169
- tcg_gen_addi_i32(addr, addr, 1 << size);
170
- rd += stride;
171
- }
172
- tcg_temp_free_i32(tmp);
173
- tcg_temp_free_i32(addr);
174
- stride = (1 << size) * nregs;
175
+ /* Load single element to all lanes -- handled by decodetree */
176
+ return 1;
177
} else {
178
/* Single element. */
179
int idx = (insn >> 4) & 0xf;
180
--
70
--
181
2.20.1
71
2.25.1
182
183
diff view generated by jsdifflib
1
Convert the Neon VQADD/VQSUB insns in the 3-reg-same grouping
1
The only time we use the int_gic_irq[] array in the Exynos4210Irq
2
to decodetree.
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.
3
8
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-19-peter.maydell@linaro.org
11
Message-id: 20220404154658.565020-5-peter.maydell@linaro.org
7
---
12
---
8
target/arm/neon-dp.decode | 6 ++++++
13
include/hw/arm/exynos4210.h | 1 -
9
target/arm/translate-neon.inc.c | 15 +++++++++++++++
14
hw/arm/exynos4210.c | 6 ++----
10
target/arm/translate.c | 14 ++------------
15
2 files changed, 2 insertions(+), 5 deletions(-)
11
3 files changed, 23 insertions(+), 12 deletions(-)
12
16
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
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/neon-dp.decode
19
--- a/include/hw/arm/exynos4210.h
16
+++ b/target/arm/neon-dp.decode
20
+++ b/include/hw/arm/exynos4210.h
17
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
22
typedef struct Exynos4210Irq {
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
20
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
21
+VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
25
- qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
22
+VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
26
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
23
+
27
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
28
} Exynos4210Irq;
25
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
26
27
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
28
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
29
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
30
31
+VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
32
+VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
33
+
34
VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
35
VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
36
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
31
--- a/hw/arm/exynos4210.c
40
+++ b/target/arm/translate-neon.inc.c
32
+++ b/hw/arm/exynos4210.c
41
@@ -XXX,XX +XXX,XX @@ static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
42
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
34
sysbus_connect_irq(busdev, n,
43
}
35
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
44
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
36
}
45
+
37
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
46
+#define DO_3SAME_GVEC4(INSN, OPARRAY) \
38
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
47
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
39
- }
48
+ uint32_t rn_ofs, uint32_t rm_ofs, \
40
49
+ uint32_t oprsz, uint32_t maxsz) \
41
/* Cache controller */
50
+ { \
42
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
51
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
43
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
52
+ rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
44
busdev = SYS_BUS_DEVICE(dev);
53
+ } \
45
sysbus_realize_and_unref(busdev, &error_fatal);
54
+ DO_3SAME(INSN, gen_##INSN##_3s)
46
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
55
+
47
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
56
+DO_3SAME_GVEC4(VQADD_S, sqadd_op)
48
+ sysbus_connect_irq(busdev, n,
57
+DO_3SAME_GVEC4(VQADD_U, uqadd_op)
49
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
58
+DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
50
}
59
+DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
51
exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
52
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate.c
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
65
}
66
return 1;
67
68
- case NEON_3R_VQADD:
69
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
70
- rn_ofs, rm_ofs, vec_size, vec_size,
71
- (u ? uqadd_op : sqadd_op) + size);
72
- return 0;
73
-
74
- case NEON_3R_VQSUB:
75
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
76
- rn_ofs, rm_ofs, vec_size, vec_size,
77
- (u ? uqsub_op : sqsub_op) + size);
78
- return 0;
79
-
80
case NEON_3R_VMUL: /* VMUL */
81
if (u) {
82
/* Polynomial case allows only P8. */
83
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
84
case NEON_3R_VTST_VCEQ:
85
case NEON_3R_VCGT:
86
case NEON_3R_VCGE:
87
+ case NEON_3R_VQADD:
88
+ case NEON_3R_VQSUB:
89
/* Already handled by decodetree */
90
return 1;
91
}
92
--
53
--
93
2.20.1
54
2.25.1
94
95
diff view generated by jsdifflib
1
Convert the VFM[AS]L (scalar) insns in the 2reg-scalar-ext group
1
The exynos4210 code currently has two very similar arrays of IRQs:
2
to decodetree. These are the last ones in the group so we can remove
3
all the legacy decode for the group.
4
2
5
Note that in disas_thumb2_insn() the parts of this encoding space
3
* board_irqs is a field of the Exynos4210Irq struct which is filled
6
where the decodetree decoder returns false will correctly be directed
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
5
for each IRQ the board/SoC can assert
8
into disas_coproc_insn() by mistake.
6
* irq_table is a set of qemu_irqs pointed to from the
7
Exynos4210State struct. It's allocated in exynos4210_init_irq,
8
and the only behaviour these irqs have is that they pass on the
9
level to the equivalent board_irqs[] irq
10
11
The extra indirection through irq_table is unnecessary, so coalesce
12
these into a single irq_table[] array as a direct field in
13
Exynos4210State which exynos4210_init_board_irqs() fills in.
9
14
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-11-peter.maydell@linaro.org
17
Message-id: 20220404154658.565020-6-peter.maydell@linaro.org
13
---
18
---
14
target/arm/neon-shared.decode | 7 +++
19
include/hw/arm/exynos4210.h | 8 ++------
15
target/arm/translate-neon.inc.c | 32 ++++++++++
20
hw/arm/exynos4210.c | 6 +-----
16
target/arm/translate.c | 107 +-------------------------------
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
17
3 files changed, 40 insertions(+), 106 deletions(-)
22
3 files changed, 11 insertions(+), 35 deletions(-)
18
23
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
26
--- a/include/hw/arm/exynos4210.h
22
+++ b/target/arm/neon-shared.decode
27
+++ b/include/hw/arm/exynos4210.h
23
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
24
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
25
VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
27
+
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
28
+%vfml_scalar_q0_rm 0:3 5:1
33
} Exynos4210Irq;
29
+%vfml_scalar_q1_index 5:1 3:1
34
30
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
35
struct Exynos4210State {
31
+ rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
36
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
32
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
37
/*< public >*/
33
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
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-neon.inc.c
61
--- a/hw/arm/exynos4210.c
37
+++ b/target/arm/translate-neon.inc.c
62
+++ b/hw/arm/exynos4210.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
63
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
39
tcg_temp_free_ptr(fpst);
64
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
40
return true;
65
}
41
}
66
42
+
67
- /*** IRQs ***/
43
+static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
68
-
44
+{
69
- s->irq_table = exynos4210_init_irq(&s->irqs);
45
+ int opr_sz;
70
-
46
+
71
/* IRQ Gate */
47
+ if (!dc_isar_feature(aa32_fhm, s)) {
72
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
48
+ return false;
73
DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
49
+ }
74
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
50
+
75
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
76
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
77
/* Initialize board IRQs. */
53
+ ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) {
78
- exynos4210_init_board_irqs(&s->irqs);
54
+ return false;
79
+ exynos4210_init_board_irqs(s);
55
+ }
80
56
+
81
/*** Memory ***/
57
+ if (a->vd & a->q) {
82
58
+ return false;
83
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ opr_sz = (1 + a->q) * 8;
66
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
67
+ vfp_reg_offset(a->q, a->vn),
68
+ vfp_reg_offset(a->q, a->rm),
69
+ cpu_env, opr_sz, opr_sz,
70
+ (a->index << 2) | a->s, /* is_2 == 0 */
71
+ gen_helper_gvec_fmlal_idx_a32);
72
+ return true;
73
+}
74
diff --git a/target/arm/translate.c b/target/arm/translate.c
75
index XXXXXXX..XXXXXXX 100644
84
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/translate.c
85
--- a/hw/intc/exynos4210_gic.c
77
+++ b/target/arm/translate.c
86
+++ b/hw/intc/exynos4210_gic.c
78
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
87
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
79
}
88
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
80
89
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
81
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
90
82
-#define VFP_SREG(insn, bigbit, smallbit) \
91
-static void exynos4210_irq_handler(void *opaque, int irq, int level)
83
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
92
-{
84
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
93
- Exynos4210Irq *s = (Exynos4210Irq *)opaque;
85
if (dc_isar_feature(aa32_simd_r32, s)) { \
86
reg = (((insn) >> (bigbit)) & 0x0f) \
87
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
88
reg = ((insn) >> (bigbit)) & 0x0f; \
89
}} while (0)
90
91
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
92
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
93
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
94
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
95
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
96
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
97
98
static void gen_neon_dup_low16(TCGv_i32 var)
99
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
100
return 0;
101
}
102
103
-/* Advanced SIMD two registers and a scalar extension.
104
- * 31 24 23 22 20 16 12 11 10 9 8 3 0
105
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
106
- * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
107
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
108
- *
109
- */
110
-
94
-
111
-static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
95
- /* Bypass */
112
-{
96
- qemu_set_irq(s->board_irqs[irq], level);
113
- gen_helper_gvec_3 *fn_gvec = NULL;
114
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
115
- int rd, rn, rm, opr_sz, data;
116
- int off_rn, off_rm;
117
- bool is_long = false, q = extract32(insn, 6, 1);
118
- bool ptr_is_env = false;
119
-
120
- if ((insn & 0xffa00f10) == 0xfe000810) {
121
- /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
122
- int is_s = extract32(insn, 20, 1);
123
- int vm20 = extract32(insn, 0, 3);
124
- int vm3 = extract32(insn, 3, 1);
125
- int m = extract32(insn, 5, 1);
126
- int index;
127
-
128
- if (!dc_isar_feature(aa32_fhm, s)) {
129
- return 1;
130
- }
131
- if (q) {
132
- rm = vm20;
133
- index = m * 2 + vm3;
134
- } else {
135
- rm = vm20 * 2 + m;
136
- index = vm3;
137
- }
138
- is_long = true;
139
- data = (index << 2) | is_s; /* is_2 == 0 */
140
- fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
141
- ptr_is_env = true;
142
- } else {
143
- return 1;
144
- }
145
-
146
- VFP_DREG_D(rd, insn);
147
- if (rd & q) {
148
- return 1;
149
- }
150
- if (q || !is_long) {
151
- VFP_DREG_N(rn, insn);
152
- if (rn & q & !is_long) {
153
- return 1;
154
- }
155
- off_rn = vfp_reg_offset(1, rn);
156
- off_rm = vfp_reg_offset(1, rm);
157
- } else {
158
- rn = VFP_SREG_N(insn);
159
- off_rn = vfp_reg_offset(0, rn);
160
- off_rm = vfp_reg_offset(0, rm);
161
- }
162
- if (s->fp_excp_el) {
163
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
164
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
165
- return 0;
166
- }
167
- if (!s->vfp_enabled) {
168
- return 1;
169
- }
170
-
171
- opr_sz = (1 + q) * 8;
172
- if (fn_gvec_ptr) {
173
- TCGv_ptr ptr;
174
- if (ptr_is_env) {
175
- ptr = cpu_env;
176
- } else {
177
- ptr = get_fpstatus_ptr(1);
178
- }
179
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
180
- opr_sz, opr_sz, data, fn_gvec_ptr);
181
- if (!ptr_is_env) {
182
- tcg_temp_free_ptr(ptr);
183
- }
184
- } else {
185
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
186
- opr_sz, opr_sz, data, fn_gvec);
187
- }
188
- return 0;
189
-}
97
-}
190
-
98
-
191
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
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)
192
{
114
{
193
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
115
uint32_t grp, bit, irq_id, n;
194
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
116
+ Exynos4210Irq *is = &s->irqs;
195
}
117
196
}
118
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
197
}
119
irq_id = 0;
198
- } else if ((insn & 0x0f000a00) == 0x0e000800
120
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
199
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
121
irq_id = EXT_GIC_ID_MCT_G1;
200
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
201
- goto illegal_op;
202
- }
203
- return;
204
}
122
}
205
goto illegal_op;
123
if (irq_id) {
124
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
125
- s->ext_gic_irq[irq_id-32]);
126
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
127
+ is->ext_gic_irq[irq_id - 32]);
128
} else {
129
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
130
- s->ext_combiner_irq[n]);
131
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
132
+ is->ext_combiner_irq[n]);
133
}
206
}
134
}
207
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
135
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
208
}
136
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
209
break;
137
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
138
139
if (irq_id) {
140
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
141
- s->ext_gic_irq[irq_id-32]);
142
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
143
+ is->ext_gic_irq[irq_id - 32]);
210
}
144
}
211
- if ((insn & 0xff000a00) == 0xfe000800
145
}
212
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
146
}
213
- /* The Thumb2 and ARM encodings are identical. */
214
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
215
- goto illegal_op;
216
- }
217
- } else if (((insn >> 24) & 3) == 3) {
218
+ if (((insn >> 24) & 3) == 3) {
219
/* Translate into the equivalent ARM encoding. */
220
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
221
if (disas_neon_data_insn(s, insn)) {
222
--
147
--
223
2.20.1
148
2.25.1
224
225
diff view generated by jsdifflib
1
Convert the Neon comparison ops in the 3-reg-same grouping
1
Fix a missing set of spaces around '-' in the definition of
2
to decodetree.
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.
3
5
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-18-peter.maydell@linaro.org
8
Message-id: 20220404154658.565020-7-peter.maydell@linaro.org
7
---
9
---
8
target/arm/neon-dp.decode | 8 ++++++++
10
hw/intc/exynos4210_gic.c | 2 +-
9
target/arm/translate-neon.inc.c | 22 ++++++++++++++++++++++
11
1 file changed, 1 insertion(+), 1 deletion(-)
10
target/arm/translate.c | 23 +++--------------------
11
3 files changed, 33 insertions(+), 20 deletions(-)
12
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
15
--- a/hw/intc/exynos4210_gic.c
16
+++ b/target/arm/neon-dp.decode
16
+++ b/hw/intc/exynos4210_gic.c
17
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
18
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
18
*/
19
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
19
20
20
static const uint32_t
21
+VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
21
-combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
22
+VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
22
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
23
+VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
23
/* int combiner groups 16-19 */
24
+VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
24
{ }, { }, { }, { },
25
+
25
/* int combiner group 20 */
26
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
27
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
28
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
29
@@ -XXX,XX +XXX,XX @@ VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
30
31
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
32
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
33
+
34
+VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
35
+VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
39
+++ b/target/arm/translate-neon.inc.c
40
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
41
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
42
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
43
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
44
+
45
+#define DO_3SAME_CMP(INSN, COND) \
46
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
47
+ uint32_t rn_ofs, uint32_t rm_ofs, \
48
+ uint32_t oprsz, uint32_t maxsz) \
49
+ { \
50
+ tcg_gen_gvec_cmp(COND, vece, rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz); \
51
+ } \
52
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
53
+
54
+DO_3SAME_CMP(VCGT_S, TCG_COND_GT)
55
+DO_3SAME_CMP(VCGT_U, TCG_COND_GTU)
56
+DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
57
+DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
58
+DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
59
+
60
+static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
61
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
62
+{
63
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
64
+}
65
+DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
u ? &mls_op[size] : &mla_op[size]);
72
return 0;
73
74
- case NEON_3R_VTST_VCEQ:
75
- if (u) { /* VCEQ */
76
- tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
77
- vec_size, vec_size);
78
- } else { /* VTST */
79
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
80
- vec_size, vec_size, &cmtst_op[size]);
81
- }
82
- return 0;
83
-
84
- case NEON_3R_VCGT:
85
- tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
86
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
87
- return 0;
88
-
89
- case NEON_3R_VCGE:
90
- tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
91
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
92
- return 0;
93
-
94
case NEON_3R_VSHL:
95
/* Note the operation is vshl vd,vm,vn */
96
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
case NEON_3R_LOGIC:
99
case NEON_3R_VMAX:
100
case NEON_3R_VMIN:
101
+ case NEON_3R_VTST_VCEQ:
102
+ case NEON_3R_VCGT:
103
+ case NEON_3R_VCGE:
104
/* Already handled by decodetree */
105
return 1;
106
}
107
--
26
--
108
2.20.1
27
2.25.1
109
110
diff view generated by jsdifflib
1
Convert the Neon "load/store single structure to one lane" insns to
1
The function exynos4210_init_board_irqs() currently lives in
2
decodetree.
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
As this is the last set of insns in the neon load/store group,
4
interrupts between the SoC's GIC and combiner components. This means
5
we can remove the whole disas_neon_ls_insn() function.
5
it fits better in exynos4210.c, which is the SoC-level code. Move it
6
there. Similarly, exynos4210_git_irq() is used almost only in the
7
SoC-level code, so move it too.
6
8
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200430181003.21682-14-peter.maydell@linaro.org
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
10
---
12
---
11
target/arm/neon-ls.decode | 11 +++
13
include/hw/arm/exynos4210.h | 4 -
12
target/arm/translate-neon.inc.c | 89 +++++++++++++++++++
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
13
target/arm/translate.c | 147 --------------------------------
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
14
3 files changed, 100 insertions(+), 147 deletions(-)
16
3 files changed, 202 insertions(+), 208 deletions(-)
15
17
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/neon-ls.decode
20
--- a/include/hw/arm/exynos4210.h
19
+++ b/target/arm/neon-ls.decode
21
+++ b/include/hw/arm/exynos4210.h
20
@@ -XXX,XX +XXX,XX @@ VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
21
23
void exynos4210_write_secondary(ARMCPU *cpu,
22
VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
24
const struct arm_boot_info *info);
23
vd=%vd_dp
25
24
+
26
-/* Initialize board IRQs.
25
+# Neon load/store single structure to one lane
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
26
+%imm1_5_p1 5:1 !function=plus1
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
27
+%imm1_6_p1 6:1 !function=plus1
29
-
28
+
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
29
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
31
* To identify IRQ source use internal combiner group and bit number
30
+ vd=%vd_dp size=0 stride=1
32
* grp - group number
31
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
33
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
32
+ vd=%vd_dp size=1 stride=%imm1_5_p1
33
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
34
+ vd=%vd_dp size=2 stride=%imm1_6_p1
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
35
--- a/hw/arm/exynos4210.c
38
+++ b/target/arm/translate-neon.inc.c
36
+++ b/hw/arm/exynos4210.c
39
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
40
* It might be possible to convert it to a standalone .c file eventually.
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
41
*/
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
42
40
43
+static inline int plus1(DisasContext *s, int x)
41
+enum ExtGicId {
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
43
+ EXT_GIC_ID_PDMA0,
44
+ EXT_GIC_ID_PDMA1,
45
+ EXT_GIC_ID_TIMER0,
46
+ EXT_GIC_ID_TIMER1,
47
+ EXT_GIC_ID_TIMER2,
48
+ EXT_GIC_ID_TIMER3,
49
+ EXT_GIC_ID_TIMER4,
50
+ EXT_GIC_ID_MCT_L0,
51
+ EXT_GIC_ID_WDT,
52
+ EXT_GIC_ID_RTC_ALARM,
53
+ EXT_GIC_ID_RTC_TIC,
54
+ EXT_GIC_ID_GPIO_XB,
55
+ EXT_GIC_ID_GPIO_XA,
56
+ EXT_GIC_ID_MCT_L1,
57
+ EXT_GIC_ID_IEM_APC,
58
+ EXT_GIC_ID_IEM_IEC,
59
+ EXT_GIC_ID_NFC,
60
+ EXT_GIC_ID_UART0,
61
+ EXT_GIC_ID_UART1,
62
+ EXT_GIC_ID_UART2,
63
+ EXT_GIC_ID_UART3,
64
+ EXT_GIC_ID_UART4,
65
+ EXT_GIC_ID_MCT_G0,
66
+ EXT_GIC_ID_I2C0,
67
+ EXT_GIC_ID_I2C1,
68
+ EXT_GIC_ID_I2C2,
69
+ EXT_GIC_ID_I2C3,
70
+ EXT_GIC_ID_I2C4,
71
+ EXT_GIC_ID_I2C5,
72
+ EXT_GIC_ID_I2C6,
73
+ EXT_GIC_ID_I2C7,
74
+ EXT_GIC_ID_SPI0,
75
+ EXT_GIC_ID_SPI1,
76
+ EXT_GIC_ID_SPI2,
77
+ EXT_GIC_ID_MCT_G1,
78
+ EXT_GIC_ID_USB_HOST,
79
+ EXT_GIC_ID_USB_DEVICE,
80
+ EXT_GIC_ID_MODEMIF,
81
+ EXT_GIC_ID_HSMMC0,
82
+ EXT_GIC_ID_HSMMC1,
83
+ EXT_GIC_ID_HSMMC2,
84
+ EXT_GIC_ID_HSMMC3,
85
+ EXT_GIC_ID_SDMMC,
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
90
+ EXT_GIC_ID_ONENAND_AUDI,
91
+ EXT_GIC_ID_ROTATOR,
92
+ EXT_GIC_ID_FIMC0,
93
+ EXT_GIC_ID_FIMC1,
94
+ EXT_GIC_ID_FIMC2,
95
+ EXT_GIC_ID_FIMC3,
96
+ EXT_GIC_ID_JPEG,
97
+ EXT_GIC_ID_2D,
98
+ EXT_GIC_ID_PCIe,
99
+ EXT_GIC_ID_MIXER,
100
+ EXT_GIC_ID_HDMI,
101
+ EXT_GIC_ID_HDMI_I2C,
102
+ EXT_GIC_ID_MFC,
103
+ EXT_GIC_ID_TVENC,
104
+};
105
+
106
+enum ExtInt {
107
+ EXT_GIC_ID_EXTINT0 = 48,
108
+ EXT_GIC_ID_EXTINT1,
109
+ EXT_GIC_ID_EXTINT2,
110
+ EXT_GIC_ID_EXTINT3,
111
+ EXT_GIC_ID_EXTINT4,
112
+ EXT_GIC_ID_EXTINT5,
113
+ EXT_GIC_ID_EXTINT6,
114
+ EXT_GIC_ID_EXTINT7,
115
+ EXT_GIC_ID_EXTINT8,
116
+ EXT_GIC_ID_EXTINT9,
117
+ EXT_GIC_ID_EXTINT10,
118
+ EXT_GIC_ID_EXTINT11,
119
+ EXT_GIC_ID_EXTINT12,
120
+ EXT_GIC_ID_EXTINT13,
121
+ EXT_GIC_ID_EXTINT14,
122
+ EXT_GIC_ID_EXTINT15
123
+};
124
+
125
+/*
126
+ * External GIC sources which are not from External Interrupt Combiner or
127
+ * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
128
+ * which is INTG16 in Internal Interrupt Combiner.
129
+ */
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)
44
+{
194
+{
45
+ return x + 1;
195
+ uint32_t grp, bit, irq_id, n;
196
+ Exynos4210Irq *is = &s->irqs;
197
+
198
+ for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
199
+ irq_id = 0;
200
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
201
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
202
+ /* MCT_G0 is passed to External GIC */
203
+ irq_id = EXT_GIC_ID_MCT_G0;
204
+ }
205
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
206
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
207
+ /* MCT_G1 is passed to External and GIC */
208
+ irq_id = EXT_GIC_ID_MCT_G1;
209
+ }
210
+ if (irq_id) {
211
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
212
+ is->ext_gic_irq[irq_id - 32]);
213
+ } else {
214
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
215
+ is->ext_combiner_irq[n]);
216
+ }
217
+ }
218
+ for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
219
+ /* these IDs are passed to Internal Combiner and External GIC */
220
+ grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
221
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
222
+ irq_id = combiner_grp_to_gic_id[grp -
223
+ EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
224
+
225
+ if (irq_id) {
226
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
227
+ is->ext_gic_irq[irq_id - 32]);
228
+ }
229
+ }
46
+}
230
+}
47
+
231
+
48
/* Include the generated Neon decoder */
232
+/*
49
#include "decode-neon-dp.inc.c"
233
+ * Get IRQ number from exynos4210 IRQ subsystem stub.
50
#include "decode-neon-ls.inc.c"
234
+ * To identify IRQ source use internal combiner group and bit number
51
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
235
+ * grp - group number
52
236
+ * bit - bit number inside group
53
return true;
237
+ */
54
}
238
+uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
55
+
56
+static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
57
+{
239
+{
58
+ /* Neon load/store single structure to one lane */
240
+ return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
59
+ int reg;
60
+ int nregs = a->n + 1;
61
+ int vd = a->vd;
62
+ TCGv_i32 addr, tmp;
63
+
64
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
65
+ return false;
66
+ }
67
+
68
+ /* UNDEF accesses to D16-D31 if they don't exist */
69
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
70
+ return false;
71
+ }
72
+
73
+ /* Catch the UNDEF cases. This is unavoidably a bit messy. */
74
+ switch (nregs) {
75
+ case 1:
76
+ if (((a->align & (1 << a->size)) != 0) ||
77
+ (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
78
+ return false;
79
+ }
80
+ break;
81
+ case 3:
82
+ if ((a->align & 1) != 0) {
83
+ return false;
84
+ }
85
+ /* fall through */
86
+ case 2:
87
+ if (a->size == 2 && (a->align & 2) != 0) {
88
+ return false;
89
+ }
90
+ break;
91
+ case 4:
92
+ if ((a->size == 2) && ((a->align & 3) == 3)) {
93
+ return false;
94
+ }
95
+ break;
96
+ default:
97
+ abort();
98
+ }
99
+ if ((vd + a->stride * (nregs - 1)) > 31) {
100
+ /*
101
+ * Attempts to write off the end of the register file are
102
+ * UNPREDICTABLE; we choose to UNDEF because otherwise we would
103
+ * access off the end of the array that holds the register data.
104
+ */
105
+ return false;
106
+ }
107
+
108
+ if (!vfp_access_check(s)) {
109
+ return true;
110
+ }
111
+
112
+ tmp = tcg_temp_new_i32();
113
+ addr = tcg_temp_new_i32();
114
+ load_reg_var(s, addr, a->rn);
115
+ /*
116
+ * TODO: if we implemented alignment exceptions, we should check
117
+ * addr against the alignment encoded in a->align here.
118
+ */
119
+ for (reg = 0; reg < nregs; reg++) {
120
+ if (a->l) {
121
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
122
+ s->be_data | a->size);
123
+ neon_store_element(vd, a->reg_idx, a->size, tmp);
124
+ } else { /* Store */
125
+ neon_load_element(tmp, vd, a->reg_idx, a->size);
126
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
127
+ s->be_data | a->size);
128
+ }
129
+ vd += a->stride;
130
+ tcg_gen_addi_i32(addr, addr, 1 << a->size);
131
+ }
132
+ tcg_temp_free_i32(addr);
133
+ tcg_temp_free_i32(tmp);
134
+
135
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
136
+
137
+ return true;
138
+}
241
+}
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
242
+
243
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
244
0x09, 0x00, 0x00, 0x00 };
245
246
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
140
index XXXXXXX..XXXXXXX 100644
247
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/translate.c
248
--- a/hw/intc/exynos4210_gic.c
142
+++ b/target/arm/translate.c
249
+++ b/hw/intc/exynos4210_gic.c
143
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
250
@@ -XXX,XX +XXX,XX @@
144
tcg_temp_free_i32(rd);
251
#include "hw/arm/exynos4210.h"
145
}
252
#include "qom/object.h"
146
253
147
-
254
-enum ExtGicId {
148
-/* Translate a NEON load/store element instruction. Return nonzero if the
255
- EXT_GIC_ID_MDMA_LCD0 = 66,
149
- instruction is invalid. */
256
- EXT_GIC_ID_PDMA0,
150
-static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
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)
151
-{
414
-{
152
- int rd, rn, rm;
415
- uint32_t grp, bit, irq_id, n;
153
- int nregs;
416
- Exynos4210Irq *is = &s->irqs;
154
- int stride;
417
-
155
- int size;
418
- for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
156
- int reg;
419
- irq_id = 0;
157
- int load;
420
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
158
- TCGv_i32 addr;
421
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
159
- TCGv_i32 tmp;
422
- /* MCT_G0 is passed to External GIC */
160
-
423
- irq_id = EXT_GIC_ID_MCT_G0;
161
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
424
- }
162
- return 1;
425
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
163
- }
426
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
164
-
427
- /* MCT_G1 is passed to External and GIC */
165
- /* FIXME: this access check should not take precedence over UNDEF
428
- irq_id = EXT_GIC_ID_MCT_G1;
166
- * for invalid encodings; we will generate incorrect syndrome information
429
- }
167
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
430
- if (irq_id) {
168
- */
431
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
169
- if (s->fp_excp_el) {
432
- is->ext_gic_irq[irq_id - 32]);
170
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
171
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
172
- return 0;
173
- }
174
-
175
- if (!s->vfp_enabled)
176
- return 1;
177
- VFP_DREG_D(rd, insn);
178
- rn = (insn >> 16) & 0xf;
179
- rm = insn & 0xf;
180
- load = (insn & (1 << 21)) != 0;
181
- if ((insn & (1 << 23)) == 0) {
182
- /* Load store all elements -- handled already by decodetree */
183
- return 1;
184
- } else {
185
- size = (insn >> 10) & 3;
186
- if (size == 3) {
187
- /* Load single element to all lanes -- handled by decodetree */
188
- return 1;
189
- } else {
433
- } else {
190
- /* Single element. */
434
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
191
- int idx = (insn >> 4) & 0xf;
435
- is->ext_combiner_irq[n]);
192
- int reg_idx;
193
- switch (size) {
194
- case 0:
195
- reg_idx = (insn >> 5) & 7;
196
- stride = 1;
197
- break;
198
- case 1:
199
- reg_idx = (insn >> 6) & 3;
200
- stride = (insn & (1 << 5)) ? 2 : 1;
201
- break;
202
- case 2:
203
- reg_idx = (insn >> 7) & 1;
204
- stride = (insn & (1 << 6)) ? 2 : 1;
205
- break;
206
- default:
207
- abort();
208
- }
209
- nregs = ((insn >> 8) & 3) + 1;
210
- /* Catch the UNDEF cases. This is unavoidably a bit messy. */
211
- switch (nregs) {
212
- case 1:
213
- if (((idx & (1 << size)) != 0) ||
214
- (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
215
- return 1;
216
- }
217
- break;
218
- case 3:
219
- if ((idx & 1) != 0) {
220
- return 1;
221
- }
222
- /* fall through */
223
- case 2:
224
- if (size == 2 && (idx & 2) != 0) {
225
- return 1;
226
- }
227
- break;
228
- case 4:
229
- if ((size == 2) && ((idx & 3) == 3)) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- abort();
235
- }
236
- if ((rd + stride * (nregs - 1)) > 31) {
237
- /* Attempts to write off the end of the register file
238
- * are UNPREDICTABLE; we choose to UNDEF because otherwise
239
- * the neon_load_reg() would write off the end of the array.
240
- */
241
- return 1;
242
- }
243
- tmp = tcg_temp_new_i32();
244
- addr = tcg_temp_new_i32();
245
- load_reg_var(s, addr, rn);
246
- for (reg = 0; reg < nregs; reg++) {
247
- if (load) {
248
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
249
- s->be_data | size);
250
- neon_store_element(rd, reg_idx, size, tmp);
251
- } else { /* Store */
252
- neon_load_element(tmp, rd, reg_idx, size);
253
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
254
- s->be_data | size);
255
- }
256
- rd += stride;
257
- tcg_gen_addi_i32(addr, addr, 1 << size);
258
- }
259
- tcg_temp_free_i32(addr);
260
- tcg_temp_free_i32(tmp);
261
- stride = nregs * (1 << size);
262
- }
436
- }
263
- }
437
- }
264
- if (rm != 15) {
438
- for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
265
- TCGv_i32 base;
439
- /* these IDs are passed to Internal Combiner and External GIC */
266
-
440
- grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
267
- base = load_reg(s, rn);
441
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
268
- if (rm == 13) {
442
- irq_id = combiner_grp_to_gic_id[grp -
269
- tcg_gen_addi_i32(base, base, stride);
443
- EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
270
- } else {
444
-
271
- TCGv_i32 index;
445
- if (irq_id) {
272
- index = load_reg(s, rm);
446
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
273
- tcg_gen_add_i32(base, base, index);
447
- is->ext_gic_irq[irq_id - 32]);
274
- tcg_temp_free_i32(index);
275
- }
448
- }
276
- store_reg(s, rn, base);
277
- }
449
- }
278
- return 0;
279
-}
450
-}
280
-
451
-
281
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
452
-/*
282
{
453
- * Get IRQ number from exynos4210 IRQ subsystem stub.
283
switch (size) {
454
- * To identify IRQ source use internal combiner group and bit number
284
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
455
- * grp - group number
285
}
456
- * bit - bit number inside group
286
return;
457
- */
287
}
458
-uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
288
- if ((insn & 0x0f100000) == 0x04000000) {
459
-{
289
- /* NEON load/store. */
460
- return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
290
- if (disas_neon_ls_insn(s, insn)) {
461
-}
291
- goto illegal_op;
462
-
292
- }
463
-/********* GIC part *********/
293
- return;
464
-
294
- }
465
#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
295
if ((insn & 0x0e000f00) == 0x0c000100) {
466
OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
296
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
467
297
/* iWMMXt register transfer. */
298
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
299
}
300
break;
301
case 12:
302
- if ((insn & 0x01100000) == 0x01000000) {
303
- if (disas_neon_ls_insn(s, insn)) {
304
- goto illegal_op;
305
- }
306
- break;
307
- }
308
goto illegal_op;
309
default:
310
illegal_op:
311
--
468
--
312
2.20.1
469
2.25.1
313
314
diff view generated by jsdifflib
1
Convert the Neon "load/store multiple structures" insns to decodetree.
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
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-12-peter.maydell@linaro.org
7
Message-id: 20220404154658.565020-9-peter.maydell@linaro.org
6
---
8
---
7
target/arm/neon-ls.decode | 7 ++
9
include/hw/arm/exynos4210.h | 2 ++
8
target/arm/translate-neon.inc.c | 124 ++++++++++++++++++++++++++++++++
10
include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 91 +----------------------
11
hw/arm/exynos4210.c | 10 ++++----
10
3 files changed, 133 insertions(+), 89 deletions(-)
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
11
16
12
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-ls.decode
19
--- a/include/hw/arm/exynos4210.h
15
+++ b/target/arm/neon-ls.decode
20
+++ b/include/hw/arm/exynos4210.h
16
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
17
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
22
#include "hw/or-irq.h"
18
# This file works on the A32 encoding only; calling code for T32 has to
23
#include "hw/sysbus.h"
19
# transform the insn into the A32 version first.
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
20
+
66
+
21
+%vd_dp 22:1 12:4
67
+#include "hw/sysbus.h"
22
+
68
+
23
+# Neon load/store multiple structures
69
+#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
70
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
24
+
71
+
25
+VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
72
+#define EXYNOS4210_GIC_NCPUS 2
26
+ vd=%vd_dp
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
30
+++ b/target/arm/translate-neon.inc.c
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
32
gen_helper_gvec_fmlal_idx_a32);
33
return true;
34
}
35
+
73
+
36
+static struct {
74
+struct Exynos4210GicState {
37
+ int nregs;
75
+ SysBusDevice parent_obj;
38
+ int interleave;
76
+
39
+ int spacing;
77
+ MemoryRegion cpu_container;
40
+} const neon_ls_element_type[11] = {
78
+ MemoryRegion dist_container;
41
+ {1, 4, 1},
79
+ MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS];
42
+ {1, 4, 2},
80
+ MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS];
43
+ {4, 1, 1},
81
+ uint32_t num_cpu;
44
+ {2, 2, 2},
82
+ DeviceState *gic;
45
+ {1, 3, 1},
46
+ {1, 3, 2},
47
+ {3, 1, 1},
48
+ {1, 1, 1},
49
+ {1, 2, 1},
50
+ {1, 2, 2},
51
+ {2, 1, 1}
52
+};
83
+};
53
+
84
+
54
+static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
85
+#endif
55
+ int stride)
86
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
56
+{
57
+ if (rm != 15) {
58
+ TCGv_i32 base;
59
+
60
+ base = load_reg(s, rn);
61
+ if (rm == 13) {
62
+ tcg_gen_addi_i32(base, base, stride);
63
+ } else {
64
+ TCGv_i32 index;
65
+ index = load_reg(s, rm);
66
+ tcg_gen_add_i32(base, base, index);
67
+ tcg_temp_free_i32(index);
68
+ }
69
+ store_reg(s, rn, base);
70
+ }
71
+}
72
+
73
+static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
74
+{
75
+ /* Neon load/store multiple structures */
76
+ int nregs, interleave, spacing, reg, n;
77
+ MemOp endian = s->be_data;
78
+ int mmu_idx = get_mem_index(s);
79
+ int size = a->size;
80
+ TCGv_i64 tmp64;
81
+ TCGv_i32 addr, tmp;
82
+
83
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
84
+ return false;
85
+ }
86
+
87
+ /* UNDEF accesses to D16-D31 if they don't exist */
88
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
89
+ return false;
90
+ }
91
+ if (a->itype > 10) {
92
+ return false;
93
+ }
94
+ /* Catch UNDEF cases for bad values of align field */
95
+ switch (a->itype & 0xc) {
96
+ case 4:
97
+ if (a->align >= 2) {
98
+ return false;
99
+ }
100
+ break;
101
+ case 8:
102
+ if (a->align == 3) {
103
+ return false;
104
+ }
105
+ break;
106
+ default:
107
+ break;
108
+ }
109
+ nregs = neon_ls_element_type[a->itype].nregs;
110
+ interleave = neon_ls_element_type[a->itype].interleave;
111
+ spacing = neon_ls_element_type[a->itype].spacing;
112
+ if (size == 3 && (interleave | spacing) != 1) {
113
+ return false;
114
+ }
115
+
116
+ if (!vfp_access_check(s)) {
117
+ return true;
118
+ }
119
+
120
+ /* For our purposes, bytes are always little-endian. */
121
+ if (size == 0) {
122
+ endian = MO_LE;
123
+ }
124
+ /*
125
+ * Consecutive little-endian elements from a single register
126
+ * can be promoted to a larger little-endian operation.
127
+ */
128
+ if (interleave == 1 && endian == MO_LE) {
129
+ size = 3;
130
+ }
131
+ tmp64 = tcg_temp_new_i64();
132
+ addr = tcg_temp_new_i32();
133
+ tmp = tcg_const_i32(1 << size);
134
+ load_reg_var(s, addr, a->rn);
135
+ for (reg = 0; reg < nregs; reg++) {
136
+ for (n = 0; n < 8 >> size; n++) {
137
+ int xs;
138
+ for (xs = 0; xs < interleave; xs++) {
139
+ int tt = a->vd + reg + spacing * xs;
140
+
141
+ if (a->l) {
142
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
143
+ neon_store_element64(tt, n, size, tmp64);
144
+ } else {
145
+ neon_load_element64(tmp64, tt, n, size);
146
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
147
+ }
148
+ tcg_gen_add_i32(addr, addr, tmp);
149
+ }
150
+ }
151
+ }
152
+ tcg_temp_free_i32(addr);
153
+ tcg_temp_free_i32(tmp);
154
+ tcg_temp_free_i64(tmp64);
155
+
156
+ gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
157
+ return true;
158
+}
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
160
index XXXXXXX..XXXXXXX 100644
87
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate.c
88
--- a/hw/arm/exynos4210.c
162
+++ b/target/arm/translate.c
89
+++ b/hw/arm/exynos4210.c
163
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
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);
164
}
118
}
165
119
166
120
static void exynos4210_class_init(ObjectClass *klass, void *data)
167
-static struct {
121
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
168
- int nregs;
122
index XXXXXXX..XXXXXXX 100644
169
- int interleave;
123
--- a/hw/intc/exynos4210_gic.c
170
- int spacing;
124
+++ b/hw/intc/exynos4210_gic.c
171
-} const neon_ls_element_type[11] = {
125
@@ -XXX,XX +XXX,XX @@
172
- {1, 4, 1},
126
#include "qemu/module.h"
173
- {1, 4, 2},
127
#include "hw/irq.h"
174
- {4, 1, 1},
128
#include "hw/qdev-properties.h"
175
- {2, 2, 2},
129
+#include "hw/intc/exynos4210_gic.h"
176
- {1, 3, 1},
130
#include "hw/arm/exynos4210.h"
177
- {1, 3, 2},
131
#include "qom/object.h"
178
- {3, 1, 1},
132
179
- {1, 1, 1},
133
@@ -XXX,XX +XXX,XX @@
180
- {1, 2, 1},
134
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
181
- {1, 2, 2},
135
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
182
- {2, 1, 1}
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;
183
-};
149
-};
184
-
150
-
185
/* Translate a NEON load/store element instruction. Return nonzero if the
151
static void exynos4210_gic_set_irq(void *opaque, int irq, int level)
186
instruction is invalid. */
187
static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
188
{
152
{
189
int rd, rn, rm;
153
Exynos4210GicState *s = (Exynos4210GicState *)opaque;
190
- int op;
154
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
191
int nregs;
155
* enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
192
- int interleave;
156
* doesn't figure this out, otherwise and gives spurious warnings.
193
- int spacing;
157
*/
194
int stride;
158
- assert(n <= EXYNOS4210_NCPUS);
195
int size;
159
+ assert(n <= EXYNOS4210_GIC_NCPUS);
196
int reg;
160
for (i = 0; i < n; i++) {
197
int load;
161
/* Map CPU interface per SMP Core */
198
- int n;
162
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
199
int vec_size;
163
diff --git a/MAINTAINERS b/MAINTAINERS
200
- int mmu_idx;
164
index XXXXXXX..XXXXXXX 100644
201
- MemOp endian;
165
--- a/MAINTAINERS
202
TCGv_i32 addr;
166
+++ b/MAINTAINERS
203
TCGv_i32 tmp;
167
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
204
- TCGv_i32 tmp2;
168
L: qemu-arm@nongnu.org
205
- TCGv_i64 tmp64;
169
S: Odd Fixes
206
170
F: hw/*/exynos*
207
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
171
-F: include/hw/arm/exynos4210.h
208
return 1;
172
+F: include/hw/*/exynos*
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
173
210
rn = (insn >> 16) & 0xf;
174
Calxeda Highbank
211
rm = insn & 0xf;
175
M: Rob Herring <robh@kernel.org>
212
load = (insn & (1 << 21)) != 0;
213
- endian = s->be_data;
214
- mmu_idx = get_mem_index(s);
215
if ((insn & (1 << 23)) == 0) {
216
- /* Load store all elements. */
217
- op = (insn >> 8) & 0xf;
218
- size = (insn >> 6) & 3;
219
- if (op > 10)
220
- return 1;
221
- /* Catch UNDEF cases for bad values of align field */
222
- switch (op & 0xc) {
223
- case 4:
224
- if (((insn >> 5) & 1) == 1) {
225
- return 1;
226
- }
227
- break;
228
- case 8:
229
- if (((insn >> 4) & 3) == 3) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- break;
235
- }
236
- nregs = neon_ls_element_type[op].nregs;
237
- interleave = neon_ls_element_type[op].interleave;
238
- spacing = neon_ls_element_type[op].spacing;
239
- if (size == 3 && (interleave | spacing) != 1) {
240
- return 1;
241
- }
242
- /* For our purposes, bytes are always little-endian. */
243
- if (size == 0) {
244
- endian = MO_LE;
245
- }
246
- /* Consecutive little-endian elements from a single register
247
- * can be promoted to a larger little-endian operation.
248
- */
249
- if (interleave == 1 && endian == MO_LE) {
250
- size = 3;
251
- }
252
- tmp64 = tcg_temp_new_i64();
253
- addr = tcg_temp_new_i32();
254
- tmp2 = tcg_const_i32(1 << size);
255
- load_reg_var(s, addr, rn);
256
- for (reg = 0; reg < nregs; reg++) {
257
- for (n = 0; n < 8 >> size; n++) {
258
- int xs;
259
- for (xs = 0; xs < interleave; xs++) {
260
- int tt = rd + reg + spacing * xs;
261
-
262
- if (load) {
263
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
264
- neon_store_element64(tt, n, size, tmp64);
265
- } else {
266
- neon_load_element64(tmp64, tt, n, size);
267
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
268
- }
269
- tcg_gen_add_i32(addr, addr, tmp2);
270
- }
271
- }
272
- }
273
- tcg_temp_free_i32(addr);
274
- tcg_temp_free_i32(tmp2);
275
- tcg_temp_free_i64(tmp64);
276
- stride = nregs * interleave * 8;
277
+ /* Load store all elements -- handled already by decodetree */
278
+ return 1;
279
} else {
280
size = (insn >> 10) & 3;
281
if (size == 3) {
282
--
176
--
283
2.20.1
177
2.25.1
284
285
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VADD and VSUB insns to decodetree.
1
The only time we use the ext_gic_irq[] array in the Exynos4210Irq
2
2
struct is during realize of the SoC -- we initialize it with the
3
Note that we don't need the neon_3r_sizes[op] check here because all
3
input IRQs of the external GIC device, and then connect those to
4
size values are OK for VADD and VSUB; we'll add this when we convert
4
outputs of other devices further on in realize (including in the
5
the first insn that has size restrictions.
5
exynos4210_init_board_irqs() function). Now that the ext_gic object
6
6
is easily accessible as s->ext_gic we can make the connections
7
For this we need one of the GVecGen*Fn typedefs currently in
7
directly from one device to the other without going via this array.
8
translate-a64.h; move them all to translate.h as a block so they
9
are visible to the 32-bit decoder.
10
8
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200430181003.21682-15-peter.maydell@linaro.org
11
Message-id: 20220404154658.565020-10-peter.maydell@linaro.org
14
---
12
---
15
target/arm/translate-a64.h | 9 --------
13
include/hw/arm/exynos4210.h | 1 -
16
target/arm/translate.h | 9 ++++++++
14
hw/arm/exynos4210.c | 12 ++++++------
17
target/arm/neon-dp.decode | 17 +++++++++++++++
15
2 files changed, 6 insertions(+), 7 deletions(-)
18
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
19
target/arm/translate.c | 14 ++++--------
20
5 files changed, 68 insertions(+), 19 deletions(-)
21
16
22
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
23
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate-a64.h
19
--- a/include/hw/arm/exynos4210.h
25
+++ b/target/arm/translate-a64.h
20
+++ b/include/hw/arm/exynos4210.h
26
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
21
@@ -XXX,XX +XXX,XX @@
27
22
typedef struct Exynos4210Irq {
28
bool disas_sve(DisasContext *, uint32_t);
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
29
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
30
-/* Note that the gvec expanders operate on offsets + sizes. */
25
- qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
31
-typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
26
} Exynos4210Irq;
32
-typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
27
33
- uint32_t, uint32_t);
28
struct Exynos4210State {
34
-typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
35
- uint32_t, uint32_t, uint32_t);
36
-typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
37
- uint32_t, uint32_t, uint32_t);
38
-
39
#endif /* TARGET_ARM_TRANSLATE_A64_H */
40
diff --git a/target/arm/translate.h b/target/arm/translate.h
41
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate.h
31
--- a/hw/arm/exynos4210.c
43
+++ b/target/arm/translate.h
32
+++ b/hw/arm/exynos4210.c
44
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
45
#define dc_isar_feature(name, ctx) \
34
{
46
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
35
uint32_t grp, bit, irq_id, n;
47
36
Exynos4210Irq *is = &s->irqs;
48
+/* Note that the gvec expanders operate on offsets + sizes. */
37
+ DeviceState *extgicdev = DEVICE(&s->ext_gic);
49
+typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
38
50
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
39
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
51
+ uint32_t, uint32_t);
40
irq_id = 0;
52
+typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
53
+ uint32_t, uint32_t, uint32_t);
42
}
54
+typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
43
if (irq_id) {
55
+ uint32_t, uint32_t, uint32_t);
44
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
56
+
45
- is->ext_gic_irq[irq_id - 32]);
57
#endif /* TARGET_ARM_TRANSLATE_H */
46
+ qdev_get_gpio_in(extgicdev,
58
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
47
+ irq_id - 32));
59
index XXXXXXX..XXXXXXX 100644
48
} else {
60
--- a/target/arm/neon-dp.decode
49
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
61
+++ b/target/arm/neon-dp.decode
50
is->ext_combiner_irq[n]);
62
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
63
#
52
64
# This file is processed by scripts/decodetree.py
53
if (irq_id) {
65
#
54
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
66
+# VFP/Neon register fields; same as vfp.decode
55
- is->ext_gic_irq[irq_id - 32]);
67
+%vm_dp 5:1 0:4
56
+ qdev_get_gpio_in(extgicdev,
68
+%vn_dp 7:1 16:4
57
+ irq_id - 32));
69
+%vd_dp 22:1 12:4
58
}
70
59
}
71
# Encodings for Neon data processing instructions where the T32 encoding
72
# is a simple transformation of the A32 encoding.
73
@@ -XXX,XX +XXX,XX @@
74
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
75
# This file works on the A32 encoding only; calling code for T32 has to
76
# transform the insn into the A32 version first.
77
+
78
+######################################################################
79
+# 3-reg-same grouping:
80
+# 1111 001 U 0 D sz:2 Vn:4 Vd:4 opc:4 N Q M op Vm:4
81
+######################################################################
82
+
83
+&3same vm vn vd q size
84
+
85
+@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
86
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
87
+
88
+VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
89
+VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
90
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-neon.inc.c
93
+++ b/target/arm/translate-neon.inc.c
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
95
96
return true;
97
}
60
}
98
+
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
99
+static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
62
sysbus_connect_irq(busdev, n,
100
+{
63
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
101
+ int vec_size = a->q ? 16 : 8;
64
}
102
+ int rd_ofs = neon_reg_offset(a->vd, 0);
65
- for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
103
+ int rn_ofs = neon_reg_offset(a->vn, 0);
66
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
104
+ int rm_ofs = neon_reg_offset(a->vm, 0);
67
- }
105
+
68
106
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
69
/* Internal Interrupt Combiner */
107
+ return false;
70
dev = qdev_new("exynos4210.combiner");
108
+ }
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
109
+
72
busdev = SYS_BUS_DEVICE(dev);
110
+ /* UNDEF accesses to D16-D31 if they don't exist. */
73
sysbus_realize_and_unref(busdev, &error_fatal);
111
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
74
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
112
+ ((a->vd | a->vn | a->vm) & 0x10)) {
75
- sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
113
+ return false;
76
+ sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
114
+ }
77
}
115
+
78
exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
116
+ if ((a->vn | a->vm | a->vd) & a->q) {
79
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
117
+ return false;
118
+ }
119
+
120
+ if (!vfp_access_check(s)) {
121
+ return true;
122
+ }
123
+
124
+ fn(a->size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
125
+ return true;
126
+}
127
+
128
+#define DO_3SAME(INSN, FUNC) \
129
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
130
+ { \
131
+ return do_3same(s, a, FUNC); \
132
+ }
133
+
134
+DO_3SAME(VADD, tcg_gen_gvec_add)
135
+DO_3SAME(VSUB, tcg_gen_gvec_sub)
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/translate.c
139
+++ b/target/arm/translate.c
140
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
141
}
142
return 0;
143
144
- case NEON_3R_VADD_VSUB:
145
- if (u) {
146
- tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
147
- vec_size, vec_size);
148
- } else {
149
- tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
150
- vec_size, vec_size);
151
- }
152
- return 0;
153
-
154
case NEON_3R_VQADD:
155
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
156
rn_ofs, rm_ofs, vec_size, vec_size,
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
159
u ? &ushl_op[size] : &sshl_op[size]);
160
return 0;
161
+
162
+ case NEON_3R_VADD_VSUB:
163
+ /* Already handled by decodetree */
164
+ return 1;
165
}
166
167
if (size == 3) {
168
--
80
--
169
2.20.1
81
2.25.1
170
171
diff view generated by jsdifflib
1
The ARMv8.2-TTS2UXN feature extends the XN field in stage 2
1
The function exynos4210_combiner_get_gpioin() currently lives in
2
translation table descriptors from just bit [54] to bits [54:53],
2
exynos4210_combiner.c, but it isn't really part of the combiner
3
allowing stage 2 to control execution permissions separately for EL0
3
device itself -- it is a function that implements the wiring up of
4
and EL1. Implement the new semantics of the XN field and enable
4
some interrupt sources to multiple combiner inputs. Move it to live
5
the feature for our 'max' CPU.
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.
6
8
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200330210400.11724-5-peter.maydell@linaro.org
11
Message-id: 20220404154658.565020-11-peter.maydell@linaro.org
11
---
12
---
12
target/arm/cpu.h | 15 +++++++++++++++
13
include/hw/arm/exynos4210.h | 11 -----
13
target/arm/cpu.c | 1 +
14
hw/arm/exynos4210.c | 82 +++++++++++++++++++++++++++++++++++
14
target/arm/cpu64.c | 2 ++
15
hw/intc/exynos4210_combiner.c | 77 --------------------------------
15
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++------
16
3 files changed, 82 insertions(+), 88 deletions(-)
16
4 files changed, 49 insertions(+), 6 deletions(-)
17
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
20
--- a/include/hw/arm/exynos4210.h
21
+++ b/target/arm/cpu.h
21
+++ b/include/hw/arm/exynos4210.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
22
@@ -XXX,XX +XXX,XX @@
23
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
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);
24
}
65
}
25
66
26
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
67
+/*
68
+ * Get Combiner input GPIO into irqs structure
69
+ */
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
71
+ DeviceState *dev, int ext)
27
+{
72
+{
28
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
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
+ }
29
+}
142
+}
30
+
143
+
31
/*
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
32
* 64-bit feature tests via id registers.
145
0x09, 0x00, 0x00, 0x00 };
33
*/
146
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
147
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
35
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
36
}
37
38
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
39
+{
40
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
41
+}
42
+
43
/*
44
* Feature tests for "does this exist in either 32-bit or 64-bit?"
45
*/
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
47
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
48
}
49
50
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
51
+{
52
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
53
+}
54
+
55
/*
56
* Forward to the above feature tests given an ARMCPU pointer.
57
*/
58
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
59
index XXXXXXX..XXXXXXX 100644
148
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/cpu.c
149
--- a/hw/intc/exynos4210_combiner.c
61
+++ b/target/arm/cpu.c
150
+++ b/hw/intc/exynos4210_combiner.c
62
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
151
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_exynos4210_combiner = {
63
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
152
}
64
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
153
};
65
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
154
66
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
155
-/*
67
cpu->isar.id_mmfr4 = t;
156
- * Get Combiner input GPIO into irqs structure
68
}
157
- */
69
#endif
158
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
70
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
159
- int ext)
71
index XXXXXXX..XXXXXXX 100644
160
-{
72
--- a/target/arm/cpu64.c
161
- int n;
73
+++ b/target/arm/cpu64.c
162
- int bit;
74
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
163
- int max;
75
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
164
- qemu_irq *irq;
76
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
165
-
77
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
166
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
78
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
167
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
79
cpu->isar.id_aa64mmfr1 = t;
168
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
80
169
-
81
t = cpu->isar.id_aa64mmfr2;
170
- /*
82
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
171
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
83
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
172
- * so let split them.
84
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
173
- */
85
u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
174
- for (n = 0; n < max; n++) {
86
+ u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
175
-
87
cpu->isar.id_mmfr4 = u;
176
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
88
177
-
89
u = cpu->isar.id_aa64dfr0;
178
- switch (n) {
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
179
- /* MDNIE_LCD1 INTG1 */
91
index XXXXXXX..XXXXXXX 100644
180
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
92
--- a/target/arm/helper.c
181
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
93
+++ b/target/arm/helper.c
182
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
94
@@ -XXX,XX +XXX,XX @@ simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
183
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
95
*
184
- continue;
96
* @env: CPUARMState
185
-
97
* @s2ap: The 2-bit stage2 access permissions (S2AP)
186
- /* TMU INTG3 */
98
- * @xn: XN (execute-never) bit
187
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
99
+ * @xn: XN (execute-never) bits
188
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
100
+ * @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
189
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
101
*/
190
- continue;
102
-static int get_S2prot(CPUARMState *env, int s2ap, int xn)
191
-
103
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
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)
104
{
234
{
105
int prot = 0;
106
107
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn)
108
if (s2ap & 2) {
109
prot |= PAGE_WRITE;
110
}
111
- if (!xn) {
112
- if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
113
+
114
+ if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
115
+ switch (xn) {
116
+ case 0:
117
prot |= PAGE_EXEC;
118
+ break;
119
+ case 1:
120
+ if (s1_is_el0) {
121
+ prot |= PAGE_EXEC;
122
+ }
123
+ break;
124
+ case 2:
125
+ break;
126
+ case 3:
127
+ if (!s1_is_el0) {
128
+ prot |= PAGE_EXEC;
129
+ }
130
+ break;
131
+ default:
132
+ g_assert_not_reached();
133
+ }
134
+ } else {
135
+ if (!extract32(xn, 1, 1)) {
136
+ if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
137
+ prot |= PAGE_EXEC;
138
+ }
139
}
140
}
141
return prot;
142
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
143
}
144
145
ap = extract32(attrs, 4, 2);
146
- xn = extract32(attrs, 12, 1);
147
148
if (mmu_idx == ARMMMUIdx_Stage2) {
149
ns = true;
150
- *prot = get_S2prot(env, ap, xn);
151
+ xn = extract32(attrs, 11, 2);
152
+ *prot = get_S2prot(env, ap, xn, s1_is_el0);
153
} else {
154
ns = extract32(attrs, 3, 1);
155
+ xn = extract32(attrs, 12, 1);
156
pxn = extract32(attrs, 11, 1);
157
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
158
}
159
--
235
--
160
2.20.1
236
2.25.1
161
162
diff view generated by jsdifflib
1
Convert the V[US]DOT (scalar) insns in the 2reg-scalar-ext group
1
Delete a couple of #defines which are never used.
2
to decodetree.
3
2
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-10-peter.maydell@linaro.org
5
Message-id: 20220404154658.565020-12-peter.maydell@linaro.org
7
---
6
---
8
target/arm/neon-shared.decode | 3 +++
7
include/hw/arm/exynos4210.h | 4 ----
9
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
8
1 file changed, 4 deletions(-)
10
target/arm/translate.c | 13 +-----------
11
3 files changed, 39 insertions(+), 12 deletions(-)
12
9
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
10
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
12
--- a/include/hw/arm/exynos4210.h
16
+++ b/target/arm/neon-shared.decode
13
+++ b/include/hw/arm/exynos4210.h
17
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
14
@@ -XXX,XX +XXX,XX @@
18
vn=%vn_dp vd=%vd_dp size=0
15
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
19
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
16
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
17
21
+
18
-/* IRQs number for external and internal GIC */
22
+VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
19
-#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
-#define EXYNOS4210_INT_GIC_NIRQ 64
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
29
tcg_temp_free_ptr(fpst);
30
return true;
31
}
32
+
33
+static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
34
+{
35
+ gen_helper_gvec_3 *fn_gvec;
36
+ int opr_sz;
37
+ TCGv_ptr fpst;
38
+
39
+ if (!dc_isar_feature(aa32_dp, s)) {
40
+ return false;
41
+ }
42
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vd | a->vn) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
58
+ opr_sz = (1 + a->q) * 8;
59
+ fpst = get_fpstatus_ptr(1);
60
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->rm),
63
+ opr_sz, opr_sz, a->index, fn_gvec);
64
+ tcg_temp_free_ptr(fpst);
65
+ return true;
66
+}
67
diff --git a/target/arm/translate.c b/target/arm/translate.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/translate.c
70
+++ b/target/arm/translate.c
71
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
72
bool is_long = false, q = extract32(insn, 6, 1);
73
bool ptr_is_env = false;
74
75
- if ((insn & 0xffb00f00) == 0xfe200d00) {
76
- /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
77
- int u = extract32(insn, 4, 1);
78
-
21
-
79
- if (!dc_isar_feature(aa32_dp, s)) {
22
#define EXYNOS4210_I2C_NUMBER 9
80
- return 1;
23
81
- }
24
#define EXYNOS4210_NUM_DMA 3
82
- fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
83
- /* rm is just Vm, and index is M. */
84
- data = extract32(insn, 5, 1); /* index */
85
- rm = extract32(insn, 0, 4);
86
- } else if ((insn & 0xffa00f10) == 0xfe000810) {
87
+ if ((insn & 0xffa00f10) == 0xfe000810) {
88
/* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
89
int is_s = extract32(insn, 20, 1);
90
int vm20 = extract32(insn, 0, 3);
91
--
25
--
92
2.20.1
26
2.25.1
93
94
diff view generated by jsdifflib
1
Convert VCMLA (scalar) in the 2reg-scalar-ext group to decodetree.
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
2
instead of qemu_irq_split().
2
3
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-9-peter.maydell@linaro.org
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
6
---
7
---
7
target/arm/neon-shared.decode | 5 +++++
8
include/hw/arm/exynos4210.h | 9 ++++++++
8
target/arm/translate-neon.inc.c | 40 +++++++++++++++++++++++++++++++++
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
9
target/arm/translate.c | 26 +--------------------
10
2 files changed, 42 insertions(+), 8 deletions(-)
10
3 files changed, 46 insertions(+), 25 deletions(-)
11
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
12
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
14
--- a/include/hw/arm/exynos4210.h
15
+++ b/target/arm/neon-shared.decode
15
+++ b/include/hw/arm/exynos4210.h
16
@@ -XXX,XX +XXX,XX @@ VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
16
@@ -XXX,XX +XXX,XX @@
17
vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
17
#include "hw/sysbus.h"
18
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
18
#include "hw/cpu/a9mpcore.h"
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
19
#include "hw/intc/exynos4210_gic.h"
20
+#include "hw/core/split-irq.h"
21
#include "target/arm/cpu-qom.h"
22
#include "qom/object.h"
23
24
@@ -XXX,XX +XXX,XX @@
25
26
#define EXYNOS4210_NUM_DMA 3
27
28
+/*
29
+ * We need one splitter for every external combiner input, plus
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
32
+ */
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
20
+
34
+
21
+VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
35
typedef struct Exynos4210Irq {
22
+ vn=%vn_dp vd=%vd_dp size=0
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
23
+VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
37
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
24
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
38
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
39
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
40
A9MPPrivState a9mpcore;
41
Exynos4210GicState ext_gic;
42
+ SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
43
};
44
45
#define TYPE_EXYNOS4210_SOC "exynos4210"
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
26
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate-neon.inc.c
48
--- a/hw/arm/exynos4210.c
28
+++ b/target/arm/translate-neon.inc.c
49
+++ b/hw/arm/exynos4210.c
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
50
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
30
gen_helper_gvec_fmlal_a32);
51
uint32_t grp, bit, irq_id, n;
31
return true;
52
Exynos4210Irq *is = &s->irqs;
53
DeviceState *extgicdev = DEVICE(&s->ext_gic);
54
+ int splitcount = 0;
55
+ DeviceState *splitter;
56
57
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
58
irq_id = 0;
59
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
60
/* MCT_G1 is passed to External and GIC */
61
irq_id = EXT_GIC_ID_MCT_G1;
62
}
63
+
64
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
65
+ splitter = DEVICE(&s->splitter[splitcount]);
66
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
67
+ qdev_realize(splitter, NULL, &error_abort);
68
+ splitcount++;
69
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
70
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
71
if (irq_id) {
72
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
73
- qdev_get_gpio_in(extgicdev,
74
- irq_id - 32));
75
+ qdev_connect_gpio_out(splitter, 1,
76
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
77
} else {
78
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
79
- is->ext_combiner_irq[n]);
80
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
81
}
82
}
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
86
87
if (irq_id) {
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
89
- qdev_get_gpio_in(extgicdev,
90
- irq_id - 32));
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
92
+ splitter = DEVICE(&s->splitter[splitcount]);
93
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
94
+ qdev_realize(splitter, NULL, &error_abort);
95
+ splitcount++;
96
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
97
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
98
+ qdev_connect_gpio_out(splitter, 1,
99
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
100
}
101
}
102
+ /*
103
+ * We check this here to avoid a more obscure assert later when
104
+ * qdev_assert_realized_properly() checks that we realized every
105
+ * child object we initialized.
106
+ */
107
+ assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
32
}
108
}
33
+
109
34
+static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
110
/*
35
+{
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
112
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
37
+ int opr_sz;
113
}
38
+ TCGv_ptr fpst;
114
39
+
115
+ for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
40
+ if (!dc_isar_feature(aa32_vcma, s)) {
116
+ g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
41
+ return false;
117
+ object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
42
+ }
43
+ if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
44
+ return false;
45
+ }
118
+ }
46
+
119
+
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
120
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
121
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
49
+ ((a->vd | a->vn | a->vm) & 0x10)) {
122
}
50
+ return false;
51
+ }
52
+
53
+ if ((a->vd | a->vn) & a->q) {
54
+ return false;
55
+ }
56
+
57
+ if (!vfp_access_check(s)) {
58
+ return true;
59
+ }
60
+
61
+ fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
62
+ : gen_helper_gvec_fcmlah_idx);
63
+ opr_sz = (1 + a->q) * 8;
64
+ fpst = get_fpstatus_ptr(1);
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(1, a->vn),
67
+ vfp_reg_offset(1, a->vm),
68
+ fpst, opr_sz, opr_sz,
69
+ (a->index << 2) | a->rot, fn_gvec_ptr);
70
+ tcg_temp_free_ptr(fpst);
71
+ return true;
72
+}
73
diff --git a/target/arm/translate.c b/target/arm/translate.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/target/arm/translate.c
76
+++ b/target/arm/translate.c
77
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
78
bool is_long = false, q = extract32(insn, 6, 1);
79
bool ptr_is_env = false;
80
81
- if ((insn & 0xff000f10) == 0xfe000800) {
82
- /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
83
- int rot = extract32(insn, 20, 2);
84
- int size = extract32(insn, 23, 1);
85
- int index;
86
-
87
- if (!dc_isar_feature(aa32_vcma, s)) {
88
- return 1;
89
- }
90
- if (size == 0) {
91
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
92
- return 1;
93
- }
94
- /* For fp16, rm is just Vm, and index is M. */
95
- rm = extract32(insn, 0, 4);
96
- index = extract32(insn, 5, 1);
97
- } else {
98
- /* For fp32, rm is the usual M:Vm, and index is 0. */
99
- VFP_DREG_M(rm, insn);
100
- index = 0;
101
- }
102
- data = (index << 2) | rot;
103
- fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
104
- : gen_helper_gvec_fcmlah_idx);
105
- } else if ((insn & 0xffb00f00) == 0xfe200d00) {
106
+ if ((insn & 0xffb00f00) == 0xfe200d00) {
107
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
108
int u = extract32(insn, 4, 1);
109
110
--
123
--
111
2.20.1
124
2.25.1
112
113
diff view generated by jsdifflib
1
Convert the V[US]DOT (vector) insns to decodetree.
1
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
2
are in a range that applies to the internal combiner only creates a
3
splitter for those interrupts which go to both the internal combiner
4
and to the external GIC, but it does nothing at all for the
5
interrupts which don't go to the external GIC, leaving the
6
irq_table[] array element empty for those. (This will result in
7
those interrupts simply being lost, not in a QEMU crash.)
8
9
I don't have a reliable datasheet for this SoC, but since we do wire
10
up one interrupt line in this category (the HDMI I2C device on
11
interrupt 16,1), this seems like it must be a bug in the existing
12
QEMU code. Fill in the irq_table[] entries where we're not splitting
13
the IRQ to both the internal combiner and the external GIC with the
14
IRQ line of the internal combiner. (That is, these IRQ lines go to
15
just one device, not multiple.)
16
17
This bug didn't have any visible guest effects because the only
18
implemented device that was affected was the HDMI I2C controller,
19
and we never connect any I2C devices to that bus.
2
20
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-7-peter.maydell@linaro.org
23
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
6
---
24
---
7
target/arm/neon-shared.decode | 4 ++++
25
hw/arm/exynos4210.c | 2 ++
8
target/arm/translate-neon.inc.c | 32 ++++++++++++++++++++++++++++++++
26
1 file changed, 2 insertions(+)
9
target/arm/translate.c | 9 +--------
10
3 files changed, 37 insertions(+), 8 deletions(-)
11
27
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
13
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
30
--- a/hw/arm/exynos4210.c
15
+++ b/target/arm/neon-shared.decode
31
+++ b/hw/arm/exynos4210.c
16
@@ -XXX,XX +XXX,XX @@ VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
32
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
17
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
18
VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
34
qdev_connect_gpio_out(splitter, 1,
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
20
+
36
+ } else {
21
+# VUDOT and VSDOT
37
+ s->irq_table[n] = is->int_combiner_irq[n];
22
+VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
38
}
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
39
}
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
40
/*
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
29
tcg_temp_free_ptr(fpst);
30
return true;
31
}
32
+
33
+static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
34
+{
35
+ int opr_sz;
36
+ gen_helper_gvec_3 *fn_gvec;
37
+
38
+ if (!dc_isar_feature(aa32_dp, s)) {
39
+ return false;
40
+ }
41
+
42
+ /* UNDEF accesses to D16-D31 if they don't exist. */
43
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
44
+ ((a->vd | a->vn | a->vm) & 0x10)) {
45
+ return false;
46
+ }
47
+
48
+ if ((a->vn | a->vm | a->vd) & a->q) {
49
+ return false;
50
+ }
51
+
52
+ if (!vfp_access_check(s)) {
53
+ return true;
54
+ }
55
+
56
+ opr_sz = (1 + a->q) * 8;
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
58
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
59
+ vfp_reg_offset(1, a->vn),
60
+ vfp_reg_offset(1, a->vm),
61
+ opr_sz, opr_sz, 0, fn_gvec);
62
+ return true;
63
+}
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
69
bool is_long = false, q = extract32(insn, 6, 1);
70
bool ptr_is_env = false;
71
72
- if ((insn & 0xfeb00f00) == 0xfc200d00) {
73
- /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
74
- bool u = extract32(insn, 4, 1);
75
- if (!dc_isar_feature(aa32_dp, s)) {
76
- return 1;
77
- }
78
- fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
79
- } else if ((insn & 0xff300f10) == 0xfc200810) {
80
+ if ((insn & 0xff300f10) == 0xfc200810) {
81
/* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
82
int is_s = extract32(insn, 23, 1);
83
if (!dc_isar_feature(aa32_fhm, s)) {
84
--
41
--
85
2.20.1
42
2.25.1
86
87
diff view generated by jsdifflib
1
Convert the VCADD (vector) insns to decodetree.
1
Currently for the interrupts MCT_G0 and MCT_G1 which are
2
the only ones in the input range of the external combiner
3
and which are also wired to the external GIC, we connect
4
them only to the internal combiner and the external GIC.
5
This seems likely to be a bug, as all other interrupts
6
which are in the input range of both combiners are
7
connected to both combiners. (The fact that the code in
8
exynos4210_combiner_get_gpioin() is also trying to wire
9
up these inputs on both combiners also suggests this.)
10
11
Wire these interrupts up to both combiners, like the rest.
2
12
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-6-peter.maydell@linaro.org
15
Message-id: 20220404154658.565020-15-peter.maydell@linaro.org
6
---
16
---
7
target/arm/neon-shared.decode | 3 +++
17
hw/arm/exynos4210.c | 7 +++----
8
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
18
1 file changed, 3 insertions(+), 4 deletions(-)
9
target/arm/translate.c | 11 +---------
10
3 files changed, 41 insertions(+), 10 deletions(-)
11
19
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
13
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
22
--- a/hw/arm/exynos4210.c
15
+++ b/target/arm/neon-shared.decode
23
+++ b/hw/arm/exynos4210.c
16
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
17
25
18
VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
splitter = DEVICE(&s->splitter[splitcount]);
20
+
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
21
+VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
22
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
30
qdev_realize(splitter, NULL, &error_abort);
23
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
splitcount++;
24
index XXXXXXX..XXXXXXX 100644
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
25
--- a/target/arm/translate-neon.inc.c
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
26
+++ b/target/arm/translate-neon.inc.c
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
35
if (irq_id) {
28
tcg_temp_free_ptr(fpst);
36
- qdev_connect_gpio_out(splitter, 1,
29
return true;
37
+ qdev_connect_gpio_out(splitter, 2,
30
}
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
31
+
39
- } else {
32
+static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
33
+{
41
}
34
+ int opr_sz;
42
}
35
+ TCGv_ptr fpst;
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
37
+
38
+ if (!dc_isar_feature(aa32_vcma, s)
39
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
40
+ return false;
41
+ }
42
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn | a->vm) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vn | a->vm | a->vd) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ opr_sz = (1 + a->q) * 8;
58
+ fpst = get_fpstatus_ptr(1);
59
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
60
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->vm),
63
+ fpst, opr_sz, opr_sz, a->rot,
64
+ fn_gvec_ptr);
65
+ tcg_temp_free_ptr(fpst);
66
+ return true;
67
+}
68
diff --git a/target/arm/translate.c b/target/arm/translate.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/translate.c
71
+++ b/target/arm/translate.c
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
73
bool is_long = false, q = extract32(insn, 6, 1);
74
bool ptr_is_env = false;
75
76
- if ((insn & 0xfea00f10) == 0xfc800800) {
77
- /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
78
- int size = extract32(insn, 20, 1);
79
- data = extract32(insn, 24, 1); /* rot */
80
- if (!dc_isar_feature(aa32_vcma, s)
81
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
82
- return 1;
83
- }
84
- fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
85
- } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
86
+ if ((insn & 0xfeb00f00) == 0xfc200d00) {
87
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
88
bool u = extract32(insn, 4, 1);
89
if (!dc_isar_feature(aa32_dp, s)) {
90
--
44
--
91
2.20.1
45
2.25.1
92
93
diff view generated by jsdifflib
1
Convert the Neon logic ops in the 3-reg-same grouping to decodetree.
1
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
2
Note that for the logic ops the 'size' field forms part of their
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
3
decode and the actual operations are always bitwise.
3
connect multiple IRQs up to the same external GIC input, which
4
is not permitted. We do the same thing in the code in
5
exynos4210_init_board_irqs() because the conditionals selecting
6
an irq_id in the first loop match multiple interrupt IDs.
7
8
Overall we do this for interrupt IDs
9
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
10
and
11
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
12
13
These correspond to the cases for the multi-core timer that we are
14
wiring up to multiple inputs on the combiner in
15
exynos4210_combiner_get_gpioin(). That code already deals with all
16
these interrupt IDs being the same input source, so we don't need to
17
connect the external GIC interrupt for any of them except the first
18
(1, 4) and (1, 5). Remove the array entries and conditionals which
19
were incorrectly causing us to wire up extra lines.
20
21
This bug didn't cause any visible effects, because we only connect
22
up a device to the "primary" ID values (1, 4) and (1, 5), so the
23
extra lines would never be set to a level.
4
24
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200430181003.21682-16-peter.maydell@linaro.org
27
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
8
---
28
---
9
target/arm/neon-dp.decode | 12 +++++++++++
29
include/hw/arm/exynos4210.h | 2 +-
10
target/arm/translate-neon.inc.c | 19 +++++++++++++++++
30
hw/arm/exynos4210.c | 12 +++++-------
11
target/arm/translate.c | 38 +--------------------------------
31
2 files changed, 6 insertions(+), 8 deletions(-)
12
3 files changed, 32 insertions(+), 37 deletions(-)
13
32
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
33
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
15
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
35
--- a/include/hw/arm/exynos4210.h
17
+++ b/target/arm/neon-dp.decode
36
+++ b/include/hw/arm/exynos4210.h
18
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
19
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
38
* one for every non-zero entry in combiner_grp_to_gic_id[].
20
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
39
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
21
40
*/
22
+@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
41
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
23
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
42
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
24
+
43
25
+VAND_3s 1111 001 0 0 . 00 .... .... 0001 ... 1 .... @3same_logic
44
typedef struct Exynos4210Irq {
26
+VBIC_3s 1111 001 0 0 . 01 .... .... 0001 ... 1 .... @3same_logic
45
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
27
+VORR_3s 1111 001 0 0 . 10 .... .... 0001 ... 1 .... @3same_logic
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
28
+VORN_3s 1111 001 0 0 . 11 .... .... 0001 ... 1 .... @3same_logic
29
+VEOR_3s 1111 001 1 0 . 00 .... .... 0001 ... 1 .... @3same_logic
30
+VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
31
+VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
32
+VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
33
+
34
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
35
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
48
--- a/hw/arm/exynos4210.c
39
+++ b/target/arm/translate-neon.inc.c
49
+++ b/hw/arm/exynos4210.c
40
@@ -XXX,XX +XXX,XX @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
50
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
41
51
/* int combiner group 34 */
42
DO_3SAME(VADD, tcg_gen_gvec_add)
52
{ EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
43
DO_3SAME(VSUB, tcg_gen_gvec_sub)
53
/* int combiner group 35 */
44
+DO_3SAME(VAND, tcg_gen_gvec_and)
54
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
45
+DO_3SAME(VBIC, tcg_gen_gvec_andc)
55
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
46
+DO_3SAME(VORR, tcg_gen_gvec_or)
56
/* int combiner group 36 */
47
+DO_3SAME(VORN, tcg_gen_gvec_orc)
57
{ EXT_GIC_ID_MIXER },
48
+DO_3SAME(VEOR, tcg_gen_gvec_xor)
58
/* int combiner group 37 */
49
+
59
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
50
+/* These insns are all gvec_bitsel but with the inputs in various orders. */
60
/* groups 38-50 */
51
+#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
61
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
52
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
62
/* int combiner group 51 */
53
+ uint32_t rn_ofs, uint32_t rm_ofs, \
63
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
54
+ uint32_t oprsz, uint32_t maxsz) \
64
+ { EXT_GIC_ID_MCT_L0 },
55
+ { \
65
/* group 52 */
56
+ tcg_gen_gvec_bitsel(vece, rd_ofs, O1, O2, O3, oprsz, maxsz); \
66
{ },
57
+ } \
67
/* int combiner group 53 */
58
+ DO_3SAME(INSN, gen_##INSN##_3s)
68
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
59
+
69
+ { EXT_GIC_ID_WDT },
60
+DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
70
/* groups 54-63 */
61
+DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
71
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
62
+DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
72
};
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
64
index XXXXXXX..XXXXXXX 100644
74
65
--- a/target/arm/translate.c
75
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
66
+++ b/target/arm/translate.c
76
irq_id = 0;
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
68
}
78
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
69
return 1;
79
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
70
80
/* MCT_G0 is passed to External GIC */
71
- case NEON_3R_LOGIC: /* Logic ops. */
81
irq_id = EXT_GIC_ID_MCT_G0;
72
- switch ((u << 2) | size) {
82
}
73
- case 0: /* VAND */
83
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
74
- tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
84
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
75
- vec_size, vec_size);
85
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
76
- break;
86
/* MCT_G1 is passed to External and GIC */
77
- case 1: /* VBIC */
87
irq_id = EXT_GIC_ID_MCT_G1;
78
- tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
79
- vec_size, vec_size);
80
- break;
81
- case 2: /* VORR */
82
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
83
- vec_size, vec_size);
84
- break;
85
- case 3: /* VORN */
86
- tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
87
- vec_size, vec_size);
88
- break;
89
- case 4: /* VEOR */
90
- tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
91
- vec_size, vec_size);
92
- break;
93
- case 5: /* VBSL */
94
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
95
- vec_size, vec_size);
96
- break;
97
- case 6: /* VBIT */
98
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
99
- vec_size, vec_size);
100
- break;
101
- case 7: /* VBIF */
102
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
103
- vec_size, vec_size);
104
- break;
105
- }
106
- return 0;
107
-
108
case NEON_3R_VQADD:
109
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
110
rn_ofs, rm_ofs, vec_size, vec_size,
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
return 0;
113
114
case NEON_3R_VADD_VSUB:
115
+ case NEON_3R_LOGIC:
116
/* Already handled by decodetree */
117
return 1;
118
}
88
}
119
--
89
--
120
2.20.1
90
2.25.1
121
122
diff view generated by jsdifflib
1
Convert the Neon VMUL, VMLA, VMLS and VSHL insns in the
1
At this point, the function exynos4210_init_board_irqs() splits input
2
3-reg-same grouping to decodetree.
2
IRQ lines to connect them to the input combiner, output combiner and
3
external GIC. The function exynos4210_combiner_get_gpioin() splits
4
some of the combiner input lines further to connect them to multiple
5
different inputs on the combiner.
6
7
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
8
configurable number of outputs, we can do all this in one place, by
9
making exynos4210_init_board_irqs() add extra outputs to the splitter
10
device when it must be connected to more than one input on each
11
combiner.
12
13
We do this with a new data structure, the combinermap, which is an
14
array each of whose elements is a list of the interrupt IDs on the
15
combiner which must be tied together. As we loop through each
16
interrupt ID, if we find that it is the first one in one of these
17
lists, we configure the splitter device with eonugh extra outputs and
18
wire them up to the other interrupt IDs in the list.
19
20
Conveniently, for all the cases where this is necessary, the
21
lowest-numbered interrupt ID in each group is in the range of the
22
external combiner, so we only need to code for this in the first of
23
the two loops in exynos4210_init_board_irqs().
24
25
The old code in exynos4210_combiner_get_gpioin() which is being
26
deleted here had several problems which don't exist in the new code
27
in its handling of the multi-core timer interrupts:
28
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
29
exist; these should have been 4 ... 7
30
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
31
multiple times as the input of several different splitters,
32
which isn't allowed
33
(3) in an apparent cut-and-paste error, the cases for all the
34
multi-core timer inputs used "bit + 4" even though the
35
bit range for the case was (intended to be) 4 ... 7, which
36
meant it was looking at non-existent bits 8 ... 11.
37
None of these exist in the new code.
3
38
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
40
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-20-peter.maydell@linaro.org
41
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
7
---
42
---
8
target/arm/neon-dp.decode | 9 +++++++
43
include/hw/arm/exynos4210.h | 6 +-
9
target/arm/translate-neon.inc.c | 44 +++++++++++++++++++++++++++++++++
44
hw/arm/exynos4210.c | 178 +++++++++++++++++++++++-------------
10
target/arm/translate.c | 28 +++------------------
45
2 files changed, 119 insertions(+), 65 deletions(-)
11
3 files changed, 56 insertions(+), 25 deletions(-)
46
12
47
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
49
--- a/include/hw/arm/exynos4210.h
16
+++ b/target/arm/neon-dp.decode
50
+++ b/include/hw/arm/exynos4210.h
17
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
51
@@ -XXX,XX +XXX,XX @@
18
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
52
19
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
53
/*
20
54
* We need one splitter for every external combiner input, plus
21
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
55
- * one for every non-zero entry in combiner_grp_to_gic_id[].
22
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
56
+ * one for every non-zero entry in combiner_grp_to_gic_id[],
23
+
57
+ * minus one for every external combiner ID in second or later
24
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
58
+ * places in a combinermap[] line.
25
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
59
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
26
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
60
*/
27
@@ -XXX,XX +XXX,XX @@ VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
61
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
28
62
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
29
VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
63
30
VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
64
typedef struct Exynos4210Irq {
31
+
65
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
32
+VMLA_3s 1111 001 0 0 . .. .... .... 1001 . . . 0 .... @3same
66
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
33
+VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
34
+
35
+VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
36
+VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
68
--- a/hw/arm/exynos4210.c
40
+++ b/target/arm/translate-neon.inc.c
69
+++ b/hw/arm/exynos4210.c
41
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
70
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
42
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
71
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
43
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
72
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
44
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
73
45
+DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
74
+/*
46
75
+ * Some interrupt lines go to multiple combiner inputs.
47
#define DO_3SAME_CMP(INSN, COND) \
76
+ * This data structure defines those: each array element is
48
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
77
+ * a list of combiner inputs which are connected together;
49
@@ -XXX,XX +XXX,XX @@ DO_3SAME_GVEC4(VQADD_S, sqadd_op)
78
+ * the one with the smallest interrupt ID value must be first.
50
DO_3SAME_GVEC4(VQADD_U, uqadd_op)
79
+ * As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
51
DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
80
+ * wired to anything so we can use 0 as a terminator.
52
DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
81
+ */
53
+
82
+#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
54
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
83
+#define IRQNONE 0
55
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
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)
56
+{
113
+{
57
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
114
+ /*
58
+ 0, gen_helper_gvec_pmul_b);
115
+ * If the interrupt number passed in is the first entry in some
116
+ * line of the combinermap, return a pointer to that line;
117
+ * otherwise return NULL.
118
+ */
119
+ int i;
120
+ for (i = 0; i < COMBINERMAP_SIZE; i++) {
121
+ if (combinermap[i][0] == irq) {
122
+ return combinermap[i];
123
+ }
124
+ }
125
+ return NULL;
59
+}
126
+}
60
+
127
+
61
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
128
+static int mapline_size(const int *mapline)
62
+{
129
+{
63
+ if (a->size != 0) {
130
+ /* Return number of entries in this mapline in total */
64
+ return false;
131
+ int i = 0;
132
+
133
+ if (!mapline) {
134
+ /* Not in the map? IRQ goes to exactly one combiner input */
135
+ return 1;
65
+ }
136
+ }
66
+ return do_3same(s, a, gen_VMUL_p_3s);
137
+ while (*mapline != IRQNONE) {
138
+ mapline++;
139
+ i++;
140
+ }
141
+ return i;
67
+}
142
+}
68
+
143
+
69
+#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
144
/*
70
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
145
* Initialize board IRQs.
71
+ uint32_t rn_ofs, uint32_t rm_ofs, \
146
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
72
+ uint32_t oprsz, uint32_t maxsz) \
147
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
73
+ { \
148
DeviceState *extgicdev = DEVICE(&s->ext_gic);
74
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
149
int splitcount = 0;
75
+ oprsz, maxsz, &OPARRAY[vece]); \
150
DeviceState *splitter;
76
+ } \
151
+ const int *mapline;
77
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
152
+ int numlines, splitin, in;
78
+
153
79
+
154
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
80
+DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
155
irq_id = 0;
81
+DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
156
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
82
+
157
irq_id = EXT_GIC_ID_MCT_G1;
83
+#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
84
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
85
+ uint32_t rn_ofs, uint32_t rm_ofs, \
86
+ uint32_t oprsz, uint32_t maxsz) \
87
+ { \
88
+ /* Note the operation is vshl vd,vm,vn */ \
89
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
90
+ oprsz, maxsz, &OPARRAY[vece]); \
91
+ } \
92
+ DO_3SAME(INSN, gen_##INSN##_3s)
93
+
94
+DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
95
+DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
101
}
102
return 1;
103
104
- case NEON_3R_VMUL: /* VMUL */
105
- if (u) {
106
- /* Polynomial case allows only P8. */
107
- if (size != 0) {
108
- return 1;
109
- }
110
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
111
- 0, gen_helper_gvec_pmul_b);
112
- } else {
113
- tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
114
- vec_size, vec_size);
115
- }
116
- return 0;
117
-
118
- case NEON_3R_VML: /* VMLA, VMLS */
119
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
120
- u ? &mls_op[size] : &mla_op[size]);
121
- return 0;
122
-
123
- case NEON_3R_VSHL:
124
- /* Note the operation is vshl vd,vm,vn */
125
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
126
- u ? &ushl_op[size] : &sshl_op[size]);
127
- return 0;
128
-
129
case NEON_3R_VADD_VSUB:
130
case NEON_3R_LOGIC:
131
case NEON_3R_VMAX:
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
133
case NEON_3R_VCGE:
134
case NEON_3R_VQADD:
135
case NEON_3R_VQSUB:
136
+ case NEON_3R_VMUL:
137
+ case NEON_3R_VML:
138
+ case NEON_3R_VSHL:
139
/* Already handled by decodetree */
140
return 1;
141
}
158
}
159
160
+ if (s->irq_table[n]) {
161
+ /*
162
+ * This must be some non-first entry in a combinermap line,
163
+ * and we've already filled it in.
164
+ */
165
+ continue;
166
+ }
167
+ mapline = combinermap_entry(n);
168
+ /*
169
+ * We need to connect the IRQ to multiple inputs on both combiners
170
+ * and possibly also to the external GIC.
171
+ */
172
+ numlines = 2 * mapline_size(mapline);
173
+ if (irq_id) {
174
+ numlines++;
175
+ }
176
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
177
splitter = DEVICE(&s->splitter[splitcount]);
178
- qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
179
+ qdev_prop_set_uint16(splitter, "num-lines", numlines);
180
qdev_realize(splitter, NULL, &error_abort);
181
splitcount++;
182
- s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
183
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
184
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
185
+
186
+ in = n;
187
+ splitin = 0;
188
+ for (;;) {
189
+ s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
190
+ qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
191
+ qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
192
+ splitin += 2;
193
+ if (!mapline) {
194
+ break;
195
+ }
196
+ mapline++;
197
+ in = *mapline;
198
+ if (in == IRQNONE) {
199
+ break;
200
+ }
201
+ }
202
if (irq_id) {
203
- qdev_connect_gpio_out(splitter, 2,
204
+ qdev_connect_gpio_out(splitter, splitin,
205
qdev_get_gpio_in(extgicdev, irq_id - 32));
206
}
207
}
208
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
209
irq_id = combiner_grp_to_gic_id[grp -
210
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
211
212
+ if (s->irq_table[n]) {
213
+ /*
214
+ * This must be some non-first entry in a combinermap line,
215
+ * and we've already filled it in.
216
+ */
217
+ continue;
218
+ }
219
+
220
if (irq_id) {
221
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
222
splitter = DEVICE(&s->splitter[splitcount]);
223
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
224
DeviceState *dev, int ext)
225
{
226
int n;
227
- int bit;
228
int max;
229
qemu_irq *irq;
230
231
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
232
EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
233
irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
234
235
- /*
236
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
237
- * so let split them.
238
- */
239
for (n = 0; n < max; n++) {
240
-
241
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
242
-
243
- switch (n) {
244
- /* MDNIE_LCD1 INTG1 */
245
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
246
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
247
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
248
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
249
- continue;
250
-
251
- /* TMU INTG3 */
252
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
253
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
254
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
255
- continue;
256
-
257
- /* LCD1 INTG12 */
258
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
259
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
260
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
261
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
262
- continue;
263
-
264
- /* Multi-Core Timer INTG12 */
265
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
266
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
267
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
268
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
269
- continue;
270
-
271
- /* Multi-Core Timer INTG35 */
272
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
273
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
274
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
275
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
276
- continue;
277
-
278
- /* Multi-Core Timer INTG51 */
279
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
280
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
281
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
282
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
283
- continue;
284
-
285
- /* Multi-Core Timer INTG53 */
286
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
287
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
288
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
289
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
290
- continue;
291
- }
292
-
293
irq[n] = qdev_get_gpio_in(dev, n);
294
}
295
}
142
--
296
--
143
2.20.1
297
2.25.1
144
145
diff view generated by jsdifflib
1
Somewhere along theline we accidentally added a duplicate
1
Switch the creation of the combiner devices to the new-style
2
"using D16-D31 when they don't exist" check to do_vfm_dp()
2
"embedded in state struct" approach, so we can easily refer
3
(probably an artifact of a patchseries rebase). Remove it.
3
to the object elsewhere during realize.
4
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20220404154658.565020-18-peter.maydell@linaro.org
8
Message-id: 20200430181003.21682-2-peter.maydell@linaro.org
9
---
8
---
10
target/arm/translate-vfp.inc.c | 6 ------
9
include/hw/arm/exynos4210.h | 3 ++
11
1 file changed, 6 deletions(-)
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
12
15
13
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-vfp.inc.c
18
--- a/include/hw/arm/exynos4210.h
16
+++ b/target/arm/translate-vfp.inc.c
19
+++ b/include/hw/arm/exynos4210.h
17
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
20
@@ -XXX,XX +XXX,XX @@
18
return false;
21
#include "hw/sysbus.h"
22
#include "hw/cpu/a9mpcore.h"
23
#include "hw/intc/exynos4210_gic.h"
24
+#include "hw/intc/exynos4210_combiner.h"
25
#include "hw/core/split-irq.h"
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)
19
}
105
}
20
106
21
- /* UNDEF accesses to D16-D31 if they don't exist. */
107
/* Internal Interrupt Combiner */
22
- if (!dc_isar_feature(aa32_simd_r32, s) &&
108
- dev = qdev_new("exynos4210.combiner");
23
- ((a->vd | a->vn | a->vm) & 0x10)) {
109
- busdev = SYS_BUS_DEVICE(dev);
24
- return false;
110
- sysbus_realize_and_unref(busdev, &error_fatal);
25
- }
111
+ busdev = SYS_BUS_DEVICE(&s->int_combiner);
112
+ sysbus_realize(busdev, &error_fatal);
113
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
114
sysbus_connect_irq(busdev, n,
115
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
116
}
117
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
118
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
119
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
120
121
/* External Interrupt Combiner */
122
- dev = qdev_new("exynos4210.combiner");
123
- qdev_prop_set_uint32(dev, "external", 1);
124
- busdev = SYS_BUS_DEVICE(dev);
125
- sysbus_realize_and_unref(busdev, &error_fatal);
126
+ qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
127
+ busdev = SYS_BUS_DEVICE(&s->ext_combiner);
128
+ sysbus_realize(busdev, &error_fatal);
129
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
130
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
131
}
132
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
133
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
134
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
135
136
/* Initialize board IRQs. */
137
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
138
139
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
140
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
141
+ object_initialize_child(obj, "int-combiner", &s->int_combiner,
142
+ TYPE_EXYNOS4210_COMBINER);
143
+ object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
144
+ TYPE_EXYNOS4210_COMBINER);
145
}
146
147
static void exynos4210_class_init(ObjectClass *klass, void *data)
148
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/hw/intc/exynos4210_combiner.c
151
+++ b/hw/intc/exynos4210_combiner.c
152
@@ -XXX,XX +XXX,XX @@
153
#include "hw/sysbus.h"
154
#include "migration/vmstate.h"
155
#include "qemu/module.h"
26
-
156
-
27
if (!vfp_access_check(s)) {
157
+#include "hw/intc/exynos4210_combiner.h"
28
return true;
158
#include "hw/arm/exynos4210.h"
29
}
159
#include "hw/hw.h"
160
#include "hw/irq.h"
161
@@ -XXX,XX +XXX,XX @@
162
#define DPRINTF(fmt, ...) do {} while (0)
163
#endif
164
165
-#define IIC_NGRP 64 /* Internal Interrupt Combiner
166
- Groups number */
167
-#define IIC_NIRQ (IIC_NGRP * 8)/* Internal Interrupt Combiner
168
- Interrupts number */
169
#define IIC_REGION_SIZE 0x108 /* Size of memory mapped region */
170
-#define IIC_REGSET_SIZE 0x41
171
-
172
-/*
173
- * State for each output signal of internal combiner
174
- */
175
-typedef struct CombinerGroupState {
176
- uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
177
- uint8_t src_pending; /* Pending source interrupts before masking */
178
-} CombinerGroupState;
179
-
180
-#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
181
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
182
-
183
-struct Exynos4210CombinerState {
184
- SysBusDevice parent_obj;
185
-
186
- MemoryRegion iomem;
187
-
188
- struct CombinerGroupState group[IIC_NGRP];
189
- uint32_t reg_set[IIC_REGSET_SIZE];
190
- uint32_t icipsr[2];
191
- uint32_t external; /* 1 means that this combiner is external */
192
-
193
- qemu_irq output_irq[IIC_NGRP];
194
-};
195
196
static const VMStateDescription vmstate_exynos4210_combiner_group_state = {
197
.name = "exynos4210.combiner.groupstate",
30
--
198
--
31
2.20.1
199
2.25.1
32
33
diff view generated by jsdifflib
1
Convert the VFM[AS]L (vector) insns to decodetree. This is the last
1
The only time we use the int_combiner_irq[] and ext_combiner_irq[]
2
insn in the legacy decoder for the 3same_ext group, so we can
2
arrays in the Exynos4210Irq struct is during realize of the SoC -- we
3
delete the legacy decoder function for the group entirely.
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.
4
9
5
Note that in disas_thumb2_insn() the parts of this encoding space
10
Since these are the only two remaining elements of Exynos4210Irq,
6
where the decodetree decoder returns false will correctly be directed
11
we can remove that struct entirely.
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
9
12
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-8-peter.maydell@linaro.org
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
13
---
16
---
14
target/arm/neon-shared.decode | 6 +++
17
include/hw/arm/exynos4210.h | 6 ------
15
target/arm/translate-neon.inc.c | 31 +++++++++++
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
16
target/arm/translate.c | 92 +--------------------------------
19
2 files changed, 8 insertions(+), 32 deletions(-)
17
3 files changed, 38 insertions(+), 91 deletions(-)
18
20
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
20
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
23
--- a/include/hw/arm/exynos4210.h
22
+++ b/target/arm/neon-shared.decode
24
+++ b/include/hw/arm/exynos4210.h
23
@@ -XXX,XX +XXX,XX @@ VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
25
@@ -XXX,XX +XXX,XX @@
24
# VUDOT and VSDOT
26
*/
25
VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
28
27
+
29
-typedef struct Exynos4210Irq {
28
+# VFM[AS]L
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
29
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
30
+ vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
32
-} Exynos4210Irq;
31
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
33
-
32
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
34
struct Exynos4210State {
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
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
34
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
45
--- a/hw/arm/exynos4210.c
36
+++ b/target/arm/translate-neon.inc.c
46
+++ b/hw/arm/exynos4210.c
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
38
opr_sz, opr_sz, 0, fn_gvec);
48
static void exynos4210_init_board_irqs(Exynos4210State *s)
39
return true;
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);
40
}
87
}
41
+
88
42
+static bool trans_VFML(DisasContext *s, arg_VFML *a)
89
-/*
43
+{
90
- * Get Combiner input GPIO into irqs structure
44
+ int opr_sz;
45
+
46
+ if (!dc_isar_feature(aa32_fhm, s)) {
47
+ return false;
48
+ }
49
+
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
52
+ (a->vd & 0x10)) {
53
+ return false;
54
+ }
55
+
56
+ if (a->vd & a->q) {
57
+ return false;
58
+ }
59
+
60
+ if (!vfp_access_check(s)) {
61
+ return true;
62
+ }
63
+
64
+ opr_sz = (1 + a->q) * 8;
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(a->q, a->vn),
67
+ vfp_reg_offset(a->q, a->vm),
68
+ cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */
69
+ gen_helper_gvec_fmlal_a32);
70
+ return true;
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
return 0;
78
}
79
80
-/* Advanced SIMD three registers of the same length extension.
81
- * 31 25 23 22 20 16 12 11 10 9 8 3 0
82
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
83
- * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
84
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
85
- */
91
- */
86
-static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
93
- DeviceState *dev, int ext)
87
-{
94
-{
88
- gen_helper_gvec_3 *fn_gvec = NULL;
95
- int n;
89
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
96
- int max;
90
- int rd, rn, rm, opr_sz;
97
- qemu_irq *irq;
91
- int data = 0;
92
- int off_rn, off_rm;
93
- bool is_long = false, q = extract32(insn, 6, 1);
94
- bool ptr_is_env = false;
95
-
98
-
96
- if ((insn & 0xff300f10) == 0xfc200810) {
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
97
- /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
98
- int is_s = extract32(insn, 23, 1);
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
99
- if (!dc_isar_feature(aa32_fhm, s)) {
102
-
100
- return 1;
103
- for (n = 0; n < max; n++) {
101
- }
104
- irq[n] = qdev_get_gpio_in(dev, n);
102
- is_long = true;
103
- data = is_s; /* is_2 == 0 */
104
- fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
105
- ptr_is_env = true;
106
- } else {
107
- return 1;
108
- }
105
- }
109
-
110
- VFP_DREG_D(rd, insn);
111
- if (rd & q) {
112
- return 1;
113
- }
114
- if (q || !is_long) {
115
- VFP_DREG_N(rn, insn);
116
- VFP_DREG_M(rm, insn);
117
- if ((rn | rm) & q & !is_long) {
118
- return 1;
119
- }
120
- off_rn = vfp_reg_offset(1, rn);
121
- off_rm = vfp_reg_offset(1, rm);
122
- } else {
123
- rn = VFP_SREG_N(insn);
124
- rm = VFP_SREG_M(insn);
125
- off_rn = vfp_reg_offset(0, rn);
126
- off_rm = vfp_reg_offset(0, rm);
127
- }
128
-
129
- if (s->fp_excp_el) {
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
131
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
132
- return 0;
133
- }
134
- if (!s->vfp_enabled) {
135
- return 1;
136
- }
137
-
138
- opr_sz = (1 + q) * 8;
139
- if (fn_gvec_ptr) {
140
- TCGv_ptr ptr;
141
- if (ptr_is_env) {
142
- ptr = cpu_env;
143
- } else {
144
- ptr = get_fpstatus_ptr(1);
145
- }
146
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
147
- opr_sz, opr_sz, data, fn_gvec_ptr);
148
- if (!ptr_is_env) {
149
- tcg_temp_free_ptr(ptr);
150
- }
151
- } else {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
153
- opr_sz, opr_sz, data, fn_gvec);
154
- }
155
- return 0;
156
-}
106
-}
157
-
107
-
158
/* Advanced SIMD two registers and a scalar extension.
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
159
* 31 24 23 22 20 16 12 11 10 9 8 3 0
109
0x09, 0x00, 0x00, 0x00 };
160
* +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
110
161
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
162
}
112
sysbus_connect_irq(busdev, n,
163
}
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
164
}
114
}
165
- } else if ((insn & 0x0e000a00) == 0x0c000800
115
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
166
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
116
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
167
- if (disas_neon_insn_3same_ext(s, insn)) {
117
168
- goto illegal_op;
118
/* External Interrupt Combiner */
169
- }
119
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
170
- return;
120
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
171
} else if ((insn & 0x0f000a00) == 0x0e000800
121
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
172
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
122
}
173
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
123
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
174
@@ -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);
175
}
125
176
break;
126
/* Initialize board IRQs. */
177
}
178
- if ((insn & 0xfe000a00) == 0xfc000800
179
+ if ((insn & 0xff000a00) == 0xfe000800
180
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
181
/* The Thumb2 and ARM encodings are identical. */
182
- if (disas_neon_insn_3same_ext(s, insn)) {
183
- goto illegal_op;
184
- }
185
- } else if ((insn & 0xff000a00) == 0xfe000800
186
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
187
- /* The Thumb2 and ARM encodings are identical. */
188
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
189
goto illegal_op;
190
}
191
--
127
--
192
2.20.1
128
2.25.1
193
194
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
Embed the UARTs into the SoC type.
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-5-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
7
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
14
hw/arm/xlnx-versal.c | 12 ++++++------
9
1 file changed, 24 insertions(+), 9 deletions(-)
15
2 files changed, 8 insertions(+), 7 deletions(-)
16
10
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
13
--- a/hw/arm/realview.c
20
+++ b/include/hw/arm/xlnx-versal.h
14
+++ b/hw/arm/realview.c
21
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@
22
#include "hw/sysbus.h"
16
#include "hw/sysbus.h"
23
#include "hw/arm/boot.h"
17
#include "hw/arm/boot.h"
24
#include "hw/intc/arm_gicv3.h"
18
#include "hw/arm/primecell.h"
25
+#include "hw/char/pl011.h"
19
+#include "hw/core/split-irq.h"
26
20
#include "hw/net/lan9118.h"
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
21
#include "hw/net/smc91c111.h"
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
22
#include "hw/pci/pci.h"
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
23
+#include "hw/qdev-core.h"
30
MemoryRegion mr_ocm;
24
#include "net/net.h"
31
25
#include "sysemu/sysemu.h"
32
struct {
26
#include "hw/boards.h"
33
- SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
27
@@ -XXX,XX +XXX,XX @@ static const int realview_board_id[] = {
34
+ PL011State uart[XLNX_VERSAL_NR_UARTS];
28
0x76d
35
SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
29
};
36
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
30
37
} iou;
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
32
+ qemu_irq out1, qemu_irq out2) {
39
index XXXXXXX..XXXXXXX 100644
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
40
--- a/hw/arm/xlnx-versal.c
34
+
41
+++ b/hw/arm/xlnx-versal.c
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
42
@@ -XXX,XX +XXX,XX @@
36
+
43
#include "kvm_arm.h"
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
44
#include "hw/misc/unimp.h"
38
+
45
#include "hw/arm/xlnx-versal.h"
39
+ qdev_connect_gpio_out(splitter, 0, out1);
46
-#include "hw/char/pl011.h"
40
+ qdev_connect_gpio_out(splitter, 1, out2);
47
41
+ qdev_connect_gpio_out_named(src, outname, 0,
48
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
42
+ qdev_get_gpio_in(splitter, 0));
49
#define GEM_REVISION 0x40070106
43
+}
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
44
+
51
DeviceState *dev;
45
static void realview_init(MachineState *machine,
52
MemoryRegion *mr;
46
enum realview_board_type board_type)
53
47
{
54
- dev = qdev_create(NULL, TYPE_PL011);
48
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
55
- s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
49
DeviceState *dev, *sysctl, *gpio2, *pl041;
56
+ sysbus_init_child_obj(OBJECT(s), name,
50
SysBusDevice *busdev;
57
+ &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]),
51
qemu_irq pic[64];
58
+ TYPE_PL011);
52
- qemu_irq mmc_irq[2];
59
+ dev = DEVICE(&s->lpd.iou.uart[i]);
53
PCIBus *pci_bus = NULL;
60
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
54
NICInfo *nd;
61
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
55
DriveInfo *dinfo;
62
qdev_init_nofail(dev);
56
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
63
57
* and the PL061 has them the other way about. Also the card
64
- mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
58
* detect line is inverted.
65
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
59
*/
66
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
60
- mmc_irq[0] = qemu_irq_split(
67
61
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
68
- sysbus_connect_irq(s->lpd.iou.uart[i], 0, pic[irqs[i]]);
62
- qdev_get_gpio_in(gpio2, 1));
69
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
63
- mmc_irq[1] = qemu_irq_split(
70
g_free(name);
64
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
71
}
65
- qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
72
}
66
- qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
67
- qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_irq[1]);
68
+ split_irq_from_named(dev, "card-read-only",
69
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
70
+ qdev_get_gpio_in(gpio2, 1));
71
+
72
+ split_irq_from_named(dev, "card-inserted",
73
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
74
+ qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
75
+
76
dinfo = drive_get(IF_SD, 0, 0);
77
if (dinfo) {
78
DeviceState *card;
73
--
79
--
74
2.20.1
80
2.25.1
75
76
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
MIDR_EL1 is a 64-bit system register with the top 32-bit being RES0.
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
Represent it in QEMU's ARMCPU struct with a uint64_t, not a
5
uint32_t.
6
7
This fixes an error when compiling with -Werror=conversion
8
because we were manipulating the register value using a
9
local uint64_t variable:
10
11
target/arm/cpu64.c: In function ‘aarch64_max_initfn’:
12
target/arm/cpu64.c:628:21: error: conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘uint32_t’ {aka ‘unsigned int’} may change value [-Werror=conversion]
13
628 | cpu->midr = t;
14
| ^
15
16
and future-proofs us against a possible future architecture
17
change using some of the top 32 bits.
18
19
Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
20
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
23
Message-id: 20200428172634.29707-1-f4bug@amsat.org
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
7
---
27
target/arm/cpu.h | 2 +-
8
hw/arm/stellaris.c | 15 +++++++++++++--
28
target/arm/cpu.c | 2 +-
9
1 file changed, 13 insertions(+), 2 deletions(-)
29
2 files changed, 2 insertions(+), 2 deletions(-)
30
10
31
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
32
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
13
--- a/hw/arm/stellaris.c
34
+++ b/target/arm/cpu.h
14
+++ b/hw/arm/stellaris.c
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
15
@@ -XXX,XX +XXX,XX @@
36
uint64_t id_aa64dfr0;
16
37
uint64_t id_aa64dfr1;
17
#include "qemu/osdep.h"
38
} isar;
18
#include "qapi/error.h"
39
- uint32_t midr;
19
+#include "hw/core/split-irq.h"
40
+ uint64_t midr;
20
#include "hw/sysbus.h"
41
uint32_t revidr;
21
#include "hw/sd/sd.h"
42
uint32_t reset_fpsid;
22
#include "hw/ssi/ssi.h"
43
uint32_t ctr;
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
24
DeviceState *ssddev;
45
index XXXXXXX..XXXXXXX 100644
25
DriveInfo *dinfo;
46
--- a/target/arm/cpu.c
26
DeviceState *carddev;
47
+++ b/target/arm/cpu.c
27
+ DeviceState *gpio_d_splitter;
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
28
BlockBackend *blk;
49
static Property arm_cpu_properties[] = {
29
50
DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
30
/*
51
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
52
- DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
32
&error_fatal);
53
+ DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
33
54
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
34
ssddev = ssi_create_peripheral(bus, "ssd0323");
55
mp_affinity, ARM64_AFFINITY_INVALID),
35
- gpio_out[GPIO_D][0] = qemu_irq_split(
56
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
36
- qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
37
+
38
+ gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
39
+ qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
40
+ qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
41
+ qdev_connect_gpio_out(
42
+ gpio_d_splitter, 0,
43
+ qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0));
44
+ qdev_connect_gpio_out(
45
+ gpio_d_splitter, 1,
46
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
47
+ gpio_out[GPIO_D][0] = qdev_get_gpio_in(gpio_d_splitter, 0);
48
+
49
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
50
51
/* Make sure the select pin is high. */
57
--
52
--
58
2.20.1
53
2.25.1
59
60
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
Add support for the RTC.
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20200427181649.26851-12-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
8
---
11
hw/arm/xlnx-versal-virt.c | 22 ++++++++++++++++++++++
9
include/hw/irq.h | 5 -----
12
1 file changed, 22 insertions(+)
10
hw/core/irq.c | 15 ---------------
11
2 files changed, 20 deletions(-)
13
12
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
15
--- a/include/hw/irq.h
17
+++ b/hw/arm/xlnx-versal-virt.c
16
+++ b/include/hw/irq.h
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_sd_nodes(VersalVirt *s)
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
19
}
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);
20
}
35
}
21
36
22
+static void fdt_add_rtc_node(VersalVirt *s)
37
-static void qemu_splitirq(void *opaque, int line, int level)
23
+{
38
-{
24
+ const char compat[] = "xlnx,zynqmp-rtc";
39
- struct IRQState **irq = opaque;
25
+ const char interrupt_names[] = "alarm\0sec";
40
- irq[0]->handler(irq[0]->opaque, irq[0]->n, level);
26
+ char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
41
- irq[1]->handler(irq[1]->opaque, irq[1]->n, level);
27
+
42
-}
28
+ qemu_fdt_add_subnode(s->fdt, name);
43
-
29
+
44
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
30
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
45
-{
31
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_ALARM_IRQ,
46
- qemu_irq *s = g_new0(qemu_irq, 2);
32
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI,
47
- s[0] = irq1;
33
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_SECONDS_IRQ,
48
- s[1] = irq2;
34
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
49
- return qemu_allocate_irq(qemu_splitirq, s, 0);
35
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
50
-}
36
+ interrupt_names, sizeof(interrupt_names));
51
-
37
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
52
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
38
+ 2, MM_PMC_RTC, 2, MM_PMC_RTC_SIZE);
39
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
40
+ g_free(name);
41
+}
42
+
43
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
44
{
53
{
45
Error *err = NULL;
54
int i;
46
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
47
fdt_add_timer_nodes(s);
48
fdt_add_zdma_nodes(s);
49
fdt_add_sd_nodes(s);
50
+ fdt_add_rtc_node(s);
51
fdt_add_cpu_nodes(s, psci_conduit);
52
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
53
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
54
--
55
--
55
2.20.1
56
2.25.1
56
57
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
2
2
3
By using the TYPE_* definitions for devices, we can:
3
Describe that the gic-version influences the maximum number of CPUs.
4
- quickly find where devices are used with 'git-grep'
5
- easily rename a device (one-line change).
6
4
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
8
Message-id: 20200428154650.21991-1-f4bug@amsat.org
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
7
[PMM: minor punctuation tweaks]
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/arm/mps2-tz.c | 2 +-
11
docs/system/arm/virt.rst | 4 ++--
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
14
13
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
16
--- a/docs/system/arm/virt.rst
18
+++ b/hw/arm/mps2-tz.c
17
+++ b/docs/system/arm/virt.rst
19
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
18
@@ -XXX,XX +XXX,XX @@ gic-version
20
exit(EXIT_FAILURE);
19
Valid values are:
21
}
20
22
21
``2``
23
- sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
22
- GICv2
24
+ sysbus_init_child_obj(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
23
+ GICv2. Note that this limits the number of CPUs to 8.
25
sizeof(mms->iotkit), mmc->armsse_type);
24
``3``
26
iotkitdev = DEVICE(&mms->iotkit);
25
- GICv3
27
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
26
+ GICv3. This allows up to 512 CPUs.
27
``host``
28
Use the same GIC version the host provides, when using KVM
29
``max``
28
--
30
--
29
2.20.1
31
2.25.1
30
31
diff view generated by jsdifflib
1
From: Fredrik Strupe <fredrik@strupe.net>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
According to Arm ARM, VQDMULL is only valid when U=0, while having
3
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
4
U=1 is unallocated.
4
the PWRON STRAP fields in their corresponding module for NPCM7XX.
5
5
6
Signed-off-by: Fredrik Strupe <fredrik@strupe.net>
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
7
Fixes: 695272dcb976 ("target-arm: Handle UNDEF cases for Neon 3-regs-different-widths")
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Message-id: 20220411165842.3912945-2-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 | 2 +-
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 30 insertions(+)
13
14
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
17
--- a/include/hw/misc/npcm7xx_gcr.h
17
+++ b/target/arm/translate.c
18
+++ b/include/hw/misc/npcm7xx_gcr.h
18
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@
19
{0, 0, 0, 0}, /* VMLSL */
20
#include "exec/memory.h"
20
{0, 0, 0, 9}, /* VQDMLSL */
21
#include "hw/sysbus.h"
21
{0, 0, 0, 0}, /* Integer VMULL */
22
22
- {0, 0, 0, 1}, /* VQDMULL */
23
+/*
23
+ {0, 0, 0, 9}, /* VQDMULL */
24
+ * NPCM7XX PWRON STRAP bit fields
24
{0, 0, 0, 0xa}, /* Polynomial VMULL */
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
25
{0, 0, 0, 7}, /* Reserved: always UNDEF */
26
+ * 11: System flash attached to BMC
26
};
27
+ * 10: BSP alternative pins.
28
+ * 9:8: Flash UART command route enabled.
29
+ * 7: Security enabled.
30
+ * 6: HI-Z state control.
31
+ * 5: ECC disabled.
32
+ * 4: Reserved
33
+ * 3: JTAG2 enabled.
34
+ * 2:0: CPU and DRAM clock frequency.
35
+ */
36
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
37
+#define NPCM7XX_PWRON_STRAP_SFAB BIT(11)
38
+#define NPCM7XX_PWRON_STRAP_BSPA BIT(10)
39
+#define NPCM7XX_PWRON_STRAP_FUP(x) ((x) << 8)
40
+#define FUP_NORM_UART2 3
41
+#define FUP_PROG_UART3 2
42
+#define FUP_PROG_UART2 1
43
+#define FUP_NORM_UART3 0
44
+#define NPCM7XX_PWRON_STRAP_SECEN BIT(7)
45
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
46
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
47
+#define NPCM7XX_PWRON_STRAP_RESERVE1 BIT(4)
48
+#define NPCM7XX_PWRON_STRAP_J2EN BIT(3)
49
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x) (x)
50
+#define CKFRQ_SKIPINIT 0x000
51
+#define CKFRQ_DEFAULT 0x111
52
+
53
/*
54
* Number of registers in our device state structure. Don't change this without
55
* incrementing the version_id in the vmstate.
27
--
56
--
28
2.20.1
57
2.25.1
29
30
diff view generated by jsdifflib
Deleted patch
1
The access_type argument to get_phys_addr_lpae() is an MMUAccessType;
2
use the enum constant MMU_DATA_LOAD rather than a literal 0 when we
3
call it in S1_ptw_translate().
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200330210400.11724-3-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 5 +++--
11
1 file changed, 3 insertions(+), 2 deletions(-)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
18
pcacheattrs = &cacheattrs;
19
}
20
21
- ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_Stage2, &s2pa,
22
- &txattrs, &s2prot, &s2size, fi, pcacheattrs);
23
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
24
+ &s2pa, &txattrs, &s2prot, &s2size, fi,
25
+ pcacheattrs);
26
if (ret) {
27
assert(fi->type != ARMFault_None);
28
fi->s2addr = addr;
29
--
30
2.20.1
31
32
diff view generated by jsdifflib
Deleted patch
1
For ARMv8.2-TTS2UXN, the stage 2 page table walk wants to know
2
whether the stage 1 access is for EL0 or not, because whether
3
exec permission is given can depend on whether this is an EL0
4
or EL1 access. Add a new argument to get_phys_addr_lpae() so
5
the call sites can pass this information in.
6
1
7
Since get_phys_addr_lpae() doesn't already have a doc comment,
8
add one so we have a place to put the documentation of the
9
semantics of the new s1_is_el0 argument.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200330210400.11724-4-peter.maydell@linaro.org
15
---
16
target/arm/helper.c | 29 ++++++++++++++++++++++++++++-
17
1 file changed, 28 insertions(+), 1 deletion(-)
18
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@
24
25
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
27
+ bool s1_is_el0,
28
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
29
target_ulong *page_size_ptr,
30
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
31
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
32
}
33
34
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
35
+ false,
36
&s2pa, &txattrs, &s2prot, &s2size, fi,
37
pcacheattrs);
38
if (ret) {
39
@@ -XXX,XX +XXX,XX @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
40
};
41
}
42
43
+/**
44
+ * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
45
+ *
46
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
47
+ * prot and page_size may not be filled in, and the populated fsr value provides
48
+ * information on why the translation aborted, in the format of a long-format
49
+ * DFSR/IFSR fault register, with the following caveats:
50
+ * * the WnR bit is never set (the caller must do this).
51
+ *
52
+ * @env: CPUARMState
53
+ * @address: virtual address to get physical address for
54
+ * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
55
+ * @mmu_idx: MMU index indicating required translation regime
56
+ * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page table
57
+ * walk), must be true if this is stage 2 of a stage 1+2 walk for an
58
+ * EL0 access). If @mmu_idx is anything else, @s1_is_el0 is ignored.
59
+ * @phys_ptr: set to the physical address corresponding to the virtual address
60
+ * @attrs: set to the memory transaction attributes to use
61
+ * @prot: set to the permissions for the page containing phys_ptr
62
+ * @page_size_ptr: set to the size of the page containing phys_ptr
63
+ * @fi: set to fault info if the translation fails
64
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
65
+ */
66
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
67
MMUAccessType access_type, ARMMMUIdx mmu_idx,
68
+ bool s1_is_el0,
69
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
70
target_ulong *page_size_ptr,
71
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
73
74
/* S1 is done. Now do S2 translation. */
75
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
76
+ mmu_idx == ARMMMUIdx_E10_0,
77
phys_ptr, attrs, &s2_prot,
78
page_size, fi,
79
cacheattrs != NULL ? &cacheattrs2 : NULL);
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
81
}
82
83
if (regime_using_lpae_format(env, mmu_idx)) {
84
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
85
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
86
phys_ptr, attrs, prot, page_size,
87
fi, cacheattrs);
88
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
89
--
90
2.20.1
91
92
diff view generated by jsdifflib
Deleted patch
1
In aarch64_max_initfn() we update both 32-bit and 64-bit ID
2
registers. The intended pattern is that for 64-bit ID registers we
3
use FIELD_DP64 and the uint64_t 't' register, while 32-bit ID
4
registers use FIELD_DP32 and the uint32_t 'u' register. For
5
ID_AA64DFR0 we accidentally used 'u', meaning that the top 32 bits of
6
this 64-bit ID register would end up always zero. Luckily at the
7
moment that's what they should be anyway, so this bug has no visible
8
effects.
9
1
10
Use the right-sized variable.
11
12
Fixes: 3bec78447a958d481991
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200423110915.10527-1-peter.maydell@linaro.org
17
---
18
target/arm/cpu64.c | 6 +++---
19
1 file changed, 3 insertions(+), 3 deletions(-)
20
21
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu64.c
24
+++ b/target/arm/cpu64.c
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
26
u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
27
cpu->isar.id_mmfr4 = u;
28
29
- u = cpu->isar.id_aa64dfr0;
30
- u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
31
- cpu->isar.id_aa64dfr0 = u;
32
+ t = cpu->isar.id_aa64dfr0;
33
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
34
+ cpu->isar.id_aa64dfr0 = t;
35
36
u = cpu->isar.id_dfr0;
37
u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
38
--
39
2.20.1
40
41
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
Remove inclusion of arm_gicv3_common.h, this already gets
3
This patch uses the defined fields to describe PWRON STRAPs for
4
included via xlnx-versal.h.
4
better readability.
5
5
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20220411165842.3912945-3-wuhaotsh@google.com
9
Message-id: 20200427181649.26851-2-edgar.iglesias@gmail.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/arm/xlnx-versal.c | 1 -
12
hw/arm/npcm7xx_boards.c | 24 +++++++++++++++++++-----
13
1 file changed, 1 deletion(-)
13
1 file changed, 19 insertions(+), 5 deletions(-)
14
14
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
17
--- a/hw/arm/npcm7xx_boards.c
18
+++ b/hw/arm/xlnx-versal.c
18
+++ b/hw/arm/npcm7xx_boards.c
19
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
20
#include "hw/arm/boot.h"
20
#include "sysemu/sysemu.h"
21
#include "kvm_arm.h"
21
#include "sysemu/block-backend.h"
22
#include "hw/misc/unimp.h"
22
23
-#include "hw/intc/arm_gicv3_common.h"
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
24
#include "hw/arm/xlnx-versal.h"
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
25
#include "hw/char/pl011.h"
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
27
-#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
28
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT ( \
29
+ NPCM7XX_PWRON_STRAP_SPI0F18 | \
30
+ NPCM7XX_PWRON_STRAP_SFAB | \
31
+ NPCM7XX_PWRON_STRAP_BSPA | \
32
+ NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) | \
33
+ NPCM7XX_PWRON_STRAP_SECEN | \
34
+ NPCM7XX_PWRON_STRAP_HIZ | \
35
+ NPCM7XX_PWRON_STRAP_ECC | \
36
+ NPCM7XX_PWRON_STRAP_RESERVE1 | \
37
+ NPCM7XX_PWRON_STRAP_J2EN | \
38
+ NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))
39
+
40
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
41
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_J2EN)
42
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
43
+#define QUANTA_GBS_POWER_ON_STRAPS ( \
44
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_SFAB)
45
+#define KUDO_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
46
+#define MORI_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
47
48
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
26
49
27
--
50
--
28
2.20.1
51
2.25.1
29
30
diff view generated by jsdifflib
Deleted patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
1
3
Move misplaced comment.
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-3-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/xlnx-versal.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
18
+++ b/hw/arm/xlnx-versal.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
20
21
obj = object_new(XLNX_VERSAL_ACPU_TYPE);
22
if (!obj) {
23
- /* Secondary CPUs start in PSCI powered-down state */
24
error_report("Unable to create apu.cpu[%d] of type %s",
25
i, XLNX_VERSAL_ACPU_TYPE);
26
exit(EXIT_FAILURE);
27
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
28
object_property_set_int(obj, s->cfg.psci_conduit,
29
"psci-conduit", &error_abort);
30
if (i) {
31
+ /* Secondary CPUs start in PSCI powered-down state */
32
object_property_set_bool(obj, true,
33
"start-powered-off", &error_abort);
34
}
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
1
3
Fix typo xlnx-ve -> xlnx-versal.
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-4-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/xlnx-versal-virt.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal-virt.c
18
+++ b/hw/arm/xlnx-versal-virt.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
20
psci_conduit = QEMU_PSCI_CONDUIT_SMC;
21
}
22
23
- sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
24
+ sysbus_init_child_obj(OBJECT(machine), "xlnx-versal", &s->soc,
25
sizeof(s->soc), TYPE_XLNX_VERSAL);
26
object_property_set_link(OBJECT(&s->soc), OBJECT(machine->ram),
27
"ddr", &error_abort);
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
Deleted patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
1
3
Embed the GEMs into the SoC type.
4
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-6-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
14
hw/arm/xlnx-versal.c | 15 ++++++++-------
15
2 files changed, 10 insertions(+), 8 deletions(-)
16
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
20
+++ b/include/hw/arm/xlnx-versal.h
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/arm/boot.h"
23
#include "hw/intc/arm_gicv3.h"
24
#include "hw/char/pl011.h"
25
+#include "hw/net/cadence_gem.h"
26
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
31
struct {
32
PL011State uart[XLNX_VERSAL_NR_UARTS];
33
- SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
34
+ CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
35
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
36
} iou;
37
} lpd;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
43
DeviceState *dev;
44
MemoryRegion *mr;
45
46
- dev = qdev_create(NULL, "cadence_gem");
47
- s->lpd.iou.gem[i] = SYS_BUS_DEVICE(dev);
48
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
49
+ sysbus_init_child_obj(OBJECT(s), name,
50
+ &s->lpd.iou.gem[i], sizeof(s->lpd.iou.gem[i]),
51
+ TYPE_CADENCE_GEM);
52
+ dev = DEVICE(&s->lpd.iou.gem[i]);
53
if (nd->used) {
54
qemu_check_nic_model(nd, "cadence_gem");
55
qdev_set_nic_properties(dev, nd);
56
}
57
- object_property_set_int(OBJECT(s->lpd.iou.gem[i]),
58
+ object_property_set_int(OBJECT(dev),
59
2, "num-priority-queues",
60
&error_abort);
61
- object_property_set_link(OBJECT(s->lpd.iou.gem[i]),
62
+ object_property_set_link(OBJECT(dev),
63
OBJECT(&s->mr_ps), "dma",
64
&error_abort);
65
qdev_init_nofail(dev);
66
67
- mr = sysbus_mmio_get_region(s->lpd.iou.gem[i], 0);
68
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
69
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
70
71
- sysbus_connect_irq(s->lpd.iou.gem[i], 0, pic[irqs[i]]);
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
73
g_free(name);
74
}
75
}
76
--
77
2.20.1
78
79
diff view generated by jsdifflib
Deleted patch
1
We were accidentally permitting decode of Thumb Neon insns even if
2
the CPU didn't have the FEATURE_NEON bit set, because the feature
3
check was being done before the call to disas_neon_data_insn() and
4
disas_neon_ls_insn() in the Arm decoder but was omitted from the
5
Thumb decoder. Push the feature bit check down into the called
6
functions so it is done for both Arm and Thumb encodings.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200430181003.21682-3-peter.maydell@linaro.org
12
---
13
target/arm/translate.c | 16 ++++++++--------
14
1 file changed, 8 insertions(+), 8 deletions(-)
15
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
19
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
21
TCGv_i32 tmp2;
22
TCGv_i64 tmp64;
23
24
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
25
+ return 1;
26
+ }
27
+
28
/* FIXME: this access check should not take precedence over UNDEF
29
* for invalid encodings; we will generate incorrect syndrome information
30
* for attempts to execute invalid vfp/neon encodings with FP disabled.
31
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
32
TCGv_ptr ptr1, ptr2, ptr3;
33
TCGv_i64 tmp64;
34
35
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
36
+ return 1;
37
+ }
38
+
39
/* FIXME: this access check should not take precedence over UNDEF
40
* for invalid encodings; we will generate incorrect syndrome information
41
* for attempts to execute invalid vfp/neon encodings with FP disabled.
42
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
43
44
if (((insn >> 25) & 7) == 1) {
45
/* NEON Data processing. */
46
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
47
- goto illegal_op;
48
- }
49
-
50
if (disas_neon_data_insn(s, insn)) {
51
goto illegal_op;
52
}
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
54
}
55
if ((insn & 0x0f100000) == 0x04000000) {
56
/* NEON load/store. */
57
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
58
- goto illegal_op;
59
- }
60
-
61
if (disas_neon_ls_insn(s, insn)) {
62
goto illegal_op;
63
}
64
--
65
2.20.1
66
67
diff view generated by jsdifflib
Deleted patch
1
Convert the VCMLA (vector) insns in the 3same extension group to
2
decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-5-peter.maydell@linaro.org
7
---
8
target/arm/neon-shared.decode | 11 ++++++++++
9
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 11 +---------
11
3 files changed, 49 insertions(+), 10 deletions(-)
12
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@
18
# More specifically, this covers:
19
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
20
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
21
+
22
+# VFP/Neon register fields; same as vfp.decode
23
+%vm_dp 5:1 0:4
24
+%vm_sp 0:4 5:1
25
+%vn_dp 7:1 16:4
26
+%vn_sp 16:4 7:1
27
+%vd_dp 22:1 12:4
28
+%vd_sp 12:4 22:1
29
+
30
+VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
31
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
32
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.inc.c
35
+++ b/target/arm/translate-neon.inc.c
36
@@ -XXX,XX +XXX,XX @@
37
#include "decode-neon-dp.inc.c"
38
#include "decode-neon-ls.inc.c"
39
#include "decode-neon-shared.inc.c"
40
+
41
+static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
42
+{
43
+ int opr_sz;
44
+ TCGv_ptr fpst;
45
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
46
+
47
+ if (!dc_isar_feature(aa32_vcma, s)
48
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
49
+ return false;
50
+ }
51
+
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
54
+ ((a->vd | a->vn | a->vm) & 0x10)) {
55
+ return false;
56
+ }
57
+
58
+ if ((a->vn | a->vm | a->vd) & a->q) {
59
+ return false;
60
+ }
61
+
62
+ if (!vfp_access_check(s)) {
63
+ return true;
64
+ }
65
+
66
+ opr_sz = (1 + a->q) * 8;
67
+ fpst = get_fpstatus_ptr(1);
68
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
69
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
70
+ vfp_reg_offset(1, a->vn),
71
+ vfp_reg_offset(1, a->vm),
72
+ fpst, opr_sz, opr_sz, a->rot,
73
+ fn_gvec_ptr);
74
+ tcg_temp_free_ptr(fpst);
75
+ return true;
76
+}
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate.c
80
+++ b/target/arm/translate.c
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
82
bool is_long = false, q = extract32(insn, 6, 1);
83
bool ptr_is_env = false;
84
85
- if ((insn & 0xfe200f10) == 0xfc200800) {
86
- /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
87
- int size = extract32(insn, 20, 1);
88
- data = extract32(insn, 23, 2); /* rot */
89
- if (!dc_isar_feature(aa32_vcma, s)
90
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
91
- return 1;
92
- }
93
- fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
94
- } else if ((insn & 0xfea00f10) == 0xfc800800) {
95
+ if ((insn & 0xfea00f10) == 0xfc800800) {
96
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
97
int size = extract32(insn, 20, 1);
98
data = extract32(insn, 24, 1); /* rot */
99
--
100
2.20.1
101
102
diff view generated by jsdifflib