1
target-arm queue: mostly just cleanup/minor stuff, but this does
1
First arm pullreq for 7.1. The bulk of this is the qemu_split_irq
2
include the raspi3 board model.
2
removal.
3
3
4
I have enough stuff in my to-review queue that I expect to do another
5
pullreq early next week, but 31 patches is enough to not hang on to.
6
7
thanks
4
-- PMM
8
-- PMM
5
9
6
The following changes since commit 9f9c53368b219a9115eddb39f0ff5ad19c977134:
10
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
7
11
8
Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-2.12-pull-request' into staging (2018-02-15 10:14:11 +0000)
12
Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700)
9
13
10
are available in the Git repository at:
14
are available in the Git repository at:
11
15
12
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180215
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220421
13
17
14
for you to fetch changes up to e545f0f9be1f9e60951017c1e6558216732cc14e:
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
15
19
16
target/arm: Implement v8M MSPLIM and PSPLIM registers (2018-02-15 13:48:11 +0000)
20
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs (2022-04-21 11:37:05 +0100)
17
21
18
----------------------------------------------------------------
22
----------------------------------------------------------------
19
target-arm queue:
23
target-arm queue:
20
* aspeed: code cleanup to use unimplemented_device
24
* hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
21
* add 'raspi3' RaspberryPi 3 machine model
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
22
* more SVE prep work
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
23
* v8M: add minor missing registers
27
* xlnx-zynqmp: Connect 4 TTC timers
24
* v7M: fix bug where we weren't migrating v7m.other_sp
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
25
* v7M: fix bugs in handling of interrupt registers for
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
26
external interrupts beyond 32
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
27
34
28
----------------------------------------------------------------
35
----------------------------------------------------------------
29
Pekka Enberg (3):
36
Edgar E. Iglesias (6):
30
bcm2836: Make CPU type configurable
37
timer: cadence_ttc: Break out header file to allow embedding
31
raspi: Raspberry Pi 3 support
38
hw/arm/xlnx-zynqmp: Connect 4 TTC timers
32
raspi: Add "raspi3" machine type
39
hw/arm: versal: Create an APU CPU Cluster
40
hw/arm: versal: Add the Cortex-R5Fs
41
hw/misc: Add a model of the Xilinx Versal CRL
42
hw/arm: versal: Connect the CRL
33
43
34
Peter Maydell (11):
44
Hao Wu (2):
35
hw/intc/armv7m_nvic: Don't hardcode M profile ID registers in NVIC
45
hw/misc: Add PWRON STRAP bit fields in GCR module
36
hw/intc/armv7m_nvic: Fix ICSR PENDNMISET/CLR handling
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
37
hw/intc/armv7m_nvic: Implement M profile cache maintenance ops
38
hw/intc/armv7m_nvic: Implement v8M CPPWR register
39
hw/intc/armv7m_nvic: Implement cache ID registers
40
hw/intc/armv7m_nvic: Implement SCR
41
target/arm: Implement writing to CONTROL_NS for v8M
42
hw/intc/armv7m_nvic: Fix byte-to-interrupt number conversions
43
target/arm: Add AIRCR to vmstate struct
44
target/arm: Migrate v7m.other_sp
45
target/arm: Implement v8M MSPLIM and PSPLIM registers
46
47
47
Philippe Mathieu-Daudé (2):
48
Heinrich Schuchardt (1):
48
hw/arm/aspeed: directly map the serial device to the system address space
49
hw/arm/virt: impact of gic-version on max CPUs
49
hw/arm/aspeed: simplify using the 'unimplemented device' for aspeed_soc.io
50
50
51
Richard Henderson (5):
51
Peter Maydell (19):
52
target/arm: Remove ARM_CP_64BIT from ZCR_EL registers
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
53
target/arm: Enforce FP access to FPCR/FPSR
53
hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device
54
target/arm: Suppress TB end for FPCR/FPSR
54
hw/intc/exynos4210_gic: Remove unused TYPE_EXYNOS4210_IRQ_GATE
55
target/arm: Enforce access to ZCR_EL at translation
55
hw/arm/exynos4210: Put a9mpcore device into state struct
56
target/arm: Handle SVE registers when using clear_vec_high
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
57
71
58
include/hw/arm/aspeed_soc.h | 1 -
72
Zongyuan Li (3):
59
include/hw/arm/bcm2836.h | 1 +
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
60
target/arm/cpu.h | 71 ++++++++++++-----
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
61
target/arm/internals.h | 6 ++
75
hw/core/irq: remove unused 'qemu_irq_split' function
62
hw/arm/aspeed_soc.c | 35 ++-------
63
hw/arm/bcm2836.c | 17 +++--
64
hw/arm/raspi.c | 57 +++++++++++---
65
hw/intc/armv7m_nvic.c | 98 ++++++++++++++++++------
66
target/arm/cpu.c | 28 +++++++
67
target/arm/helper.c | 84 +++++++++++++++-----
68
target/arm/machine.c | 84 ++++++++++++++++++++
69
target/arm/translate-a64.c | 181 ++++++++++++++++++++------------------------
70
12 files changed, 452 insertions(+), 211 deletions(-)
71
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
New patch
1
It's not possible to provide the guest with the Security extensions
2
(TrustZone) when using KVM or HVF, because the hardware
3
virtualization extensions don't permit running EL3 guest code.
4
However, we weren't checking for this combination, with the result
5
that QEMU would assert if you tried it:
1
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
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20220404155301.566542-1-peter.maydell@linaro.org
22
---
23
hw/arm/virt.c | 7 +++++++
24
1 file changed, 7 insertions(+)
25
26
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/virt.c
29
+++ b/hw/arm/virt.c
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
31
exit(1);
32
}
33
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
35
+ error_report("mach-virt: %s does not support providing "
36
+ "Security extensions (TrustZone) to the guest CPU",
37
+ kvm_enabled() ? "KVM" : "HVF");
38
+ exit(1);
39
+ }
40
+
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
42
error_report("mach-virt: %s does not support providing "
43
"Virtualization extensions to the guest CPU",
44
--
45
2.25.1
diff view generated by jsdifflib
New patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
2
3
Break out header file to allow embedding of the the TTC.
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Message-id: 20220331222017.2914409-2-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++
13
hw/timer/cadence_ttc.c | 32 ++------------------
14
2 files changed, 56 insertions(+), 30 deletions(-)
15
create mode 100644 include/hw/timer/cadence_ttc.h
16
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
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/timer/cadence_ttc.c
80
+++ b/hw/timer/cadence_ttc.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qemu/timer.h"
83
#include "qom/object.h"
84
85
+#include "hw/timer/cadence_ttc.h"
86
+
87
#ifdef CADENCE_TTC_ERR_DEBUG
88
#define DB_PRINT(...) do { \
89
fprintf(stderr, ": %s: ", __func__); \
90
@@ -XXX,XX +XXX,XX @@
91
#define CLOCK_CTRL_PS_EN 0x00000001
92
#define CLOCK_CTRL_PS_V 0x0000001e
93
94
-typedef struct {
95
- QEMUTimer *timer;
96
- int freq;
97
-
98
- uint32_t reg_clock;
99
- uint32_t reg_count;
100
- uint32_t reg_value;
101
- uint16_t reg_interval;
102
- uint16_t reg_match[3];
103
- uint32_t reg_intr;
104
- uint32_t reg_intr_en;
105
- uint32_t reg_event_ctrl;
106
- uint32_t reg_event;
107
-
108
- uint64_t cpu_time;
109
- unsigned int cpu_time_valid;
110
-
111
- qemu_irq irq;
112
-} CadenceTimerState;
113
-
114
-#define TYPE_CADENCE_TTC "cadence_ttc"
115
-OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
116
-
117
-struct CadenceTTCState {
118
- SysBusDevice parent_obj;
119
-
120
- MemoryRegion iomem;
121
- CadenceTimerState timer[3];
122
-};
123
-
124
static void cadence_timer_update(CadenceTimerState *s)
125
{
126
qemu_set_irq(s->irq, !!(s->reg_intr & s->reg_intr_en));
127
--
128
2.25.1
diff view generated by jsdifflib
New patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
2
3
Connect the 4 TTC timers on the ZynqMP.
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Message-id: 20220331222017.2914409-3-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/xlnx-zynqmp.h | 4 ++++
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
14
2 files changed, 26 insertions(+)
15
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-zynqmp.h
19
+++ b/include/hw/arm/xlnx-zynqmp.h
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/or-irq.h"
22
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
23
#include "hw/misc/xlnx-zynqmp-crf.h"
24
+#include "hw/timer/cadence_ttc.h"
25
26
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
27
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
29
#define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
30
XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
31
32
+#define XLNX_ZYNQMP_NUM_TTC 4
33
+
34
/*
35
* Unimplemented mmio regions needed to boot some images.
36
*/
37
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
38
qemu_or_irq qspi_irq_orgate;
39
XlnxZynqMPAPUCtrl apu_ctrl;
40
XlnxZynqMPCRF crf;
41
+ CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
42
43
char *boot_cpu;
44
ARMCPU *boot_cpu_ptr;
45
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/xlnx-zynqmp.c
48
+++ b/hw/arm/xlnx-zynqmp.c
49
@@ -XXX,XX +XXX,XX @@
50
#define APU_ADDR 0xfd5c0000
51
#define APU_IRQ 153
52
53
+#define TTC0_ADDR 0xFF110000
54
+#define TTC0_IRQ 36
55
+
56
#define IPI_ADDR 0xFF300000
57
#define IPI_IRQ 64
58
59
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, qemu_irq *gic)
60
sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
61
}
62
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
64
+{
65
+ SysBusDevice *sbd;
66
+ int i, irq;
67
+
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
70
+ TYPE_CADENCE_TTC);
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
72
+
73
+ sysbus_realize(sbd, &error_fatal);
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
75
+ for (irq = 0; irq < 3; irq++) {
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
77
+ }
78
+ }
79
+}
80
+
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
82
{
83
static const struct UnimpInfo {
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
85
xlnx_zynqmp_create_efuse(s, gic_spi);
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
87
xlnx_zynqmp_create_crf(s, gic_spi);
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
89
xlnx_zynqmp_create_unimp_mmio(s);
90
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
92
--
93
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Create an APU CPU Cluster. This is in preparation to add the RPU.
4
Message-id: 20180211205848.4568-3-richard.henderson@linaro.org
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
target/arm/cpu.h | 35 ++++++++++++++++++-----------------
10
include/hw/arm/xlnx-versal.h | 2 ++
9
target/arm/helper.c | 6 ++++--
11
hw/arm/xlnx-versal.c | 9 ++++++++-
10
target/arm/translate-a64.c | 3 +++
12
2 files changed, 10 insertions(+), 1 deletion(-)
11
3 files changed, 25 insertions(+), 19 deletions(-)
12
13
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
16
--- a/include/hw/arm/xlnx-versal.h
16
+++ b/target/arm/cpu.h
17
+++ b/include/hw/arm/xlnx-versal.h
17
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
18
@@ -XXX,XX +XXX,XX @@
19
20
#include "hw/sysbus.h"
21
#include "hw/arm/boot.h"
22
+#include "hw/cpu/cluster.h"
23
#include "hw/or-irq.h"
24
#include "hw/sd/sdhci.h"
25
#include "hw/intc/arm_gicv3.h"
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
27
struct {
28
struct {
29
MemoryRegion mr;
30
+ CPUClusterState cluster;
31
ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
32
GICv3State gic;
33
} apu;
34
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/xlnx-versal.c
37
+++ b/hw/arm/xlnx-versal.c
38
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
39
{
40
int i;
41
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
43
+ TYPE_CPU_CLUSTER);
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
45
+
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
47
Object *obj;
48
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
52
XLNX_VERSAL_ACPU_TYPE);
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
54
if (i) {
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
56
&error_abort);
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
58
}
59
+
60
+ qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
18
}
61
}
19
62
20
/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
63
static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
21
- * special-behaviour cp reg and bits [15..8] indicate what behaviour
22
+ * special-behaviour cp reg and bits [11..8] indicate what behaviour
23
* it has. Otherwise it is a simple cp reg, where CONST indicates that
24
* TCG can assume the value to be constant (ie load at translate time)
25
* and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
26
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
27
* need to be surrounded by gen_io_start()/gen_io_end(). In particular,
28
* registers which implement clocks or timers require this.
29
*/
30
-#define ARM_CP_SPECIAL 1
31
-#define ARM_CP_CONST 2
32
-#define ARM_CP_64BIT 4
33
-#define ARM_CP_SUPPRESS_TB_END 8
34
-#define ARM_CP_OVERRIDE 16
35
-#define ARM_CP_ALIAS 32
36
-#define ARM_CP_IO 64
37
-#define ARM_CP_NO_RAW 128
38
-#define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
39
-#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
40
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8))
41
-#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
42
-#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
43
-#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
44
+#define ARM_CP_SPECIAL 0x0001
45
+#define ARM_CP_CONST 0x0002
46
+#define ARM_CP_64BIT 0x0004
47
+#define ARM_CP_SUPPRESS_TB_END 0x0008
48
+#define ARM_CP_OVERRIDE 0x0010
49
+#define ARM_CP_ALIAS 0x0020
50
+#define ARM_CP_IO 0x0040
51
+#define ARM_CP_NO_RAW 0x0080
52
+#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
53
+#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
54
+#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
55
+#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
56
+#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
57
+#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
58
+#define ARM_CP_FPU 0x1000
59
/* Used only as a terminator for ARMCPRegInfo lists */
60
-#define ARM_CP_SENTINEL 0xffff
61
+#define ARM_CP_SENTINEL 0xffff
62
/* Mask of only the flag bits in a type field */
63
-#define ARM_CP_FLAG_MASK 0xff
64
+#define ARM_CP_FLAG_MASK 0x10ff
65
66
/* Valid values for ARMCPRegInfo state field, indicating which of
67
* the AArch32 and AArch64 execution states this register is visible in.
68
diff --git a/target/arm/helper.c b/target/arm/helper.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/helper.c
71
+++ b/target/arm/helper.c
72
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
73
.writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore },
74
{ .name = "FPCR", .state = ARM_CP_STATE_AA64,
75
.opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
76
- .access = PL0_RW, .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
77
+ .access = PL0_RW, .type = ARM_CP_FPU,
78
+ .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
79
{ .name = "FPSR", .state = ARM_CP_STATE_AA64,
80
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
81
- .access = PL0_RW, .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
82
+ .access = PL0_RW, .type = ARM_CP_FPU,
83
+ .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
84
{ .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64,
85
.opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
86
.access = PL0_R, .type = ARM_CP_NO_RAW,
87
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/translate-a64.c
90
+++ b/target/arm/translate-a64.c
91
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
92
default:
93
break;
94
}
95
+ if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
96
+ return;
97
+ }
98
99
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
100
gen_io_start();
101
--
64
--
102
2.16.1
65
2.25.1
103
104
diff view generated by jsdifflib
1
From: Pekka Enberg <penberg@iki.fi>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
This patch adds a "cpu-type" property to BCM2836 SoC in preparation for
3
Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit)
4
reusing the code for the Raspberry Pi 3, which has a different processor
4
subsystem.
5
model.
6
5
7
Signed-off-by: Pekka Enberg <penberg@iki.fi>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
include/hw/arm/bcm2836.h | 1 +
11
include/hw/arm/xlnx-versal.h | 10 ++++++++++
12
hw/arm/bcm2836.c | 17 +++++++++--------
12
hw/arm/xlnx-versal-virt.c | 6 +++---
13
hw/arm/raspi.c | 3 +++
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
14
3 files changed, 13 insertions(+), 8 deletions(-)
14
3 files changed, 49 insertions(+), 3 deletions(-)
15
15
16
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.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/bcm2836.h
18
--- a/include/hw/arm/xlnx-versal.h
19
+++ b/include/hw/arm/bcm2836.h
19
+++ b/include/hw/arm/xlnx-versal.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2836State {
20
@@ -XXX,XX +XXX,XX @@
21
DeviceState parent_obj;
21
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
22
/*< public >*/
22
23
23
#define XLNX_VERSAL_NR_ACPUS 2
24
+ char *cpu_type;
24
+#define XLNX_VERSAL_NR_RCPUS 2
25
uint32_t enabled_cpus;
25
#define XLNX_VERSAL_NR_UARTS 2
26
26
#define XLNX_VERSAL_NR_GEMS 2
27
ARMCPU cpus[BCM2836_NCPUS];
27
#define XLNX_VERSAL_NR_ADMAS 8
28
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
29
VersalUsb2 usb;
30
} iou;
31
32
+ /* Real-time Processing Unit. */
33
+ struct {
34
+ MemoryRegion mr;
35
+ MemoryRegion mr_ps_alias;
36
+
37
+ CPUClusterState cluster;
38
+ ARMCPU cpu[XLNX_VERSAL_NR_RCPUS];
39
+ } rpu;
40
+
41
struct {
42
qemu_or_irq irq_orgate;
43
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
44
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
29
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/bcm2836.c
46
--- a/hw/arm/xlnx-versal-virt.c
31
+++ b/hw/arm/bcm2836.c
47
+++ b/hw/arm/xlnx-versal-virt.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
49
50
mc->desc = "Xilinx Versal Virtual development board";
51
mc->init = versal_virt_init;
52
- mc->min_cpus = XLNX_VERSAL_NR_ACPUS;
53
- mc->max_cpus = XLNX_VERSAL_NR_ACPUS;
54
- mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
55
+ mc->min_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
56
+ mc->max_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
57
+ mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
58
mc->no_cdrom = true;
59
mc->default_ram_id = "ddr";
60
}
61
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/xlnx-versal.c
64
+++ b/hw/arm/xlnx-versal.c
32
@@ -XXX,XX +XXX,XX @@
65
@@ -XXX,XX +XXX,XX @@
33
static void bcm2836_init(Object *obj)
66
#include "hw/sysbus.h"
34
{
67
35
BCM2836State *s = BCM2836(obj);
68
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
36
- int n;
69
+#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
37
-
70
#define GEM_REVISION 0x40070106
38
- for (n = 0; n < BCM2836_NCPUS; n++) {
71
39
- object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
72
#define VERSAL_NUM_PMC_APB_IRQS 3
40
- "cortex-a15-" TYPE_ARM_CPU);
73
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
41
- object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
74
}
42
- &error_abort);
75
}
43
- }
76
44
77
+static void versal_create_rpu_cpus(Versal *s)
45
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
78
+{
46
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
79
+ int i;
47
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
80
+
48
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
49
/* common peripherals from bcm2835 */
82
+ TYPE_CPU_CLUSTER);
50
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
51
+ obj = OBJECT(dev);
84
+
52
+ for (n = 0; n < BCM2836_NCPUS; n++) {
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
53
+ object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
86
+ Object *obj;
54
+ s->cpu_type);
87
+
55
+ object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
56
+ &error_abort);
89
+ "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
90
+ XLNX_VERSAL_RCPU_TYPE);
91
+ obj = OBJECT(&s->lpd.rpu.cpu[i]);
92
+ object_property_set_bool(obj, "start-powered-off", true,
93
+ &error_abort);
94
+
95
+ object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
96
+ object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
97
+ &error_abort);
98
+ object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
99
+ &error_abort);
100
+ qdev_realize(DEVICE(obj), NULL, &error_fatal);
57
+ }
101
+ }
58
+
102
+
59
obj = object_property_get_link(OBJECT(dev), "ram", &err);
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
60
if (obj == NULL) {
104
+}
61
error_setg(errp, "%s: required ram link not found: %s",
105
+
62
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
107
{
108
int i;
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
110
111
versal_create_apu_cpus(s);
112
versal_create_apu_gic(s, pic);
113
+ versal_create_rpu_cpus(s);
114
versal_create_uarts(s, pic);
115
versal_create_usbs(s, pic);
116
versal_create_gems(s, pic);
117
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
118
119
memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0);
120
memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0);
121
+ memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0,
122
+ &s->lpd.rpu.mr_ps_alias, 0);
63
}
123
}
64
124
65
static Property bcm2836_props[] = {
125
static void versal_init(Object *obj)
66
+ DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type),
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
67
DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
127
Versal *s = XLNX_VERSAL(obj);
68
DEFINE_PROP_END_OF_LIST()
128
69
};
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
70
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
71
index XXXXXXX..XXXXXXX 100644
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
72
--- a/hw/arm/raspi.c
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
73
+++ b/hw/arm/raspi.c
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
74
@@ -XXX,XX +XXX,XX @@ static void raspi2_init(MachineState *machine)
134
}
75
/* Setup the SOC */
135
76
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
136
static Property versal_properties[] = {
77
&error_abort);
78
+ object_property_set_str(OBJECT(&s->soc), machine->cpu_type, "cpu-type",
79
+ &error_abort);
80
object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
81
&error_abort);
82
object_property_set_int(OBJECT(&s->soc), 0xa21041, "board-rev",
83
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
84
mc->no_parallel = 1;
85
mc->no_floppy = 1;
86
mc->no_cdrom = 1;
87
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
88
mc->max_cpus = BCM2836_NCPUS;
89
mc->min_cpus = BCM2836_NCPUS;
90
mc->default_cpus = BCM2836_NCPUS;
91
--
137
--
92
2.16.1
138
2.25.1
93
94
diff view generated by jsdifflib
1
We were previously making the system control register (SCR)
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
just RAZ/WI. Although we don't implement the functionality
3
this register controls, we should at least provide the state,
4
including the banked state for v8M.
5
2
3
Add a model of the Xilinx Versal CRL.
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com
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>
8
Message-id: 20180209165810.6668-7-peter.maydell@linaro.org
9
---
10
---
10
target/arm/cpu.h | 7 +++++++
11
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++
11
hw/intc/armv7m_nvic.c | 12 ++++++++----
12
hw/misc/xlnx-versal-crl.c | 421 ++++++++++++++++++++++++++++++
12
target/arm/machine.c | 12 ++++++++++++
13
hw/misc/meson.build | 1 +
13
3 files changed, 27 insertions(+), 4 deletions(-)
14
3 files changed, 657 insertions(+)
15
create mode 100644 include/hw/misc/xlnx-versal-crl.h
16
create mode 100644 hw/misc/xlnx-versal-crl.c
14
17
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
16
index XXXXXXX..XXXXXXX 100644
19
new file mode 100644
17
--- a/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX
18
+++ b/target/arm/cpu.h
21
--- /dev/null
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
22
+++ b/include/hw/misc/xlnx-versal-crl.h
20
uint32_t aircr; /* only holds r/w state if security extn implemented */
23
@@ -XXX,XX +XXX,XX @@
21
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
24
+/*
22
uint32_t csselr[M_REG_NUM_BANKS];
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
23
+ uint32_t scr[M_REG_NUM_BANKS];
26
+ *
24
} v7m;
27
+ * Copyright (c) 2022 Xilinx Inc.
25
28
+ * SPDX-License-Identifier: GPL-2.0-or-later
26
/* Information associated with an exception about to be taken:
29
+ *
27
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CCR, STKALIGN, 9, 1)
30
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
28
FIELD(V7M_CCR, DC, 16, 1)
31
+ */
29
FIELD(V7M_CCR, IC, 17, 1)
32
+#ifndef HW_MISC_XLNX_VERSAL_CRL_H
30
33
+#define HW_MISC_XLNX_VERSAL_CRL_H
31
+/* V7M SCR bits */
34
+
32
+FIELD(V7M_SCR, SLEEPONEXIT, 1, 1)
35
+#include "hw/sysbus.h"
33
+FIELD(V7M_SCR, SLEEPDEEP, 2, 1)
36
+#include "hw/register.h"
34
+FIELD(V7M_SCR, SLEEPDEEPS, 3, 1)
37
+#include "target/arm/cpu.h"
35
+FIELD(V7M_SCR, SEVONPEND, 4, 1)
38
+
36
+
39
+#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl"
37
/* V7M AIRCR bits */
40
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL)
38
FIELD(V7M_AIRCR, VECTRESET, 0, 1)
41
+
39
FIELD(V7M_AIRCR, VECTCLRACTIVE, 1, 1)
42
+REG32(ERR_CTRL, 0x0)
40
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
43
+ FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
41
index XXXXXXX..XXXXXXX 100644
44
+REG32(IR_STATUS, 0x4)
42
--- a/hw/intc/armv7m_nvic.c
45
+ FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1)
43
+++ b/hw/intc/armv7m_nvic.c
46
+REG32(IR_MASK, 0x8)
44
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
47
+ FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1)
45
}
48
+REG32(IR_ENABLE, 0xc)
46
return val;
49
+ FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1)
47
case 0xd10: /* System Control. */
50
+REG32(IR_DISABLE, 0x10)
48
- /* TODO: Implement SLEEPONEXIT. */
51
+ FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1)
49
- return 0;
52
+REG32(WPROT, 0x1c)
50
+ return cpu->env.v7m.scr[attrs.secure];
53
+ FIELD(WPROT, ACTIVE, 0, 1)
51
case 0xd14: /* Configuration Control. */
54
+REG32(PLL_CLK_OTHER_DMN, 0x20)
52
/* The BFHFNMIGN bit is the only non-banked bit; we
55
+ FIELD(PLL_CLK_OTHER_DMN, APLL_BYPASS, 0, 1)
53
* keep it in the non-secure copy of the register.
56
+REG32(RPLL_CTRL, 0x40)
54
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
57
+ FIELD(RPLL_CTRL, POST_SRC, 24, 3)
55
}
58
+ FIELD(RPLL_CTRL, PRE_SRC, 20, 3)
56
break;
59
+ FIELD(RPLL_CTRL, CLKOUTDIV, 16, 2)
57
case 0xd10: /* System Control. */
60
+ FIELD(RPLL_CTRL, FBDIV, 8, 8)
58
- /* TODO: Implement control registers. */
61
+ FIELD(RPLL_CTRL, BYPASS, 3, 1)
59
- qemu_log_mask(LOG_UNIMP, "NVIC: SCR unimplemented\n");
62
+ FIELD(RPLL_CTRL, RESET, 0, 1)
60
+ /* We don't implement deep-sleep so these bits are RAZ/WI.
63
+REG32(RPLL_CFG, 0x44)
61
+ * The other bits in the register are banked.
64
+ FIELD(RPLL_CFG, LOCK_DLY, 25, 7)
62
+ * QEMU's implementation ignores SEVONPEND and SLEEPONEXIT, which
65
+ FIELD(RPLL_CFG, LOCK_CNT, 13, 10)
63
+ * is architecturally permitted.
66
+ FIELD(RPLL_CFG, LFHF, 10, 2)
64
+ */
67
+ FIELD(RPLL_CFG, CP, 5, 4)
65
+ value &= ~(R_V7M_SCR_SLEEPDEEP_MASK | R_V7M_SCR_SLEEPDEEPS_MASK);
68
+ FIELD(RPLL_CFG, RES, 0, 4)
66
+ cpu->env.v7m.scr[attrs.secure] = value;
69
+REG32(RPLL_FRAC_CFG, 0x48)
67
break;
70
+ FIELD(RPLL_FRAC_CFG, ENABLED, 31, 1)
68
case 0xd14: /* Configuration Control. */
71
+ FIELD(RPLL_FRAC_CFG, SEED, 22, 3)
69
/* Enforce RAZ/WI on reserved and must-RAZ/WI bits */
72
+ FIELD(RPLL_FRAC_CFG, ALGRTHM, 19, 1)
70
diff --git a/target/arm/machine.c b/target/arm/machine.c
73
+ FIELD(RPLL_FRAC_CFG, ORDER, 18, 1)
71
index XXXXXXX..XXXXXXX 100644
74
+ FIELD(RPLL_FRAC_CFG, DATA, 0, 16)
72
--- a/target/arm/machine.c
75
+REG32(PLL_STATUS, 0x50)
73
+++ b/target/arm/machine.c
76
+ FIELD(PLL_STATUS, RPLL_STABLE, 2, 1)
74
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_csselr = {
77
+ FIELD(PLL_STATUS, RPLL_LOCK, 0, 1)
75
}
78
+REG32(RPLL_TO_XPD_CTRL, 0x100)
76
};
79
+ FIELD(RPLL_TO_XPD_CTRL, CLKACT, 25, 1)
77
80
+ FIELD(RPLL_TO_XPD_CTRL, DIVISOR0, 8, 10)
78
+static const VMStateDescription vmstate_m_scr = {
81
+REG32(LPD_TOP_SWITCH_CTRL, 0x104)
79
+ .name = "cpu/m/scr",
82
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT_ADMA, 26, 1)
83
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT, 25, 1)
84
+ FIELD(LPD_TOP_SWITCH_CTRL, DIVISOR0, 8, 10)
85
+ FIELD(LPD_TOP_SWITCH_CTRL, SRCSEL, 0, 3)
86
+REG32(LPD_LSBUS_CTRL, 0x108)
87
+ FIELD(LPD_LSBUS_CTRL, CLKACT, 25, 1)
88
+ FIELD(LPD_LSBUS_CTRL, DIVISOR0, 8, 10)
89
+ FIELD(LPD_LSBUS_CTRL, SRCSEL, 0, 3)
90
+REG32(CPU_R5_CTRL, 0x10c)
91
+ FIELD(CPU_R5_CTRL, CLKACT_OCM2, 28, 1)
92
+ FIELD(CPU_R5_CTRL, CLKACT_OCM, 27, 1)
93
+ FIELD(CPU_R5_CTRL, CLKACT_CORE, 26, 1)
94
+ FIELD(CPU_R5_CTRL, CLKACT, 25, 1)
95
+ FIELD(CPU_R5_CTRL, DIVISOR0, 8, 10)
96
+ FIELD(CPU_R5_CTRL, SRCSEL, 0, 3)
97
+REG32(IOU_SWITCH_CTRL, 0x114)
98
+ FIELD(IOU_SWITCH_CTRL, CLKACT, 25, 1)
99
+ FIELD(IOU_SWITCH_CTRL, DIVISOR0, 8, 10)
100
+ FIELD(IOU_SWITCH_CTRL, SRCSEL, 0, 3)
101
+REG32(GEM0_REF_CTRL, 0x118)
102
+ FIELD(GEM0_REF_CTRL, CLKACT_RX, 27, 1)
103
+ FIELD(GEM0_REF_CTRL, CLKACT_TX, 26, 1)
104
+ FIELD(GEM0_REF_CTRL, CLKACT, 25, 1)
105
+ FIELD(GEM0_REF_CTRL, DIVISOR0, 8, 10)
106
+ FIELD(GEM0_REF_CTRL, SRCSEL, 0, 3)
107
+REG32(GEM1_REF_CTRL, 0x11c)
108
+ FIELD(GEM1_REF_CTRL, CLKACT_RX, 27, 1)
109
+ FIELD(GEM1_REF_CTRL, CLKACT_TX, 26, 1)
110
+ FIELD(GEM1_REF_CTRL, CLKACT, 25, 1)
111
+ FIELD(GEM1_REF_CTRL, DIVISOR0, 8, 10)
112
+ FIELD(GEM1_REF_CTRL, SRCSEL, 0, 3)
113
+REG32(GEM_TSU_REF_CTRL, 0x120)
114
+ FIELD(GEM_TSU_REF_CTRL, CLKACT, 25, 1)
115
+ FIELD(GEM_TSU_REF_CTRL, DIVISOR0, 8, 10)
116
+ FIELD(GEM_TSU_REF_CTRL, SRCSEL, 0, 3)
117
+REG32(USB0_BUS_REF_CTRL, 0x124)
118
+ FIELD(USB0_BUS_REF_CTRL, CLKACT, 25, 1)
119
+ FIELD(USB0_BUS_REF_CTRL, DIVISOR0, 8, 10)
120
+ FIELD(USB0_BUS_REF_CTRL, SRCSEL, 0, 3)
121
+REG32(UART0_REF_CTRL, 0x128)
122
+ FIELD(UART0_REF_CTRL, CLKACT, 25, 1)
123
+ FIELD(UART0_REF_CTRL, DIVISOR0, 8, 10)
124
+ FIELD(UART0_REF_CTRL, SRCSEL, 0, 3)
125
+REG32(UART1_REF_CTRL, 0x12c)
126
+ FIELD(UART1_REF_CTRL, CLKACT, 25, 1)
127
+ FIELD(UART1_REF_CTRL, DIVISOR0, 8, 10)
128
+ FIELD(UART1_REF_CTRL, SRCSEL, 0, 3)
129
+REG32(SPI0_REF_CTRL, 0x130)
130
+ FIELD(SPI0_REF_CTRL, CLKACT, 25, 1)
131
+ FIELD(SPI0_REF_CTRL, DIVISOR0, 8, 10)
132
+ FIELD(SPI0_REF_CTRL, SRCSEL, 0, 3)
133
+REG32(SPI1_REF_CTRL, 0x134)
134
+ FIELD(SPI1_REF_CTRL, CLKACT, 25, 1)
135
+ FIELD(SPI1_REF_CTRL, DIVISOR0, 8, 10)
136
+ FIELD(SPI1_REF_CTRL, SRCSEL, 0, 3)
137
+REG32(CAN0_REF_CTRL, 0x138)
138
+ FIELD(CAN0_REF_CTRL, CLKACT, 25, 1)
139
+ FIELD(CAN0_REF_CTRL, DIVISOR0, 8, 10)
140
+ FIELD(CAN0_REF_CTRL, SRCSEL, 0, 3)
141
+REG32(CAN1_REF_CTRL, 0x13c)
142
+ FIELD(CAN1_REF_CTRL, CLKACT, 25, 1)
143
+ FIELD(CAN1_REF_CTRL, DIVISOR0, 8, 10)
144
+ FIELD(CAN1_REF_CTRL, SRCSEL, 0, 3)
145
+REG32(I2C0_REF_CTRL, 0x140)
146
+ FIELD(I2C0_REF_CTRL, CLKACT, 25, 1)
147
+ FIELD(I2C0_REF_CTRL, DIVISOR0, 8, 10)
148
+ FIELD(I2C0_REF_CTRL, SRCSEL, 0, 3)
149
+REG32(I2C1_REF_CTRL, 0x144)
150
+ FIELD(I2C1_REF_CTRL, CLKACT, 25, 1)
151
+ FIELD(I2C1_REF_CTRL, DIVISOR0, 8, 10)
152
+ FIELD(I2C1_REF_CTRL, SRCSEL, 0, 3)
153
+REG32(DBG_LPD_CTRL, 0x148)
154
+ FIELD(DBG_LPD_CTRL, CLKACT, 25, 1)
155
+ FIELD(DBG_LPD_CTRL, DIVISOR0, 8, 10)
156
+ FIELD(DBG_LPD_CTRL, SRCSEL, 0, 3)
157
+REG32(TIMESTAMP_REF_CTRL, 0x14c)
158
+ FIELD(TIMESTAMP_REF_CTRL, CLKACT, 25, 1)
159
+ FIELD(TIMESTAMP_REF_CTRL, DIVISOR0, 8, 10)
160
+ FIELD(TIMESTAMP_REF_CTRL, SRCSEL, 0, 3)
161
+REG32(CRL_SAFETY_CHK, 0x150)
162
+REG32(PSM_REF_CTRL, 0x154)
163
+ FIELD(PSM_REF_CTRL, DIVISOR0, 8, 10)
164
+ FIELD(PSM_REF_CTRL, SRCSEL, 0, 3)
165
+REG32(DBG_TSTMP_CTRL, 0x158)
166
+ FIELD(DBG_TSTMP_CTRL, CLKACT, 25, 1)
167
+ FIELD(DBG_TSTMP_CTRL, DIVISOR0, 8, 10)
168
+ FIELD(DBG_TSTMP_CTRL, SRCSEL, 0, 3)
169
+REG32(CPM_TOPSW_REF_CTRL, 0x15c)
170
+ FIELD(CPM_TOPSW_REF_CTRL, CLKACT, 25, 1)
171
+ FIELD(CPM_TOPSW_REF_CTRL, DIVISOR0, 8, 10)
172
+ FIELD(CPM_TOPSW_REF_CTRL, SRCSEL, 0, 3)
173
+REG32(USB3_DUAL_REF_CTRL, 0x160)
174
+ FIELD(USB3_DUAL_REF_CTRL, CLKACT, 25, 1)
175
+ FIELD(USB3_DUAL_REF_CTRL, DIVISOR0, 8, 10)
176
+ FIELD(USB3_DUAL_REF_CTRL, SRCSEL, 0, 3)
177
+REG32(RST_CPU_R5, 0x300)
178
+ FIELD(RST_CPU_R5, RESET_PGE, 4, 1)
179
+ FIELD(RST_CPU_R5, RESET_AMBA, 2, 1)
180
+ FIELD(RST_CPU_R5, RESET_CPU1, 1, 1)
181
+ FIELD(RST_CPU_R5, RESET_CPU0, 0, 1)
182
+REG32(RST_ADMA, 0x304)
183
+ FIELD(RST_ADMA, RESET, 0, 1)
184
+REG32(RST_GEM0, 0x308)
185
+ FIELD(RST_GEM0, RESET, 0, 1)
186
+REG32(RST_GEM1, 0x30c)
187
+ FIELD(RST_GEM1, RESET, 0, 1)
188
+REG32(RST_SPARE, 0x310)
189
+ FIELD(RST_SPARE, RESET, 0, 1)
190
+REG32(RST_USB0, 0x314)
191
+ FIELD(RST_USB0, RESET, 0, 1)
192
+REG32(RST_UART0, 0x318)
193
+ FIELD(RST_UART0, RESET, 0, 1)
194
+REG32(RST_UART1, 0x31c)
195
+ FIELD(RST_UART1, RESET, 0, 1)
196
+REG32(RST_SPI0, 0x320)
197
+ FIELD(RST_SPI0, RESET, 0, 1)
198
+REG32(RST_SPI1, 0x324)
199
+ FIELD(RST_SPI1, RESET, 0, 1)
200
+REG32(RST_CAN0, 0x328)
201
+ FIELD(RST_CAN0, RESET, 0, 1)
202
+REG32(RST_CAN1, 0x32c)
203
+ FIELD(RST_CAN1, RESET, 0, 1)
204
+REG32(RST_I2C0, 0x330)
205
+ FIELD(RST_I2C0, RESET, 0, 1)
206
+REG32(RST_I2C1, 0x334)
207
+ FIELD(RST_I2C1, RESET, 0, 1)
208
+REG32(RST_DBG_LPD, 0x338)
209
+ FIELD(RST_DBG_LPD, RPU_DBG1_RESET, 5, 1)
210
+ FIELD(RST_DBG_LPD, RPU_DBG0_RESET, 4, 1)
211
+ FIELD(RST_DBG_LPD, RESET_HSDP, 1, 1)
212
+ FIELD(RST_DBG_LPD, RESET, 0, 1)
213
+REG32(RST_GPIO, 0x33c)
214
+ FIELD(RST_GPIO, RESET, 0, 1)
215
+REG32(RST_TTC, 0x344)
216
+ FIELD(RST_TTC, TTC3_RESET, 3, 1)
217
+ FIELD(RST_TTC, TTC2_RESET, 2, 1)
218
+ FIELD(RST_TTC, TTC1_RESET, 1, 1)
219
+ FIELD(RST_TTC, TTC0_RESET, 0, 1)
220
+REG32(RST_TIMESTAMP, 0x348)
221
+ FIELD(RST_TIMESTAMP, RESET, 0, 1)
222
+REG32(RST_SWDT, 0x34c)
223
+ FIELD(RST_SWDT, RESET, 0, 1)
224
+REG32(RST_OCM, 0x350)
225
+ FIELD(RST_OCM, RESET, 0, 1)
226
+REG32(RST_IPI, 0x354)
227
+ FIELD(RST_IPI, RESET, 0, 1)
228
+REG32(RST_SYSMON, 0x358)
229
+ FIELD(RST_SYSMON, SEQ_RST, 1, 1)
230
+ FIELD(RST_SYSMON, CFG_RST, 0, 1)
231
+REG32(RST_FPD, 0x360)
232
+ FIELD(RST_FPD, SRST, 1, 1)
233
+ FIELD(RST_FPD, POR, 0, 1)
234
+REG32(PSM_RST_MODE, 0x370)
235
+ FIELD(PSM_RST_MODE, WAKEUP, 2, 1)
236
+ FIELD(PSM_RST_MODE, RST_MODE, 0, 2)
237
+
238
+#define CRL_R_MAX (R_PSM_RST_MODE + 1)
239
+
240
+#define RPU_MAX_CPU 2
241
+
242
+struct XlnxVersalCRL {
243
+ SysBusDevice parent_obj;
244
+ qemu_irq irq;
245
+
246
+ struct {
247
+ ARMCPU *cpu_r5[RPU_MAX_CPU];
248
+ DeviceState *adma[8];
249
+ DeviceState *uart[2];
250
+ DeviceState *gem[2];
251
+ DeviceState *usb;
252
+ } cfg;
253
+
254
+ RegisterInfoArray *reg_array;
255
+ uint32_t regs[CRL_R_MAX];
256
+ RegisterInfo regs_info[CRL_R_MAX];
257
+};
258
+#endif
259
diff --git a/hw/misc/xlnx-versal-crl.c b/hw/misc/xlnx-versal-crl.c
260
new file mode 100644
261
index XXXXXXX..XXXXXXX
262
--- /dev/null
263
+++ b/hw/misc/xlnx-versal-crl.c
264
@@ -XXX,XX +XXX,XX @@
265
+/*
266
+ * QEMU model of the Clock-Reset-LPD (CRL).
267
+ *
268
+ * Copyright (c) 2022 Advanced Micro Devices, Inc.
269
+ * SPDX-License-Identifier: GPL-2.0-or-later
270
+ *
271
+ * Written by Edgar E. Iglesias <edgar.iglesias@amd.com>
272
+ */
273
+
274
+#include "qemu/osdep.h"
275
+#include "qapi/error.h"
276
+#include "qemu/log.h"
277
+#include "qemu/bitops.h"
278
+#include "migration/vmstate.h"
279
+#include "hw/qdev-properties.h"
280
+#include "hw/sysbus.h"
281
+#include "hw/irq.h"
282
+#include "hw/register.h"
283
+#include "hw/resettable.h"
284
+
285
+#include "target/arm/arm-powerctl.h"
286
+#include "hw/misc/xlnx-versal-crl.h"
287
+
288
+#ifndef XLNX_VERSAL_CRL_ERR_DEBUG
289
+#define XLNX_VERSAL_CRL_ERR_DEBUG 0
290
+#endif
291
+
292
+static void crl_update_irq(XlnxVersalCRL *s)
293
+{
294
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
295
+ qemu_set_irq(s->irq, pending);
296
+}
297
+
298
+static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
299
+{
300
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
301
+ crl_update_irq(s);
302
+}
303
+
304
+static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
305
+{
306
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
307
+ uint32_t val = val64;
308
+
309
+ s->regs[R_IR_MASK] &= ~val;
310
+ crl_update_irq(s);
311
+ return 0;
312
+}
313
+
314
+static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
315
+{
316
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
317
+ uint32_t val = val64;
318
+
319
+ s->regs[R_IR_MASK] |= val;
320
+ crl_update_irq(s);
321
+ return 0;
322
+}
323
+
324
+static void crl_reset_dev(XlnxVersalCRL *s, DeviceState *dev,
325
+ bool rst_old, bool rst_new)
326
+{
327
+ device_cold_reset(dev);
328
+}
329
+
330
+static void crl_reset_cpu(XlnxVersalCRL *s, ARMCPU *armcpu,
331
+ bool rst_old, bool rst_new)
332
+{
333
+ if (rst_new) {
334
+ arm_set_cpu_off(armcpu->mp_affinity);
335
+ } else {
336
+ arm_set_cpu_on_and_reset(armcpu->mp_affinity);
337
+ }
338
+}
339
+
340
+#define REGFIELD_RESET(type, s, reg, f, new_val, dev) { \
341
+ bool old_f = ARRAY_FIELD_EX32((s)->regs, reg, f); \
342
+ bool new_f = FIELD_EX32(new_val, reg, f); \
343
+ \
344
+ /* Detect edges. */ \
345
+ if (dev && old_f != new_f) { \
346
+ crl_reset_ ## type(s, dev, old_f, new_f); \
347
+ } \
348
+}
349
+
350
+static uint64_t crl_rst_r5_prew(RegisterInfo *reg, uint64_t val64)
351
+{
352
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
353
+
354
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU0, val64, s->cfg.cpu_r5[0]);
355
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU1, val64, s->cfg.cpu_r5[1]);
356
+ return val64;
357
+}
358
+
359
+static uint64_t crl_rst_adma_prew(RegisterInfo *reg, uint64_t val64)
360
+{
361
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
362
+ int i;
363
+
364
+ /* A single register fans out to all ADMA reset inputs. */
365
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); i++) {
366
+ REGFIELD_RESET(dev, s, RST_ADMA, RESET, val64, s->cfg.adma[i]);
367
+ }
368
+ return val64;
369
+}
370
+
371
+static uint64_t crl_rst_uart0_prew(RegisterInfo *reg, uint64_t val64)
372
+{
373
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
374
+
375
+ REGFIELD_RESET(dev, s, RST_UART0, RESET, val64, s->cfg.uart[0]);
376
+ return val64;
377
+}
378
+
379
+static uint64_t crl_rst_uart1_prew(RegisterInfo *reg, uint64_t val64)
380
+{
381
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
382
+
383
+ REGFIELD_RESET(dev, s, RST_UART1, RESET, val64, s->cfg.uart[1]);
384
+ return val64;
385
+}
386
+
387
+static uint64_t crl_rst_gem0_prew(RegisterInfo *reg, uint64_t val64)
388
+{
389
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
390
+
391
+ REGFIELD_RESET(dev, s, RST_GEM0, RESET, val64, s->cfg.gem[0]);
392
+ return val64;
393
+}
394
+
395
+static uint64_t crl_rst_gem1_prew(RegisterInfo *reg, uint64_t val64)
396
+{
397
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
398
+
399
+ REGFIELD_RESET(dev, s, RST_GEM1, RESET, val64, s->cfg.gem[1]);
400
+ return val64;
401
+}
402
+
403
+static uint64_t crl_rst_usb_prew(RegisterInfo *reg, uint64_t val64)
404
+{
405
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
406
+
407
+ REGFIELD_RESET(dev, s, RST_USB0, RESET, val64, s->cfg.usb);
408
+ return val64;
409
+}
410
+
411
+static const RegisterAccessInfo crl_regs_info[] = {
412
+ { .name = "ERR_CTRL", .addr = A_ERR_CTRL,
413
+ },{ .name = "IR_STATUS", .addr = A_IR_STATUS,
414
+ .w1c = 0x1,
415
+ .post_write = crl_status_postw,
416
+ },{ .name = "IR_MASK", .addr = A_IR_MASK,
417
+ .reset = 0x1,
418
+ .ro = 0x1,
419
+ },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE,
420
+ .pre_write = crl_enable_prew,
421
+ },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE,
422
+ .pre_write = crl_disable_prew,
423
+ },{ .name = "WPROT", .addr = A_WPROT,
424
+ },{ .name = "PLL_CLK_OTHER_DMN", .addr = A_PLL_CLK_OTHER_DMN,
425
+ .reset = 0x1,
426
+ .rsvd = 0xe,
427
+ },{ .name = "RPLL_CTRL", .addr = A_RPLL_CTRL,
428
+ .reset = 0x24809,
429
+ .rsvd = 0xf88c00f6,
430
+ },{ .name = "RPLL_CFG", .addr = A_RPLL_CFG,
431
+ .reset = 0x2000000,
432
+ .rsvd = 0x1801210,
433
+ },{ .name = "RPLL_FRAC_CFG", .addr = A_RPLL_FRAC_CFG,
434
+ .rsvd = 0x7e330000,
435
+ },{ .name = "PLL_STATUS", .addr = A_PLL_STATUS,
436
+ .reset = R_PLL_STATUS_RPLL_STABLE_MASK |
437
+ R_PLL_STATUS_RPLL_LOCK_MASK,
438
+ .rsvd = 0xfa,
439
+ .ro = 0x5,
440
+ },{ .name = "RPLL_TO_XPD_CTRL", .addr = A_RPLL_TO_XPD_CTRL,
441
+ .reset = 0x2000100,
442
+ .rsvd = 0xfdfc00ff,
443
+ },{ .name = "LPD_TOP_SWITCH_CTRL", .addr = A_LPD_TOP_SWITCH_CTRL,
444
+ .reset = 0x6000300,
445
+ .rsvd = 0xf9fc00f8,
446
+ },{ .name = "LPD_LSBUS_CTRL", .addr = A_LPD_LSBUS_CTRL,
447
+ .reset = 0x2000800,
448
+ .rsvd = 0xfdfc00f8,
449
+ },{ .name = "CPU_R5_CTRL", .addr = A_CPU_R5_CTRL,
450
+ .reset = 0xe000300,
451
+ .rsvd = 0xe1fc00f8,
452
+ },{ .name = "IOU_SWITCH_CTRL", .addr = A_IOU_SWITCH_CTRL,
453
+ .reset = 0x2000500,
454
+ .rsvd = 0xfdfc00f8,
455
+ },{ .name = "GEM0_REF_CTRL", .addr = A_GEM0_REF_CTRL,
456
+ .reset = 0xe000a00,
457
+ .rsvd = 0xf1fc00f8,
458
+ },{ .name = "GEM1_REF_CTRL", .addr = A_GEM1_REF_CTRL,
459
+ .reset = 0xe000a00,
460
+ .rsvd = 0xf1fc00f8,
461
+ },{ .name = "GEM_TSU_REF_CTRL", .addr = A_GEM_TSU_REF_CTRL,
462
+ .reset = 0x300,
463
+ .rsvd = 0xfdfc00f8,
464
+ },{ .name = "USB0_BUS_REF_CTRL", .addr = A_USB0_BUS_REF_CTRL,
465
+ .reset = 0x2001900,
466
+ .rsvd = 0xfdfc00f8,
467
+ },{ .name = "UART0_REF_CTRL", .addr = A_UART0_REF_CTRL,
468
+ .reset = 0xc00,
469
+ .rsvd = 0xfdfc00f8,
470
+ },{ .name = "UART1_REF_CTRL", .addr = A_UART1_REF_CTRL,
471
+ .reset = 0xc00,
472
+ .rsvd = 0xfdfc00f8,
473
+ },{ .name = "SPI0_REF_CTRL", .addr = A_SPI0_REF_CTRL,
474
+ .reset = 0x600,
475
+ .rsvd = 0xfdfc00f8,
476
+ },{ .name = "SPI1_REF_CTRL", .addr = A_SPI1_REF_CTRL,
477
+ .reset = 0x600,
478
+ .rsvd = 0xfdfc00f8,
479
+ },{ .name = "CAN0_REF_CTRL", .addr = A_CAN0_REF_CTRL,
480
+ .reset = 0xc00,
481
+ .rsvd = 0xfdfc00f8,
482
+ },{ .name = "CAN1_REF_CTRL", .addr = A_CAN1_REF_CTRL,
483
+ .reset = 0xc00,
484
+ .rsvd = 0xfdfc00f8,
485
+ },{ .name = "I2C0_REF_CTRL", .addr = A_I2C0_REF_CTRL,
486
+ .reset = 0xc00,
487
+ .rsvd = 0xfdfc00f8,
488
+ },{ .name = "I2C1_REF_CTRL", .addr = A_I2C1_REF_CTRL,
489
+ .reset = 0xc00,
490
+ .rsvd = 0xfdfc00f8,
491
+ },{ .name = "DBG_LPD_CTRL", .addr = A_DBG_LPD_CTRL,
492
+ .reset = 0x300,
493
+ .rsvd = 0xfdfc00f8,
494
+ },{ .name = "TIMESTAMP_REF_CTRL", .addr = A_TIMESTAMP_REF_CTRL,
495
+ .reset = 0x2000c00,
496
+ .rsvd = 0xfdfc00f8,
497
+ },{ .name = "CRL_SAFETY_CHK", .addr = A_CRL_SAFETY_CHK,
498
+ },{ .name = "PSM_REF_CTRL", .addr = A_PSM_REF_CTRL,
499
+ .reset = 0xf04,
500
+ .rsvd = 0xfffc00f8,
501
+ },{ .name = "DBG_TSTMP_CTRL", .addr = A_DBG_TSTMP_CTRL,
502
+ .reset = 0x300,
503
+ .rsvd = 0xfdfc00f8,
504
+ },{ .name = "CPM_TOPSW_REF_CTRL", .addr = A_CPM_TOPSW_REF_CTRL,
505
+ .reset = 0x300,
506
+ .rsvd = 0xfdfc00f8,
507
+ },{ .name = "USB3_DUAL_REF_CTRL", .addr = A_USB3_DUAL_REF_CTRL,
508
+ .reset = 0x3c00,
509
+ .rsvd = 0xfdfc00f8,
510
+ },{ .name = "RST_CPU_R5", .addr = A_RST_CPU_R5,
511
+ .reset = 0x17,
512
+ .rsvd = 0x8,
513
+ .pre_write = crl_rst_r5_prew,
514
+ },{ .name = "RST_ADMA", .addr = A_RST_ADMA,
515
+ .reset = 0x1,
516
+ .pre_write = crl_rst_adma_prew,
517
+ },{ .name = "RST_GEM0", .addr = A_RST_GEM0,
518
+ .reset = 0x1,
519
+ .pre_write = crl_rst_gem0_prew,
520
+ },{ .name = "RST_GEM1", .addr = A_RST_GEM1,
521
+ .reset = 0x1,
522
+ .pre_write = crl_rst_gem1_prew,
523
+ },{ .name = "RST_SPARE", .addr = A_RST_SPARE,
524
+ .reset = 0x1,
525
+ },{ .name = "RST_USB0", .addr = A_RST_USB0,
526
+ .reset = 0x1,
527
+ .pre_write = crl_rst_usb_prew,
528
+ },{ .name = "RST_UART0", .addr = A_RST_UART0,
529
+ .reset = 0x1,
530
+ .pre_write = crl_rst_uart0_prew,
531
+ },{ .name = "RST_UART1", .addr = A_RST_UART1,
532
+ .reset = 0x1,
533
+ .pre_write = crl_rst_uart1_prew,
534
+ },{ .name = "RST_SPI0", .addr = A_RST_SPI0,
535
+ .reset = 0x1,
536
+ },{ .name = "RST_SPI1", .addr = A_RST_SPI1,
537
+ .reset = 0x1,
538
+ },{ .name = "RST_CAN0", .addr = A_RST_CAN0,
539
+ .reset = 0x1,
540
+ },{ .name = "RST_CAN1", .addr = A_RST_CAN1,
541
+ .reset = 0x1,
542
+ },{ .name = "RST_I2C0", .addr = A_RST_I2C0,
543
+ .reset = 0x1,
544
+ },{ .name = "RST_I2C1", .addr = A_RST_I2C1,
545
+ .reset = 0x1,
546
+ },{ .name = "RST_DBG_LPD", .addr = A_RST_DBG_LPD,
547
+ .reset = 0x33,
548
+ .rsvd = 0xcc,
549
+ },{ .name = "RST_GPIO", .addr = A_RST_GPIO,
550
+ .reset = 0x1,
551
+ },{ .name = "RST_TTC", .addr = A_RST_TTC,
552
+ .reset = 0xf,
553
+ },{ .name = "RST_TIMESTAMP", .addr = A_RST_TIMESTAMP,
554
+ .reset = 0x1,
555
+ },{ .name = "RST_SWDT", .addr = A_RST_SWDT,
556
+ .reset = 0x1,
557
+ },{ .name = "RST_OCM", .addr = A_RST_OCM,
558
+ },{ .name = "RST_IPI", .addr = A_RST_IPI,
559
+ },{ .name = "RST_FPD", .addr = A_RST_FPD,
560
+ .reset = 0x3,
561
+ },{ .name = "PSM_RST_MODE", .addr = A_PSM_RST_MODE,
562
+ .reset = 0x1,
563
+ .rsvd = 0xf8,
564
+ }
565
+};
566
+
567
+static void crl_reset_enter(Object *obj, ResetType type)
568
+{
569
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
570
+ unsigned int i;
571
+
572
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
573
+ register_reset(&s->regs_info[i]);
574
+ }
575
+}
576
+
577
+static void crl_reset_hold(Object *obj)
578
+{
579
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
580
+
581
+ crl_update_irq(s);
582
+}
583
+
584
+static const MemoryRegionOps crl_ops = {
585
+ .read = register_read_memory,
586
+ .write = register_write_memory,
587
+ .endianness = DEVICE_LITTLE_ENDIAN,
588
+ .valid = {
589
+ .min_access_size = 4,
590
+ .max_access_size = 4,
591
+ },
592
+};
593
+
594
+static void crl_init(Object *obj)
595
+{
596
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
597
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
598
+ int i;
599
+
600
+ s->reg_array =
601
+ register_init_block32(DEVICE(obj), crl_regs_info,
602
+ ARRAY_SIZE(crl_regs_info),
603
+ s->regs_info, s->regs,
604
+ &crl_ops,
605
+ XLNX_VERSAL_CRL_ERR_DEBUG,
606
+ CRL_R_MAX * 4);
607
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
608
+ sysbus_init_irq(sbd, &s->irq);
609
+
610
+ for (i = 0; i < ARRAY_SIZE(s->cfg.cpu_r5); ++i) {
611
+ object_property_add_link(obj, "cpu_r5[*]", TYPE_ARM_CPU,
612
+ (Object **)&s->cfg.cpu_r5[i],
613
+ qdev_prop_allow_set_link_before_realize,
614
+ OBJ_PROP_LINK_STRONG);
615
+ }
616
+
617
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); ++i) {
618
+ object_property_add_link(obj, "adma[*]", TYPE_DEVICE,
619
+ (Object **)&s->cfg.adma[i],
620
+ qdev_prop_allow_set_link_before_realize,
621
+ OBJ_PROP_LINK_STRONG);
622
+ }
623
+
624
+ for (i = 0; i < ARRAY_SIZE(s->cfg.uart); ++i) {
625
+ object_property_add_link(obj, "uart[*]", TYPE_DEVICE,
626
+ (Object **)&s->cfg.uart[i],
627
+ qdev_prop_allow_set_link_before_realize,
628
+ OBJ_PROP_LINK_STRONG);
629
+ }
630
+
631
+ for (i = 0; i < ARRAY_SIZE(s->cfg.gem); ++i) {
632
+ object_property_add_link(obj, "gem[*]", TYPE_DEVICE,
633
+ (Object **)&s->cfg.gem[i],
634
+ qdev_prop_allow_set_link_before_realize,
635
+ OBJ_PROP_LINK_STRONG);
636
+ }
637
+
638
+ object_property_add_link(obj, "usb", TYPE_DEVICE,
639
+ (Object **)&s->cfg.gem[i],
640
+ qdev_prop_allow_set_link_before_realize,
641
+ OBJ_PROP_LINK_STRONG);
642
+}
643
+
644
+static void crl_finalize(Object *obj)
645
+{
646
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
647
+ register_finalize_block(s->reg_array);
648
+}
649
+
650
+static const VMStateDescription vmstate_crl = {
651
+ .name = TYPE_XLNX_VERSAL_CRL,
80
+ .version_id = 1,
652
+ .version_id = 1,
81
+ .minimum_version_id = 1,
653
+ .minimum_version_id = 1,
82
+ .fields = (VMStateField[]) {
654
+ .fields = (VMStateField[]) {
83
+ VMSTATE_UINT32(env.v7m.scr[M_REG_NS], ARMCPU),
655
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalCRL, CRL_R_MAX),
84
+ VMSTATE_END_OF_LIST()
656
+ VMSTATE_END_OF_LIST(),
85
+ }
657
+ }
86
+};
658
+};
87
+
659
+
88
static const VMStateDescription vmstate_m = {
660
+static void crl_class_init(ObjectClass *klass, void *data)
89
.name = "cpu/m",
661
+{
90
.version_id = 4,
662
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
91
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
663
+ DeviceClass *dc = DEVICE_CLASS(klass);
92
.subsections = (const VMStateDescription*[]) {
664
+
93
&vmstate_m_faultmask_primask,
665
+ dc->vmsd = &vmstate_crl;
94
&vmstate_m_csselr,
666
+
95
+ &vmstate_m_scr,
667
+ rc->phases.enter = crl_reset_enter;
96
NULL
668
+ rc->phases.hold = crl_reset_hold;
97
}
669
+}
98
};
670
+
99
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
671
+static const TypeInfo crl_info = {
100
VMSTATE_UINT32(env.sau.rnr, ARMCPU),
672
+ .name = TYPE_XLNX_VERSAL_CRL,
101
VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate),
673
+ .parent = TYPE_SYS_BUS_DEVICE,
102
VMSTATE_UINT32(env.sau.ctrl, ARMCPU),
674
+ .instance_size = sizeof(XlnxVersalCRL),
103
+ VMSTATE_UINT32(env.v7m.scr[M_REG_S], ARMCPU),
675
+ .class_init = crl_class_init,
104
VMSTATE_END_OF_LIST()
676
+ .instance_init = crl_init,
105
}
677
+ .instance_finalize = crl_finalize,
106
};
678
+};
679
+
680
+static void crl_register_types(void)
681
+{
682
+ type_register_static(&crl_info);
683
+}
684
+
685
+type_init(crl_register_types)
686
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
687
index XXXXXXX..XXXXXXX 100644
688
--- a/hw/misc/meson.build
689
+++ b/hw/misc/meson.build
690
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
691
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
692
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-crf.c'))
693
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-apu-ctrl.c'))
694
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
695
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
696
'xlnx-versal-xramc.c',
697
'xlnx-versal-pmc-iou-slcr.c',
107
--
698
--
108
2.16.1
699
2.25.1
109
110
diff view generated by jsdifflib
1
From: Pekka Enberg <penberg@iki.fi>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
This patch adds Raspberry Pi 3 support to hw/arm/raspi.c. The
3
Connect the CRL (Clock Reset LPD) to the Versal SoC.
4
differences to Pi 2 are:
5
4
6
- Firmware address
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
7
- Board ID
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
8
- Board revision
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
9
8
Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com
10
The CPU is different too, but that's going to be configured as part of
11
the machine default CPU when we introduce a new machine type.
12
13
The patch was written from scratch by me but the logic is similar to
14
Zoltán Baldaszti's previous work, which I used as a reference (with
15
permission from the author):
16
17
https://github.com/bztsrc/qemu-raspi3
18
19
Signed-off-by: Pekka Enberg <penberg@iki.fi>
20
[PMM: fixed trailing whitespace on one line]
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
10
---
24
hw/arm/raspi.c | 31 +++++++++++++++++++++----------
11
include/hw/arm/xlnx-versal.h | 4 +++
25
1 file changed, 21 insertions(+), 10 deletions(-)
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
13
2 files changed, 56 insertions(+), 2 deletions(-)
26
14
27
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
28
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/raspi.c
17
--- a/include/hw/arm/xlnx-versal.h
30
+++ b/hw/arm/raspi.c
18
+++ b/include/hw/arm/xlnx-versal.h
31
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
32
* Rasperry Pi 2 emulation Copyright (c) 2015, Microsoft
20
#include "hw/nvram/xlnx-versal-efuse.h"
33
* Written by Andrew Baumann
21
#include "hw/ssi/xlnx-versal-ospi.h"
34
*
22
#include "hw/dma/xlnx_csu_dma.h"
35
+ * Raspberry Pi 3 emulation Copyright (c) 2018 Zoltán Baldaszti
23
+#include "hw/misc/xlnx-versal-crl.h"
36
+ * Upstream code cleanup (c) 2018 Pekka Enberg
24
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
37
+ *
25
38
* This code is licensed under the GNU GPLv2 and later.
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
39
*/
27
@@ -XXX,XX +XXX,XX @@ struct Versal {
40
28
qemu_or_irq irq_orgate;
41
@@ -XXX,XX +XXX,XX @@
29
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
42
#define SMPBOOT_ADDR 0x300 /* this should leave enough space for ATAGS */
30
} xram;
43
#define MVBAR_ADDR 0x400 /* secure vectors */
31
+
44
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
32
+ XlnxVersalCRL crl;
45
-#define FIRMWARE_ADDR 0x8000 /* Pi loads kernel.img here by default */
33
} lpd;
46
+#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
34
47
+#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
35
/* The Platform Management Controller subsystem. */
48
36
@@ -XXX,XX +XXX,XX @@ struct Versal {
49
/* Table of Linux board IDs for different Pi versions */
37
#define VERSAL_TIMER_NS_EL1_IRQ 14
50
-static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43};
38
#define VERSAL_TIMER_NS_EL2_IRQ 10
51
+static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
39
52
40
+#define VERSAL_CRL_IRQ 10
53
typedef struct RasPiState {
41
#define VERSAL_UART0_IRQ_0 18
54
BCM2836State soc;
42
#define VERSAL_UART1_IRQ_0 19
55
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
43
#define VERSAL_USB0_IRQ_0 22
56
binfo.secure_board_setup = true;
44
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
57
binfo.secure_boot = true;
45
index XXXXXXX..XXXXXXX 100644
58
46
--- a/hw/arm/xlnx-versal.c
59
- /* Pi2 requires SMP setup */
47
+++ b/hw/arm/xlnx-versal.c
60
- if (version == 2) {
48
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
61
+ /* Pi2 and Pi3 requires SMP setup */
49
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
62
+ if (version >= 2) {
63
binfo.smp_loader_start = SMPBOOT_ADDR;
64
binfo.write_secondary_boot = write_smpboot;
65
binfo.secondary_cpu_reset_hook = reset_secondary;
66
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
67
* the normal Linux boot process
68
*/
69
if (machine->firmware) {
70
+ hwaddr firmware_addr = version == 3 ? FIRMWARE_ADDR_3 : FIRMWARE_ADDR_2;
71
/* load the firmware image (typically kernel.img) */
72
- r = load_image_targphys(machine->firmware, FIRMWARE_ADDR,
73
- ram_size - FIRMWARE_ADDR);
74
+ r = load_image_targphys(machine->firmware, firmware_addr,
75
+ ram_size - firmware_addr);
76
if (r < 0) {
77
error_report("Failed to load firmware from %s", machine->firmware);
78
exit(1);
79
}
80
81
- binfo.entry = FIRMWARE_ADDR;
82
+ binfo.entry = firmware_addr;
83
binfo.firmware_loaded = true;
84
} else {
85
binfo.kernel_filename = machine->kernel_filename;
86
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
87
arm_load_kernel(ARM_CPU(first_cpu), &binfo);
88
}
50
}
89
51
90
-static void raspi2_init(MachineState *machine)
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
91
+static void raspi_init(MachineState *machine, int version)
53
+{
92
{
54
+ SysBusDevice *sbd;
93
RasPiState *s = g_new0(RasPiState, 1);
55
+ int i;
94
uint32_t vcram_size;
56
+
95
@@ -XXX,XX +XXX,XX @@ static void raspi2_init(MachineState *machine)
57
+ object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
96
&error_abort);
58
+ TYPE_XLNX_VERSAL_CRL);
97
object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
59
+ sbd = SYS_BUS_DEVICE(&s->lpd.crl);
98
&error_abort);
60
+
99
- object_property_set_int(OBJECT(&s->soc), 0xa21041, "board-rev",
61
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
100
+ int board_rev = version == 3 ? 0xa02082 : 0xa21041;
62
+ g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
101
+ object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev",
63
+
102
&error_abort);
64
+ object_property_set_link(OBJECT(&s->lpd.crl),
103
object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort);
65
+ name, OBJECT(&s->lpd.rpu.cpu[i]),
104
66
+ &error_abort);
105
@@ -XXX,XX +XXX,XX @@ static void raspi2_init(MachineState *machine)
67
+ }
106
68
+
107
vcram_size = object_property_get_uint(OBJECT(&s->soc), "vcram-size",
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
108
&error_abort);
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
109
- setup_boot(machine, 2, machine->ram_size - vcram_size);
71
+
110
+ setup_boot(machine, version, machine->ram_size - vcram_size);
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]);
111
+}
101
+}
112
+
102
+
113
+static void raspi2_init(MachineState *machine)
103
/* This takes the board allocated linear DDR memory and creates aliases
114
+{
104
* for each split DDR range/aperture on the Versal address map.
115
+ raspi_init(machine, 2);
105
*/
116
}
106
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
117
107
118
static void raspi2_machine_init(MachineClass *mc)
108
versal_unimp_area(s, "psm", &s->mr_ps,
109
MM_PSM_START, MM_PSM_END - MM_PSM_START);
110
- versal_unimp_area(s, "crl", &s->mr_ps,
111
- MM_CRL, MM_CRL_SIZE);
112
versal_unimp_area(s, "crf", &s->mr_ps,
113
MM_FPD_CRF, MM_FPD_CRF_SIZE);
114
versal_unimp_area(s, "apu", &s->mr_ps,
115
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
116
versal_create_efuse(s, pic);
117
versal_create_pmc_iou_slcr(s, pic);
118
versal_create_ospi(s, pic);
119
+ versal_create_crl(s, pic);
120
versal_map_ddr(s);
121
versal_unimp(s);
122
119
--
123
--
120
2.16.1
124
2.25.1
121
122
diff view generated by jsdifflib
New patch
1
The Exynos4210 SoC device currently uses a custom device
2
"exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ
3
line. We have a standard TYPE_OR_IRQ device for this now, so use
4
that instead.
1
5
6
(This is a migration compatibility break, but that is OK for this
7
machine type.)
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-2-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 +
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
15
2 files changed, 17 insertions(+), 15 deletions(-)
16
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
22
MemoryRegion bootreg_mem;
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
26
};
27
28
#define TYPE_EXYNOS4210_SOC "exynos4210"
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
{
35
Exynos4210State *s = EXYNOS4210_SOC(socdev);
36
MemoryRegion *system_mem = get_system_memory();
37
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
38
SysBusDevice *busdev;
39
DeviceState *dev, *uart[4], *pl330[3];
40
int i, n;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
42
43
/* IRQ Gate */
44
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
45
- dev = qdev_new("exynos4210.irq_gate");
46
- qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
47
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
48
- /* Get IRQ Gate input in gate_irq */
49
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
50
- gate_irq[i][n] = qdev_get_gpio_in(dev, n);
51
- }
52
- busdev = SYS_BUS_DEVICE(dev);
53
-
54
- /* Connect IRQ Gate output to CPU's IRQ line */
55
- sysbus_connect_irq(busdev, 0,
56
- qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
57
+ DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
58
+ object_property_set_int(OBJECT(orgate), "num-lines",
59
+ EXYNOS4210_IRQ_GATE_NINPUTS,
60
+ &error_abort);
61
+ qdev_realize(orgate, NULL, &error_abort);
62
+ qdev_connect_gpio_out(orgate, 0,
63
+ qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
64
}
65
66
/* Private memory region and Internal GIC */
67
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
68
sysbus_realize_and_unref(busdev, &error_fatal);
69
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
70
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
71
- sysbus_connect_irq(busdev, n, gate_irq[n][0]);
72
+ sysbus_connect_irq(busdev, n,
73
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
74
}
75
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
76
s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
77
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
78
/* Map Distributer interface */
79
sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
80
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
81
- sysbus_connect_irq(busdev, n, gate_irq[n][1]);
82
+ sysbus_connect_irq(busdev, n,
83
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
84
}
85
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
86
s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
87
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
88
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
89
g_free(name);
90
}
91
+
92
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
93
+ g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
94
+ object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
95
+ }
96
}
97
98
static void exynos4210_class_init(ObjectClass *klass, void *data)
99
--
100
2.25.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Now we have removed the only use of TYPE_EXYNOS4210_IRQ_GATE we can
2
delete the device entirely.
2
3
3
(qemu) info mtree
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
address-space: cpu-memory-0
5
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
0000000000000000-ffffffffffffffff (prio 0, i/o): system
6
Message-id: 20220404154658.565020-3-peter.maydell@linaro.org
6
0000000000000000-0000000007ffffff (prio 0, rom): aspeed.boot_rom
7
---
7
- 000000001e600000-000000001e7fffff (prio -1, i/o): aspeed_soc.io
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
8
+ 000000001e600000-000000001e7fffff (prio -1000, i/o): aspeed_soc.io
9
1 file changed, 107 deletions(-)
9
000000001e620000-000000001e6200ff (prio 0, i/o): aspeed.smc.ast2500-fmc
10
000000001e630000-000000001e6300ff (prio 0, i/o): aspeed.smc.ast2500-spi1
11
000000001e631000-000000001e6310ff (prio 0, i/o): aspeed.smc.ast2500-spi2
12
10
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
14
Reviewed-by: Cédric Le Goater <clg@kaod.org>
15
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
16
Message-id: 20180209085755.30414-3-f4bug@amsat.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
include/hw/arm/aspeed_soc.h | 1 -
20
hw/arm/aspeed_soc.c | 32 +++-----------------------------
21
2 files changed, 3 insertions(+), 30 deletions(-)
22
23
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
24
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/aspeed_soc.h
13
--- a/hw/intc/exynos4210_gic.c
26
+++ b/include/hw/arm/aspeed_soc.h
14
+++ b/hw/intc/exynos4210_gic.c
27
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
28
16
}
29
/*< public >*/
17
30
ARMCPU cpu;
18
type_init(exynos4210_gic_register_types)
31
- MemoryRegion iomem;
19
-
32
MemoryRegion sram;
20
-/* IRQ OR Gate struct.
33
AspeedVICState vic;
21
- *
34
AspeedTimerCtrlState timerctrl;
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
35
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
36
index XXXXXXX..XXXXXXX 100644
24
- * gpio inputs.
37
--- a/hw/arm/aspeed_soc.c
38
+++ b/hw/arm/aspeed_soc.c
39
@@ -XXX,XX +XXX,XX @@
40
#include "qemu-common.h"
41
#include "cpu.h"
42
#include "exec/address-spaces.h"
43
+#include "hw/misc/unimp.h"
44
#include "hw/arm/aspeed_soc.h"
45
#include "hw/char/serial.h"
46
#include "qemu/log.h"
47
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
48
},
49
};
50
51
-/*
52
- * IO handlers: simply catch any reads/writes to IO addresses that aren't
53
- * handled by a device mapping.
54
- */
25
- */
55
-
26
-
56
-static uint64_t aspeed_soc_io_read(void *p, hwaddr offset, unsigned size)
27
-#define TYPE_EXYNOS4210_IRQ_GATE "exynos4210.irq_gate"
28
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210IRQGateState, EXYNOS4210_IRQ_GATE)
29
-
30
-struct Exynos4210IRQGateState {
31
- SysBusDevice parent_obj;
32
-
33
- uint32_t n_in; /* inputs amount */
34
- uint32_t *level; /* input levels */
35
- qemu_irq out; /* output IRQ */
36
-};
37
-
38
-static Property exynos4210_irq_gate_properties[] = {
39
- DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
40
- DEFINE_PROP_END_OF_LIST(),
41
-};
42
-
43
-static const VMStateDescription vmstate_exynos4210_irq_gate = {
44
- .name = "exynos4210.irq_gate",
45
- .version_id = 2,
46
- .minimum_version_id = 2,
47
- .fields = (VMStateField[]) {
48
- VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, n_in),
49
- VMSTATE_END_OF_LIST()
50
- }
51
-};
52
-
53
-/* Process a change in IRQ input. */
54
-static void exynos4210_irq_gate_handler(void *opaque, int irq, int level)
57
-{
55
-{
58
- qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
56
- Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)opaque;
59
- __func__, offset, size);
57
- uint32_t i;
60
- return 0;
58
-
59
- assert(irq < s->n_in);
60
-
61
- s->level[irq] = level;
62
-
63
- for (i = 0; i < s->n_in; i++) {
64
- if (s->level[i] >= 1) {
65
- qemu_irq_raise(s->out);
66
- return;
67
- }
68
- }
69
-
70
- qemu_irq_lower(s->out);
61
-}
71
-}
62
-
72
-
63
-static void aspeed_soc_io_write(void *opaque, hwaddr offset, uint64_t value,
73
-static void exynos4210_irq_gate_reset(DeviceState *d)
64
- unsigned size)
65
-{
74
-{
66
- qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
75
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(d);
67
- __func__, offset, value, size);
76
-
77
- memset(s->level, 0, s->n_in * sizeof(*s->level));
68
-}
78
-}
69
-
79
-
70
-static const MemoryRegionOps aspeed_soc_io_ops = {
80
-/*
71
- .read = aspeed_soc_io_read,
81
- * IRQ Gate initialization.
72
- .write = aspeed_soc_io_write,
82
- */
73
- .endianness = DEVICE_LITTLE_ENDIAN,
83
-static void exynos4210_irq_gate_init(Object *obj)
84
-{
85
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(obj);
86
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
87
-
88
- sysbus_init_irq(sbd, &s->out);
89
-}
90
-
91
-static void exynos4210_irq_gate_realize(DeviceState *dev, Error **errp)
92
-{
93
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(dev);
94
-
95
- /* Allocate general purpose input signals and connect a handler to each of
96
- * them */
97
- qdev_init_gpio_in(dev, exynos4210_irq_gate_handler, s->n_in);
98
-
99
- s->level = g_malloc0(s->n_in * sizeof(*s->level));
100
-}
101
-
102
-static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
103
-{
104
- DeviceClass *dc = DEVICE_CLASS(klass);
105
-
106
- dc->reset = exynos4210_irq_gate_reset;
107
- dc->vmsd = &vmstate_exynos4210_irq_gate;
108
- device_class_set_props(dc, exynos4210_irq_gate_properties);
109
- dc->realize = exynos4210_irq_gate_realize;
110
-}
111
-
112
-static const TypeInfo exynos4210_irq_gate_info = {
113
- .name = TYPE_EXYNOS4210_IRQ_GATE,
114
- .parent = TYPE_SYS_BUS_DEVICE,
115
- .instance_size = sizeof(Exynos4210IRQGateState),
116
- .instance_init = exynos4210_irq_gate_init,
117
- .class_init = exynos4210_irq_gate_class_init,
74
-};
118
-};
75
-
119
-
76
static void aspeed_soc_init(Object *obj)
120
-static void exynos4210_irq_gate_register_types(void)
77
{
121
-{
78
AspeedSoCState *s = ASPEED_SOC(obj);
122
- type_register_static(&exynos4210_irq_gate_info);
79
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
123
-}
80
Error *err = NULL, *local_err = NULL;
124
-
81
125
-type_init(exynos4210_irq_gate_register_types)
82
/* IO space */
83
- memory_region_init_io(&s->iomem, NULL, &aspeed_soc_io_ops, NULL,
84
- "aspeed_soc.io", ASPEED_SOC_IOMEM_SIZE);
85
- memory_region_add_subregion_overlap(get_system_memory(),
86
- ASPEED_SOC_IOMEM_BASE, &s->iomem, -1);
87
+ create_unimplemented_device("aspeed_soc.io",
88
+ ASPEED_SOC_IOMEM_BASE, ASPEED_SOC_IOMEM_SIZE);
89
90
/* CPU */
91
object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
92
--
126
--
93
2.16.1
127
2.25.1
94
95
diff view generated by jsdifflib
New patch
1
The exynos4210 SoC mostly creates its child devices as if it were
2
board code. This includes the a9mpcore object. Switch that to a
3
new-style "embedded in the state struct" creation, because in the
4
next commit we're going to want to refer to the object again further
5
down in the exynos4210_realize() function.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220404154658.565020-4-peter.maydell@linaro.org
10
---
11
include/hw/arm/exynos4210.h | 2 ++
12
hw/arm/exynos4210.c | 11 ++++++-----
13
2 files changed, 8 insertions(+), 5 deletions(-)
14
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/exynos4210.h
18
+++ b/include/hw/arm/exynos4210.h
19
@@ -XXX,XX +XXX,XX @@
20
21
#include "hw/or-irq.h"
22
#include "hw/sysbus.h"
23
+#include "hw/cpu/a9mpcore.h"
24
#include "target/arm/cpu-qom.h"
25
#include "qom/object.h"
26
27
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
28
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
29
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
30
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
31
+ A9MPPrivState a9mpcore;
32
};
33
34
#define TYPE_EXYNOS4210_SOC "exynos4210"
35
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/arm/exynos4210.c
38
+++ b/hw/arm/exynos4210.c
39
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
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
}
65
+
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
67
}
68
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
70
--
71
2.25.1
diff view generated by jsdifflib
New patch
1
The only time we use the int_gic_irq[] array in the Exynos4210Irq
2
struct is in the exynos4210_realize() function: we initialize it with
3
the GPIO inputs of the a9mpcore device, and then a bit later on we
4
connect those to the outputs of the internal combiner. Now that the
5
a9mpcore object is easily accessible as s->a9mpcore we can make the
6
connection directly from one device to the other without going via
7
this array.
1
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-5-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 -
14
hw/arm/exynos4210.c | 6 ++----
15
2 files changed, 2 insertions(+), 5 deletions(-)
16
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@
22
typedef struct Exynos4210Irq {
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
25
- qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
26
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
27
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
28
} Exynos4210Irq;
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
sysbus_connect_irq(busdev, n,
35
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
36
}
37
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
38
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
39
- }
40
41
/* Cache controller */
42
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
43
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
44
busdev = SYS_BUS_DEVICE(dev);
45
sysbus_realize_and_unref(busdev, &error_fatal);
46
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
47
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
48
+ sysbus_connect_irq(busdev, n,
49
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
50
}
51
exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
52
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
53
--
54
2.25.1
diff view generated by jsdifflib
New patch
1
The exynos4210 code currently has two very similar arrays of IRQs:
1
2
3
* board_irqs is a field of the Exynos4210Irq struct which is filled
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
5
for each IRQ the board/SoC can assert
6
* irq_table is a set of qemu_irqs pointed to from the
7
Exynos4210State struct. It's allocated in exynos4210_init_irq,
8
and the only behaviour these irqs have is that they pass on the
9
level to the equivalent board_irqs[] irq
10
11
The extra indirection through irq_table is unnecessary, so coalesce
12
these into a single irq_table[] array as a direct field in
13
Exynos4210State which exynos4210_init_board_irqs() fills in.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20220404154658.565020-6-peter.maydell@linaro.org
18
---
19
include/hw/arm/exynos4210.h | 8 ++------
20
hw/arm/exynos4210.c | 6 +-----
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
22
3 files changed, 11 insertions(+), 35 deletions(-)
23
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/arm/exynos4210.h
27
+++ b/include/hw/arm/exynos4210.h
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
33
} Exynos4210Irq;
34
35
struct Exynos4210State {
36
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
37
/*< public >*/
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
39
Exynos4210Irq irqs;
40
- qemu_irq *irq_table;
41
+ qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
42
43
MemoryRegion chipid_mem;
44
MemoryRegion iram_mem;
45
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
46
void exynos4210_write_secondary(ARMCPU *cpu,
47
const struct arm_boot_info *info);
48
49
-/* Initialize exynos4210 IRQ subsystem stub */
50
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
51
-
52
/* Initialize board IRQs.
53
* These IRQs contain splitted Int/External Combiner and External Gic IRQs */
54
-void exynos4210_init_board_irqs(Exynos4210Irq *s);
55
+void exynos4210_init_board_irqs(Exynos4210State *s);
56
57
/* Get IRQ number from exynos4210 IRQ subsystem stub.
58
* To identify IRQ source use internal combiner group and bit number
59
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/exynos4210.c
62
+++ b/hw/arm/exynos4210.c
63
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
64
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
65
}
66
67
- /*** IRQs ***/
68
-
69
- s->irq_table = exynos4210_init_irq(&s->irqs);
70
-
71
/* IRQ Gate */
72
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
73
DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
74
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
75
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
76
77
/* Initialize board IRQs. */
78
- exynos4210_init_board_irqs(&s->irqs);
79
+ exynos4210_init_board_irqs(s);
80
81
/*** Memory ***/
82
83
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/intc/exynos4210_gic.c
86
+++ b/hw/intc/exynos4210_gic.c
87
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
88
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
89
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
90
91
-static void exynos4210_irq_handler(void *opaque, int irq, int level)
92
-{
93
- Exynos4210Irq *s = (Exynos4210Irq *)opaque;
94
-
95
- /* Bypass */
96
- qemu_set_irq(s->board_irqs[irq], level);
97
-}
98
-
99
-/*
100
- * Initialize exynos4210 IRQ subsystem stub.
101
- */
102
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *s)
103
-{
104
- return qemu_allocate_irqs(exynos4210_irq_handler, s,
105
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ);
106
-}
107
-
108
/*
109
* Initialize board IRQs.
110
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
111
*/
112
-void exynos4210_init_board_irqs(Exynos4210Irq *s)
113
+void exynos4210_init_board_irqs(Exynos4210State *s)
114
{
115
uint32_t grp, bit, irq_id, n;
116
+ Exynos4210Irq *is = &s->irqs;
117
118
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
119
irq_id = 0;
120
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
121
irq_id = EXT_GIC_ID_MCT_G1;
122
}
123
if (irq_id) {
124
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
125
- s->ext_gic_irq[irq_id-32]);
126
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
127
+ is->ext_gic_irq[irq_id - 32]);
128
} else {
129
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
130
- s->ext_combiner_irq[n]);
131
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
132
+ is->ext_combiner_irq[n]);
133
}
134
}
135
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
136
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
137
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
138
139
if (irq_id) {
140
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
141
- s->ext_gic_irq[irq_id-32]);
142
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
143
+ is->ext_gic_irq[irq_id - 32]);
144
}
145
}
146
}
147
--
148
2.25.1
diff view generated by jsdifflib
New patch
1
Fix a missing set of spaces around '-' in the definition of
2
combiner_grp_to_gic_id[]. We're about to move this code, so
3
fix the style issue first to keep checkpatch happy with the
4
code-motion patch.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220404154658.565020-7-peter.maydell@linaro.org
9
---
10
hw/intc/exynos4210_gic.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
12
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/exynos4210_gic.c
16
+++ b/hw/intc/exynos4210_gic.c
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
18
*/
19
20
static const uint32_t
21
-combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
22
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
23
/* int combiner groups 16-19 */
24
{ }, { }, { }, { },
25
/* int combiner group 20 */
26
--
27
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The function exynos4210_init_board_irqs() currently lives in
2
exynos4210_gic.c, but it isn't really part of the exynos4210.gic
3
device -- it is a function that implements (some of) the wiring up of
4
interrupts between the SoC's GIC and combiner components. This means
5
it fits better in exynos4210.c, which is the SoC-level code. Move it
6
there. Similarly, exynos4210_git_irq() is used almost only in the
7
SoC-level code, so move it too.
2
8
3
When storing to an AdvSIMD FP register, all of the high
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
bits of the SVE register are zeroed. Therefore, call it
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
more often with is_q as a parameter.
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 4 -
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
16
3 files changed, 202 insertions(+), 208 deletions(-)
6
17
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
8
Message-id: 20180211205848.4568-6-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 162 +++++++++++++++++----------------------------
13
1 file changed, 62 insertions(+), 100 deletions(-)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
20
--- a/include/hw/arm/exynos4210.h
18
+++ b/target/arm/translate-a64.c
21
+++ b/include/hw/arm/exynos4210.h
19
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
20
return v;
23
void exynos4210_write_secondary(ARMCPU *cpu,
21
}
24
const struct arm_boot_info *info);
22
25
23
+/* Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64).
26
-/* Initialize board IRQs.
24
+ * If SVE is not enabled, then there are only 128 bits in the vector.
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
29
-
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
31
* To identify IRQ source use internal combiner group and bit number
32
* grp - group number
33
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/exynos4210.c
36
+++ b/hw/arm/exynos4210.c
37
@@ -XXX,XX +XXX,XX @@
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
40
41
+enum ExtGicId {
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
43
+ EXT_GIC_ID_PDMA0,
44
+ EXT_GIC_ID_PDMA1,
45
+ EXT_GIC_ID_TIMER0,
46
+ EXT_GIC_ID_TIMER1,
47
+ EXT_GIC_ID_TIMER2,
48
+ EXT_GIC_ID_TIMER3,
49
+ EXT_GIC_ID_TIMER4,
50
+ EXT_GIC_ID_MCT_L0,
51
+ EXT_GIC_ID_WDT,
52
+ EXT_GIC_ID_RTC_ALARM,
53
+ EXT_GIC_ID_RTC_TIC,
54
+ EXT_GIC_ID_GPIO_XB,
55
+ EXT_GIC_ID_GPIO_XA,
56
+ EXT_GIC_ID_MCT_L1,
57
+ EXT_GIC_ID_IEM_APC,
58
+ EXT_GIC_ID_IEM_IEC,
59
+ EXT_GIC_ID_NFC,
60
+ EXT_GIC_ID_UART0,
61
+ EXT_GIC_ID_UART1,
62
+ EXT_GIC_ID_UART2,
63
+ EXT_GIC_ID_UART3,
64
+ EXT_GIC_ID_UART4,
65
+ EXT_GIC_ID_MCT_G0,
66
+ EXT_GIC_ID_I2C0,
67
+ EXT_GIC_ID_I2C1,
68
+ EXT_GIC_ID_I2C2,
69
+ EXT_GIC_ID_I2C3,
70
+ EXT_GIC_ID_I2C4,
71
+ EXT_GIC_ID_I2C5,
72
+ EXT_GIC_ID_I2C6,
73
+ EXT_GIC_ID_I2C7,
74
+ EXT_GIC_ID_SPI0,
75
+ EXT_GIC_ID_SPI1,
76
+ EXT_GIC_ID_SPI2,
77
+ EXT_GIC_ID_MCT_G1,
78
+ EXT_GIC_ID_USB_HOST,
79
+ EXT_GIC_ID_USB_DEVICE,
80
+ EXT_GIC_ID_MODEMIF,
81
+ EXT_GIC_ID_HSMMC0,
82
+ EXT_GIC_ID_HSMMC1,
83
+ EXT_GIC_ID_HSMMC2,
84
+ EXT_GIC_ID_HSMMC3,
85
+ EXT_GIC_ID_SDMMC,
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
90
+ EXT_GIC_ID_ONENAND_AUDI,
91
+ EXT_GIC_ID_ROTATOR,
92
+ EXT_GIC_ID_FIMC0,
93
+ EXT_GIC_ID_FIMC1,
94
+ EXT_GIC_ID_FIMC2,
95
+ EXT_GIC_ID_FIMC3,
96
+ EXT_GIC_ID_JPEG,
97
+ EXT_GIC_ID_2D,
98
+ EXT_GIC_ID_PCIe,
99
+ EXT_GIC_ID_MIXER,
100
+ EXT_GIC_ID_HDMI,
101
+ EXT_GIC_ID_HDMI_I2C,
102
+ EXT_GIC_ID_MFC,
103
+ EXT_GIC_ID_TVENC,
104
+};
105
+
106
+enum ExtInt {
107
+ EXT_GIC_ID_EXTINT0 = 48,
108
+ EXT_GIC_ID_EXTINT1,
109
+ EXT_GIC_ID_EXTINT2,
110
+ EXT_GIC_ID_EXTINT3,
111
+ EXT_GIC_ID_EXTINT4,
112
+ EXT_GIC_ID_EXTINT5,
113
+ EXT_GIC_ID_EXTINT6,
114
+ EXT_GIC_ID_EXTINT7,
115
+ EXT_GIC_ID_EXTINT8,
116
+ EXT_GIC_ID_EXTINT9,
117
+ EXT_GIC_ID_EXTINT10,
118
+ EXT_GIC_ID_EXTINT11,
119
+ EXT_GIC_ID_EXTINT12,
120
+ EXT_GIC_ID_EXTINT13,
121
+ EXT_GIC_ID_EXTINT14,
122
+ EXT_GIC_ID_EXTINT15
123
+};
124
+
125
+/*
126
+ * External GIC sources which are not from External Interrupt Combiner or
127
+ * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
128
+ * which is INTG16 in Internal Interrupt Combiner.
25
+ */
129
+ */
26
+static void clear_vec_high(DisasContext *s, bool is_q, int rd)
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)
27
+{
194
+{
28
+ unsigned ofs = fp_reg_offset(s, rd, MO_64);
195
+ uint32_t grp, bit, irq_id, n;
29
+ unsigned vsz = vec_full_reg_size(s);
196
+ Exynos4210Irq *is = &s->irqs;
30
+
197
+
31
+ if (!is_q) {
198
+ for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
32
+ TCGv_i64 tcg_zero = tcg_const_i64(0);
199
+ irq_id = 0;
33
+ tcg_gen_st_i64(tcg_zero, cpu_env, ofs + 8);
200
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
34
+ tcg_temp_free_i64(tcg_zero);
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
+ }
35
+ }
217
+ }
36
+ if (vsz > 16) {
218
+ for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
37
+ tcg_gen_gvec_dup8i(ofs + 16, vsz - 16, vsz - 16, 0);
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
+ }
38
+ }
229
+ }
39
+}
230
+}
40
+
231
+
41
static void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v)
232
+/*
42
{
233
+ * Get IRQ number from exynos4210 IRQ subsystem stub.
43
- TCGv_i64 tcg_zero = tcg_const_i64(0);
234
+ * To identify IRQ source use internal combiner group and bit number
44
+ unsigned ofs = fp_reg_offset(s, reg, MO_64);
235
+ * grp - group number
45
236
+ * bit - bit number inside group
46
- tcg_gen_st_i64(v, cpu_env, fp_reg_offset(s, reg, MO_64));
237
+ */
47
- tcg_gen_st_i64(tcg_zero, cpu_env, fp_reg_hi_offset(s, reg));
238
+uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
48
- tcg_temp_free_i64(tcg_zero);
239
+{
49
+ tcg_gen_st_i64(v, cpu_env, ofs);
240
+ return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
50
+ clear_vec_high(s, false, reg);
241
+}
51
}
242
+
52
243
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
53
static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v)
244
0x09, 0x00, 0x00, 0x00 };
54
@@ -XXX,XX +XXX,XX @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
245
55
246
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
56
tcg_temp_free_i64(tmplo);
247
index XXXXXXX..XXXXXXX 100644
57
tcg_temp_free_i64(tmphi);
248
--- a/hw/intc/exynos4210_gic.c
58
+
249
+++ b/hw/intc/exynos4210_gic.c
59
+ clear_vec_high(s, true, destidx);
250
@@ -XXX,XX +XXX,XX @@
60
}
251
#include "hw/arm/exynos4210.h"
61
252
#include "qom/object.h"
62
/*
253
63
@@ -XXX,XX +XXX,XX @@ static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
254
-enum ExtGicId {
64
}
255
- EXT_GIC_ID_MDMA_LCD0 = 66,
65
}
256
- EXT_GIC_ID_PDMA0,
66
257
- EXT_GIC_ID_PDMA1,
67
-/* Clear the high 64 bits of a 128 bit vector (in general non-quad
258
- EXT_GIC_ID_TIMER0,
68
- * vector ops all need to do this).
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.
69
- */
342
- */
70
-static void clear_vec_high(DisasContext *s, int rd)
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)
71
-{
414
-{
72
- TCGv_i64 tcg_zero = tcg_const_i64(0);
415
- uint32_t grp, bit, irq_id, n;
73
-
416
- Exynos4210Irq *is = &s->irqs;
74
- write_vec_element(s, tcg_zero, rd, 1, MO_64);
417
-
75
- tcg_temp_free_i64(tcg_zero);
418
- for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
419
- irq_id = 0;
420
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
421
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
422
- /* MCT_G0 is passed to External GIC */
423
- irq_id = EXT_GIC_ID_MCT_G0;
424
- }
425
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
426
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
427
- /* MCT_G1 is passed to External and GIC */
428
- irq_id = EXT_GIC_ID_MCT_G1;
429
- }
430
- if (irq_id) {
431
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
432
- is->ext_gic_irq[irq_id - 32]);
433
- } else {
434
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
435
- is->ext_combiner_irq[n]);
436
- }
437
- }
438
- for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
439
- /* these IDs are passed to Internal Combiner and External GIC */
440
- grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
441
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
442
- irq_id = combiner_grp_to_gic_id[grp -
443
- EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
444
-
445
- if (irq_id) {
446
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
447
- is->ext_gic_irq[irq_id - 32]);
448
- }
449
- }
76
-}
450
-}
77
-
451
-
78
/* Store from vector register to memory */
452
-/*
79
static void do_vec_st(DisasContext *s, int srcidx, int element,
453
- * Get IRQ number from exynos4210 IRQ subsystem stub.
80
TCGv_i64 tcg_addr, int size)
454
- * To identify IRQ source use internal combiner group and bit number
81
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
455
- * grp - group number
82
/* For non-quad operations, setting a slice of the low
456
- * bit - bit number inside group
83
* 64 bits of the register clears the high 64 bits (in
457
- */
84
* the ARM ARM pseudocode this is implicit in the fact
458
-uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
85
- * that 'rval' is a 64 bit wide variable). We optimize
459
-{
86
- * by noticing that we only need to do this the first
460
- return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
87
- * time we touch a register.
461
-}
88
+ * that 'rval' is a 64 bit wide variable).
462
-
89
+ * For quad operations, we might still need to zero the
463
-/********* GIC part *********/
90
+ * high bits of SVE. We optimize by noticing that we only
464
-
91
+ * need to do this the first time we touch a register.
465
#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
92
*/
466
OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
93
- if (!is_q && e == 0 && (r == 0 || xs == selem - 1)) {
94
- clear_vec_high(s, tt);
95
+ if (e == 0 && (r == 0 || xs == selem - 1)) {
96
+ clear_vec_high(s, is_q, tt);
97
}
98
}
99
tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
100
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
101
write_vec_element(s, tcg_tmp, rt, 0, MO_64);
102
if (is_q) {
103
write_vec_element(s, tcg_tmp, rt, 1, MO_64);
104
- } else {
105
- clear_vec_high(s, rt);
106
}
107
tcg_temp_free_i64(tcg_tmp);
108
+ clear_vec_high(s, is_q, rt);
109
} else {
110
/* Load/store one element per register */
111
if (is_load) {
112
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_sqshrn(DisasContext *s, bool is_scalar, bool is_q,
113
}
114
115
if (!is_q) {
116
- clear_vec_high(s, rd);
117
write_vec_element(s, tcg_final, rd, 0, MO_64);
118
} else {
119
write_vec_element(s, tcg_final, rd, 1, MO_64);
120
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_sqshrn(DisasContext *s, bool is_scalar, bool is_q,
121
tcg_temp_free_i64(tcg_rd);
122
tcg_temp_free_i32(tcg_rd_narrowed);
123
tcg_temp_free_i64(tcg_final);
124
- return;
125
+
126
+ clear_vec_high(s, is_q, rd);
127
}
128
129
/* SQSHLU, UQSHL, SQSHL: saturating left shifts */
130
@@ -XXX,XX +XXX,XX @@ static void handle_simd_qshl(DisasContext *s, bool scalar, bool is_q,
131
tcg_temp_free_i64(tcg_op);
132
}
133
tcg_temp_free_i64(tcg_shift);
134
-
135
- if (!is_q) {
136
- clear_vec_high(s, rd);
137
- }
138
+ clear_vec_high(s, is_q, rd);
139
} else {
140
TCGv_i32 tcg_shift = tcg_const_i32(shift);
141
static NeonGenTwoOpEnvFn * const fns[2][2][3] = {
142
@@ -XXX,XX +XXX,XX @@ static void handle_simd_qshl(DisasContext *s, bool scalar, bool is_q,
143
}
144
tcg_temp_free_i32(tcg_shift);
145
146
- if (!is_q && !scalar) {
147
- clear_vec_high(s, rd);
148
+ if (!scalar) {
149
+ clear_vec_high(s, is_q, rd);
150
}
151
}
152
}
153
@@ -XXX,XX +XXX,XX @@ static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
154
}
155
}
156
157
- if (!is_double && elements == 2) {
158
- clear_vec_high(s, rd);
159
- }
160
-
161
tcg_temp_free_i64(tcg_int);
162
tcg_temp_free_ptr(tcg_fpst);
163
tcg_temp_free_i32(tcg_shift);
164
+
165
+ clear_vec_high(s, elements << size == 16, rd);
166
}
167
168
/* UCVTF/SCVTF - Integer to FP conversion */
169
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
170
write_vec_element(s, tcg_op, rd, pass, MO_64);
171
tcg_temp_free_i64(tcg_op);
172
}
173
- if (!is_q) {
174
- clear_vec_high(s, rd);
175
- }
176
+ clear_vec_high(s, is_q, rd);
177
} else {
178
int maxpass = is_scalar ? 1 : is_q ? 4 : 2;
179
for (pass = 0; pass < maxpass; pass++) {
180
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
181
}
182
tcg_temp_free_i32(tcg_op);
183
}
184
- if (!is_q && !is_scalar) {
185
- clear_vec_high(s, rd);
186
+ if (!is_scalar) {
187
+ clear_vec_high(s, is_q, rd);
188
}
189
}
190
191
@@ -XXX,XX +XXX,XX @@ static void handle_3same_float(DisasContext *s, int size, int elements,
192
193
tcg_temp_free_ptr(fpst);
194
195
- if ((elements << size) < 4) {
196
- /* scalar, or non-quad vector op */
197
- clear_vec_high(s, rd);
198
- }
199
+ clear_vec_high(s, elements * (size ? 8 : 4) > 8, rd);
200
}
201
202
/* AdvSIMD scalar three same
203
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
204
}
205
write_vec_element(s, tcg_res, rd, pass, MO_64);
206
}
207
- if (is_scalar) {
208
- clear_vec_high(s, rd);
209
- }
210
-
211
tcg_temp_free_i64(tcg_res);
212
tcg_temp_free_i64(tcg_zero);
213
tcg_temp_free_i64(tcg_op);
214
+
215
+ clear_vec_high(s, !is_scalar, rd);
216
} else {
217
TCGv_i32 tcg_op = tcg_temp_new_i32();
218
TCGv_i32 tcg_zero = tcg_const_i32(0);
219
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
220
tcg_temp_free_i32(tcg_res);
221
tcg_temp_free_i32(tcg_zero);
222
tcg_temp_free_i32(tcg_op);
223
- if (!is_q && !is_scalar) {
224
- clear_vec_high(s, rd);
225
+ if (!is_scalar) {
226
+ clear_vec_high(s, is_q, rd);
227
}
228
}
229
230
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode,
231
}
232
write_vec_element(s, tcg_res, rd, pass, MO_64);
233
}
234
- if (is_scalar) {
235
- clear_vec_high(s, rd);
236
- }
237
-
238
tcg_temp_free_i64(tcg_res);
239
tcg_temp_free_i64(tcg_op);
240
+ clear_vec_high(s, !is_scalar, rd);
241
} else {
242
TCGv_i32 tcg_op = tcg_temp_new_i32();
243
TCGv_i32 tcg_res = tcg_temp_new_i32();
244
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode,
245
}
246
tcg_temp_free_i32(tcg_res);
247
tcg_temp_free_i32(tcg_op);
248
- if (!is_q && !is_scalar) {
249
- clear_vec_high(s, rd);
250
+ if (!is_scalar) {
251
+ clear_vec_high(s, is_q, rd);
252
}
253
}
254
tcg_temp_free_ptr(fpst);
255
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar,
256
write_vec_element_i32(s, tcg_res[pass], rd, destelt + pass, MO_32);
257
tcg_temp_free_i32(tcg_res[pass]);
258
}
259
- if (!is_q) {
260
- clear_vec_high(s, rd);
261
- }
262
+ clear_vec_high(s, is_q, rd);
263
}
264
265
/* Remaining saturating accumulating ops */
266
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_satacc(DisasContext *s, bool is_scalar, bool is_u,
267
}
268
write_vec_element(s, tcg_rd, rd, pass, MO_64);
269
}
270
- if (is_scalar) {
271
- clear_vec_high(s, rd);
272
- }
273
-
274
tcg_temp_free_i64(tcg_rd);
275
tcg_temp_free_i64(tcg_rn);
276
+ clear_vec_high(s, !is_scalar, rd);
277
} else {
278
TCGv_i32 tcg_rn = tcg_temp_new_i32();
279
TCGv_i32 tcg_rd = tcg_temp_new_i32();
280
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_satacc(DisasContext *s, bool is_scalar, bool is_u,
281
}
282
write_vec_element_i32(s, tcg_rd, rd, pass, MO_32);
283
}
284
-
285
- if (!is_q) {
286
- clear_vec_high(s, rd);
287
- }
288
-
289
tcg_temp_free_i32(tcg_rd);
290
tcg_temp_free_i32(tcg_rn);
291
+ clear_vec_high(s, is_q, rd);
292
}
293
}
294
295
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
296
tcg_temp_free_i64(tcg_round);
297
298
done:
299
- if (!is_q) {
300
- clear_vec_high(s, rd);
301
- }
302
+ clear_vec_high(s, is_q, rd);
303
}
304
305
static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
306
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shrn(DisasContext *s, bool is_q,
307
}
308
309
if (!is_q) {
310
- clear_vec_high(s, rd);
311
write_vec_element(s, tcg_final, rd, 0, MO_64);
312
} else {
313
write_vec_element(s, tcg_final, rd, 1, MO_64);
314
}
315
-
316
if (round) {
317
tcg_temp_free_i64(tcg_round);
318
}
319
tcg_temp_free_i64(tcg_rn);
320
tcg_temp_free_i64(tcg_rd);
321
tcg_temp_free_i64(tcg_final);
322
- return;
323
+
324
+ clear_vec_high(s, is_q, rd);
325
}
326
327
328
@@ -XXX,XX +XXX,XX @@ static void handle_3rd_narrowing(DisasContext *s, int is_q, int is_u, int size,
329
write_vec_element_i32(s, tcg_res[pass], rd, pass + part, MO_32);
330
tcg_temp_free_i32(tcg_res[pass]);
331
}
332
- if (!is_q) {
333
- clear_vec_high(s, rd);
334
- }
335
+ clear_vec_high(s, is_q, rd);
336
}
337
338
static void handle_pmull_64(DisasContext *s, int is_q, int rd, int rn, int rm)
339
@@ -XXX,XX +XXX,XX @@ static void handle_simd_3same_pair(DisasContext *s, int is_q, int u, int opcode,
340
write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_32);
341
tcg_temp_free_i32(tcg_res[pass]);
342
}
343
- if (!is_q) {
344
- clear_vec_high(s, rd);
345
- }
346
+ clear_vec_high(s, is_q, rd);
347
}
348
349
if (fpst) {
350
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
351
tcg_temp_free_i32(tcg_op2);
352
}
353
}
354
-
355
- if (!is_q) {
356
- clear_vec_high(s, rd);
357
- }
358
+ clear_vec_high(s, is_q, rd);
359
}
360
361
/* AdvSIMD three same
362
@@ -XXX,XX +XXX,XX @@ static void handle_rev(DisasContext *s, int opcode, bool u,
363
write_vec_element(s, tcg_tmp, rd, i, grp_size);
364
tcg_temp_free_i64(tcg_tmp);
365
}
366
- if (!is_q) {
367
- clear_vec_high(s, rd);
368
- }
369
+ clear_vec_high(s, is_q, rd);
370
} else {
371
int revmask = (1 << grp_size) - 1;
372
int esize = 8 << size;
373
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
374
tcg_temp_free_i32(tcg_op);
375
}
376
}
377
- if (!is_q) {
378
- clear_vec_high(s, rd);
379
- }
380
+ clear_vec_high(s, is_q, rd);
381
382
if (need_rmode) {
383
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
384
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
385
tcg_temp_free_i64(tcg_res);
386
}
387
388
- if (is_scalar) {
389
- clear_vec_high(s, rd);
390
- }
391
-
392
tcg_temp_free_i64(tcg_idx);
393
+ clear_vec_high(s, !is_scalar, rd);
394
} else if (!is_long) {
395
/* 32 bit floating point, or 16 or 32 bit integer.
396
* For the 16 bit scalar case we use the usual Neon helpers and
397
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
398
}
399
400
tcg_temp_free_i32(tcg_idx);
401
-
402
- if (!is_q) {
403
- clear_vec_high(s, rd);
404
- }
405
+ clear_vec_high(s, is_q, rd);
406
} else {
407
/* long ops: 16x16->32 or 32x32->64 */
408
TCGv_i64 tcg_res[2];
409
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
410
}
411
tcg_temp_free_i64(tcg_idx);
412
413
- if (is_scalar) {
414
- clear_vec_high(s, rd);
415
- }
416
+ clear_vec_high(s, !is_scalar, rd);
417
} else {
418
TCGv_i32 tcg_idx = tcg_temp_new_i32();
419
467
420
--
468
--
421
2.16.1
469
2.25.1
422
423
diff view generated by jsdifflib
1
The v8M architecture includes hardware support for enforcing
1
Switch the creation of the external GIC to the new-style "embedded in
2
stack pointer limits. We don't implement this behaviour yet,
2
state struct" approach, so we can easily refer to the object
3
but provide the MSPLIM and PSPLIM stack pointer limit registers
3
elsewhere during realize.
4
as reads-as-written, so that when we do implement the checks
5
in future this won't break guest migration.
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180209165810.6668-12-peter.maydell@linaro.org
7
Message-id: 20220404154658.565020-9-peter.maydell@linaro.org
10
---
8
---
11
target/arm/cpu.h | 2 ++
9
include/hw/arm/exynos4210.h | 2 ++
12
target/arm/helper.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
10
include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++
13
target/arm/machine.c | 21 +++++++++++++++++++++
11
hw/arm/exynos4210.c | 10 ++++----
14
3 files changed, 69 insertions(+)
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
15
16
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
--- a/include/hw/arm/exynos4210.h
19
+++ b/target/arm/cpu.h
20
+++ b/include/hw/arm/exynos4210.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
21
@@ -XXX,XX +XXX,XX @@
21
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
22
#include "hw/or-irq.h"
22
uint32_t csselr[M_REG_NUM_BANKS];
23
#include "hw/sysbus.h"
23
uint32_t scr[M_REG_NUM_BANKS];
24
#include "hw/cpu/a9mpcore.h"
24
+ uint32_t msplim[M_REG_NUM_BANKS];
25
+#include "hw/intc/exynos4210_gic.h"
25
+ uint32_t psplim[M_REG_NUM_BANKS];
26
#include "target/arm/cpu-qom.h"
26
} v7m;
27
#include "qom/object.h"
27
28
28
/* Information associated with an exception about to be taken:
29
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
29
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
30
index XXXXXXX..XXXXXXX 100644
31
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
31
--- a/target/arm/helper.c
32
A9MPPrivState a9mpcore;
32
+++ b/target/arm/helper.c
33
+ Exynos4210GicState ext_gic;
33
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
34
return 0;
35
}
36
return env->v7m.other_ss_psp;
37
+ case 0x8a: /* MSPLIM_NS */
38
+ if (!env->v7m.secure) {
39
+ return 0;
40
+ }
41
+ return env->v7m.msplim[M_REG_NS];
42
+ case 0x8b: /* PSPLIM_NS */
43
+ if (!env->v7m.secure) {
44
+ return 0;
45
+ }
46
+ return env->v7m.psplim[M_REG_NS];
47
case 0x90: /* PRIMASK_NS */
48
if (!env->v7m.secure) {
49
return 0;
50
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
51
return v7m_using_psp(env) ? env->v7m.other_sp : env->regs[13];
52
case 9: /* PSP */
53
return v7m_using_psp(env) ? env->regs[13] : env->v7m.other_sp;
54
+ case 10: /* MSPLIM */
55
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
56
+ goto bad_reg;
57
+ }
58
+ return env->v7m.msplim[env->v7m.secure];
59
+ case 11: /* PSPLIM */
60
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
61
+ goto bad_reg;
62
+ }
63
+ return env->v7m.psplim[env->v7m.secure];
64
case 16: /* PRIMASK */
65
return env->v7m.primask[env->v7m.secure];
66
case 17: /* BASEPRI */
67
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
68
case 19: /* FAULTMASK */
69
return env->v7m.faultmask[env->v7m.secure];
70
default:
71
+ bad_reg:
72
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special"
73
" register %d\n", reg);
74
return 0;
75
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
76
}
77
env->v7m.other_ss_psp = val;
78
return;
79
+ case 0x8a: /* MSPLIM_NS */
80
+ if (!env->v7m.secure) {
81
+ return;
82
+ }
83
+ env->v7m.msplim[M_REG_NS] = val & ~7;
84
+ return;
85
+ case 0x8b: /* PSPLIM_NS */
86
+ if (!env->v7m.secure) {
87
+ return;
88
+ }
89
+ env->v7m.psplim[M_REG_NS] = val & ~7;
90
+ return;
91
case 0x90: /* PRIMASK_NS */
92
if (!env->v7m.secure) {
93
return;
94
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
95
env->v7m.other_sp = val;
96
}
97
break;
98
+ case 10: /* MSPLIM */
99
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
100
+ goto bad_reg;
101
+ }
102
+ env->v7m.msplim[env->v7m.secure] = val & ~7;
103
+ break;
104
+ case 11: /* PSPLIM */
105
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
106
+ goto bad_reg;
107
+ }
108
+ env->v7m.psplim[env->v7m.secure] = val & ~7;
109
+ break;
110
case 16: /* PRIMASK */
111
env->v7m.primask[env->v7m.secure] = val & 1;
112
break;
113
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
114
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
115
break;
116
default:
117
+ bad_reg:
118
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special"
119
" register %d\n", reg);
120
return;
121
diff --git a/target/arm/machine.c b/target/arm/machine.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/target/arm/machine.c
124
+++ b/target/arm/machine.c
125
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_other_sp = {
126
}
127
};
34
};
128
35
129
+static bool m_v8m_needed(void *opaque)
36
#define TYPE_EXYNOS4210_SOC "exynos4210"
130
+{
37
diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h
131
+ ARMCPU *cpu = opaque;
38
new file mode 100644
132
+ CPUARMState *env = &cpu->env;
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
133
+
66
+
134
+ return arm_feature(env, ARM_FEATURE_M) && arm_feature(env, ARM_FEATURE_V8);
67
+#include "hw/sysbus.h"
135
+}
136
+
68
+
137
+static const VMStateDescription vmstate_m_v8m = {
69
+#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
138
+ .name = "cpu/m/v8m",
70
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
139
+ .version_id = 1,
71
+
140
+ .minimum_version_id = 1,
72
+#define EXYNOS4210_GIC_NCPUS 2
141
+ .needed = m_v8m_needed,
73
+
142
+ .fields = (VMStateField[]) {
74
+struct Exynos4210GicState {
143
+ VMSTATE_UINT32_ARRAY(env.v7m.msplim, ARMCPU, M_REG_NUM_BANKS),
75
+ SysBusDevice parent_obj;
144
+ VMSTATE_UINT32_ARRAY(env.v7m.psplim, ARMCPU, M_REG_NUM_BANKS),
76
+
145
+ VMSTATE_END_OF_LIST()
77
+ MemoryRegion cpu_container;
146
+ }
78
+ MemoryRegion dist_container;
79
+ MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS];
80
+ MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS];
81
+ uint32_t num_cpu;
82
+ DeviceState *gic;
147
+};
83
+};
148
+
84
+
149
static const VMStateDescription vmstate_m = {
85
+#endif
150
.name = "cpu/m",
86
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
151
.version_id = 4,
87
index XXXXXXX..XXXXXXX 100644
152
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
88
--- a/hw/arm/exynos4210.c
153
&vmstate_m_csselr,
89
+++ b/hw/arm/exynos4210.c
154
&vmstate_m_scr,
90
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
155
&vmstate_m_other_sp,
91
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
156
+ &vmstate_m_v8m,
92
157
NULL
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));
158
}
106
}
159
};
107
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
108
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
109
+ s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
110
}
111
112
/* Internal Interrupt Combiner */
113
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
114
}
115
116
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
117
+ object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
118
}
119
120
static void exynos4210_class_init(ObjectClass *klass, void *data)
121
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/hw/intc/exynos4210_gic.c
124
+++ b/hw/intc/exynos4210_gic.c
125
@@ -XXX,XX +XXX,XX @@
126
#include "qemu/module.h"
127
#include "hw/irq.h"
128
#include "hw/qdev-properties.h"
129
+#include "hw/intc/exynos4210_gic.h"
130
#include "hw/arm/exynos4210.h"
131
#include "qom/object.h"
132
133
@@ -XXX,XX +XXX,XX @@
134
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
135
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
136
137
-#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
138
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
139
-
140
-struct Exynos4210GicState {
141
- SysBusDevice parent_obj;
142
-
143
- MemoryRegion cpu_container;
144
- MemoryRegion dist_container;
145
- MemoryRegion cpu_alias[EXYNOS4210_NCPUS];
146
- MemoryRegion dist_alias[EXYNOS4210_NCPUS];
147
- uint32_t num_cpu;
148
- DeviceState *gic;
149
-};
150
-
151
static void exynos4210_gic_set_irq(void *opaque, int irq, int level)
152
{
153
Exynos4210GicState *s = (Exynos4210GicState *)opaque;
154
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
155
* enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
156
* doesn't figure this out, otherwise and gives spurious warnings.
157
*/
158
- assert(n <= EXYNOS4210_NCPUS);
159
+ assert(n <= EXYNOS4210_GIC_NCPUS);
160
for (i = 0; i < n; i++) {
161
/* Map CPU interface per SMP Core */
162
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
163
diff --git a/MAINTAINERS b/MAINTAINERS
164
index XXXXXXX..XXXXXXX 100644
165
--- a/MAINTAINERS
166
+++ b/MAINTAINERS
167
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
168
L: qemu-arm@nongnu.org
169
S: Odd Fixes
170
F: hw/*/exynos*
171
-F: include/hw/arm/exynos4210.h
172
+F: include/hw/*/exynos*
173
174
Calxeda Highbank
175
M: Rob Herring <robh@kernel.org>
160
--
176
--
161
2.16.1
177
2.25.1
162
163
diff view generated by jsdifflib
New patch
1
The only time we use the ext_gic_irq[] array in the Exynos4210Irq
2
struct is during realize of the SoC -- we initialize it with the
3
input IRQs of the external GIC device, and then connect those to
4
outputs of other devices further on in realize (including in the
5
exynos4210_init_board_irqs() function). Now that the ext_gic object
6
is easily accessible as s->ext_gic we can make the connections
7
directly from one device to the other without going via this array.
1
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-10-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 -
14
hw/arm/exynos4210.c | 12 ++++++------
15
2 files changed, 6 insertions(+), 7 deletions(-)
16
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@
22
typedef struct Exynos4210Irq {
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
25
- qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
26
} Exynos4210Irq;
27
28
struct Exynos4210State {
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
34
{
35
uint32_t grp, bit, irq_id, n;
36
Exynos4210Irq *is = &s->irqs;
37
+ DeviceState *extgicdev = DEVICE(&s->ext_gic);
38
39
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
40
irq_id = 0;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
42
}
43
if (irq_id) {
44
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
45
- is->ext_gic_irq[irq_id - 32]);
46
+ qdev_get_gpio_in(extgicdev,
47
+ irq_id - 32));
48
} else {
49
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
50
is->ext_combiner_irq[n]);
51
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
52
53
if (irq_id) {
54
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
55
- is->ext_gic_irq[irq_id - 32]);
56
+ qdev_get_gpio_in(extgicdev,
57
+ irq_id - 32));
58
}
59
}
60
}
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
62
sysbus_connect_irq(busdev, n,
63
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
64
}
65
- for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
66
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
67
- }
68
69
/* Internal Interrupt Combiner */
70
dev = qdev_new("exynos4210.combiner");
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
72
busdev = SYS_BUS_DEVICE(dev);
73
sysbus_realize_and_unref(busdev, &error_fatal);
74
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
75
- sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
76
+ sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
77
}
78
exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
79
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
80
--
81
2.25.1
diff view generated by jsdifflib
1
M profile cores have a similar setup for cache ID registers
1
The function exynos4210_combiner_get_gpioin() currently lives in
2
to A profile:
2
exynos4210_combiner.c, but it isn't really part of the combiner
3
* Cache Level ID Register (CLIDR) is a fixed value
3
device itself -- it is a function that implements the wiring up of
4
* Cache Type Register (CTR) is a fixed value
4
some interrupt sources to multiple combiner inputs. Move it to live
5
* Cache Size ID Registers (CCSIDR) are a bank of registers;
5
with the other SoC-level code in exynos4210.c, along with a few
6
which one you see is selected by the Cache Size Selection
6
macros previously defined in exynos4210.h which are now used only
7
Register (CSSELR)
7
in exynos4210.c.
8
9
The only difference is that they're in the NVIC memory mapped
10
register space rather than being coprocessor registers.
11
Implement the M profile view of them.
12
13
Since neither Cortex-M3 nor Cortex-M4 implement caches,
14
we don't need to update their init functions and can leave
15
the ctr/clidr/ccsidr[] fields in their ARMCPU structs at zero.
16
Newer cores (like the Cortex-M33) will want to be able to
17
set these ID registers to non-zero values, though.
18
8
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20180209165810.6668-6-peter.maydell@linaro.org
11
Message-id: 20220404154658.565020-11-peter.maydell@linaro.org
22
---
12
---
23
target/arm/cpu.h | 26 ++++++++++++++++++++++++++
13
include/hw/arm/exynos4210.h | 11 -----
24
hw/intc/armv7m_nvic.c | 16 ++++++++++++++++
14
hw/arm/exynos4210.c | 82 +++++++++++++++++++++++++++++++++++
25
target/arm/machine.c | 36 ++++++++++++++++++++++++++++++++++++
15
hw/intc/exynos4210_combiner.c | 77 --------------------------------
26
3 files changed, 78 insertions(+)
16
3 files changed, 82 insertions(+), 88 deletions(-)
27
17
28
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
29
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
20
--- a/include/hw/arm/exynos4210.h
31
+++ b/target/arm/cpu.h
21
+++ b/include/hw/arm/exynos4210.h
32
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
22
@@ -XXX,XX +XXX,XX @@
33
uint32_t faultmask[M_REG_NUM_BANKS];
23
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
34
uint32_t aircr; /* only holds r/w state if security extn implemented */
24
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
35
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
25
36
+ uint32_t csselr[M_REG_NUM_BANKS];
26
-#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
37
} v7m;
27
-#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
38
28
-#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
39
/* Information associated with an exception about to be taken:
29
- ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
40
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_MPU_CTRL, ENABLE, 0, 1)
30
-
41
FIELD(V7M_MPU_CTRL, HFNMIENA, 1, 1)
31
/* IRQs number for external and internal GIC */
42
FIELD(V7M_MPU_CTRL, PRIVDEFENA, 2, 1)
32
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
43
33
#define EXYNOS4210_INT_GIC_NIRQ 64
44
+/* v7M CLIDR bits */
34
@@ -XXX,XX +XXX,XX @@ void exynos4210_write_secondary(ARMCPU *cpu,
45
+FIELD(V7M_CLIDR, CTYPE_ALL, 0, 21)
35
* bit - bit number inside group */
46
+FIELD(V7M_CLIDR, LOUIS, 21, 3)
36
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
47
+FIELD(V7M_CLIDR, LOC, 24, 3)
37
48
+FIELD(V7M_CLIDR, LOUU, 27, 3)
38
-/*
49
+FIELD(V7M_CLIDR, ICB, 30, 2)
39
- * Get Combiner input GPIO into irqs structure
50
+
40
- */
51
+FIELD(V7M_CSSELR, IND, 0, 1)
41
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
52
+FIELD(V7M_CSSELR, LEVEL, 1, 3)
42
- int ext);
53
+/* We use the combination of InD and Level to index into cpu->ccsidr[];
43
-
54
+ * define a mask for this and check that it doesn't permit running off
44
/*
55
+ * the end of the array.
45
* exynos4210 UART
46
*/
47
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/exynos4210.c
50
+++ b/hw/arm/exynos4210.c
51
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
52
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
53
};
54
55
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
56
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
57
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
58
+ ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
59
+
60
/*
61
* Initialize board IRQs.
62
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
63
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
64
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
65
}
66
67
+/*
68
+ * Get Combiner input GPIO into irqs structure
56
+ */
69
+ */
57
+FIELD(V7M_CSSELR, INDEX, 0, 4)
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
58
+
71
+ DeviceState *dev, int ext)
59
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
60
+
61
/* If adding a feature bit which corresponds to a Linux ELF
62
* HWCAP bit, remember to update the feature-bit-to-hwcap
63
* mapping in linux-user/elfload.c:get_elf_hwcap().
64
@@ -XXX,XX +XXX,XX @@ static inline int arm_debug_target_el(CPUARMState *env)
65
}
66
}
67
68
+static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
69
+{
72
+{
70
+ /* If all the CLIDR.Ctypem bits are 0 there are no caches, and
73
+ int n;
71
+ * CSSELR is RAZ/WI.
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.
72
+ */
85
+ */
73
+ return (cpu->clidr & R_V7M_CLIDR_CTYPE_ALL_MASK) != 0;
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
+ }
74
+}
142
+}
75
+
143
+
76
static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
77
{
145
0x09, 0x00, 0x00, 0x00 };
78
if (arm_is_secure(env)) {
146
79
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
147
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
80
index XXXXXXX..XXXXXXX 100644
148
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/intc/armv7m_nvic.c
149
--- a/hw/intc/exynos4210_combiner.c
82
+++ b/hw/intc/armv7m_nvic.c
150
+++ b/hw/intc/exynos4210_combiner.c
83
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
151
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_exynos4210_combiner = {
84
return cpu->id_isar4;
85
case 0xd74: /* ISAR5. */
86
return cpu->id_isar5;
87
+ case 0xd78: /* CLIDR */
88
+ return cpu->clidr;
89
+ case 0xd7c: /* CTR */
90
+ return cpu->ctr;
91
+ case 0xd80: /* CSSIDR */
92
+ {
93
+ int idx = cpu->env.v7m.csselr[attrs.secure] & R_V7M_CSSELR_INDEX_MASK;
94
+ return cpu->ccsidr[idx];
95
+ }
96
+ case 0xd84: /* CSSELR */
97
+ return cpu->env.v7m.csselr[attrs.secure];
98
/* TODO: Implement debug registers. */
99
case 0xd90: /* MPU_TYPE */
100
/* Unified MPU; if the MPU is not present this value is zero */
101
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
102
qemu_log_mask(LOG_UNIMP,
103
"NVIC: Aux fault status registers unimplemented\n");
104
break;
105
+ case 0xd84: /* CSSELR */
106
+ if (!arm_v7m_csselr_razwi(cpu)) {
107
+ cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK;
108
+ }
109
+ break;
110
case 0xd90: /* MPU_TYPE */
111
return; /* RO */
112
case 0xd94: /* MPU_CTRL */
113
diff --git a/target/arm/machine.c b/target/arm/machine.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/machine.c
116
+++ b/target/arm/machine.c
117
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_faultmask_primask = {
118
}
152
}
119
};
153
};
120
154
121
+/* CSSELR is in a subsection because we didn't implement it previously.
155
-/*
122
+ * Migration from an old implementation will leave it at zero, which
156
- * Get Combiner input GPIO into irqs structure
123
+ * is OK since the only CPUs in the old implementation make the
157
- */
124
+ * register RAZ/WI.
158
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
125
+ * Since there was no version of QEMU which implemented the CSSELR for
159
- int ext)
126
+ * just non-secure, we transfer both banks here rather than putting
160
-{
127
+ * the secure banked version in the m-security subsection.
161
- int n;
128
+ */
162
- int bit;
129
+static bool csselr_vmstate_validate(void *opaque, int version_id)
163
- int max;
130
+{
164
- qemu_irq *irq;
131
+ ARMCPU *cpu = opaque;
165
-
132
+
166
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
133
+ return cpu->env.v7m.csselr[M_REG_NS] <= R_V7M_CSSELR_INDEX_MASK
167
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
134
+ && cpu->env.v7m.csselr[M_REG_S] <= R_V7M_CSSELR_INDEX_MASK;
168
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
135
+}
169
-
136
+
170
- /*
137
+static bool m_csselr_needed(void *opaque)
171
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
138
+{
172
- * so let split them.
139
+ ARMCPU *cpu = opaque;
173
- */
140
+
174
- for (n = 0; n < max; n++) {
141
+ return !arm_v7m_csselr_razwi(cpu);
175
-
142
+}
176
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
143
+
177
-
144
+static const VMStateDescription vmstate_m_csselr = {
178
- switch (n) {
145
+ .name = "cpu/m/csselr",
179
- /* MDNIE_LCD1 INTG1 */
146
+ .version_id = 1,
180
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
147
+ .minimum_version_id = 1,
181
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
148
+ .needed = m_csselr_needed,
182
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
149
+ .fields = (VMStateField[]) {
183
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
150
+ VMSTATE_UINT32_ARRAY(env.v7m.csselr, ARMCPU, M_REG_NUM_BANKS),
184
- continue;
151
+ VMSTATE_VALIDATE("CSSELR is valid", csselr_vmstate_validate),
185
-
152
+ VMSTATE_END_OF_LIST()
186
- /* TMU INTG3 */
153
+ }
187
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
154
+};
188
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
155
+
189
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
156
static const VMStateDescription vmstate_m = {
190
- continue;
157
.name = "cpu/m",
191
-
158
.version_id = 4,
192
- /* LCD1 INTG12 */
159
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
193
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
160
},
194
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
161
.subsections = (const VMStateDescription*[]) {
195
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
162
&vmstate_m_faultmask_primask,
196
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
163
+ &vmstate_m_csselr,
197
- continue;
164
NULL
198
-
165
}
199
- /* Multi-Core Timer INTG12 */
166
};
200
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
201
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
202
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
203
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
204
- continue;
205
-
206
- /* Multi-Core Timer INTG35 */
207
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
208
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
209
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
210
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
211
- continue;
212
-
213
- /* Multi-Core Timer INTG51 */
214
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
215
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
216
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
217
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
218
- continue;
219
-
220
- /* Multi-Core Timer INTG53 */
221
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
222
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
223
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
224
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
225
- continue;
226
- }
227
-
228
- irq[n] = qdev_get_gpio_in(dev, n);
229
- }
230
-}
231
-
232
static uint64_t
233
exynos4210_combiner_read(void *opaque, hwaddr offset, unsigned size)
234
{
167
--
235
--
168
2.16.1
236
2.25.1
169
170
diff view generated by jsdifflib
1
In commit commit 3b2e934463121 we added support for the AIRCR
1
Delete a couple of #defines which are never used.
2
register holding state, but forgot to add it to the vmstate
3
structs. Since it only holds r/w state if the security extension
4
is implemented, we can just add it to vmstate_m_security.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180209165810.6668-10-peter.maydell@linaro.org
5
Message-id: 20220404154658.565020-12-peter.maydell@linaro.org
9
---
6
---
10
target/arm/machine.c | 4 ++++
7
include/hw/arm/exynos4210.h | 4 ----
11
1 file changed, 4 insertions(+)
8
1 file changed, 4 deletions(-)
12
9
13
diff --git a/target/arm/machine.c b/target/arm/machine.c
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/machine.c
12
--- a/include/hw/arm/exynos4210.h
16
+++ b/target/arm/machine.c
13
+++ b/include/hw/arm/exynos4210.h
17
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
14
@@ -XXX,XX +XXX,XX @@
18
VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate),
15
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
19
VMSTATE_UINT32(env.sau.ctrl, ARMCPU),
16
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
20
VMSTATE_UINT32(env.v7m.scr[M_REG_S], ARMCPU),
17
21
+ /* AIRCR is not secure-only, but our implementation is R/O if the
18
-/* IRQs number for external and internal GIC */
22
+ * security extension is unimplemented, so we migrate it here.
19
-#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
23
+ */
20
-#define EXYNOS4210_INT_GIC_NIRQ 64
24
+ VMSTATE_UINT32(env.v7m.aircr, ARMCPU),
21
-
25
VMSTATE_END_OF_LIST()
22
#define EXYNOS4210_I2C_NUMBER 9
26
}
23
27
};
24
#define EXYNOS4210_NUM_DMA 3
28
--
25
--
29
2.16.1
26
2.25.1
30
31
diff view generated by jsdifflib
1
In many of the NVIC registers relating to interrupts, we
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
2
have to convert from a byte offset within a register set
2
instead of qemu_irq_split().
3
into the number of the first interrupt which is affected.
4
We were getting this wrong for:
5
* reads of NVIC_ISPR<n>, NVIC_ISER<n>, NVIC_ICPR<n>, NVIC_ICER<n>,
6
NVIC_IABR<n> -- in all these cases we were missing the "* 8"
7
needed to convert from the byte offset to the interrupt number
8
(since all these registers use one bit per interrupt)
9
* writes of NVIC_IPR<n> had the opposite problem of a spurious
10
"* 8" (since these registers use one byte per interrupt)
11
3
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20180209165810.6668-9-peter.maydell@linaro.org
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
15
---
7
---
16
hw/intc/armv7m_nvic.c | 8 ++++----
8
include/hw/arm/exynos4210.h | 9 ++++++++
17
1 file changed, 4 insertions(+), 4 deletions(-)
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
10
2 files changed, 42 insertions(+), 8 deletions(-)
18
11
19
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
12
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/intc/armv7m_nvic.c
14
--- a/include/hw/arm/exynos4210.h
22
+++ b/hw/intc/armv7m_nvic.c
15
+++ b/include/hw/arm/exynos4210.h
23
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
16
@@ -XXX,XX +XXX,XX @@
24
/* fall through */
17
#include "hw/sysbus.h"
25
case 0x180 ... 0x1bf: /* NVIC Clear enable */
18
#include "hw/cpu/a9mpcore.h"
26
val = 0;
19
#include "hw/intc/exynos4210_gic.h"
27
- startvec = offset - 0x180 + NVIC_FIRST_IRQ; /* vector # */
20
+#include "hw/core/split-irq.h"
28
+ startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ; /* vector # */
21
#include "target/arm/cpu-qom.h"
29
22
#include "qom/object.h"
30
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
23
31
if (s->vectors[startvec + i].enabled &&
24
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
25
33
/* fall through */
26
#define EXYNOS4210_NUM_DMA 3
34
case 0x280 ... 0x2bf: /* NVIC Clear pend */
27
35
val = 0;
28
+/*
36
- startvec = offset - 0x280 + NVIC_FIRST_IRQ; /* vector # */
29
+ * We need one splitter for every external combiner input, plus
37
+ startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
38
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
39
if (s->vectors[startvec + i].pending &&
32
+ */
40
(attrs.secure || s->itns[startvec + i])) {
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
41
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
34
+
42
break;
35
typedef struct Exynos4210Irq {
43
case 0x300 ... 0x33f: /* NVIC Active */
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
44
val = 0;
37
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
45
- startvec = offset - 0x300 + NVIC_FIRST_IRQ; /* vector # */
38
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
46
+ startvec = 8 * (offset - 0x300) + NVIC_FIRST_IRQ; /* vector # */
39
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
47
40
A9MPPrivState a9mpcore;
48
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
41
Exynos4210GicState ext_gic;
49
if (s->vectors[startvec + i].active &&
42
+ SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
50
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
43
};
51
case 0x300 ... 0x33f: /* NVIC Active */
44
52
return MEMTX_OK; /* R/O */
45
#define TYPE_EXYNOS4210_SOC "exynos4210"
53
case 0x400 ... 0x5ef: /* NVIC Priority */
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
54
- startvec = 8 * (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
47
index XXXXXXX..XXXXXXX 100644
55
+ startvec = (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
48
--- a/hw/arm/exynos4210.c
56
49
+++ b/hw/arm/exynos4210.c
57
for (i = 0; i < size && startvec + i < s->num_irq; i++) {
50
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
58
if (attrs.secure || s->itns[startvec + i]) {
51
uint32_t grp, bit, irq_id, n;
52
Exynos4210Irq *is = &s->irqs;
53
DeviceState *extgicdev = DEVICE(&s->ext_gic);
54
+ int splitcount = 0;
55
+ DeviceState *splitter;
56
57
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
58
irq_id = 0;
59
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
60
/* MCT_G1 is passed to External and GIC */
61
irq_id = EXT_GIC_ID_MCT_G1;
62
}
63
+
64
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
65
+ splitter = DEVICE(&s->splitter[splitcount]);
66
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
67
+ qdev_realize(splitter, NULL, &error_abort);
68
+ splitcount++;
69
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
70
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
71
if (irq_id) {
72
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
73
- qdev_get_gpio_in(extgicdev,
74
- irq_id - 32));
75
+ qdev_connect_gpio_out(splitter, 1,
76
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
77
} else {
78
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
79
- is->ext_combiner_irq[n]);
80
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
81
}
82
}
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
86
87
if (irq_id) {
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
89
- qdev_get_gpio_in(extgicdev,
90
- irq_id - 32));
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
92
+ splitter = DEVICE(&s->splitter[splitcount]);
93
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
94
+ qdev_realize(splitter, NULL, &error_abort);
95
+ splitcount++;
96
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
97
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
98
+ qdev_connect_gpio_out(splitter, 1,
99
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
100
}
101
}
102
+ /*
103
+ * We check this here to avoid a more obscure assert later when
104
+ * qdev_assert_realized_properly() checks that we realized every
105
+ * child object we initialized.
106
+ */
107
+ assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
108
}
109
110
/*
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
112
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
113
}
114
115
+ for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
116
+ g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
117
+ object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
118
+ }
119
+
120
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
121
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
122
}
59
--
123
--
60
2.16.1
124
2.25.1
61
62
diff view generated by jsdifflib
1
In commit 50f11062d4c896 we added support for MSR/MRS access
1
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
2
to the NS banked special registers, but we forgot to implement
2
are in a range that applies to the internal combiner only creates a
3
the support for writing to CONTROL_NS. Correct the omission.
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.
4
20
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180209165810.6668-8-peter.maydell@linaro.org
23
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
8
---
24
---
9
target/arm/helper.c | 10 ++++++++++
25
hw/arm/exynos4210.c | 2 ++
10
1 file changed, 10 insertions(+)
26
1 file changed, 2 insertions(+)
11
27
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
13
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
30
--- a/hw/arm/exynos4210.c
15
+++ b/target/arm/helper.c
31
+++ b/hw/arm/exynos4210.c
16
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
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
env->v7m.faultmask[M_REG_NS] = val & 1;
34
qdev_connect_gpio_out(splitter, 1,
19
return;
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
20
+ case 0x94: /* CONTROL_NS */
36
+ } else {
21
+ if (!env->v7m.secure) {
37
+ s->irq_table[n] = is->int_combiner_irq[n];
22
+ return;
38
}
23
+ }
39
}
24
+ write_v7m_control_spsel_for_secstate(env,
40
/*
25
+ val & R_V7M_CONTROL_SPSEL_MASK,
26
+ M_REG_NS);
27
+ env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
28
+ env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
29
+ return;
30
case 0x98: /* SP_NS */
31
{
32
/* This gives the non-secure SP selected based on whether we're
33
--
41
--
34
2.16.1
42
2.25.1
35
36
diff view generated by jsdifflib
1
The Coprocessor Power Control Register (CPPWR) is new in v8M.
1
Currently for the interrupts MCT_G0 and MCT_G1 which are
2
It allows software to control whether coprocessors are allowed
2
the only ones in the input range of the external combiner
3
to power down and lose their state. QEMU doesn't have any
3
and which are also wired to the external GIC, we connect
4
notion of power control, so we choose the IMPDEF option of
4
them only to the internal combiner and the external GIC.
5
making the whole register RAZ/WI (indicating that no coprocessors
5
This seems likely to be a bug, as all other interrupts
6
can ever power down and lose state).
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.
7
12
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180209165810.6668-5-peter.maydell@linaro.org
15
Message-id: 20220404154658.565020-15-peter.maydell@linaro.org
11
---
16
---
12
hw/intc/armv7m_nvic.c | 14 ++++++++++++++
17
hw/arm/exynos4210.c | 7 +++----
13
1 file changed, 14 insertions(+)
18
1 file changed, 3 insertions(+), 4 deletions(-)
14
19
15
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/armv7m_nvic.c
22
--- a/hw/arm/exynos4210.c
18
+++ b/hw/intc/armv7m_nvic.c
23
+++ b/hw/arm/exynos4210.c
19
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
20
switch (offset) {
25
21
case 4: /* Interrupt Control Type. */
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
22
return ((s->num_irq - NVIC_FIRST_IRQ) / 32) - 1;
27
splitter = DEVICE(&s->splitter[splitcount]);
23
+ case 0xc: /* CPPWR */
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
24
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
25
+ goto bad_offset;
30
qdev_realize(splitter, NULL, &error_abort);
26
+ }
31
splitcount++;
27
+ /* We make the IMPDEF choice that nothing can ever go into a
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
28
+ * non-retentive power state, which allows us to RAZ/WI this.
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
29
+ */
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
30
+ return 0;
35
if (irq_id) {
31
case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
36
- qdev_connect_gpio_out(splitter, 1,
32
{
37
+ qdev_connect_gpio_out(splitter, 2,
33
int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ;
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
34
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
39
- } else {
35
ARMCPU *cpu = s->cpu;
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
36
41
}
37
switch (offset) {
42
}
38
+ case 0xc: /* CPPWR */
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
39
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
40
+ goto bad_offset;
41
+ }
42
+ /* Make the IMPDEF choice to RAZ/WI this. */
43
+ break;
44
case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
45
{
46
int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ;
47
--
44
--
48
2.16.1
45
2.25.1
49
50
diff view generated by jsdifflib
1
For M profile cores, cache maintenance operations are done by
1
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
2
writing to special registers in the system register space.
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
3
For QEMU, cache operations are always NOPs, since we don't
3
connect multiple IRQs up to the same external GIC input, which
4
implement the cache. Implementing these explicitly avoids
4
is not permitted. We do the same thing in the code in
5
a spurious LOG_GUEST_ERROR when the guest uses them.
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.
6
24
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180209165810.6668-4-peter.maydell@linaro.org
27
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
10
---
28
---
11
hw/intc/armv7m_nvic.c | 12 ++++++++++++
29
include/hw/arm/exynos4210.h | 2 +-
12
1 file changed, 12 insertions(+)
30
hw/arm/exynos4210.c | 12 +++++-------
31
2 files changed, 6 insertions(+), 8 deletions(-)
13
32
14
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
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/hw/intc/armv7m_nvic.c
35
--- a/include/hw/arm/exynos4210.h
17
+++ b/hw/intc/armv7m_nvic.c
36
+++ b/include/hw/arm/exynos4210.h
18
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
37
@@ -XXX,XX +XXX,XX @@
38
* one for every non-zero entry in combiner_grp_to_gic_id[].
39
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
40
*/
41
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
42
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
43
44
typedef struct Exynos4210Irq {
45
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/exynos4210.c
49
+++ b/hw/arm/exynos4210.c
50
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
51
/* int combiner group 34 */
52
{ EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
53
/* int combiner group 35 */
54
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
55
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
56
/* int combiner group 36 */
57
{ EXT_GIC_ID_MIXER },
58
/* int combiner group 37 */
59
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
60
/* groups 38-50 */
61
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
62
/* int combiner group 51 */
63
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
64
+ { EXT_GIC_ID_MCT_L0 },
65
/* group 52 */
66
{ },
67
/* int combiner group 53 */
68
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
69
+ { EXT_GIC_ID_WDT },
70
/* groups 54-63 */
71
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
72
};
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
74
75
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
76
irq_id = 0;
77
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
78
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
79
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
80
/* MCT_G0 is passed to External GIC */
81
irq_id = EXT_GIC_ID_MCT_G0;
19
}
82
}
20
break;
83
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
21
}
84
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
22
+ case 0xf50: /* ICIALLU */
85
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
23
+ case 0xf58: /* ICIMVAU */
86
/* MCT_G1 is passed to External and GIC */
24
+ case 0xf5c: /* DCIMVAC */
87
irq_id = EXT_GIC_ID_MCT_G1;
25
+ case 0xf60: /* DCISW */
88
}
26
+ case 0xf64: /* DCCMVAU */
27
+ case 0xf68: /* DCCMVAC */
28
+ case 0xf6c: /* DCCSW */
29
+ case 0xf70: /* DCCIMVAC */
30
+ case 0xf74: /* DCCISW */
31
+ case 0xf78: /* BPIALL */
32
+ /* Cache and branch predictor maintenance: for QEMU these always NOP */
33
+ break;
34
default:
35
bad_offset:
36
qemu_log_mask(LOG_GUEST_ERROR,
37
--
89
--
38
2.16.1
90
2.25.1
39
40
diff view generated by jsdifflib
1
The PENDNMISET/CLR bits in the ICSR should be RAZ/WI from
1
At this point, the function exynos4210_init_board_irqs() splits input
2
NonSecure state if the AIRCR.BFHFNMINS bit is zero. We had
2
IRQ lines to connect them to the input combiner, output combiner and
3
misimplemented this as making the bits RAZ/WI from both
3
external GIC. The function exynos4210_combiner_get_gpioin() splits
4
Secure and NonSecure states. Fix this bug by checking
4
some of the combiner input lines further to connect them to multiple
5
attrs.secure so that Secure code can pend and unpend NMIs.
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.
6
38
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
40
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180209165810.6668-3-peter.maydell@linaro.org
41
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
10
---
42
---
11
hw/intc/armv7m_nvic.c | 6 +++---
43
include/hw/arm/exynos4210.h | 6 +-
12
1 file changed, 3 insertions(+), 3 deletions(-)
44
hw/arm/exynos4210.c | 178 +++++++++++++++++++++++-------------
13
45
2 files changed, 119 insertions(+), 65 deletions(-)
14
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
46
47
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
15
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/armv7m_nvic.c
49
--- a/include/hw/arm/exynos4210.h
17
+++ b/hw/intc/armv7m_nvic.c
50
+++ b/include/hw/arm/exynos4210.h
18
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
51
@@ -XXX,XX +XXX,XX @@
19
}
52
53
/*
54
* We need one splitter for every external combiner input, plus
55
- * one for every non-zero entry in combiner_grp_to_gic_id[].
56
+ * one for every non-zero entry in combiner_grp_to_gic_id[],
57
+ * minus one for every external combiner ID in second or later
58
+ * places in a combinermap[] line.
59
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
60
*/
61
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
62
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
63
64
typedef struct Exynos4210Irq {
65
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
66
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/exynos4210.c
69
+++ b/hw/arm/exynos4210.c
70
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
71
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
72
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
73
74
+/*
75
+ * Some interrupt lines go to multiple combiner inputs.
76
+ * This data structure defines those: each array element is
77
+ * a list of combiner inputs which are connected together;
78
+ * the one with the smallest interrupt ID value must be first.
79
+ * As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
80
+ * wired to anything so we can use 0 as a terminator.
81
+ */
82
+#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
83
+#define IRQNONE 0
84
+
85
+#define COMBINERMAP_SIZE 16
86
+
87
+static const int combinermap[COMBINERMAP_SIZE][6] = {
88
+ /* MDNIE_LCD1 */
89
+ { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
90
+ { IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
91
+ { IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
92
+ { IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
93
+ /* TMU */
94
+ { IRQNO(2, 4), IRQNO(3, 4), IRQNONE },
95
+ { IRQNO(2, 5), IRQNO(3, 5), IRQNONE },
96
+ { IRQNO(2, 6), IRQNO(3, 6), IRQNONE },
97
+ { IRQNO(2, 7), IRQNO(3, 7), IRQNONE },
98
+ /* LCD1 */
99
+ { IRQNO(11, 4), IRQNO(12, 0), IRQNONE },
100
+ { IRQNO(11, 5), IRQNO(12, 1), IRQNONE },
101
+ { IRQNO(11, 6), IRQNO(12, 2), IRQNONE },
102
+ { IRQNO(11, 7), IRQNO(12, 3), IRQNONE },
103
+ /* Multi-core timer */
104
+ { IRQNO(1, 4), IRQNO(12, 4), IRQNO(35, 4), IRQNO(51, 4), IRQNO(53, 4), IRQNONE },
105
+ { IRQNO(1, 5), IRQNO(12, 5), IRQNO(35, 5), IRQNO(51, 5), IRQNO(53, 5), IRQNONE },
106
+ { IRQNO(1, 6), IRQNO(12, 6), IRQNO(35, 6), IRQNO(51, 6), IRQNO(53, 6), IRQNONE },
107
+ { IRQNO(1, 7), IRQNO(12, 7), IRQNO(35, 7), IRQNO(51, 7), IRQNO(53, 7), IRQNONE },
108
+};
109
+
110
+#undef IRQNO
111
+
112
+static const int *combinermap_entry(int irq)
113
+{
114
+ /*
115
+ * If the interrupt number passed in is the first entry in some
116
+ * line of the combinermap, return a pointer to that line;
117
+ * otherwise return NULL.
118
+ */
119
+ int i;
120
+ for (i = 0; i < COMBINERMAP_SIZE; i++) {
121
+ if (combinermap[i][0] == irq) {
122
+ return combinermap[i];
123
+ }
124
+ }
125
+ return NULL;
126
+}
127
+
128
+static int mapline_size(const int *mapline)
129
+{
130
+ /* Return number of entries in this mapline in total */
131
+ int i = 0;
132
+
133
+ if (!mapline) {
134
+ /* Not in the map? IRQ goes to exactly one combiner input */
135
+ return 1;
136
+ }
137
+ while (*mapline != IRQNONE) {
138
+ mapline++;
139
+ i++;
140
+ }
141
+ return i;
142
+}
143
+
144
/*
145
* Initialize board IRQs.
146
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
147
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
148
DeviceState *extgicdev = DEVICE(&s->ext_gic);
149
int splitcount = 0;
150
DeviceState *splitter;
151
+ const int *mapline;
152
+ int numlines, splitin, in;
153
154
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
155
irq_id = 0;
156
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
157
irq_id = EXT_GIC_ID_MCT_G1;
20
}
158
}
21
/* NMIPENDSET */
159
22
- if ((cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&
160
+ if (s->irq_table[n]) {
23
- s->vectors[ARMV7M_EXCP_NMI].pending) {
161
+ /*
24
+ if ((attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))
162
+ * This must be some non-first entry in a combinermap line,
25
+ && s->vectors[ARMV7M_EXCP_NMI].pending) {
163
+ * and we've already filled it in.
26
val |= (1 << 31);
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));
27
}
206
}
28
/* ISRPREEMPT: RES0 when halting debug not implemented */
29
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
30
break;
31
}
207
}
32
case 0xd04: /* Interrupt Control State (ICSR) */
208
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
33
- if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
209
irq_id = combiner_grp_to_gic_id[grp -
34
+ if (attrs.secure || cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
210
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
35
if (value & (1 << 31)) {
211
36
armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
212
+ if (s->irq_table[n]) {
37
} else if (value & (1 << 30) &&
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
}
38
--
296
--
39
2.16.1
297
2.25.1
40
41
diff view generated by jsdifflib
1
In commit abc24d86cc0364f we accidentally broke migration of
1
Switch the creation of the combiner devices to the new-style
2
the stack pointer value for the mode (process, handler) the CPU
2
"embedded in state struct" approach, so we can easily refer
3
is not currently running as. (The commit correctly removed the
3
to the object elsewhere during realize.
4
no-longer-used v7m.current_sp flag from the VMState but also
5
deleted the still very much in use v7m.other_sp SP value field.)
6
7
Add a subsection to migrate it again. (We don't need to care
8
about trying to retain compatibility with pre-abc24d86cc0364f
9
versions of QEMU, because that commit bumped the version_id
10
and we've since bumped it again a couple of times.)
11
4
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20180209165810.6668-11-peter.maydell@linaro.org
7
Message-id: 20220404154658.565020-18-peter.maydell@linaro.org
15
---
8
---
16
target/arm/machine.c | 11 +++++++++++
9
include/hw/arm/exynos4210.h | 3 ++
17
1 file changed, 11 insertions(+)
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
18
15
19
diff --git a/target/arm/machine.c b/target/arm/machine.c
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/machine.c
18
--- a/include/hw/arm/exynos4210.h
22
+++ b/target/arm/machine.c
19
+++ b/include/hw/arm/exynos4210.h
23
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_scr = {
20
@@ -XXX,XX +XXX,XX @@
24
}
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];
25
};
35
};
26
36
27
+static const VMStateDescription vmstate_m_other_sp = {
37
diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h
28
+ .name = "cpu/m/other-sp",
38
new file mode 100644
29
+ .version_id = 1,
39
index XXXXXXX..XXXXXXX
30
+ .minimum_version_id = 1,
40
--- /dev/null
31
+ .fields = (VMStateField[]) {
41
+++ b/include/hw/intc/exynos4210_combiner.h
32
+ VMSTATE_UINT32(env.v7m.other_sp, ARMCPU),
42
@@ -XXX,XX +XXX,XX @@
33
+ VMSTATE_END_OF_LIST()
43
+/*
34
+ }
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];
35
+};
97
+};
36
+
98
+
37
static const VMStateDescription vmstate_m = {
99
+#endif
38
.name = "cpu/m",
100
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
39
.version_id = 4,
101
index XXXXXXX..XXXXXXX 100644
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
102
--- a/hw/arm/exynos4210.c
41
&vmstate_m_faultmask_primask,
103
+++ b/hw/arm/exynos4210.c
42
&vmstate_m_csselr,
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
43
&vmstate_m_scr,
44
+ &vmstate_m_other_sp,
45
NULL
46
}
105
}
47
};
106
107
/* Internal Interrupt Combiner */
108
- dev = qdev_new("exynos4210.combiner");
109
- busdev = SYS_BUS_DEVICE(dev);
110
- sysbus_realize_and_unref(busdev, &error_fatal);
111
+ busdev = SYS_BUS_DEVICE(&s->int_combiner);
112
+ sysbus_realize(busdev, &error_fatal);
113
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
114
sysbus_connect_irq(busdev, n,
115
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
116
}
117
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
118
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
119
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
120
121
/* External Interrupt Combiner */
122
- dev = qdev_new("exynos4210.combiner");
123
- qdev_prop_set_uint32(dev, "external", 1);
124
- busdev = SYS_BUS_DEVICE(dev);
125
- sysbus_realize_and_unref(busdev, &error_fatal);
126
+ qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
127
+ busdev = SYS_BUS_DEVICE(&s->ext_combiner);
128
+ sysbus_realize(busdev, &error_fatal);
129
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
130
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
131
}
132
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
133
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
134
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
135
136
/* Initialize board IRQs. */
137
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
138
139
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
140
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
141
+ object_initialize_child(obj, "int-combiner", &s->int_combiner,
142
+ TYPE_EXYNOS4210_COMBINER);
143
+ object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
144
+ TYPE_EXYNOS4210_COMBINER);
145
}
146
147
static void exynos4210_class_init(ObjectClass *klass, void *data)
148
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/hw/intc/exynos4210_combiner.c
151
+++ b/hw/intc/exynos4210_combiner.c
152
@@ -XXX,XX +XXX,XX @@
153
#include "hw/sysbus.h"
154
#include "migration/vmstate.h"
155
#include "qemu/module.h"
156
-
157
+#include "hw/intc/exynos4210_combiner.h"
158
#include "hw/arm/exynos4210.h"
159
#include "hw/hw.h"
160
#include "hw/irq.h"
161
@@ -XXX,XX +XXX,XX @@
162
#define DPRINTF(fmt, ...) do {} while (0)
163
#endif
164
165
-#define IIC_NGRP 64 /* Internal Interrupt Combiner
166
- Groups number */
167
-#define IIC_NIRQ (IIC_NGRP * 8)/* Internal Interrupt Combiner
168
- Interrupts number */
169
#define IIC_REGION_SIZE 0x108 /* Size of memory mapped region */
170
-#define IIC_REGSET_SIZE 0x41
171
-
172
-/*
173
- * State for each output signal of internal combiner
174
- */
175
-typedef struct CombinerGroupState {
176
- uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
177
- uint8_t src_pending; /* Pending source interrupts before masking */
178
-} CombinerGroupState;
179
-
180
-#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
181
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
182
-
183
-struct Exynos4210CombinerState {
184
- SysBusDevice parent_obj;
185
-
186
- MemoryRegion iomem;
187
-
188
- struct CombinerGroupState group[IIC_NGRP];
189
- uint32_t reg_set[IIC_REGSET_SIZE];
190
- uint32_t icipsr[2];
191
- uint32_t external; /* 1 means that this combiner is external */
192
-
193
- qemu_irq output_irq[IIC_NGRP];
194
-};
195
196
static const VMStateDescription vmstate_exynos4210_combiner_group_state = {
197
.name = "exynos4210.combiner.groupstate",
48
--
198
--
49
2.16.1
199
2.25.1
50
51
diff view generated by jsdifflib
1
Instead of hardcoding the values of M profile ID registers in the
1
The only time we use the int_combiner_irq[] and ext_combiner_irq[]
2
NVIC, use the fields in the CPU struct. This will allow us to
2
arrays in the Exynos4210Irq struct is during realize of the SoC -- we
3
give different M profile CPU types different ID register values.
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
This commit includes the addition of the missing ID_ISAR5,
10
Since these are the only two remaining elements of Exynos4210Irq,
6
which exists as RES0 in both v7M and v8M.
11
we can remove that struct entirely.
7
8
(The values of the ID registers might be wrong for the M4 --
9
this commit leaves the behaviour there unchanged.)
10
12
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20180209165810.6668-2-peter.maydell@linaro.org
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
15
---
16
---
16
hw/intc/armv7m_nvic.c | 30 ++++++++++++++++--------------
17
include/hw/arm/exynos4210.h | 6 ------
17
target/arm/cpu.c | 28 ++++++++++++++++++++++++++++
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
18
2 files changed, 44 insertions(+), 14 deletions(-)
19
2 files changed, 8 insertions(+), 32 deletions(-)
19
20
20
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/armv7m_nvic.c
23
--- a/include/hw/arm/exynos4210.h
23
+++ b/hw/intc/armv7m_nvic.c
24
+++ b/include/hw/arm/exynos4210.h
24
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
25
@@ -XXX,XX +XXX,XX @@
25
"Aux Fault status registers unimplemented\n");
26
*/
26
return 0;
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
27
case 0xd40: /* PFR0. */
28
28
- return 0x00000030;
29
-typedef struct Exynos4210Irq {
29
- case 0xd44: /* PRF1. */
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
30
- return 0x00000200;
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
31
+ return cpu->id_pfr0;
32
-} Exynos4210Irq;
32
+ case 0xd44: /* PFR1. */
33
-
33
+ return cpu->id_pfr1;
34
struct Exynos4210State {
34
case 0xd48: /* DFR0. */
35
/*< private >*/
35
- return 0x00100000;
36
SysBusDevice parent_obj;
36
+ return cpu->id_dfr0;
37
/*< public >*/
37
case 0xd4c: /* AFR0. */
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
38
- return 0x00000000;
39
- Exynos4210Irq irqs;
39
+ return cpu->id_afr0;
40
qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
40
case 0xd50: /* MMFR0. */
41
41
- return 0x00000030;
42
MemoryRegion chipid_mem;
42
+ return cpu->id_mmfr0;
43
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
43
case 0xd54: /* MMFR1. */
44
- return 0x00000000;
45
+ return cpu->id_mmfr1;
46
case 0xd58: /* MMFR2. */
47
- return 0x00000000;
48
+ return cpu->id_mmfr2;
49
case 0xd5c: /* MMFR3. */
50
- return 0x00000000;
51
+ return cpu->id_mmfr3;
52
case 0xd60: /* ISAR0. */
53
- return 0x01141110;
54
+ return cpu->id_isar0;
55
case 0xd64: /* ISAR1. */
56
- return 0x02111000;
57
+ return cpu->id_isar1;
58
case 0xd68: /* ISAR2. */
59
- return 0x21112231;
60
+ return cpu->id_isar2;
61
case 0xd6c: /* ISAR3. */
62
- return 0x01111110;
63
+ return cpu->id_isar3;
64
case 0xd70: /* ISAR4. */
65
- return 0x01310102;
66
+ return cpu->id_isar4;
67
+ case 0xd74: /* ISAR5. */
68
+ return cpu->id_isar5;
69
/* TODO: Implement debug registers. */
70
case 0xd90: /* MPU_TYPE */
71
/* Unified MPU; if the MPU is not present this value is zero */
72
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
73
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/cpu.c
45
--- a/hw/arm/exynos4210.c
75
+++ b/target/arm/cpu.c
46
+++ b/hw/arm/exynos4210.c
76
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
77
set_feature(&cpu->env, ARM_FEATURE_M);
48
static void exynos4210_init_board_irqs(Exynos4210State *s)
78
cpu->midr = 0x410fc231;
49
{
79
cpu->pmsav7_dregion = 8;
50
uint32_t grp, bit, irq_id, n;
80
+ cpu->id_pfr0 = 0x00000030;
51
- Exynos4210Irq *is = &s->irqs;
81
+ cpu->id_pfr1 = 0x00000200;
52
DeviceState *extgicdev = DEVICE(&s->ext_gic);
82
+ cpu->id_dfr0 = 0x00100000;
53
+ DeviceState *intcdev = DEVICE(&s->int_combiner);
83
+ cpu->id_afr0 = 0x00000000;
54
+ DeviceState *extcdev = DEVICE(&s->ext_combiner);
84
+ cpu->id_mmfr0 = 0x00000030;
55
int splitcount = 0;
85
+ cpu->id_mmfr1 = 0x00000000;
56
DeviceState *splitter;
86
+ cpu->id_mmfr2 = 0x00000000;
57
const int *mapline;
87
+ cpu->id_mmfr3 = 0x00000000;
58
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
88
+ cpu->id_isar0 = 0x01141110;
59
splitin = 0;
89
+ cpu->id_isar1 = 0x02111000;
60
for (;;) {
90
+ cpu->id_isar2 = 0x21112231;
61
s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
91
+ cpu->id_isar3 = 0x01111110;
62
- qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
92
+ cpu->id_isar4 = 0x01310102;
63
- qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
93
+ cpu->id_isar5 = 0x00000000;
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);
94
}
87
}
95
88
96
static void cortex_m4_initfn(Object *obj)
89
-/*
97
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
90
- * Get Combiner input GPIO into irqs structure
98
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
91
- */
99
cpu->midr = 0x410fc240; /* r0p0 */
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
100
cpu->pmsav7_dregion = 8;
93
- DeviceState *dev, int ext)
101
+ cpu->id_pfr0 = 0x00000030;
94
-{
102
+ cpu->id_pfr1 = 0x00000200;
95
- int n;
103
+ cpu->id_dfr0 = 0x00100000;
96
- int max;
104
+ cpu->id_afr0 = 0x00000000;
97
- qemu_irq *irq;
105
+ cpu->id_mmfr0 = 0x00000030;
98
-
106
+ cpu->id_mmfr1 = 0x00000000;
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
107
+ cpu->id_mmfr2 = 0x00000000;
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
108
+ cpu->id_mmfr3 = 0x00000000;
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
109
+ cpu->id_isar0 = 0x01141110;
102
-
110
+ cpu->id_isar1 = 0x02111000;
103
- for (n = 0; n < max; n++) {
111
+ cpu->id_isar2 = 0x21112231;
104
- irq[n] = qdev_get_gpio_in(dev, n);
112
+ cpu->id_isar3 = 0x01111110;
105
- }
113
+ cpu->id_isar4 = 0x01310102;
106
-}
114
+ cpu->id_isar5 = 0x00000000;
107
-
115
}
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
116
109
0x09, 0x00, 0x00, 0x00 };
117
static void arm_v7m_class_init(ObjectClass *oc, void *data)
110
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
112
sysbus_connect_irq(busdev, n,
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
114
}
115
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
116
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
117
118
/* External Interrupt Combiner */
119
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
120
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
121
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
122
}
123
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
124
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
125
126
/* Initialize board IRQs. */
118
--
127
--
119
2.16.1
128
2.25.1
120
121
diff view generated by jsdifflib
1
From: Pekka Enberg <penberg@iki.fi>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
This patch adds a "raspi3" machine type, which can now be selected as
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
the machine to run on by users via the "-M" command line option to QEMU.
5
6
The machine type does *not* ignore memory transaction failures so we
7
likely need to add some dummy devices later when people run something
8
more complicated than what I'm using for testing.
9
10
Signed-off-by: Pekka Enberg <penberg@iki.fi>
11
[PMM: added #ifdef TARGET_AARCH64 so we don't provide the 64-bit
12
board in the 32-bit only arm-softmmu build.]
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
7
---
17
hw/arm/raspi.c | 23 +++++++++++++++++++++++
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
18
1 file changed, 23 insertions(+)
9
1 file changed, 24 insertions(+), 9 deletions(-)
19
10
20
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
21
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/raspi.c
13
--- a/hw/arm/realview.c
23
+++ b/hw/arm/raspi.c
14
+++ b/hw/arm/realview.c
24
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
15
@@ -XXX,XX +XXX,XX @@
25
mc->ignore_memory_transaction_failures = true;
16
#include "hw/sysbus.h"
17
#include "hw/arm/boot.h"
18
#include "hw/arm/primecell.h"
19
+#include "hw/core/split-irq.h"
20
#include "hw/net/lan9118.h"
21
#include "hw/net/smc91c111.h"
22
#include "hw/pci/pci.h"
23
+#include "hw/qdev-core.h"
24
#include "net/net.h"
25
#include "sysemu/sysemu.h"
26
#include "hw/boards.h"
27
@@ -XXX,XX +XXX,XX @@ static const int realview_board_id[] = {
28
0x76d
26
};
29
};
27
DEFINE_MACHINE("raspi2", raspi2_machine_init)
30
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
32
+ qemu_irq out1, qemu_irq out2) {
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
28
+
34
+
29
+#ifdef TARGET_AARCH64
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
30
+static void raspi3_init(MachineState *machine)
36
+
31
+{
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
32
+ raspi_init(machine, 3);
38
+
39
+ qdev_connect_gpio_out(splitter, 0, out1);
40
+ qdev_connect_gpio_out(splitter, 1, out2);
41
+ qdev_connect_gpio_out_named(src, outname, 0,
42
+ qdev_get_gpio_in(splitter, 0));
33
+}
43
+}
34
+
44
+
35
+static void raspi3_machine_init(MachineClass *mc)
45
static void realview_init(MachineState *machine,
36
+{
46
enum realview_board_type board_type)
37
+ mc->desc = "Raspberry Pi 3";
47
{
38
+ mc->init = raspi3_init;
48
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
39
+ mc->block_default_type = IF_SD;
49
DeviceState *dev, *sysctl, *gpio2, *pl041;
40
+ mc->no_parallel = 1;
50
SysBusDevice *busdev;
41
+ mc->no_floppy = 1;
51
qemu_irq pic[64];
42
+ mc->no_cdrom = 1;
52
- qemu_irq mmc_irq[2];
43
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
53
PCIBus *pci_bus = NULL;
44
+ mc->max_cpus = BCM2836_NCPUS;
54
NICInfo *nd;
45
+ mc->min_cpus = BCM2836_NCPUS;
55
DriveInfo *dinfo;
46
+ mc->default_cpus = BCM2836_NCPUS;
56
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
47
+ mc->default_ram_size = 1024 * 1024 * 1024;
57
* and the PL061 has them the other way about. Also the card
48
+}
58
* detect line is inverted.
49
+DEFINE_MACHINE("raspi3", raspi3_machine_init)
59
*/
50
+#endif
60
- mmc_irq[0] = qemu_irq_split(
61
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
62
- qdev_get_gpio_in(gpio2, 1));
63
- mmc_irq[1] = qemu_irq_split(
64
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
65
- qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
66
- qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
67
- qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_irq[1]);
68
+ split_irq_from_named(dev, "card-read-only",
69
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
70
+ qdev_get_gpio_in(gpio2, 1));
71
+
72
+ split_irq_from_named(dev, "card-inserted",
73
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
74
+ qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
75
+
76
dinfo = drive_get(IF_SD, 0, 0);
77
if (dinfo) {
78
DeviceState *card;
51
--
79
--
52
2.16.1
80
2.25.1
53
54
diff view generated by jsdifflib
New patch
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
hw/arm/stellaris.c | 15 +++++++++++++--
9
1 file changed, 13 insertions(+), 2 deletions(-)
10
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/stellaris.c
14
+++ b/hw/arm/stellaris.c
15
@@ -XXX,XX +XXX,XX @@
16
17
#include "qemu/osdep.h"
18
#include "qapi/error.h"
19
+#include "hw/core/split-irq.h"
20
#include "hw/sysbus.h"
21
#include "hw/sd/sd.h"
22
#include "hw/ssi/ssi.h"
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
24
DeviceState *ssddev;
25
DriveInfo *dinfo;
26
DeviceState *carddev;
27
+ DeviceState *gpio_d_splitter;
28
BlockBackend *blk;
29
30
/*
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
32
&error_fatal);
33
34
ssddev = ssi_create_peripheral(bus, "ssd0323");
35
- gpio_out[GPIO_D][0] = qemu_irq_split(
36
- qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
37
+
38
+ gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
39
+ qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
40
+ qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
41
+ qdev_connect_gpio_out(
42
+ gpio_d_splitter, 0,
43
+ qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0));
44
+ qdev_connect_gpio_out(
45
+ gpio_d_splitter, 1,
46
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
47
+ gpio_out[GPIO_D][0] = qdev_get_gpio_in(gpio_d_splitter, 0);
48
+
49
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
50
51
/* Make sure the select pin is high. */
52
--
53
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
This also makes sure that we get the correct ordering of
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
SVE vs FP exceptions.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180211205848.4568-5-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
8
---
11
target/arm/cpu.h | 3 ++-
9
include/hw/irq.h | 5 -----
12
target/arm/internals.h | 6 ++++++
10
hw/core/irq.c | 15 ---------------
13
target/arm/helper.c | 22 ++++------------------
11
2 files changed, 20 deletions(-)
14
target/arm/translate-a64.c | 16 ++++++++++++++++
15
4 files changed, 28 insertions(+), 19 deletions(-)
16
12
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
15
--- a/include/hw/irq.h
20
+++ b/target/arm/cpu.h
16
+++ b/include/hw/irq.h
21
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
22
#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
18
/* Returns a new IRQ with opposite polarity. */
23
#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
19
qemu_irq qemu_irq_invert(qemu_irq irq);
24
#define ARM_CP_FPU 0x1000
20
25
+#define ARM_CP_SVE 0x2000
21
-/* Returns a new IRQ which feeds into both the passed IRQs.
26
/* Used only as a terminator for ARMCPRegInfo lists */
22
- * It's probably better to use the TYPE_SPLIT_IRQ device instead.
27
#define ARM_CP_SENTINEL 0xffff
23
- */
28
/* Mask of only the flag bits in a type field */
24
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
29
-#define ARM_CP_FLAG_MASK 0x10ff
25
-
30
+#define ARM_CP_FLAG_MASK 0x30ff
26
/* For internal use in qtest. Similar to qemu_irq_split, but operating
31
27
on an existing vector of qemu_irq. */
32
/* Valid values for ARMCPRegInfo state field, indicating which of
28
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
33
* the AArch32 and AArch64 execution states this register is visible in.
29
diff --git a/hw/core/irq.c b/hw/core/irq.c
34
diff --git a/target/arm/internals.h b/target/arm/internals.h
35
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/internals.h
31
--- a/hw/core/irq.c
37
+++ b/target/arm/internals.h
32
+++ b/hw/core/irq.c
38
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
33
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_invert(qemu_irq irq)
39
EC_AA64_HVC = 0x16,
34
return qemu_allocate_irq(qemu_notirq, irq, 0);
40
EC_AA64_SMC = 0x17,
41
EC_SYSTEMREGISTERTRAP = 0x18,
42
+ EC_SVEACCESSTRAP = 0x19,
43
EC_INSNABORT = 0x20,
44
EC_INSNABORT_SAME_EL = 0x21,
45
EC_PCALIGNMENT = 0x22,
46
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit)
47
| (cv << 24) | (cond << 20);
48
}
35
}
49
36
50
+static inline uint32_t syn_sve_access_trap(void)
37
-static void qemu_splitirq(void *opaque, int line, int level)
51
+{
52
+ return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
53
+}
54
+
55
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
56
{
57
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
58
diff --git a/target/arm/helper.c b/target/arm/helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/helper.c
61
+++ b/target/arm/helper.c
62
@@ -XXX,XX +XXX,XX @@ static int sve_exception_el(CPUARMState *env)
63
return 0;
64
}
65
66
-static CPAccessResult zcr_access(CPUARMState *env, const ARMCPRegInfo *ri,
67
- bool isread)
68
-{
38
-{
69
- switch (sve_exception_el(env)) {
39
- struct IRQState **irq = opaque;
70
- case 3:
40
- irq[0]->handler(irq[0]->opaque, irq[0]->n, level);
71
- return CP_ACCESS_TRAP_EL3;
41
- irq[1]->handler(irq[1]->opaque, irq[1]->n, level);
72
- case 2:
73
- return CP_ACCESS_TRAP_EL2;
74
- case 1:
75
- return CP_ACCESS_TRAP;
76
- }
77
- return CP_ACCESS_OK;
78
-}
42
-}
79
-
43
-
80
static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
44
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
81
uint64_t value)
45
-{
46
- qemu_irq *s = g_new0(qemu_irq, 2);
47
- s[0] = irq1;
48
- s[1] = irq2;
49
- return qemu_allocate_irq(qemu_splitirq, s, 0);
50
-}
51
-
52
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
82
{
53
{
83
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
54
int i;
84
static const ARMCPRegInfo zcr_el1_reginfo = {
85
.name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
86
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
87
- .access = PL1_RW, .accessfn = zcr_access,
88
+ .access = PL1_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
89
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
90
.writefn = zcr_write, .raw_writefn = raw_write
91
};
92
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el1_reginfo = {
93
static const ARMCPRegInfo zcr_el2_reginfo = {
94
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
95
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
96
- .access = PL2_RW, .accessfn = zcr_access,
97
+ .access = PL2_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
98
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
99
.writefn = zcr_write, .raw_writefn = raw_write
100
};
101
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el2_reginfo = {
102
static const ARMCPRegInfo zcr_no_el2_reginfo = {
103
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
104
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
105
- .access = PL2_RW,
106
+ .access = PL2_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
107
.readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
108
};
109
110
static const ARMCPRegInfo zcr_el3_reginfo = {
111
.name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
112
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
113
- .access = PL3_RW, .accessfn = zcr_access,
114
+ .access = PL3_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
115
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
116
.writefn = zcr_write, .raw_writefn = raw_write
117
};
118
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/arm/translate-a64.c
121
+++ b/target/arm/translate-a64.c
122
@@ -XXX,XX +XXX,XX @@ static inline bool fp_access_check(DisasContext *s)
123
return false;
124
}
125
126
+/* Check that SVE access is enabled. If it is, return true.
127
+ * If not, emit code to generate an appropriate exception and return false.
128
+ */
129
+static inline bool sve_access_check(DisasContext *s)
130
+{
131
+ if (s->sve_excp_el) {
132
+ gen_exception_insn(s, 4, EXCP_UDEF, syn_sve_access_trap(),
133
+ s->sve_excp_el);
134
+ return false;
135
+ }
136
+ return true;
137
+}
138
+
139
/*
140
* This utility function is for doing register extension with an
141
* optional shift. You will likely want to pass a temporary for the
142
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
143
default:
144
break;
145
}
146
+ if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
147
+ return;
148
+ }
149
if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
150
return;
151
}
152
--
55
--
153
2.16.1
56
2.25.1
154
155
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
2
2
3
Nothing in either register affects the TB.
3
Describe that the gic-version influences the maximum number of CPUs.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
6
Message-id: 20180211205848.4568-4-richard.henderson@linaro.org
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
7
[PMM: minor punctuation tweaks]
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/helper.c | 4 ++--
11
docs/system/arm/virt.rst | 4 ++--
11
1 file changed, 2 insertions(+), 2 deletions(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
12
13
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
--- a/docs/system/arm/virt.rst
16
+++ b/target/arm/helper.c
17
+++ b/docs/system/arm/virt.rst
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
18
@@ -XXX,XX +XXX,XX @@ gic-version
18
.writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore },
19
Valid values are:
19
{ .name = "FPCR", .state = ARM_CP_STATE_AA64,
20
20
.opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
21
``2``
21
- .access = PL0_RW, .type = ARM_CP_FPU,
22
- GICv2
22
+ .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
23
+ GICv2. Note that this limits the number of CPUs to 8.
23
.readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
24
``3``
24
{ .name = "FPSR", .state = ARM_CP_STATE_AA64,
25
- GICv3
25
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
26
+ GICv3. This allows up to 512 CPUs.
26
- .access = PL0_RW, .type = ARM_CP_FPU,
27
``host``
27
+ .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
28
Use the same GIC version the host provides, when using KVM
28
.readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
29
``max``
29
{ .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64,
30
.opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
31
--
30
--
32
2.16.1
31
2.25.1
33
34
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
Because they are ARM_CP_STATE_AA64, ARM_CP_64BIT is implied.
3
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
4
the PWRON STRAP fields in their corresponding module for NPCM7XX.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
6
Message-id: 20180211205848.4568-2-richard.henderson@linaro.org
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Message-id: 20220411165842.3912945-2-wuhaotsh@google.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
target/arm/helper.c | 8 ++++----
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
11
1 file changed, 4 insertions(+), 4 deletions(-)
13
1 file changed, 30 insertions(+)
12
14
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
17
--- a/include/hw/misc/npcm7xx_gcr.h
16
+++ b/target/arm/helper.c
18
+++ b/include/hw/misc/npcm7xx_gcr.h
17
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
19
@@ -XXX,XX +XXX,XX @@
18
static const ARMCPRegInfo zcr_el1_reginfo = {
20
#include "exec/memory.h"
19
.name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
21
#include "hw/sysbus.h"
20
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
22
21
- .access = PL1_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
23
+/*
22
+ .access = PL1_RW, .accessfn = zcr_access,
24
+ * NPCM7XX PWRON STRAP bit fields
23
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
24
.writefn = zcr_write, .raw_writefn = raw_write
26
+ * 11: System flash attached to BMC
25
};
27
+ * 10: BSP alternative pins.
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el1_reginfo = {
28
+ * 9:8: Flash UART command route enabled.
27
static const ARMCPRegInfo zcr_el2_reginfo = {
29
+ * 7: Security enabled.
28
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
30
+ * 6: HI-Z state control.
29
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
31
+ * 5: ECC disabled.
30
- .access = PL2_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
32
+ * 4: Reserved
31
+ .access = PL2_RW, .accessfn = zcr_access,
33
+ * 3: JTAG2 enabled.
32
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
34
+ * 2:0: CPU and DRAM clock frequency.
33
.writefn = zcr_write, .raw_writefn = raw_write
35
+ */
34
};
36
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
35
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el2_reginfo = {
37
+#define NPCM7XX_PWRON_STRAP_SFAB BIT(11)
36
static const ARMCPRegInfo zcr_no_el2_reginfo = {
38
+#define NPCM7XX_PWRON_STRAP_BSPA BIT(10)
37
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
39
+#define NPCM7XX_PWRON_STRAP_FUP(x) ((x) << 8)
38
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
40
+#define FUP_NORM_UART2 3
39
- .access = PL2_RW, .type = ARM_CP_64BIT,
41
+#define FUP_PROG_UART3 2
40
+ .access = PL2_RW,
42
+#define FUP_PROG_UART2 1
41
.readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
43
+#define FUP_NORM_UART3 0
42
};
44
+#define NPCM7XX_PWRON_STRAP_SECEN BIT(7)
43
45
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
44
static const ARMCPRegInfo zcr_el3_reginfo = {
46
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
45
.name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
47
+#define NPCM7XX_PWRON_STRAP_RESERVE1 BIT(4)
46
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
48
+#define NPCM7XX_PWRON_STRAP_J2EN BIT(3)
47
- .access = PL3_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
49
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x) (x)
48
+ .access = PL3_RW, .accessfn = zcr_access,
50
+#define CKFRQ_SKIPINIT 0x000
49
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
51
+#define CKFRQ_DEFAULT 0x111
50
.writefn = zcr_write, .raw_writefn = raw_write
52
+
51
};
53
/*
54
* Number of registers in our device state structure. Don't change this without
55
* incrementing the version_id in the vmstate.
52
--
56
--
53
2.16.1
57
2.25.1
54
55
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
(qemu) info mtree
3
This patch uses the defined fields to describe PWRON STRAPs for
4
address-space: cpu-memory-0
4
better readability.
5
0000000000000000-ffffffffffffffff (prio 0, i/o): system
6
0000000000000000-0000000007ffffff (prio 0, rom): aspeed.boot_rom
7
000000001e600000-000000001e7fffff (prio -1, i/o): aspeed_soc.io
8
- 000000001e784000-000000001e78401f (prio 0, i/o): serial
9
000000001e620000-000000001e6200ff (prio 0, i/o): aspeed.smc.ast2500-fmc
10
000000001e630000-000000001e6300ff (prio 0, i/o): aspeed.smc.ast2500-spi1
11
[...]
12
000000001e720000-000000001e728fff (prio 0, ram): aspeed.sram
13
000000001e782000-000000001e782fff (prio 0, i/o): aspeed.timer
14
+ 000000001e784000-000000001e78401f (prio 0, i/o): serial
15
000000001e785000-000000001e78501f (prio 0, i/o): aspeed.wdt
16
000000001e785020-000000001e78503f (prio 0, i/o): aspeed.wdt
17
5
18
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
19
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Patrick Venture <venture@google.com>
20
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
8
Message-id: 20220411165842.3912945-3-wuhaotsh@google.com
21
Message-id: 20180209085755.30414-2-f4bug@amsat.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
11
---
24
hw/arm/aspeed_soc.c | 3 ++-
12
hw/arm/npcm7xx_boards.c | 24 +++++++++++++++++++-----
25
1 file changed, 2 insertions(+), 1 deletion(-)
13
1 file changed, 19 insertions(+), 5 deletions(-)
26
14
27
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
28
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/aspeed_soc.c
17
--- a/hw/arm/npcm7xx_boards.c
30
+++ b/hw/arm/aspeed_soc.c
18
+++ b/hw/arm/npcm7xx_boards.c
31
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
19
@@ -XXX,XX +XXX,XX @@
32
/* UART - attach an 8250 to the IO space as our UART5 */
20
#include "sysemu/sysemu.h"
33
if (serial_hds[0]) {
21
#include "sysemu/block-backend.h"
34
qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
22
35
- serial_mm_init(&s->iomem, ASPEED_SOC_UART_5_BASE, 2,
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
36
+ serial_mm_init(get_system_memory(),
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
37
+ ASPEED_SOC_IOMEM_BASE + ASPEED_SOC_UART_5_BASE, 2,
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
38
uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
39
}
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";
40
49
41
--
50
--
42
2.16.1
51
2.25.1
43
44
diff view generated by jsdifflib