1
More arm patches (mostly the SDHCI ones from Philippe)
1
First arm pullreq for 7.1. The bulk of this is the qemu_split_irq
2
removal.
3
4
I have enough stuff in my to-review queue that I expect to do another
5
pullreq early next week, but 31 patches is enough to not hang on to.
2
6
3
thanks
7
thanks
4
-- PMM
8
-- PMM
5
9
6
The following changes since commit f521eeee3bd060b460c99e605472b7e03967db43:
10
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
7
11
8
Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20180115' into staging (2018-01-15 13:17:47 +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-20180116
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 60765b6ceeb4998a0d4220b3a53f1f185061da77:
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
15
19
16
sdhci: add a 'dma' property to the sysbus devices (2018-01-16 13:28:21 +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
* SDHCI: cleanups and minor bug fixes
24
* hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
21
* target/arm: minor refactor preparatory to fp16 support
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
22
* omap_ssd, ssi-sd, pl181, milkymist-memcard: reset the SD
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
23
card on controller reset (fixes migration failures)
27
* xlnx-zynqmp: Connect 4 TTC timers
24
* target/arm: Handle page table walk load failures correctly
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
25
* hw/arm/virt: Add virt-2.12 machine type
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
26
* get_phys_addr_pmsav7: Support AP=0b111 for v7M
30
* stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
27
* hw/intc/armv7m: Support byte and halfword accesses to CFSR
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
28
34
29
----------------------------------------------------------------
35
----------------------------------------------------------------
30
Andrey Smirnov (1):
36
Edgar E. Iglesias (6):
31
sdhci: Implement write method of ACMD12ERRSTS register
37
timer: cadence_ttc: Break out header file to allow embedding
38
hw/arm/xlnx-zynqmp: Connect 4 TTC timers
39
hw/arm: versal: Create an APU CPU Cluster
40
hw/arm: versal: Add the Cortex-R5Fs
41
hw/misc: Add a model of the Xilinx Versal CRL
42
hw/arm: versal: Connect the CRL
32
43
33
Peter Maydell (8):
44
Hao Wu (2):
34
hw/intc/armv7m: Support byte and halfword accesses to CFSR
45
hw/misc: Add PWRON STRAP bit fields in GCR module
35
get_phys_addr_pmsav7: Support AP=0b111 for v7M
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
36
hw/arm/virt: Add virt-2.12 machine type
37
target/arm: Handle page table walk load failures correctly
38
hw/sd/pl181: Reset SD card on controller reset
39
hw/sd/milkymist-memcard: Reset SD card on controller reset
40
hw/sd/ssi-sd: Reset SD card on controller reset
41
hw/sd/omap_mmc: Reset SD card on controller reset
42
47
43
Philippe Mathieu-Daudé (13):
48
Heinrich Schuchardt (1):
44
sdhci: clean up includes
49
hw/arm/virt: impact of gic-version on max CPUs
45
sdhci: remove dead code
46
sdhci: use DEFINE_SDHCI_COMMON_PROPERTIES() for common sysbus/pci properties
47
sdhci: refactor common sysbus/pci class_init() into sdhci_common_class_init()
48
sdhci: refactor common sysbus/pci realize() into sdhci_common_realize()
49
sdhci: refactor common sysbus/pci unrealize() into sdhci_common_unrealize()
50
sdhci: use qemu_log_mask(UNIMP) instead of fprintf()
51
sdhci: convert the DPRINT() calls into trace events
52
sdhci: move MASK_TRNMOD with other SDHC_TRN* defines in "sd-internal.h"
53
sdhci: rename the SDHC_CAPAB register
54
sdhci: fix CAPAB/MAXCURR registers, both are 64bit and read-only
55
sdhci: fix the PCI device, using the PCI address space for DMA
56
sdhci: add a 'dma' property to the sysbus devices
57
50
58
Richard Henderson (2):
51
Peter Maydell (19):
59
target/arm: Split out vfp_expand_imm
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
60
target/arm: Add fp16 support to vfp_expand_imm
53
hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device
54
hw/intc/exynos4210_gic: Remove unused TYPE_EXYNOS4210_IRQ_GATE
55
hw/arm/exynos4210: Put a9mpcore device into state struct
56
hw/arm/exynos4210: Drop int_gic_irq[] from Exynos4210Irq struct
57
hw/arm/exynos4210: Coalesce board_irqs and irq_table
58
hw/arm/exynos4210: Fix code style nit in combiner_grp_to_gic_id[]
59
hw/arm/exynos4210: Move exynos4210_init_board_irqs() into exynos4210.c
60
hw/arm/exynos4210: Put external GIC into state struct
61
hw/arm/exynos4210: Drop ext_gic_irq[] from Exynos4210Irq struct
62
hw/arm/exynos4210: Move exynos4210_combiner_get_gpioin() into exynos4210.c
63
hw/arm/exynos4210: Delete unused macro definitions
64
hw/arm/exynos4210: Use TYPE_SPLIT_IRQ in exynos4210_init_board_irqs()
65
hw/arm/exynos4210: Fill in irq_table[] for internal-combiner-only IRQ lines
66
hw/arm/exynos4210: Connect MCT_G0 and MCT_G1 to both combiners
67
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
68
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
69
hw/arm/exynos4210: Put combiners into state struct
70
hw/arm/exynos4210: Drop Exynos4210Irq struct
61
71
62
hw/sd/sdhci-internal.h | 7 +-
72
Zongyuan Li (3):
63
include/hw/sd/sdhci.h | 19 +++-
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
64
target/arm/internals.h | 10 ++
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
65
hw/arm/virt.c | 19 +++-
75
hw/core/irq: remove unused 'qemu_irq_split' function
66
hw/intc/armv7m_nvic.c | 38 ++++---
67
hw/sd/milkymist-memcard.c | 4 +
68
hw/sd/omap_mmc.c | 14 ++-
69
hw/sd/pl181.c | 4 +
70
hw/sd/sdhci.c | 266 +++++++++++++++++++++++++++------------------
71
hw/sd/ssi-sd.c | 25 ++++-
72
target/arm/helper.c | 53 ++++++++-
73
target/arm/op_helper.c | 7 +-
74
target/arm/translate-a64.c | 49 ++++++---
75
hw/sd/trace-events | 14 +++
76
14 files changed, 362 insertions(+), 167 deletions(-)
77
76
77
docs/system/arm/virt.rst | 4 +-
78
include/hw/arm/exynos4210.h | 50 ++--
79
include/hw/arm/xlnx-versal.h | 16 ++
80
include/hw/arm/xlnx-zynqmp.h | 4 +
81
include/hw/intc/exynos4210_combiner.h | 57 +++++
82
include/hw/intc/exynos4210_gic.h | 43 ++++
83
include/hw/irq.h | 5 -
84
include/hw/misc/npcm7xx_gcr.h | 30 +++
85
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++++
86
include/hw/timer/cadence_ttc.h | 54 +++++
87
hw/arm/exynos4210.c | 430 ++++++++++++++++++++++++++++++----
88
hw/arm/npcm7xx_boards.c | 24 +-
89
hw/arm/realview.c | 33 ++-
90
hw/arm/stellaris.c | 15 +-
91
hw/arm/virt.c | 7 +
92
hw/arm/xlnx-versal-virt.c | 6 +-
93
hw/arm/xlnx-versal.c | 99 +++++++-
94
hw/arm/xlnx-zynqmp.c | 22 ++
95
hw/core/irq.c | 15 --
96
hw/intc/exynos4210_combiner.c | 108 +--------
97
hw/intc/exynos4210_gic.c | 344 +--------------------------
98
hw/misc/xlnx-versal-crl.c | 421 +++++++++++++++++++++++++++++++++
99
hw/timer/cadence_ttc.c | 32 +--
100
MAINTAINERS | 2 +-
101
hw/misc/meson.build | 1 +
102
25 files changed, 1457 insertions(+), 600 deletions(-)
103
create mode 100644 include/hw/intc/exynos4210_combiner.h
104
create mode 100644 include/hw/intc/exynos4210_gic.h
105
create mode 100644 include/hw/misc/xlnx-versal-crl.h
106
create mode 100644 include/hw/timer/cadence_ttc.h
107
create mode 100644 hw/misc/xlnx-versal-crl.c
diff view generated by jsdifflib
1
Add virt-2.12 machine type.
1
It's not possible to provide the guest with the Security extensions
2
(TrustZone) when using KVM or HVF, because the hardware
3
virtualization extensions don't permit running EL3 guest code.
4
However, we weren't checking for this combination, with the result
5
that QEMU would assert if you tried it:
2
6
7
$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none
8
Unexpected error in object_property_find_err() at ../../qom/object.c:1304:
9
qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found
10
Aborted
11
12
Check for this combination of options and report an error, in the
13
same way we already do for attempts to give a KVM or HVF guest the
14
Virtualization or MTE extensions. Now we will report:
15
16
qemu-system-aarch64: mach-virt: KVM does not support providing Security extensions (TrustZone) to the guest CPU
17
18
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/961
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20220404155301.566542-1-peter.maydell@linaro.org
4
---
22
---
5
hw/arm/virt.c | 19 +++++++++++++++++--
23
hw/arm/virt.c | 7 +++++++
6
1 file changed, 17 insertions(+), 2 deletions(-)
24
1 file changed, 7 insertions(+)
7
25
8
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
26
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
9
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/arm/virt.c
28
--- a/hw/arm/virt.c
11
+++ b/hw/arm/virt.c
29
+++ b/hw/arm/virt.c
12
@@ -XXX,XX +XXX,XX @@ static void machvirt_machine_init(void)
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
13
}
31
exit(1);
14
type_init(machvirt_machine_init);
32
}
15
33
16
-static void virt_2_11_instance_init(Object *obj)
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
17
+static void virt_2_12_instance_init(Object *obj)
35
+ error_report("mach-virt: %s does not support providing "
18
{
36
+ "Security extensions (TrustZone) to the guest CPU",
19
VirtMachineState *vms = VIRT_MACHINE(obj);
37
+ kvm_enabled() ? "KVM" : "HVF");
20
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
38
+ exit(1);
21
@@ -XXX,XX +XXX,XX @@ static void virt_2_11_instance_init(Object *obj)
39
+ }
22
vms->irqmap = a15irqmap;
23
}
24
25
+static void virt_machine_2_12_options(MachineClass *mc)
26
+{
27
+}
28
+DEFINE_VIRT_MACHINE_AS_LATEST(2, 12)
29
+
40
+
30
+#define VIRT_COMPAT_2_11 \
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
31
+ HW_COMPAT_2_11
42
error_report("mach-virt: %s does not support providing "
32
+
43
"Virtualization extensions to the guest CPU",
33
+static void virt_2_11_instance_init(Object *obj)
34
+{
35
+ virt_2_12_instance_init(obj);
36
+}
37
+
38
static void virt_machine_2_11_options(MachineClass *mc)
39
{
40
+ virt_machine_2_12_options(mc);
41
+ SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_11);
42
}
43
-DEFINE_VIRT_MACHINE_AS_LATEST(2, 11)
44
+DEFINE_VIRT_MACHINE(2, 11)
45
46
#define VIRT_COMPAT_2_10 \
47
HW_COMPAT_2_10
48
--
44
--
49
2.7.4
45
2.25.1
50
51
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
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
Connect the 4 TTC timers on the ZynqMP.
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
5
Message-id: 20180110063337.21538-2-richard.henderson@linaro.org
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/translate-a64.c | 44 ++++++++++++++++++++++++++++----------------
12
include/hw/arm/xlnx-zynqmp.h | 4 ++++
9
1 file changed, 28 insertions(+), 16 deletions(-)
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
14
2 files changed, 26 insertions(+)
10
15
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
18
--- a/include/hw/arm/xlnx-zynqmp.h
14
+++ b/target/arm/translate-a64.c
19
+++ b/include/hw/arm/xlnx-zynqmp.h
15
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
20
@@ -XXX,XX +XXX,XX @@
16
}
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]);
17
}
61
}
18
62
19
+/* The imm8 encodes the sign bit, enough bits to represent an exponent in
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
20
+ * the range 01....1xx to 10....0xx, and the most significant 4 bits of
21
+ * the mantissa; see VFPExpandImm() in the v8 ARM ARM.
22
+ */
23
+static uint64_t vfp_expand_imm(int size, uint8_t imm8)
24
+{
64
+{
25
+ uint64_t imm;
65
+ SysBusDevice *sbd;
66
+ int i, irq;
26
+
67
+
27
+ switch (size) {
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
28
+ case MO_64:
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
29
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
70
+ TYPE_CADENCE_TTC);
30
+ (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
31
+ extract32(imm8, 0, 6);
72
+
32
+ imm <<= 48;
73
+ sysbus_realize(sbd, &error_fatal);
33
+ break;
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
34
+ case MO_32:
75
+ for (irq = 0; irq < 3; irq++) {
35
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
36
+ (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
77
+ }
37
+ (extract32(imm8, 0, 6) << 3);
38
+ imm <<= 16;
39
+ break;
40
+ default:
41
+ g_assert_not_reached();
42
+ }
78
+ }
43
+ return imm;
44
+}
79
+}
45
+
80
+
46
/* Floating point immediate
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
47
* 31 30 29 28 24 23 22 21 20 13 12 10 9 5 4 0
82
{
48
* +---+---+---+-----------+------+---+------------+-------+------+------+
83
static const struct UnimpInfo {
49
@@ -XXX,XX +XXX,XX @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
50
return;
85
xlnx_zynqmp_create_efuse(s, gic_spi);
51
}
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
52
87
xlnx_zynqmp_create_crf(s, gic_spi);
53
- /* The imm8 encodes the sign bit, enough bits to represent
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
54
- * an exponent in the range 01....1xx to 10....0xx,
89
xlnx_zynqmp_create_unimp_mmio(s);
55
- * and the most significant 4 bits of the mantissa; see
90
56
- * VFPExpandImm() in the v8 ARM ARM.
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
57
- */
58
- if (is_double) {
59
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
60
- (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
61
- extract32(imm8, 0, 6);
62
- imm <<= 48;
63
- } else {
64
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
65
- (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
66
- (extract32(imm8, 0, 6) << 3);
67
- imm <<= 16;
68
- }
69
+ imm = vfp_expand_imm(MO_32 + is_double, imm8);
70
71
tcg_res = tcg_const_i64(imm);
72
write_fp_dreg(s, rd, tcg_res);
73
--
92
--
74
2.7.4
93
2.25.1
75
76
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
zero-initialize ADMADescr 'dscr' in sdhci_do_adma() to avoid:
3
Create an APU CPU Cluster. This is in preparation to add the RPU.
4
4
5
hw/sd/sdhci.c: In function ‘sdhci_do_adma’:
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
hw/sd/sdhci.c:714:29: error: ‘dscr.addr’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
trace_sdhci_adma("link", s->admasysaddr);
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
8
^
9
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
12
Message-id: 20180115182436.2066-9-f4bug@amsat.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
9
---
15
hw/sd/sdhci.c | 89 ++++++++++++++++++------------------------------------
10
include/hw/arm/xlnx-versal.h | 2 ++
16
hw/sd/trace-events | 14 +++++++++
11
hw/arm/xlnx-versal.c | 9 ++++++++-
17
2 files changed, 44 insertions(+), 59 deletions(-)
12
2 files changed, 10 insertions(+), 1 deletion(-)
18
13
19
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/sd/sdhci.c
16
--- a/include/hw/arm/xlnx-versal.h
22
+++ b/hw/sd/sdhci.c
17
+++ b/include/hw/arm/xlnx-versal.h
23
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
24
#include "sdhci-internal.h"
19
25
#include "qapi/error.h"
20
#include "hw/sysbus.h"
26
#include "qemu/log.h"
21
#include "hw/arm/boot.h"
27
-
22
+#include "hw/cpu/cluster.h"
28
-/* host controller debug messages */
23
#include "hw/or-irq.h"
29
-#ifndef SDHC_DEBUG
24
#include "hw/sd/sdhci.h"
30
-#define SDHC_DEBUG 0
25
#include "hw/intc/arm_gicv3.h"
31
-#endif
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
32
-
27
struct {
33
-#define DPRINT_L1(fmt, args...) \
28
struct {
34
- do { \
29
MemoryRegion mr;
35
- if (SDHC_DEBUG) { \
30
+ CPUClusterState cluster;
36
- fprintf(stderr, "QEMU SDHC: " fmt, ## args); \
31
ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
37
- } \
32
GICv3State gic;
38
- } while (0)
33
} apu;
39
-#define DPRINT_L2(fmt, args...) \
34
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
40
- do { \
35
index XXXXXXX..XXXXXXX 100644
41
- if (SDHC_DEBUG > 1) { \
36
--- a/hw/arm/xlnx-versal.c
42
- fprintf(stderr, "QEMU SDHC: " fmt, ## args); \
37
+++ b/hw/arm/xlnx-versal.c
43
- } \
38
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
44
- } while (0)
45
-#define ERRPRINT(fmt, args...) \
46
- do { \
47
- if (SDHC_DEBUG) { \
48
- fprintf(stderr, "QEMU SDHC ERROR: " fmt, ## args); \
49
- } \
50
- } while (0)
51
+#include "trace.h"
52
53
#define TYPE_SDHCI_BUS "sdhci-bus"
54
#define SDHCI_BUS(obj) OBJECT_CHECK(SDBus, (obj), TYPE_SDHCI_BUS)
55
@@ -XXX,XX +XXX,XX @@ static void sdhci_raise_insertion_irq(void *opaque)
56
static void sdhci_set_inserted(DeviceState *dev, bool level)
57
{
39
{
58
SDHCIState *s = (SDHCIState *)dev;
40
int i;
59
- DPRINT_L1("Card state changed: %s!\n", level ? "insert" : "eject");
41
60
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
61
+ trace_sdhci_set_inserted(level ? "insert" : "eject");
43
+ TYPE_CPU_CLUSTER);
62
if ((s->norintsts & SDHC_NIS_REMOVE) && level) {
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
63
/* Give target some time to notice card ejection */
64
timer_mod(s->insert_timer,
65
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
66
s->acmd12errsts = 0;
67
request.cmd = s->cmdreg >> 8;
68
request.arg = s->argument;
69
- DPRINT_L1("sending CMD%u ARG[0x%08x]\n", request.cmd, request.arg);
70
+
45
+
71
+ trace_sdhci_send_command(request.cmd, request.arg);
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
72
rlen = sdbus_do_command(&s->sdbus, &request, response);
47
Object *obj;
73
48
74
if (s->cmdreg & SDHC_CMD_RESPONSE) {
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
75
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
76
s->rspreg[0] = (response[0] << 24) | (response[1] << 16) |
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
77
(response[2] << 8) | response[3];
52
XLNX_VERSAL_ACPU_TYPE);
78
s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
79
- DPRINT_L1("Response: RSPREG[31..0]=0x%08x\n", s->rspreg[0]);
54
if (i) {
80
+ trace_sdhci_response4(s->rspreg[0]);
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
81
} else if (rlen == 16) {
56
&error_abort);
82
s->rspreg[0] = (response[11] << 24) | (response[12] << 16) |
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
83
(response[13] << 8) | response[14];
84
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
85
(response[5] << 8) | response[6];
86
s->rspreg[3] = (response[0] << 16) | (response[1] << 8) |
87
response[2];
88
- DPRINT_L1("Response received:\n RSPREG[127..96]=0x%08x, RSPREG[95.."
89
- "64]=0x%08x,\n RSPREG[63..32]=0x%08x, RSPREG[31..0]=0x%08x\n",
90
- s->rspreg[3], s->rspreg[2], s->rspreg[1], s->rspreg[0]);
91
+ trace_sdhci_response16(s->rspreg[3], s->rspreg[2],
92
+ s->rspreg[1], s->rspreg[0]);
93
} else {
94
- ERRPRINT("Timeout waiting for command response\n");
95
+ trace_sdhci_error("timeout waiting for command response");
96
if (s->errintstsen & SDHC_EISEN_CMDTIMEOUT) {
97
s->errintsts |= SDHC_EIS_CMDTIMEOUT;
98
s->norintsts |= SDHC_NIS_ERR;
99
@@ -XXX,XX +XXX,XX @@ static void sdhci_end_transfer(SDHCIState *s)
100
101
request.cmd = 0x0C;
102
request.arg = 0;
103
- DPRINT_L1("Automatically issue CMD%d %08x\n", request.cmd, request.arg);
104
+ trace_sdhci_end_transfer(request.cmd, request.arg);
105
sdbus_do_command(&s->sdbus, &request, response);
106
/* Auto CMD12 response goes to the upper Response register */
107
s->rspreg[3] = (response[0] << 24) | (response[1] << 16) |
108
@@ -XXX,XX +XXX,XX @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)
109
110
/* first check that a valid data exists in host controller input buffer */
111
if ((s->prnsts & SDHC_DATA_AVAILABLE) == 0) {
112
- ERRPRINT("Trying to read from empty buffer\n");
113
+ trace_sdhci_error("read from empty buffer");
114
return 0;
115
}
58
}
116
59
+
117
@@ -XXX,XX +XXX,XX @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)
60
+ qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
118
s->data_count++;
119
/* check if we've read all valid data (blksize bytes) from buffer */
120
if ((s->data_count) >= (s->blksize & 0x0fff)) {
121
- DPRINT_L2("All %u bytes of data have been read from input buffer\n",
122
- s->data_count);
123
+ trace_sdhci_read_dataport(s->data_count);
124
s->prnsts &= ~SDHC_DATA_AVAILABLE; /* no more data in a buffer */
125
s->data_count = 0; /* next buff read must start at position [0] */
126
127
@@ -XXX,XX +XXX,XX @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
128
129
/* Check that there is free space left in a buffer */
130
if (!(s->prnsts & SDHC_SPACE_AVAILABLE)) {
131
- ERRPRINT("Can't write to data buffer: buffer full\n");
132
+ trace_sdhci_error("Can't write to data buffer: buffer full");
133
return;
134
}
135
136
@@ -XXX,XX +XXX,XX @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
137
s->data_count++;
138
value >>= 8;
139
if (s->data_count >= (s->blksize & 0x0fff)) {
140
- DPRINT_L2("write buffer filled with %u bytes of data\n",
141
- s->data_count);
142
+ trace_sdhci_write_dataport(s->data_count);
143
s->data_count = 0;
144
s->prnsts &= ~SDHC_SPACE_AVAILABLE;
145
if (s->prnsts & SDHC_DOING_WRITE) {
146
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
147
{
148
unsigned int n, begin, length;
149
const uint16_t block_size = s->blksize & 0x0fff;
150
- ADMADescr dscr;
151
+ ADMADescr dscr = {};
152
int i;
153
154
for (i = 0; i < SDHC_ADMA_DESCS_PER_DELAY; ++i) {
155
s->admaerr &= ~SDHC_ADMAERR_LENGTH_MISMATCH;
156
157
get_adma_description(s, &dscr);
158
- DPRINT_L2("ADMA loop: addr=" TARGET_FMT_plx ", len=%d, attr=%x\n",
159
- dscr.addr, dscr.length, dscr.attr);
160
+ trace_sdhci_adma_loop(dscr.addr, dscr.length, dscr.attr);
161
162
if ((dscr.attr & SDHC_ADMA_ATTR_VALID) == 0) {
163
/* Indicate that error occurred in ST_FDS state */
164
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
165
break;
166
case SDHC_ADMA_ATTR_ACT_LINK: /* link to next descriptor table */
167
s->admasysaddr = dscr.addr;
168
- DPRINT_L1("ADMA link: admasysaddr=0x%" PRIx64 "\n",
169
- s->admasysaddr);
170
+ trace_sdhci_adma("link", s->admasysaddr);
171
break;
172
default:
173
s->admasysaddr += dscr.incr;
174
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
175
}
176
177
if (dscr.attr & SDHC_ADMA_ATTR_INT) {
178
- DPRINT_L1("ADMA interrupt: admasysaddr=0x%" PRIx64 "\n",
179
- s->admasysaddr);
180
+ trace_sdhci_adma("interrupt", s->admasysaddr);
181
if (s->norintstsen & SDHC_NISEN_DMA) {
182
s->norintsts |= SDHC_NIS_DMA;
183
}
184
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
185
/* ADMA transfer terminates if blkcnt == 0 or by END attribute */
186
if (((s->trnmod & SDHC_TRNS_BLK_CNT_EN) &&
187
(s->blkcnt == 0)) || (dscr.attr & SDHC_ADMA_ATTR_END)) {
188
- DPRINT_L2("ADMA transfer completed\n");
189
+ trace_sdhci_adma_transfer_completed();
190
if (length || ((dscr.attr & SDHC_ADMA_ATTR_END) &&
191
(s->trnmod & SDHC_TRNS_BLK_CNT_EN) &&
192
s->blkcnt != 0)) {
193
- ERRPRINT("SD/MMC host ADMA length mismatch\n");
194
+ trace_sdhci_error("SD/MMC host ADMA length mismatch");
195
s->admaerr |= SDHC_ADMAERR_LENGTH_MISMATCH |
196
SDHC_ADMAERR_STATE_ST_TFR;
197
if (s->errintstsen & SDHC_EISEN_ADMAERR) {
198
- ERRPRINT("Set ADMA error flag\n");
199
+ trace_sdhci_error("Set ADMA error flag");
200
s->errintsts |= SDHC_EIS_ADMAERR;
201
s->norintsts |= SDHC_NIS_ERR;
202
}
203
@@ -XXX,XX +XXX,XX @@ static void sdhci_data_transfer(void *opaque)
204
break;
205
case SDHC_CTRL_ADMA1_32:
206
if (!(s->capareg & SDHC_CAN_DO_ADMA1)) {
207
- ERRPRINT("ADMA1 not supported\n");
208
+ trace_sdhci_error("ADMA1 not supported");
209
break;
210
}
211
212
@@ -XXX,XX +XXX,XX @@ static void sdhci_data_transfer(void *opaque)
213
break;
214
case SDHC_CTRL_ADMA2_32:
215
if (!(s->capareg & SDHC_CAN_DO_ADMA2)) {
216
- ERRPRINT("ADMA2 not supported\n");
217
+ trace_sdhci_error("ADMA2 not supported");
218
break;
219
}
220
221
@@ -XXX,XX +XXX,XX @@ static void sdhci_data_transfer(void *opaque)
222
case SDHC_CTRL_ADMA2_64:
223
if (!(s->capareg & SDHC_CAN_DO_ADMA2) ||
224
!(s->capareg & SDHC_64_BIT_BUS_SUPPORT)) {
225
- ERRPRINT("64 bit ADMA not supported\n");
226
+ trace_sdhci_error("64 bit ADMA not supported");
227
break;
228
}
229
230
sdhci_do_adma(s);
231
break;
232
default:
233
- ERRPRINT("Unsupported DMA type\n");
234
+ trace_sdhci_error("Unsupported DMA type");
235
break;
236
}
237
} else {
238
@@ -XXX,XX +XXX,XX @@ static inline bool
239
sdhci_buff_access_is_sequential(SDHCIState *s, unsigned byte_num)
240
{
241
if ((s->data_count & 0x3) != byte_num) {
242
- ERRPRINT("Non-sequential access to Buffer Data Port register"
243
- "is prohibited\n");
244
+ trace_sdhci_error("Non-sequential access to Buffer Data Port register"
245
+ "is prohibited\n");
246
return false;
247
}
248
return true;
249
@@ -XXX,XX +XXX,XX @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
250
case SDHC_BDATA:
251
if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {
252
ret = sdhci_read_dataport(s, size);
253
- DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, (int)offset,
254
- ret, ret);
255
+ trace_sdhci_access("rd", size << 3, offset, "->", ret, ret);
256
return ret;
257
}
258
break;
259
@@ -XXX,XX +XXX,XX @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
260
261
ret >>= (offset & 0x3) * 8;
262
ret &= (1ULL << (size * 8)) - 1;
263
- DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, (int)offset, ret, ret);
264
+ trace_sdhci_access("rd", size << 3, offset, "->", ret, ret);
265
return ret;
266
}
61
}
267
62
268
@@ -XXX,XX +XXX,XX @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
63
static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
269
"not implemented\n", size, offset, value >> shift);
270
break;
271
}
272
- DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",
273
- size, (int)offset, value >> shift, value >> shift);
274
+ trace_sdhci_access("wr", size << 3, offset, "<-",
275
+ value >> shift, value >> shift);
276
}
277
278
static const MemoryRegionOps sdhci_mmio_ops = {
279
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
280
index XXXXXXX..XXXXXXX 100644
281
--- a/hw/sd/trace-events
282
+++ b/hw/sd/trace-events
283
@@ -XXX,XX +XXX,XX @@
284
# See docs/devel/tracing.txt for syntax documentation.
285
286
+# hw/sd/sdhci.c
287
+sdhci_set_inserted(const char *level) "card state changed: %s"
288
+sdhci_send_command(uint8_t cmd, uint32_t arg) "CMD%02u ARG[0x%08x]"
289
+sdhci_error(const char *msg) "%s"
290
+sdhci_response4(uint32_t r0) "RSPREG[31..0]=0x%08x"
291
+sdhci_response16(uint32_t r3, uint32_t r2, uint32_t r1, uint32_t r0) "RSPREG[127..96]=0x%08x, RSPREG[95..64]=0x%08x, RSPREG[63..32]=0x%08x, RSPREG[31..0]=0x%08x"
292
+sdhci_end_transfer(uint8_t cmd, uint32_t arg) "Automatically issue CMD%02u 0x%08x"
293
+sdhci_adma(const char *desc, uint32_t sysad) "%s: admasysaddr=0x%" PRIx32
294
+sdhci_adma_loop(uint64_t addr, uint16_t length, uint8_t attr) "addr=0x%08" PRIx64 ", len=%d, attr=0x%x"
295
+sdhci_adma_transfer_completed(void) ""
296
+sdhci_access(const char *access, unsigned int size, uint64_t offset, const char *dir, uint64_t val, uint64_t val2) "%s%u: addr[0x%04" PRIx64 "] %s 0x%08" PRIx64 " (%" PRIu64 ")"
297
+sdhci_read_dataport(uint16_t data_count) "all %u bytes of data have been read from input buffer"
298
+sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes of data"
299
+
300
# hw/sd/milkymist-memcard.c
301
milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
302
milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
303
--
64
--
304
2.7.4
65
2.25.1
305
306
diff view generated by jsdifflib
1
Since ssi-sd is still using the legacy SD card API, the SD
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
card created by sd_init() is not plugged into any bus. This
3
means that the controller has to reset it manually.
4
2
5
Failing to do this mostly didn't affect the guest since the
3
Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit)
6
guest typically does a programmed SD card reset as part of
4
subsystem.
7
its SD controller driver initialization, but meant that
8
migration failed because it's only in sd_reset() that we
9
set up the wpgrps_size field.
10
5
11
In the case of sd-ssi, we have to implement an entire
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
12
reset function since there wasn't one previously, and
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
13
that requires a QOM cast macro that got omitted when this
8
Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com
14
device was QOMified.
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/xlnx-versal.h | 10 ++++++++++
12
hw/arm/xlnx-versal-virt.c | 6 +++---
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
14
3 files changed, 49 insertions(+), 3 deletions(-)
15
15
16
Cc: qemu-stable@nongnu.org
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Message-id: 1515506513-31961-4-git-send-email-peter.maydell@linaro.org
21
---
22
hw/sd/ssi-sd.c | 25 +++++++++++++++++++++++--
23
1 file changed, 23 insertions(+), 2 deletions(-)
24
25
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/sd/ssi-sd.c
18
--- a/include/hw/arm/xlnx-versal.h
28
+++ b/hw/sd/ssi-sd.c
19
+++ b/include/hw/arm/xlnx-versal.h
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
20
@@ -XXX,XX +XXX,XX @@
30
SDState *sd;
21
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
31
} ssi_sd_state;
22
32
23
#define XLNX_VERSAL_NR_ACPUS 2
33
+#define TYPE_SSI_SD "ssi-sd"
24
+#define XLNX_VERSAL_NR_RCPUS 2
34
+#define SSI_SD(obj) OBJECT_CHECK(ssi_sd_state, (obj), TYPE_SSI_SD)
25
#define XLNX_VERSAL_NR_UARTS 2
26
#define XLNX_VERSAL_NR_GEMS 2
27
#define XLNX_VERSAL_NR_ADMAS 8
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;
35
+
36
+
36
/* State word bits. */
37
+ CPUClusterState cluster;
37
#define SSI_SDR_LOCKED 0x0001
38
+ ARMCPU cpu[XLNX_VERSAL_NR_RCPUS];
38
#define SSI_SDR_WP_ERASE 0x0002
39
+ } rpu;
39
@@ -XXX,XX +XXX,XX @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
40
+
40
ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
41
struct {
41
DriveInfo *dinfo;
42
qemu_or_irq irq_orgate;
42
43
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
43
- s->mode = SSI_SD_CMD;
44
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
44
/* FIXME use a qdev drive property instead of drive_get_next() */
45
index XXXXXXX..XXXXXXX 100644
45
dinfo = drive_get_next(IF_SD);
46
--- a/hw/arm/xlnx-versal-virt.c
46
s->sd = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, true);
47
+++ b/hw/arm/xlnx-versal-virt.c
47
@@ -XXX,XX +XXX,XX @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
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
65
@@ -XXX,XX +XXX,XX @@
66
#include "hw/sysbus.h"
67
68
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
69
+#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
70
#define GEM_REVISION 0x40070106
71
72
#define VERSAL_NUM_PMC_APB_IRQS 3
73
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
48
}
74
}
49
}
75
}
50
76
51
+static void ssi_sd_reset(DeviceState *dev)
77
+static void versal_create_rpu_cpus(Versal *s)
52
+{
78
+{
53
+ ssi_sd_state *s = SSI_SD(dev);
79
+ int i;
54
+
80
+
55
+ s->mode = SSI_SD_CMD;
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
56
+ s->cmd = 0;
82
+ TYPE_CPU_CLUSTER);
57
+ memset(s->cmdarg, 0, sizeof(s->cmdarg));
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
58
+ memset(s->response, 0, sizeof(s->response));
59
+ s->arglen = 0;
60
+ s->response_pos = 0;
61
+ s->stopping = 0;
62
+
84
+
63
+ /* Since we're still using the legacy SD API the card is not plugged
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
64
+ * into any bus, and we must reset it manually.
86
+ Object *obj;
65
+ */
87
+
66
+ device_reset(DEVICE(s->sd));
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
89
+ "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
90
+ XLNX_VERSAL_RCPU_TYPE);
91
+ obj = OBJECT(&s->lpd.rpu.cpu[i]);
92
+ object_property_set_bool(obj, "start-powered-off", true,
93
+ &error_abort);
94
+
95
+ object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
96
+ object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
97
+ &error_abort);
98
+ object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
99
+ &error_abort);
100
+ qdev_realize(DEVICE(obj), NULL, &error_fatal);
101
+ }
102
+
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
67
+}
104
+}
68
+
105
+
69
static void ssi_sd_class_init(ObjectClass *klass, void *data)
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
70
{
107
{
71
DeviceClass *dc = DEVICE_CLASS(klass);
108
int i;
72
@@ -XXX,XX +XXX,XX @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
73
k->transfer = ssi_sd_transfer;
110
74
k->cs_polarity = SSI_CS_LOW;
111
versal_create_apu_cpus(s);
75
dc->vmsd = &vmstate_ssi_sd;
112
versal_create_apu_gic(s, pic);
76
+ dc->reset = ssi_sd_reset;
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);
77
}
123
}
78
124
79
static const TypeInfo ssi_sd_info = {
125
static void versal_init(Object *obj)
80
- .name = "ssi-sd",
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
81
+ .name = TYPE_SSI_SD,
127
Versal *s = XLNX_VERSAL(obj);
82
.parent = TYPE_SSI_SLAVE,
128
83
.instance_size = sizeof(ssi_sd_state),
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
84
.class_init = ssi_sd_class_init,
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
134
}
135
136
static Property versal_properties[] = {
85
--
137
--
86
2.7.4
138
2.25.1
87
88
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
3
Add a model of the Xilinx Versal CRL.
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
Message-id: 20180115182436.2066-13-f4bug@amsat.org
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
hw/sd/sdhci.c | 3 +++
11
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++
11
1 file changed, 3 insertions(+)
12
hw/misc/xlnx-versal-crl.c | 421 ++++++++++++++++++++++++++++++
13
hw/misc/meson.build | 1 +
14
3 files changed, 657 insertions(+)
15
create mode 100644 include/hw/misc/xlnx-versal-crl.h
16
create mode 100644 hw/misc/xlnx-versal-crl.c
12
17
13
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
18
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
19
new file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- /dev/null
22
+++ b/include/hw/misc/xlnx-versal-crl.h
23
@@ -XXX,XX +XXX,XX @@
24
+/*
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
26
+ *
27
+ * Copyright (c) 2022 Xilinx Inc.
28
+ * SPDX-License-Identifier: GPL-2.0-or-later
29
+ *
30
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
31
+ */
32
+#ifndef HW_MISC_XLNX_VERSAL_CRL_H
33
+#define HW_MISC_XLNX_VERSAL_CRL_H
34
+
35
+#include "hw/sysbus.h"
36
+#include "hw/register.h"
37
+#include "target/arm/cpu.h"
38
+
39
+#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl"
40
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL)
41
+
42
+REG32(ERR_CTRL, 0x0)
43
+ FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
44
+REG32(IR_STATUS, 0x4)
45
+ FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1)
46
+REG32(IR_MASK, 0x8)
47
+ FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1)
48
+REG32(IR_ENABLE, 0xc)
49
+ FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1)
50
+REG32(IR_DISABLE, 0x10)
51
+ FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1)
52
+REG32(WPROT, 0x1c)
53
+ FIELD(WPROT, ACTIVE, 0, 1)
54
+REG32(PLL_CLK_OTHER_DMN, 0x20)
55
+ FIELD(PLL_CLK_OTHER_DMN, APLL_BYPASS, 0, 1)
56
+REG32(RPLL_CTRL, 0x40)
57
+ FIELD(RPLL_CTRL, POST_SRC, 24, 3)
58
+ FIELD(RPLL_CTRL, PRE_SRC, 20, 3)
59
+ FIELD(RPLL_CTRL, CLKOUTDIV, 16, 2)
60
+ FIELD(RPLL_CTRL, FBDIV, 8, 8)
61
+ FIELD(RPLL_CTRL, BYPASS, 3, 1)
62
+ FIELD(RPLL_CTRL, RESET, 0, 1)
63
+REG32(RPLL_CFG, 0x44)
64
+ FIELD(RPLL_CFG, LOCK_DLY, 25, 7)
65
+ FIELD(RPLL_CFG, LOCK_CNT, 13, 10)
66
+ FIELD(RPLL_CFG, LFHF, 10, 2)
67
+ FIELD(RPLL_CFG, CP, 5, 4)
68
+ FIELD(RPLL_CFG, RES, 0, 4)
69
+REG32(RPLL_FRAC_CFG, 0x48)
70
+ FIELD(RPLL_FRAC_CFG, ENABLED, 31, 1)
71
+ FIELD(RPLL_FRAC_CFG, SEED, 22, 3)
72
+ FIELD(RPLL_FRAC_CFG, ALGRTHM, 19, 1)
73
+ FIELD(RPLL_FRAC_CFG, ORDER, 18, 1)
74
+ FIELD(RPLL_FRAC_CFG, DATA, 0, 16)
75
+REG32(PLL_STATUS, 0x50)
76
+ FIELD(PLL_STATUS, RPLL_STABLE, 2, 1)
77
+ FIELD(PLL_STATUS, RPLL_LOCK, 0, 1)
78
+REG32(RPLL_TO_XPD_CTRL, 0x100)
79
+ FIELD(RPLL_TO_XPD_CTRL, CLKACT, 25, 1)
80
+ FIELD(RPLL_TO_XPD_CTRL, DIVISOR0, 8, 10)
81
+REG32(LPD_TOP_SWITCH_CTRL, 0x104)
82
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT_ADMA, 26, 1)
83
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT, 25, 1)
84
+ FIELD(LPD_TOP_SWITCH_CTRL, DIVISOR0, 8, 10)
85
+ FIELD(LPD_TOP_SWITCH_CTRL, SRCSEL, 0, 3)
86
+REG32(LPD_LSBUS_CTRL, 0x108)
87
+ FIELD(LPD_LSBUS_CTRL, CLKACT, 25, 1)
88
+ FIELD(LPD_LSBUS_CTRL, DIVISOR0, 8, 10)
89
+ FIELD(LPD_LSBUS_CTRL, SRCSEL, 0, 3)
90
+REG32(CPU_R5_CTRL, 0x10c)
91
+ FIELD(CPU_R5_CTRL, CLKACT_OCM2, 28, 1)
92
+ FIELD(CPU_R5_CTRL, CLKACT_OCM, 27, 1)
93
+ FIELD(CPU_R5_CTRL, CLKACT_CORE, 26, 1)
94
+ FIELD(CPU_R5_CTRL, CLKACT, 25, 1)
95
+ FIELD(CPU_R5_CTRL, DIVISOR0, 8, 10)
96
+ FIELD(CPU_R5_CTRL, SRCSEL, 0, 3)
97
+REG32(IOU_SWITCH_CTRL, 0x114)
98
+ FIELD(IOU_SWITCH_CTRL, CLKACT, 25, 1)
99
+ FIELD(IOU_SWITCH_CTRL, DIVISOR0, 8, 10)
100
+ FIELD(IOU_SWITCH_CTRL, SRCSEL, 0, 3)
101
+REG32(GEM0_REF_CTRL, 0x118)
102
+ FIELD(GEM0_REF_CTRL, CLKACT_RX, 27, 1)
103
+ FIELD(GEM0_REF_CTRL, CLKACT_TX, 26, 1)
104
+ FIELD(GEM0_REF_CTRL, CLKACT, 25, 1)
105
+ FIELD(GEM0_REF_CTRL, DIVISOR0, 8, 10)
106
+ FIELD(GEM0_REF_CTRL, SRCSEL, 0, 3)
107
+REG32(GEM1_REF_CTRL, 0x11c)
108
+ FIELD(GEM1_REF_CTRL, CLKACT_RX, 27, 1)
109
+ FIELD(GEM1_REF_CTRL, CLKACT_TX, 26, 1)
110
+ FIELD(GEM1_REF_CTRL, CLKACT, 25, 1)
111
+ FIELD(GEM1_REF_CTRL, DIVISOR0, 8, 10)
112
+ FIELD(GEM1_REF_CTRL, SRCSEL, 0, 3)
113
+REG32(GEM_TSU_REF_CTRL, 0x120)
114
+ FIELD(GEM_TSU_REF_CTRL, CLKACT, 25, 1)
115
+ FIELD(GEM_TSU_REF_CTRL, DIVISOR0, 8, 10)
116
+ FIELD(GEM_TSU_REF_CTRL, SRCSEL, 0, 3)
117
+REG32(USB0_BUS_REF_CTRL, 0x124)
118
+ FIELD(USB0_BUS_REF_CTRL, CLKACT, 25, 1)
119
+ FIELD(USB0_BUS_REF_CTRL, DIVISOR0, 8, 10)
120
+ FIELD(USB0_BUS_REF_CTRL, SRCSEL, 0, 3)
121
+REG32(UART0_REF_CTRL, 0x128)
122
+ FIELD(UART0_REF_CTRL, CLKACT, 25, 1)
123
+ FIELD(UART0_REF_CTRL, DIVISOR0, 8, 10)
124
+ FIELD(UART0_REF_CTRL, SRCSEL, 0, 3)
125
+REG32(UART1_REF_CTRL, 0x12c)
126
+ FIELD(UART1_REF_CTRL, CLKACT, 25, 1)
127
+ FIELD(UART1_REF_CTRL, DIVISOR0, 8, 10)
128
+ FIELD(UART1_REF_CTRL, SRCSEL, 0, 3)
129
+REG32(SPI0_REF_CTRL, 0x130)
130
+ FIELD(SPI0_REF_CTRL, CLKACT, 25, 1)
131
+ FIELD(SPI0_REF_CTRL, DIVISOR0, 8, 10)
132
+ FIELD(SPI0_REF_CTRL, SRCSEL, 0, 3)
133
+REG32(SPI1_REF_CTRL, 0x134)
134
+ FIELD(SPI1_REF_CTRL, CLKACT, 25, 1)
135
+ FIELD(SPI1_REF_CTRL, DIVISOR0, 8, 10)
136
+ FIELD(SPI1_REF_CTRL, SRCSEL, 0, 3)
137
+REG32(CAN0_REF_CTRL, 0x138)
138
+ FIELD(CAN0_REF_CTRL, CLKACT, 25, 1)
139
+ FIELD(CAN0_REF_CTRL, DIVISOR0, 8, 10)
140
+ FIELD(CAN0_REF_CTRL, SRCSEL, 0, 3)
141
+REG32(CAN1_REF_CTRL, 0x13c)
142
+ FIELD(CAN1_REF_CTRL, CLKACT, 25, 1)
143
+ FIELD(CAN1_REF_CTRL, DIVISOR0, 8, 10)
144
+ FIELD(CAN1_REF_CTRL, SRCSEL, 0, 3)
145
+REG32(I2C0_REF_CTRL, 0x140)
146
+ FIELD(I2C0_REF_CTRL, CLKACT, 25, 1)
147
+ FIELD(I2C0_REF_CTRL, DIVISOR0, 8, 10)
148
+ FIELD(I2C0_REF_CTRL, SRCSEL, 0, 3)
149
+REG32(I2C1_REF_CTRL, 0x144)
150
+ FIELD(I2C1_REF_CTRL, CLKACT, 25, 1)
151
+ FIELD(I2C1_REF_CTRL, DIVISOR0, 8, 10)
152
+ FIELD(I2C1_REF_CTRL, SRCSEL, 0, 3)
153
+REG32(DBG_LPD_CTRL, 0x148)
154
+ FIELD(DBG_LPD_CTRL, CLKACT, 25, 1)
155
+ FIELD(DBG_LPD_CTRL, DIVISOR0, 8, 10)
156
+ FIELD(DBG_LPD_CTRL, SRCSEL, 0, 3)
157
+REG32(TIMESTAMP_REF_CTRL, 0x14c)
158
+ FIELD(TIMESTAMP_REF_CTRL, CLKACT, 25, 1)
159
+ FIELD(TIMESTAMP_REF_CTRL, DIVISOR0, 8, 10)
160
+ FIELD(TIMESTAMP_REF_CTRL, SRCSEL, 0, 3)
161
+REG32(CRL_SAFETY_CHK, 0x150)
162
+REG32(PSM_REF_CTRL, 0x154)
163
+ FIELD(PSM_REF_CTRL, DIVISOR0, 8, 10)
164
+ FIELD(PSM_REF_CTRL, SRCSEL, 0, 3)
165
+REG32(DBG_TSTMP_CTRL, 0x158)
166
+ FIELD(DBG_TSTMP_CTRL, CLKACT, 25, 1)
167
+ FIELD(DBG_TSTMP_CTRL, DIVISOR0, 8, 10)
168
+ FIELD(DBG_TSTMP_CTRL, SRCSEL, 0, 3)
169
+REG32(CPM_TOPSW_REF_CTRL, 0x15c)
170
+ FIELD(CPM_TOPSW_REF_CTRL, CLKACT, 25, 1)
171
+ FIELD(CPM_TOPSW_REF_CTRL, DIVISOR0, 8, 10)
172
+ FIELD(CPM_TOPSW_REF_CTRL, SRCSEL, 0, 3)
173
+REG32(USB3_DUAL_REF_CTRL, 0x160)
174
+ FIELD(USB3_DUAL_REF_CTRL, CLKACT, 25, 1)
175
+ FIELD(USB3_DUAL_REF_CTRL, DIVISOR0, 8, 10)
176
+ FIELD(USB3_DUAL_REF_CTRL, SRCSEL, 0, 3)
177
+REG32(RST_CPU_R5, 0x300)
178
+ FIELD(RST_CPU_R5, RESET_PGE, 4, 1)
179
+ FIELD(RST_CPU_R5, RESET_AMBA, 2, 1)
180
+ FIELD(RST_CPU_R5, RESET_CPU1, 1, 1)
181
+ FIELD(RST_CPU_R5, RESET_CPU0, 0, 1)
182
+REG32(RST_ADMA, 0x304)
183
+ FIELD(RST_ADMA, RESET, 0, 1)
184
+REG32(RST_GEM0, 0x308)
185
+ FIELD(RST_GEM0, RESET, 0, 1)
186
+REG32(RST_GEM1, 0x30c)
187
+ FIELD(RST_GEM1, RESET, 0, 1)
188
+REG32(RST_SPARE, 0x310)
189
+ FIELD(RST_SPARE, RESET, 0, 1)
190
+REG32(RST_USB0, 0x314)
191
+ FIELD(RST_USB0, RESET, 0, 1)
192
+REG32(RST_UART0, 0x318)
193
+ FIELD(RST_UART0, RESET, 0, 1)
194
+REG32(RST_UART1, 0x31c)
195
+ FIELD(RST_UART1, RESET, 0, 1)
196
+REG32(RST_SPI0, 0x320)
197
+ FIELD(RST_SPI0, RESET, 0, 1)
198
+REG32(RST_SPI1, 0x324)
199
+ FIELD(RST_SPI1, RESET, 0, 1)
200
+REG32(RST_CAN0, 0x328)
201
+ FIELD(RST_CAN0, RESET, 0, 1)
202
+REG32(RST_CAN1, 0x32c)
203
+ FIELD(RST_CAN1, RESET, 0, 1)
204
+REG32(RST_I2C0, 0x330)
205
+ FIELD(RST_I2C0, RESET, 0, 1)
206
+REG32(RST_I2C1, 0x334)
207
+ FIELD(RST_I2C1, RESET, 0, 1)
208
+REG32(RST_DBG_LPD, 0x338)
209
+ FIELD(RST_DBG_LPD, RPU_DBG1_RESET, 5, 1)
210
+ FIELD(RST_DBG_LPD, RPU_DBG0_RESET, 4, 1)
211
+ FIELD(RST_DBG_LPD, RESET_HSDP, 1, 1)
212
+ FIELD(RST_DBG_LPD, RESET, 0, 1)
213
+REG32(RST_GPIO, 0x33c)
214
+ FIELD(RST_GPIO, RESET, 0, 1)
215
+REG32(RST_TTC, 0x344)
216
+ FIELD(RST_TTC, TTC3_RESET, 3, 1)
217
+ FIELD(RST_TTC, TTC2_RESET, 2, 1)
218
+ FIELD(RST_TTC, TTC1_RESET, 1, 1)
219
+ FIELD(RST_TTC, TTC0_RESET, 0, 1)
220
+REG32(RST_TIMESTAMP, 0x348)
221
+ FIELD(RST_TIMESTAMP, RESET, 0, 1)
222
+REG32(RST_SWDT, 0x34c)
223
+ FIELD(RST_SWDT, RESET, 0, 1)
224
+REG32(RST_OCM, 0x350)
225
+ FIELD(RST_OCM, RESET, 0, 1)
226
+REG32(RST_IPI, 0x354)
227
+ FIELD(RST_IPI, RESET, 0, 1)
228
+REG32(RST_SYSMON, 0x358)
229
+ FIELD(RST_SYSMON, SEQ_RST, 1, 1)
230
+ FIELD(RST_SYSMON, CFG_RST, 0, 1)
231
+REG32(RST_FPD, 0x360)
232
+ FIELD(RST_FPD, SRST, 1, 1)
233
+ FIELD(RST_FPD, POR, 0, 1)
234
+REG32(PSM_RST_MODE, 0x370)
235
+ FIELD(PSM_RST_MODE, WAKEUP, 2, 1)
236
+ FIELD(PSM_RST_MODE, RST_MODE, 0, 2)
237
+
238
+#define CRL_R_MAX (R_PSM_RST_MODE + 1)
239
+
240
+#define RPU_MAX_CPU 2
241
+
242
+struct XlnxVersalCRL {
243
+ SysBusDevice parent_obj;
244
+ qemu_irq irq;
245
+
246
+ struct {
247
+ ARMCPU *cpu_r5[RPU_MAX_CPU];
248
+ DeviceState *adma[8];
249
+ DeviceState *uart[2];
250
+ DeviceState *gem[2];
251
+ DeviceState *usb;
252
+ } cfg;
253
+
254
+ RegisterInfoArray *reg_array;
255
+ uint32_t regs[CRL_R_MAX];
256
+ RegisterInfo regs_info[CRL_R_MAX];
257
+};
258
+#endif
259
diff --git a/hw/misc/xlnx-versal-crl.c b/hw/misc/xlnx-versal-crl.c
260
new file mode 100644
261
index XXXXXXX..XXXXXXX
262
--- /dev/null
263
+++ b/hw/misc/xlnx-versal-crl.c
264
@@ -XXX,XX +XXX,XX @@
265
+/*
266
+ * QEMU model of the Clock-Reset-LPD (CRL).
267
+ *
268
+ * Copyright (c) 2022 Advanced Micro Devices, Inc.
269
+ * SPDX-License-Identifier: GPL-2.0-or-later
270
+ *
271
+ * Written by Edgar E. Iglesias <edgar.iglesias@amd.com>
272
+ */
273
+
274
+#include "qemu/osdep.h"
275
+#include "qapi/error.h"
276
+#include "qemu/log.h"
277
+#include "qemu/bitops.h"
278
+#include "migration/vmstate.h"
279
+#include "hw/qdev-properties.h"
280
+#include "hw/sysbus.h"
281
+#include "hw/irq.h"
282
+#include "hw/register.h"
283
+#include "hw/resettable.h"
284
+
285
+#include "target/arm/arm-powerctl.h"
286
+#include "hw/misc/xlnx-versal-crl.h"
287
+
288
+#ifndef XLNX_VERSAL_CRL_ERR_DEBUG
289
+#define XLNX_VERSAL_CRL_ERR_DEBUG 0
290
+#endif
291
+
292
+static void crl_update_irq(XlnxVersalCRL *s)
293
+{
294
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
295
+ qemu_set_irq(s->irq, pending);
296
+}
297
+
298
+static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
299
+{
300
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
301
+ crl_update_irq(s);
302
+}
303
+
304
+static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
305
+{
306
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
307
+ uint32_t val = val64;
308
+
309
+ s->regs[R_IR_MASK] &= ~val;
310
+ crl_update_irq(s);
311
+ return 0;
312
+}
313
+
314
+static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
315
+{
316
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
317
+ uint32_t val = val64;
318
+
319
+ s->regs[R_IR_MASK] |= val;
320
+ crl_update_irq(s);
321
+ return 0;
322
+}
323
+
324
+static void crl_reset_dev(XlnxVersalCRL *s, DeviceState *dev,
325
+ bool rst_old, bool rst_new)
326
+{
327
+ device_cold_reset(dev);
328
+}
329
+
330
+static void crl_reset_cpu(XlnxVersalCRL *s, ARMCPU *armcpu,
331
+ bool rst_old, bool rst_new)
332
+{
333
+ if (rst_new) {
334
+ arm_set_cpu_off(armcpu->mp_affinity);
335
+ } else {
336
+ arm_set_cpu_on_and_reset(armcpu->mp_affinity);
337
+ }
338
+}
339
+
340
+#define REGFIELD_RESET(type, s, reg, f, new_val, dev) { \
341
+ bool old_f = ARRAY_FIELD_EX32((s)->regs, reg, f); \
342
+ bool new_f = FIELD_EX32(new_val, reg, f); \
343
+ \
344
+ /* Detect edges. */ \
345
+ if (dev && old_f != new_f) { \
346
+ crl_reset_ ## type(s, dev, old_f, new_f); \
347
+ } \
348
+}
349
+
350
+static uint64_t crl_rst_r5_prew(RegisterInfo *reg, uint64_t val64)
351
+{
352
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
353
+
354
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU0, val64, s->cfg.cpu_r5[0]);
355
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU1, val64, s->cfg.cpu_r5[1]);
356
+ return val64;
357
+}
358
+
359
+static uint64_t crl_rst_adma_prew(RegisterInfo *reg, uint64_t val64)
360
+{
361
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
362
+ int i;
363
+
364
+ /* A single register fans out to all ADMA reset inputs. */
365
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); i++) {
366
+ REGFIELD_RESET(dev, s, RST_ADMA, RESET, val64, s->cfg.adma[i]);
367
+ }
368
+ return val64;
369
+}
370
+
371
+static uint64_t crl_rst_uart0_prew(RegisterInfo *reg, uint64_t val64)
372
+{
373
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
374
+
375
+ REGFIELD_RESET(dev, s, RST_UART0, RESET, val64, s->cfg.uart[0]);
376
+ return val64;
377
+}
378
+
379
+static uint64_t crl_rst_uart1_prew(RegisterInfo *reg, uint64_t val64)
380
+{
381
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
382
+
383
+ REGFIELD_RESET(dev, s, RST_UART1, RESET, val64, s->cfg.uart[1]);
384
+ return val64;
385
+}
386
+
387
+static uint64_t crl_rst_gem0_prew(RegisterInfo *reg, uint64_t val64)
388
+{
389
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
390
+
391
+ REGFIELD_RESET(dev, s, RST_GEM0, RESET, val64, s->cfg.gem[0]);
392
+ return val64;
393
+}
394
+
395
+static uint64_t crl_rst_gem1_prew(RegisterInfo *reg, uint64_t val64)
396
+{
397
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
398
+
399
+ REGFIELD_RESET(dev, s, RST_GEM1, RESET, val64, s->cfg.gem[1]);
400
+ return val64;
401
+}
402
+
403
+static uint64_t crl_rst_usb_prew(RegisterInfo *reg, uint64_t val64)
404
+{
405
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
406
+
407
+ REGFIELD_RESET(dev, s, RST_USB0, RESET, val64, s->cfg.usb);
408
+ return val64;
409
+}
410
+
411
+static const RegisterAccessInfo crl_regs_info[] = {
412
+ { .name = "ERR_CTRL", .addr = A_ERR_CTRL,
413
+ },{ .name = "IR_STATUS", .addr = A_IR_STATUS,
414
+ .w1c = 0x1,
415
+ .post_write = crl_status_postw,
416
+ },{ .name = "IR_MASK", .addr = A_IR_MASK,
417
+ .reset = 0x1,
418
+ .ro = 0x1,
419
+ },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE,
420
+ .pre_write = crl_enable_prew,
421
+ },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE,
422
+ .pre_write = crl_disable_prew,
423
+ },{ .name = "WPROT", .addr = A_WPROT,
424
+ },{ .name = "PLL_CLK_OTHER_DMN", .addr = A_PLL_CLK_OTHER_DMN,
425
+ .reset = 0x1,
426
+ .rsvd = 0xe,
427
+ },{ .name = "RPLL_CTRL", .addr = A_RPLL_CTRL,
428
+ .reset = 0x24809,
429
+ .rsvd = 0xf88c00f6,
430
+ },{ .name = "RPLL_CFG", .addr = A_RPLL_CFG,
431
+ .reset = 0x2000000,
432
+ .rsvd = 0x1801210,
433
+ },{ .name = "RPLL_FRAC_CFG", .addr = A_RPLL_FRAC_CFG,
434
+ .rsvd = 0x7e330000,
435
+ },{ .name = "PLL_STATUS", .addr = A_PLL_STATUS,
436
+ .reset = R_PLL_STATUS_RPLL_STABLE_MASK |
437
+ R_PLL_STATUS_RPLL_LOCK_MASK,
438
+ .rsvd = 0xfa,
439
+ .ro = 0x5,
440
+ },{ .name = "RPLL_TO_XPD_CTRL", .addr = A_RPLL_TO_XPD_CTRL,
441
+ .reset = 0x2000100,
442
+ .rsvd = 0xfdfc00ff,
443
+ },{ .name = "LPD_TOP_SWITCH_CTRL", .addr = A_LPD_TOP_SWITCH_CTRL,
444
+ .reset = 0x6000300,
445
+ .rsvd = 0xf9fc00f8,
446
+ },{ .name = "LPD_LSBUS_CTRL", .addr = A_LPD_LSBUS_CTRL,
447
+ .reset = 0x2000800,
448
+ .rsvd = 0xfdfc00f8,
449
+ },{ .name = "CPU_R5_CTRL", .addr = A_CPU_R5_CTRL,
450
+ .reset = 0xe000300,
451
+ .rsvd = 0xe1fc00f8,
452
+ },{ .name = "IOU_SWITCH_CTRL", .addr = A_IOU_SWITCH_CTRL,
453
+ .reset = 0x2000500,
454
+ .rsvd = 0xfdfc00f8,
455
+ },{ .name = "GEM0_REF_CTRL", .addr = A_GEM0_REF_CTRL,
456
+ .reset = 0xe000a00,
457
+ .rsvd = 0xf1fc00f8,
458
+ },{ .name = "GEM1_REF_CTRL", .addr = A_GEM1_REF_CTRL,
459
+ .reset = 0xe000a00,
460
+ .rsvd = 0xf1fc00f8,
461
+ },{ .name = "GEM_TSU_REF_CTRL", .addr = A_GEM_TSU_REF_CTRL,
462
+ .reset = 0x300,
463
+ .rsvd = 0xfdfc00f8,
464
+ },{ .name = "USB0_BUS_REF_CTRL", .addr = A_USB0_BUS_REF_CTRL,
465
+ .reset = 0x2001900,
466
+ .rsvd = 0xfdfc00f8,
467
+ },{ .name = "UART0_REF_CTRL", .addr = A_UART0_REF_CTRL,
468
+ .reset = 0xc00,
469
+ .rsvd = 0xfdfc00f8,
470
+ },{ .name = "UART1_REF_CTRL", .addr = A_UART1_REF_CTRL,
471
+ .reset = 0xc00,
472
+ .rsvd = 0xfdfc00f8,
473
+ },{ .name = "SPI0_REF_CTRL", .addr = A_SPI0_REF_CTRL,
474
+ .reset = 0x600,
475
+ .rsvd = 0xfdfc00f8,
476
+ },{ .name = "SPI1_REF_CTRL", .addr = A_SPI1_REF_CTRL,
477
+ .reset = 0x600,
478
+ .rsvd = 0xfdfc00f8,
479
+ },{ .name = "CAN0_REF_CTRL", .addr = A_CAN0_REF_CTRL,
480
+ .reset = 0xc00,
481
+ .rsvd = 0xfdfc00f8,
482
+ },{ .name = "CAN1_REF_CTRL", .addr = A_CAN1_REF_CTRL,
483
+ .reset = 0xc00,
484
+ .rsvd = 0xfdfc00f8,
485
+ },{ .name = "I2C0_REF_CTRL", .addr = A_I2C0_REF_CTRL,
486
+ .reset = 0xc00,
487
+ .rsvd = 0xfdfc00f8,
488
+ },{ .name = "I2C1_REF_CTRL", .addr = A_I2C1_REF_CTRL,
489
+ .reset = 0xc00,
490
+ .rsvd = 0xfdfc00f8,
491
+ },{ .name = "DBG_LPD_CTRL", .addr = A_DBG_LPD_CTRL,
492
+ .reset = 0x300,
493
+ .rsvd = 0xfdfc00f8,
494
+ },{ .name = "TIMESTAMP_REF_CTRL", .addr = A_TIMESTAMP_REF_CTRL,
495
+ .reset = 0x2000c00,
496
+ .rsvd = 0xfdfc00f8,
497
+ },{ .name = "CRL_SAFETY_CHK", .addr = A_CRL_SAFETY_CHK,
498
+ },{ .name = "PSM_REF_CTRL", .addr = A_PSM_REF_CTRL,
499
+ .reset = 0xf04,
500
+ .rsvd = 0xfffc00f8,
501
+ },{ .name = "DBG_TSTMP_CTRL", .addr = A_DBG_TSTMP_CTRL,
502
+ .reset = 0x300,
503
+ .rsvd = 0xfdfc00f8,
504
+ },{ .name = "CPM_TOPSW_REF_CTRL", .addr = A_CPM_TOPSW_REF_CTRL,
505
+ .reset = 0x300,
506
+ .rsvd = 0xfdfc00f8,
507
+ },{ .name = "USB3_DUAL_REF_CTRL", .addr = A_USB3_DUAL_REF_CTRL,
508
+ .reset = 0x3c00,
509
+ .rsvd = 0xfdfc00f8,
510
+ },{ .name = "RST_CPU_R5", .addr = A_RST_CPU_R5,
511
+ .reset = 0x17,
512
+ .rsvd = 0x8,
513
+ .pre_write = crl_rst_r5_prew,
514
+ },{ .name = "RST_ADMA", .addr = A_RST_ADMA,
515
+ .reset = 0x1,
516
+ .pre_write = crl_rst_adma_prew,
517
+ },{ .name = "RST_GEM0", .addr = A_RST_GEM0,
518
+ .reset = 0x1,
519
+ .pre_write = crl_rst_gem0_prew,
520
+ },{ .name = "RST_GEM1", .addr = A_RST_GEM1,
521
+ .reset = 0x1,
522
+ .pre_write = crl_rst_gem1_prew,
523
+ },{ .name = "RST_SPARE", .addr = A_RST_SPARE,
524
+ .reset = 0x1,
525
+ },{ .name = "RST_USB0", .addr = A_RST_USB0,
526
+ .reset = 0x1,
527
+ .pre_write = crl_rst_usb_prew,
528
+ },{ .name = "RST_UART0", .addr = A_RST_UART0,
529
+ .reset = 0x1,
530
+ .pre_write = crl_rst_uart0_prew,
531
+ },{ .name = "RST_UART1", .addr = A_RST_UART1,
532
+ .reset = 0x1,
533
+ .pre_write = crl_rst_uart1_prew,
534
+ },{ .name = "RST_SPI0", .addr = A_RST_SPI0,
535
+ .reset = 0x1,
536
+ },{ .name = "RST_SPI1", .addr = A_RST_SPI1,
537
+ .reset = 0x1,
538
+ },{ .name = "RST_CAN0", .addr = A_RST_CAN0,
539
+ .reset = 0x1,
540
+ },{ .name = "RST_CAN1", .addr = A_RST_CAN1,
541
+ .reset = 0x1,
542
+ },{ .name = "RST_I2C0", .addr = A_RST_I2C0,
543
+ .reset = 0x1,
544
+ },{ .name = "RST_I2C1", .addr = A_RST_I2C1,
545
+ .reset = 0x1,
546
+ },{ .name = "RST_DBG_LPD", .addr = A_RST_DBG_LPD,
547
+ .reset = 0x33,
548
+ .rsvd = 0xcc,
549
+ },{ .name = "RST_GPIO", .addr = A_RST_GPIO,
550
+ .reset = 0x1,
551
+ },{ .name = "RST_TTC", .addr = A_RST_TTC,
552
+ .reset = 0xf,
553
+ },{ .name = "RST_TIMESTAMP", .addr = A_RST_TIMESTAMP,
554
+ .reset = 0x1,
555
+ },{ .name = "RST_SWDT", .addr = A_RST_SWDT,
556
+ .reset = 0x1,
557
+ },{ .name = "RST_OCM", .addr = A_RST_OCM,
558
+ },{ .name = "RST_IPI", .addr = A_RST_IPI,
559
+ },{ .name = "RST_FPD", .addr = A_RST_FPD,
560
+ .reset = 0x3,
561
+ },{ .name = "PSM_RST_MODE", .addr = A_PSM_RST_MODE,
562
+ .reset = 0x1,
563
+ .rsvd = 0xf8,
564
+ }
565
+};
566
+
567
+static void crl_reset_enter(Object *obj, ResetType type)
568
+{
569
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
570
+ unsigned int i;
571
+
572
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
573
+ register_reset(&s->regs_info[i]);
574
+ }
575
+}
576
+
577
+static void crl_reset_hold(Object *obj)
578
+{
579
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
580
+
581
+ crl_update_irq(s);
582
+}
583
+
584
+static const MemoryRegionOps crl_ops = {
585
+ .read = register_read_memory,
586
+ .write = register_write_memory,
587
+ .endianness = DEVICE_LITTLE_ENDIAN,
588
+ .valid = {
589
+ .min_access_size = 4,
590
+ .max_access_size = 4,
591
+ },
592
+};
593
+
594
+static void crl_init(Object *obj)
595
+{
596
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
597
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
598
+ int i;
599
+
600
+ s->reg_array =
601
+ register_init_block32(DEVICE(obj), crl_regs_info,
602
+ ARRAY_SIZE(crl_regs_info),
603
+ s->regs_info, s->regs,
604
+ &crl_ops,
605
+ XLNX_VERSAL_CRL_ERR_DEBUG,
606
+ CRL_R_MAX * 4);
607
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
608
+ sysbus_init_irq(sbd, &s->irq);
609
+
610
+ for (i = 0; i < ARRAY_SIZE(s->cfg.cpu_r5); ++i) {
611
+ object_property_add_link(obj, "cpu_r5[*]", TYPE_ARM_CPU,
612
+ (Object **)&s->cfg.cpu_r5[i],
613
+ qdev_prop_allow_set_link_before_realize,
614
+ OBJ_PROP_LINK_STRONG);
615
+ }
616
+
617
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); ++i) {
618
+ object_property_add_link(obj, "adma[*]", TYPE_DEVICE,
619
+ (Object **)&s->cfg.adma[i],
620
+ qdev_prop_allow_set_link_before_realize,
621
+ OBJ_PROP_LINK_STRONG);
622
+ }
623
+
624
+ for (i = 0; i < ARRAY_SIZE(s->cfg.uart); ++i) {
625
+ object_property_add_link(obj, "uart[*]", TYPE_DEVICE,
626
+ (Object **)&s->cfg.uart[i],
627
+ qdev_prop_allow_set_link_before_realize,
628
+ OBJ_PROP_LINK_STRONG);
629
+ }
630
+
631
+ for (i = 0; i < ARRAY_SIZE(s->cfg.gem); ++i) {
632
+ object_property_add_link(obj, "gem[*]", TYPE_DEVICE,
633
+ (Object **)&s->cfg.gem[i],
634
+ qdev_prop_allow_set_link_before_realize,
635
+ OBJ_PROP_LINK_STRONG);
636
+ }
637
+
638
+ object_property_add_link(obj, "usb", TYPE_DEVICE,
639
+ (Object **)&s->cfg.gem[i],
640
+ qdev_prop_allow_set_link_before_realize,
641
+ OBJ_PROP_LINK_STRONG);
642
+}
643
+
644
+static void crl_finalize(Object *obj)
645
+{
646
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
647
+ register_finalize_block(s->reg_array);
648
+}
649
+
650
+static const VMStateDescription vmstate_crl = {
651
+ .name = TYPE_XLNX_VERSAL_CRL,
652
+ .version_id = 1,
653
+ .minimum_version_id = 1,
654
+ .fields = (VMStateField[]) {
655
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalCRL, CRL_R_MAX),
656
+ VMSTATE_END_OF_LIST(),
657
+ }
658
+};
659
+
660
+static void crl_class_init(ObjectClass *klass, void *data)
661
+{
662
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
663
+ DeviceClass *dc = DEVICE_CLASS(klass);
664
+
665
+ dc->vmsd = &vmstate_crl;
666
+
667
+ rc->phases.enter = crl_reset_enter;
668
+ rc->phases.hold = crl_reset_hold;
669
+}
670
+
671
+static const TypeInfo crl_info = {
672
+ .name = TYPE_XLNX_VERSAL_CRL,
673
+ .parent = TYPE_SYS_BUS_DEVICE,
674
+ .instance_size = sizeof(XlnxVersalCRL),
675
+ .class_init = crl_class_init,
676
+ .instance_init = crl_init,
677
+ .instance_finalize = crl_finalize,
678
+};
679
+
680
+static void crl_register_types(void)
681
+{
682
+ type_register_static(&crl_info);
683
+}
684
+
685
+type_init(crl_register_types)
686
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
14
index XXXXXXX..XXXXXXX 100644
687
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/sd/sdhci.c
688
--- a/hw/misc/meson.build
16
+++ b/hw/sd/sdhci.c
689
+++ b/hw/misc/meson.build
17
@@ -XXX,XX +XXX,XX @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
690
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
18
}
691
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
19
sdhci_update_irq(s);
692
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-crf.c'))
20
break;
693
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-apu-ctrl.c'))
21
+ case SDHC_ACMD12ERRSTS:
694
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
22
+ MASKED_WRITE(s->acmd12errsts, mask, value);
695
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
23
+ break;
696
'xlnx-versal-xramc.c',
24
697
'xlnx-versal-pmc-iou-slcr.c',
25
case SDHC_CAPAB:
26
case SDHC_CAPAB + 4:
27
--
698
--
28
2.7.4
699
2.25.1
29
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Connect the CRL (Clock Reset LPD) to the Versal SoC.
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
5
Message-id: 20180115182436.2066-6-f4bug@amsat.org
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-5-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
---
10
---
8
hw/sd/sdhci.c | 30 +++++++++++++++++++++---------
11
include/hw/arm/xlnx-versal.h | 4 +++
9
1 file changed, 21 insertions(+), 9 deletions(-)
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
13
2 files changed, 56 insertions(+), 2 deletions(-)
10
14
11
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/sdhci.c
17
--- a/include/hw/arm/xlnx-versal.h
14
+++ b/hw/sd/sdhci.c
18
+++ b/include/hw/arm/xlnx-versal.h
15
@@ -XXX,XX +XXX,XX @@ static void sdhci_uninitfn(SDHCIState *s)
19
@@ -XXX,XX +XXX,XX @@
16
s->fifo_buffer = NULL;
20
#include "hw/nvram/xlnx-versal-efuse.h"
21
#include "hw/ssi/xlnx-versal-ospi.h"
22
#include "hw/dma/xlnx_csu_dma.h"
23
+#include "hw/misc/xlnx-versal-crl.h"
24
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
25
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
@@ -XXX,XX +XXX,XX @@ struct Versal {
28
qemu_or_irq irq_orgate;
29
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
30
} xram;
31
+
32
+ XlnxVersalCRL crl;
33
} lpd;
34
35
/* The Platform Management Controller subsystem. */
36
@@ -XXX,XX +XXX,XX @@ struct Versal {
37
#define VERSAL_TIMER_NS_EL1_IRQ 14
38
#define VERSAL_TIMER_NS_EL2_IRQ 10
39
40
+#define VERSAL_CRL_IRQ 10
41
#define VERSAL_UART0_IRQ_0 18
42
#define VERSAL_UART1_IRQ_0 19
43
#define VERSAL_USB0_IRQ_0 22
44
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal.c
47
+++ b/hw/arm/xlnx-versal.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
49
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
17
}
50
}
18
51
19
+static void sdhci_common_realize(SDHCIState *s, Error **errp)
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
20
+{
53
+{
21
+ s->buf_maxsz = sdhci_get_fifolen(s);
54
+ SysBusDevice *sbd;
22
+ s->fifo_buffer = g_malloc0(s->buf_maxsz);
55
+ int i;
23
+
56
+
24
+ memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
57
+ object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
25
+ SDHC_REGISTERS_MAP_SIZE);
58
+ TYPE_XLNX_VERSAL_CRL);
59
+ sbd = SYS_BUS_DEVICE(&s->lpd.crl);
60
+
61
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
62
+ g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
63
+
64
+ object_property_set_link(OBJECT(&s->lpd.crl),
65
+ name, OBJECT(&s->lpd.rpu.cpu[i]),
66
+ &error_abort);
67
+ }
68
+
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
71
+
72
+ object_property_set_link(OBJECT(&s->lpd.crl),
73
+ name, OBJECT(&s->lpd.iou.gem[i]),
74
+ &error_abort);
75
+ }
76
+
77
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
78
+ g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
79
+
80
+ object_property_set_link(OBJECT(&s->lpd.crl),
81
+ name, OBJECT(&s->lpd.iou.adma[i]),
82
+ &error_abort);
83
+ }
84
+
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
86
+ g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
87
+
88
+ object_property_set_link(OBJECT(&s->lpd.crl),
89
+ name, OBJECT(&s->lpd.iou.uart[i]),
90
+ &error_abort);
91
+ }
92
+
93
+ object_property_set_link(OBJECT(&s->lpd.crl),
94
+ "usb", OBJECT(&s->lpd.iou.usb),
95
+ &error_abort);
96
+
97
+ sysbus_realize(sbd, &error_fatal);
98
+ memory_region_add_subregion(&s->mr_ps, MM_CRL,
99
+ sysbus_mmio_get_region(sbd, 0));
100
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
26
+}
101
+}
27
+
102
+
28
static bool sdhci_pending_insert_vmstate_needed(void *opaque)
103
/* This takes the board allocated linear DDR memory and creates aliases
29
{
104
* for each split DDR range/aperture on the Versal address map.
30
SDHCIState *s = opaque;
105
*/
31
@@ -XXX,XX +XXX,XX @@ static Property sdhci_pci_properties[] = {
106
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
32
static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
107
33
{
108
versal_unimp_area(s, "psm", &s->mr_ps,
34
SDHCIState *s = PCI_SDHCI(dev);
109
MM_PSM_START, MM_PSM_END - MM_PSM_START);
35
+
110
- versal_unimp_area(s, "crl", &s->mr_ps,
36
+ sdhci_initfn(s);
111
- MM_CRL, MM_CRL_SIZE);
37
+ sdhci_common_realize(s, errp);
112
versal_unimp_area(s, "crf", &s->mr_ps,
38
+ if (errp && *errp) {
113
MM_FPD_CRF, MM_FPD_CRF_SIZE);
39
+ return;
114
versal_unimp_area(s, "apu", &s->mr_ps,
40
+ }
115
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
41
+
116
versal_create_efuse(s, pic);
42
dev->config[PCI_CLASS_PROG] = 0x01; /* Standard Host supported DMA */
117
versal_create_pmc_iou_slcr(s, pic);
43
dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
118
versal_create_ospi(s, pic);
44
- sdhci_initfn(s);
119
+ versal_create_crl(s, pic);
45
- s->buf_maxsz = sdhci_get_fifolen(s);
120
versal_map_ddr(s);
46
- s->fifo_buffer = g_malloc0(s->buf_maxsz);
121
versal_unimp(s);
47
s->irq = pci_allocate_irq(dev);
48
- memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
49
- SDHC_REGISTERS_MAP_SIZE);
50
pci_register_bar(dev, 0, 0, &s->iomem);
51
}
52
53
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
54
SDHCIState *s = SYSBUS_SDHCI(dev);
55
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
56
57
- s->buf_maxsz = sdhci_get_fifolen(s);
58
- s->fifo_buffer = g_malloc0(s->buf_maxsz);
59
+ sdhci_common_realize(s, errp);
60
+ if (errp && *errp) {
61
+ return;
62
+ }
63
+
64
sysbus_init_irq(sbd, &s->irq);
65
- memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
66
- SDHC_REGISTERS_MAP_SIZE);
67
sysbus_init_mmio(sbd, &s->iomem);
68
}
69
122
70
--
123
--
71
2.7.4
124
2.25.1
72
73
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The Exynos4210 SoC device currently uses a custom device
2
"exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ
3
line. We have a standard TYPE_OR_IRQ device for this now, so use
4
that instead.
2
5
3
Add a 'dma' property allowing machine creation to provide the address-space
6
(This is a migration compatibility break, but that is OK for this
4
SDHCI DMA operates on.
7
machine type.)
5
8
6
[based on a patch from Alistair Francis <alistair.francis@xilinx.com>
7
from qemu/xilinx tag xilinx-v2016.1]
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20180115182436.2066-15-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-2-peter.maydell@linaro.org
11
---
12
---
12
include/hw/sd/sdhci.h | 1 +
13
include/hw/arm/exynos4210.h | 1 +
13
hw/sd/sdhci.c | 18 +++++++++++++++++-
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
14
2 files changed, 18 insertions(+), 1 deletion(-)
15
2 files changed, 17 insertions(+), 15 deletions(-)
15
16
16
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.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/include/hw/sd/sdhci.h
19
--- a/include/hw/arm/exynos4210.h
19
+++ b/include/hw/sd/sdhci.h
20
+++ b/include/hw/arm/exynos4210.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
21
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
21
SDBus sdbus;
22
MemoryRegion bootreg_mem;
22
MemoryRegion iomem;
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
23
AddressSpace *dma_as;
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
24
+ MemoryRegion *dma_mr;
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
25
26
};
26
QEMUTimer *insert_timer; /* timer for 'changing' sd card. */
27
27
QEMUTimer *transfer_timer;
28
#define TYPE_EXYNOS4210_SOC "exynos4210"
28
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
29
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/sd/sdhci.c
31
--- a/hw/arm/exynos4210.c
31
+++ b/hw/sd/sdhci.c
32
+++ b/hw/arm/exynos4210.c
32
@@ -XXX,XX +XXX,XX @@ static Property sdhci_sysbus_properties[] = {
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
33
DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState),
34
DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk,
35
false),
36
+ DEFINE_PROP_LINK("dma", SDHCIState,
37
+ dma_mr, TYPE_MEMORY_REGION, MemoryRegion *),
38
DEFINE_PROP_END_OF_LIST(),
39
};
40
41
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_init(Object *obj)
42
static void sdhci_sysbus_finalize(Object *obj)
43
{
34
{
44
SDHCIState *s = SYSBUS_SDHCI(obj);
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
}
45
+
91
+
46
+ if (s->dma_mr) {
92
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
47
+ object_unparent(OBJECT(s->dma_mr));
93
+ g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
48
+ }
94
+ object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
49
+
50
sdhci_uninitfn(s);
51
}
52
53
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
54
return;
55
}
56
57
- s->dma_as = &address_space_memory;
58
+ if (s->dma_mr) {
59
+ address_space_init(s->dma_as, s->dma_mr, "sdhci-dma");
60
+ } else {
61
+ /* use system_memory() if property "dma" not set */
62
+ s->dma_as = &address_space_memory;
63
+ }
64
65
sysbus_init_irq(sbd, &s->irq);
66
sysbus_init_mmio(sbd, &s->iomem);
67
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_unrealize(DeviceState *dev, Error **errp)
68
SDHCIState *s = SYSBUS_SDHCI(dev);
69
70
sdhci_common_unrealize(s, &error_abort);
71
+
72
+ if (s->dma_mr) {
73
+ address_space_destroy(s->dma_as);
74
+ }
95
+ }
75
}
96
}
76
97
77
static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
98
static void exynos4210_class_init(ObjectClass *klass, void *data)
78
--
99
--
79
2.7.4
100
2.25.1
80
81
diff view generated by jsdifflib
New patch
1
Now we have removed the only use of TYPE_EXYNOS4210_IRQ_GATE we can
2
delete the device entirely.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
6
Message-id: 20220404154658.565020-3-peter.maydell@linaro.org
7
---
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
9
1 file changed, 107 deletions(-)
10
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/intc/exynos4210_gic.c
14
+++ b/hw/intc/exynos4210_gic.c
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
16
}
17
18
type_init(exynos4210_gic_register_types)
19
-
20
-/* IRQ OR Gate struct.
21
- *
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
24
- * gpio inputs.
25
- */
26
-
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)
55
-{
56
- Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)opaque;
57
- uint32_t i;
58
-
59
- assert(irq < s->n_in);
60
-
61
- s->level[irq] = level;
62
-
63
- for (i = 0; i < s->n_in; i++) {
64
- if (s->level[i] >= 1) {
65
- qemu_irq_raise(s->out);
66
- return;
67
- }
68
- }
69
-
70
- qemu_irq_lower(s->out);
71
-}
72
-
73
-static void exynos4210_irq_gate_reset(DeviceState *d)
74
-{
75
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(d);
76
-
77
- memset(s->level, 0, s->n_in * sizeof(*s->level));
78
-}
79
-
80
-/*
81
- * IRQ Gate initialization.
82
- */
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,
118
-};
119
-
120
-static void exynos4210_irq_gate_register_types(void)
121
-{
122
- type_register_static(&exynos4210_irq_gate_info);
123
-}
124
-
125
-type_init(exynos4210_irq_gate_register_types)
126
--
127
2.25.1
diff view generated by jsdifflib
1
Since omap_mmc is still using the legacy SD card API, the SD
1
The exynos4210 SoC mostly creates its child devices as if it were
2
card created by sd_init() is not plugged into any bus. This
2
board code. This includes the a9mpcore object. Switch that to a
3
means that the controller has to reset it manually.
3
new-style "embedded in the state struct" creation, because in the
4
4
next commit we're going to want to refer to the object again further
5
Failing to do this mostly didn't affect the guest since the
5
down in the exynos4210_realize() function.
6
guest typically does a programmed SD card reset as part of
7
its SD controller driver initialization, but would mean that
8
migration fails because it's only in sd_reset() that we
9
set up the wpgrps_size field.
10
6
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20220404154658.565020-4-peter.maydell@linaro.org
14
Message-id: 1515506513-31961-5-git-send-email-peter.maydell@linaro.org
15
---
10
---
16
hw/sd/omap_mmc.c | 14 ++++++++++----
11
include/hw/arm/exynos4210.h | 2 ++
17
1 file changed, 10 insertions(+), 4 deletions(-)
12
hw/arm/exynos4210.c | 11 ++++++-----
13
2 files changed, 8 insertions(+), 5 deletions(-)
18
14
19
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/sd/omap_mmc.c
17
--- a/include/hw/arm/exynos4210.h
22
+++ b/hw/sd/omap_mmc.c
18
+++ b/include/hw/arm/exynos4210.h
23
@@ -XXX,XX +XXX,XX @@ void omap_mmc_reset(struct omap_mmc_s *host)
19
@@ -XXX,XX +XXX,XX @@
24
host->cdet_enable = 0;
20
25
qemu_set_irq(host->coverswitch, host->cdet_state);
21
#include "hw/or-irq.h"
26
host->clkdiv = 0;
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
}
27
+
65
+
28
+ /* Since we're still using the legacy SD API the card is not plugged
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
29
+ * into any bus, and we must reset it manually. When omap_mmc is
30
+ * QOMified this must move into the QOM reset function.
31
+ */
32
+ device_reset(DEVICE(host->card));
33
}
67
}
34
68
35
static uint64_t omap_mmc_read(void *opaque, hwaddr offset,
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
36
@@ -XXX,XX +XXX,XX @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
37
s->lines = 1;    /* TODO: needs to be settable per-board */
38
s->rev = 1;
39
40
- omap_mmc_reset(s);
41
-
42
memory_region_init_io(&s->iomem, NULL, &omap_mmc_ops, s, "omap.mmc", 0x800);
43
memory_region_add_subregion(sysmem, base, &s->iomem);
44
45
@@ -XXX,XX +XXX,XX @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
46
exit(1);
47
}
48
49
+ omap_mmc_reset(s);
50
+
51
return s;
52
}
53
54
@@ -XXX,XX +XXX,XX @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
55
s->lines = 4;
56
s->rev = 2;
57
58
- omap_mmc_reset(s);
59
-
60
memory_region_init_io(&s->iomem, NULL, &omap_mmc_ops, s, "omap.mmc",
61
omap_l4_region_size(ta, 0));
62
omap_l4_attach(ta, 0, &s->iomem);
63
@@ -XXX,XX +XXX,XX @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
64
s->cdet = qemu_allocate_irq(omap_mmc_cover_cb, s, 0);
65
sd_set_cb(s->card, NULL, s->cdet);
66
67
+ omap_mmc_reset(s);
68
+
69
return s;
70
}
71
72
--
70
--
73
2.7.4
71
2.25.1
74
75
diff view generated by jsdifflib
New patch
1
The only time we use the int_gic_irq[] array in the Exynos4210Irq
2
struct is in the exynos4210_realize() function: we initialize it with
3
the GPIO inputs of the a9mpcore device, and then a bit later on we
4
connect those to the outputs of the internal combiner. Now that the
5
a9mpcore object is easily accessible as s->a9mpcore we can make the
6
connection directly from one device to the other without going via
7
this array.
1
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-5-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 -
14
hw/arm/exynos4210.c | 6 ++----
15
2 files changed, 2 insertions(+), 5 deletions(-)
16
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@
22
typedef struct Exynos4210Irq {
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
25
- qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
26
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
27
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
28
} Exynos4210Irq;
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
sysbus_connect_irq(busdev, n,
35
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
36
}
37
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
38
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
39
- }
40
41
/* Cache controller */
42
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
43
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
44
busdev = SYS_BUS_DEVICE(dev);
45
sysbus_realize_and_unref(busdev, &error_fatal);
46
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
47
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
48
+ sysbus_connect_irq(busdev, n,
49
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
50
}
51
exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
52
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
53
--
54
2.25.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The exynos4210 code currently has two very similar arrays of IRQs:
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
* board_irqs is a field of the Exynos4210Irq struct which is filled
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
5
Message-id: 20180115182436.2066-8-f4bug@amsat.org
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20220404154658.565020-6-peter.maydell@linaro.org
7
---
18
---
8
hw/sd/sdhci.c | 7 ++++---
19
include/hw/arm/exynos4210.h | 8 ++------
9
1 file changed, 4 insertions(+), 3 deletions(-)
20
hw/arm/exynos4210.c | 6 +-----
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
22
3 files changed, 11 insertions(+), 35 deletions(-)
10
23
11
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/sdhci.c
26
--- a/include/hw/arm/exynos4210.h
14
+++ b/hw/sd/sdhci.c
27
+++ b/include/hw/arm/exynos4210.h
15
@@ -XXX,XX +XXX,XX @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
16
ret = (SD_HOST_SPECv2_VERS << 16) | sdhci_slotint(s);
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
17
break;
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
18
default:
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
19
- ERRPRINT("bad %ub read: addr[0x%04x]\n", size, (int)offset);
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
20
+ qemu_log_mask(LOG_UNIMP, "SDHC rd_%ub @0x%02" HWADDR_PRIx " "
33
} Exynos4210Irq;
21
+ "not implemented\n", size, offset);
34
22
break;
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);
23
}
65
}
24
66
25
@@ -XXX,XX +XXX,XX @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
67
- /*** IRQs ***/
26
sdhci_update_irq(s);
68
-
27
break;
69
- s->irq_table = exynos4210_init_irq(&s->irqs);
28
default:
70
-
29
- ERRPRINT("bad %ub write offset: addr[0x%04x] <- %u(0x%x)\n",
71
/* IRQ Gate */
30
- size, (int)offset, value >> shift, value >> shift);
72
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
31
+ qemu_log_mask(LOG_UNIMP, "SDHC wr_%ub @0x%02" HWADDR_PRIx " <- 0x%08x "
73
DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
32
+ "not implemented\n", size, offset, value >> shift);
74
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
33
break;
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
}
34
}
134
}
35
DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",
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
}
36
--
147
--
37
2.7.4
148
2.25.1
38
39
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: Philippe Mathieu-Daudé <f4bug@amsat.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
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
5
Message-id: 20180115182436.2066-7-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
7
---
12
---
8
hw/sd/sdhci.c | 22 ++++++++++++++++++++++
13
include/hw/arm/exynos4210.h | 4 -
9
1 file changed, 22 insertions(+)
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
16
3 files changed, 202 insertions(+), 208 deletions(-)
10
17
11
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/sdhci.c
20
--- a/include/hw/arm/exynos4210.h
14
+++ b/hw/sd/sdhci.c
21
+++ b/include/hw/arm/exynos4210.h
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
23
void exynos4210_write_secondary(ARMCPU *cpu,
24
const struct arm_boot_info *info);
25
26
-/* Initialize board IRQs.
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
29
-
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
31
* To identify IRQ source use internal combiner group and bit number
32
* grp - group number
33
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/exynos4210.c
36
+++ b/hw/arm/exynos4210.c
15
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
16
#include "qemu/bitops.h"
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
17
#include "hw/sd/sdhci.h"
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
18
#include "sdhci-internal.h"
40
19
+#include "qapi/error.h"
41
+enum ExtGicId {
20
#include "qemu/log.h"
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
21
43
+ EXT_GIC_ID_PDMA0,
22
/* host controller debug messages */
44
+ EXT_GIC_ID_PDMA1,
23
@@ -XXX,XX +XXX,XX @@ static void sdhci_common_realize(SDHCIState *s, Error **errp)
45
+ EXT_GIC_ID_TIMER0,
24
SDHC_REGISTERS_MAP_SIZE);
46
+ EXT_GIC_ID_TIMER1,
25
}
47
+ EXT_GIC_ID_TIMER2,
26
48
+ EXT_GIC_ID_TIMER3,
27
+static void sdhci_common_unrealize(SDHCIState *s, Error **errp)
49
+ EXT_GIC_ID_TIMER4,
50
+ EXT_GIC_ID_MCT_L0,
51
+ EXT_GIC_ID_WDT,
52
+ EXT_GIC_ID_RTC_ALARM,
53
+ EXT_GIC_ID_RTC_TIC,
54
+ EXT_GIC_ID_GPIO_XB,
55
+ EXT_GIC_ID_GPIO_XA,
56
+ EXT_GIC_ID_MCT_L1,
57
+ EXT_GIC_ID_IEM_APC,
58
+ EXT_GIC_ID_IEM_IEC,
59
+ EXT_GIC_ID_NFC,
60
+ EXT_GIC_ID_UART0,
61
+ EXT_GIC_ID_UART1,
62
+ EXT_GIC_ID_UART2,
63
+ EXT_GIC_ID_UART3,
64
+ EXT_GIC_ID_UART4,
65
+ EXT_GIC_ID_MCT_G0,
66
+ EXT_GIC_ID_I2C0,
67
+ EXT_GIC_ID_I2C1,
68
+ EXT_GIC_ID_I2C2,
69
+ EXT_GIC_ID_I2C3,
70
+ EXT_GIC_ID_I2C4,
71
+ EXT_GIC_ID_I2C5,
72
+ EXT_GIC_ID_I2C6,
73
+ EXT_GIC_ID_I2C7,
74
+ EXT_GIC_ID_SPI0,
75
+ EXT_GIC_ID_SPI1,
76
+ EXT_GIC_ID_SPI2,
77
+ EXT_GIC_ID_MCT_G1,
78
+ EXT_GIC_ID_USB_HOST,
79
+ EXT_GIC_ID_USB_DEVICE,
80
+ EXT_GIC_ID_MODEMIF,
81
+ EXT_GIC_ID_HSMMC0,
82
+ EXT_GIC_ID_HSMMC1,
83
+ EXT_GIC_ID_HSMMC2,
84
+ EXT_GIC_ID_HSMMC3,
85
+ EXT_GIC_ID_SDMMC,
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
90
+ EXT_GIC_ID_ONENAND_AUDI,
91
+ EXT_GIC_ID_ROTATOR,
92
+ EXT_GIC_ID_FIMC0,
93
+ EXT_GIC_ID_FIMC1,
94
+ EXT_GIC_ID_FIMC2,
95
+ EXT_GIC_ID_FIMC3,
96
+ EXT_GIC_ID_JPEG,
97
+ EXT_GIC_ID_2D,
98
+ EXT_GIC_ID_PCIe,
99
+ EXT_GIC_ID_MIXER,
100
+ EXT_GIC_ID_HDMI,
101
+ EXT_GIC_ID_HDMI_I2C,
102
+ EXT_GIC_ID_MFC,
103
+ EXT_GIC_ID_TVENC,
104
+};
105
+
106
+enum ExtInt {
107
+ EXT_GIC_ID_EXTINT0 = 48,
108
+ EXT_GIC_ID_EXTINT1,
109
+ EXT_GIC_ID_EXTINT2,
110
+ EXT_GIC_ID_EXTINT3,
111
+ EXT_GIC_ID_EXTINT4,
112
+ EXT_GIC_ID_EXTINT5,
113
+ EXT_GIC_ID_EXTINT6,
114
+ EXT_GIC_ID_EXTINT7,
115
+ EXT_GIC_ID_EXTINT8,
116
+ EXT_GIC_ID_EXTINT9,
117
+ EXT_GIC_ID_EXTINT10,
118
+ EXT_GIC_ID_EXTINT11,
119
+ EXT_GIC_ID_EXTINT12,
120
+ EXT_GIC_ID_EXTINT13,
121
+ EXT_GIC_ID_EXTINT14,
122
+ EXT_GIC_ID_EXTINT15
123
+};
124
+
125
+/*
126
+ * External GIC sources which are not from External Interrupt Combiner or
127
+ * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
128
+ * which is INTG16 in Internal Interrupt Combiner.
129
+ */
130
+
131
+static const uint32_t
132
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
133
+ /* int combiner groups 16-19 */
134
+ { }, { }, { }, { },
135
+ /* int combiner group 20 */
136
+ { 0, EXT_GIC_ID_MDMA_LCD0 },
137
+ /* int combiner group 21 */
138
+ { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
139
+ /* int combiner group 22 */
140
+ { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
141
+ EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
142
+ /* int combiner group 23 */
143
+ { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
144
+ /* int combiner group 24 */
145
+ { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
146
+ /* int combiner group 25 */
147
+ { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
148
+ /* int combiner group 26 */
149
+ { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
150
+ EXT_GIC_ID_UART4 },
151
+ /* int combiner group 27 */
152
+ { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
153
+ EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
154
+ EXT_GIC_ID_I2C7 },
155
+ /* int combiner group 28 */
156
+ { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
157
+ /* int combiner group 29 */
158
+ { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
159
+ EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
160
+ /* int combiner group 30 */
161
+ { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
162
+ /* int combiner group 31 */
163
+ { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
164
+ /* int combiner group 32 */
165
+ { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
166
+ /* int combiner group 33 */
167
+ { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
168
+ /* int combiner group 34 */
169
+ { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
170
+ /* int combiner group 35 */
171
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
172
+ /* int combiner group 36 */
173
+ { EXT_GIC_ID_MIXER },
174
+ /* int combiner group 37 */
175
+ { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
176
+ EXT_GIC_ID_EXTINT7 },
177
+ /* groups 38-50 */
178
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
179
+ /* int combiner group 51 */
180
+ { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
181
+ /* group 52 */
182
+ { },
183
+ /* int combiner group 53 */
184
+ { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
185
+ /* groups 54-63 */
186
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
187
+};
188
+
189
+/*
190
+ * Initialize board IRQs.
191
+ * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
192
+ */
193
+static void exynos4210_init_board_irqs(Exynos4210State *s)
28
+{
194
+{
29
+ /* This function is expected to be called only once for each class:
195
+ uint32_t grp, bit, irq_id, n;
30
+ * - SysBus: via DeviceClass->unrealize(),
196
+ Exynos4210Irq *is = &s->irqs;
31
+ * - PCI: via PCIDeviceClass->exit().
197
+
32
+ * However to avoid double-free and/or use-after-free we still nullify
198
+ for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
33
+ * this variable (better safe than sorry!). */
199
+ irq_id = 0;
34
+ g_free(s->fifo_buffer);
200
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
35
+ s->fifo_buffer = NULL;
201
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
202
+ /* MCT_G0 is passed to External GIC */
203
+ irq_id = EXT_GIC_ID_MCT_G0;
204
+ }
205
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
206
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
207
+ /* MCT_G1 is passed to External and GIC */
208
+ irq_id = EXT_GIC_ID_MCT_G1;
209
+ }
210
+ if (irq_id) {
211
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
212
+ is->ext_gic_irq[irq_id - 32]);
213
+ } else {
214
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
215
+ is->ext_combiner_irq[n]);
216
+ }
217
+ }
218
+ for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
219
+ /* these IDs are passed to Internal Combiner and External GIC */
220
+ grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
221
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
222
+ irq_id = combiner_grp_to_gic_id[grp -
223
+ EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
224
+
225
+ if (irq_id) {
226
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
227
+ is->ext_gic_irq[irq_id - 32]);
228
+ }
229
+ }
36
+}
230
+}
37
+
231
+
38
static bool sdhci_pending_insert_vmstate_needed(void *opaque)
232
+/*
39
{
233
+ * Get IRQ number from exynos4210 IRQ subsystem stub.
40
SDHCIState *s = opaque;
234
+ * To identify IRQ source use internal combiner group and bit number
41
@@ -XXX,XX +XXX,XX @@ static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
235
+ * grp - group number
42
static void sdhci_pci_exit(PCIDevice *dev)
236
+ * bit - bit number inside group
43
{
237
+ */
44
SDHCIState *s = PCI_SDHCI(dev);
238
+uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
45
+
46
+ sdhci_common_unrealize(s, &error_abort);
47
sdhci_uninitfn(s);
48
}
49
50
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
51
sysbus_init_mmio(sbd, &s->iomem);
52
}
53
54
+static void sdhci_sysbus_unrealize(DeviceState *dev, Error **errp)
55
+{
239
+{
56
+ SDHCIState *s = SYSBUS_SDHCI(dev);
240
+ return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
57
+
58
+ sdhci_common_unrealize(s, &error_abort);
59
+}
241
+}
60
+
242
+
61
static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
243
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
62
{
244
0x09, 0x00, 0x00, 0x00 };
63
DeviceClass *dc = DEVICE_CLASS(klass);
245
64
246
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
65
dc->props = sdhci_sysbus_properties;
247
index XXXXXXX..XXXXXXX 100644
66
dc->realize = sdhci_sysbus_realize;
248
--- a/hw/intc/exynos4210_gic.c
67
+ dc->unrealize = sdhci_sysbus_unrealize;
249
+++ b/hw/intc/exynos4210_gic.c
68
250
@@ -XXX,XX +XXX,XX @@
69
sdhci_common_class_init(klass, data);
251
#include "hw/arm/exynos4210.h"
70
}
252
#include "qom/object.h"
253
254
-enum ExtGicId {
255
- EXT_GIC_ID_MDMA_LCD0 = 66,
256
- EXT_GIC_ID_PDMA0,
257
- EXT_GIC_ID_PDMA1,
258
- EXT_GIC_ID_TIMER0,
259
- EXT_GIC_ID_TIMER1,
260
- EXT_GIC_ID_TIMER2,
261
- EXT_GIC_ID_TIMER3,
262
- EXT_GIC_ID_TIMER4,
263
- EXT_GIC_ID_MCT_L0,
264
- EXT_GIC_ID_WDT,
265
- EXT_GIC_ID_RTC_ALARM,
266
- EXT_GIC_ID_RTC_TIC,
267
- EXT_GIC_ID_GPIO_XB,
268
- EXT_GIC_ID_GPIO_XA,
269
- EXT_GIC_ID_MCT_L1,
270
- EXT_GIC_ID_IEM_APC,
271
- EXT_GIC_ID_IEM_IEC,
272
- EXT_GIC_ID_NFC,
273
- EXT_GIC_ID_UART0,
274
- EXT_GIC_ID_UART1,
275
- EXT_GIC_ID_UART2,
276
- EXT_GIC_ID_UART3,
277
- EXT_GIC_ID_UART4,
278
- EXT_GIC_ID_MCT_G0,
279
- EXT_GIC_ID_I2C0,
280
- EXT_GIC_ID_I2C1,
281
- EXT_GIC_ID_I2C2,
282
- EXT_GIC_ID_I2C3,
283
- EXT_GIC_ID_I2C4,
284
- EXT_GIC_ID_I2C5,
285
- EXT_GIC_ID_I2C6,
286
- EXT_GIC_ID_I2C7,
287
- EXT_GIC_ID_SPI0,
288
- EXT_GIC_ID_SPI1,
289
- EXT_GIC_ID_SPI2,
290
- EXT_GIC_ID_MCT_G1,
291
- EXT_GIC_ID_USB_HOST,
292
- EXT_GIC_ID_USB_DEVICE,
293
- EXT_GIC_ID_MODEMIF,
294
- EXT_GIC_ID_HSMMC0,
295
- EXT_GIC_ID_HSMMC1,
296
- EXT_GIC_ID_HSMMC2,
297
- EXT_GIC_ID_HSMMC3,
298
- EXT_GIC_ID_SDMMC,
299
- EXT_GIC_ID_MIPI_CSI_4LANE,
300
- EXT_GIC_ID_MIPI_DSI_4LANE,
301
- EXT_GIC_ID_MIPI_CSI_2LANE,
302
- EXT_GIC_ID_MIPI_DSI_2LANE,
303
- EXT_GIC_ID_ONENAND_AUDI,
304
- EXT_GIC_ID_ROTATOR,
305
- EXT_GIC_ID_FIMC0,
306
- EXT_GIC_ID_FIMC1,
307
- EXT_GIC_ID_FIMC2,
308
- EXT_GIC_ID_FIMC3,
309
- EXT_GIC_ID_JPEG,
310
- EXT_GIC_ID_2D,
311
- EXT_GIC_ID_PCIe,
312
- EXT_GIC_ID_MIXER,
313
- EXT_GIC_ID_HDMI,
314
- EXT_GIC_ID_HDMI_I2C,
315
- EXT_GIC_ID_MFC,
316
- EXT_GIC_ID_TVENC,
317
-};
318
-
319
-enum ExtInt {
320
- EXT_GIC_ID_EXTINT0 = 48,
321
- EXT_GIC_ID_EXTINT1,
322
- EXT_GIC_ID_EXTINT2,
323
- EXT_GIC_ID_EXTINT3,
324
- EXT_GIC_ID_EXTINT4,
325
- EXT_GIC_ID_EXTINT5,
326
- EXT_GIC_ID_EXTINT6,
327
- EXT_GIC_ID_EXTINT7,
328
- EXT_GIC_ID_EXTINT8,
329
- EXT_GIC_ID_EXTINT9,
330
- EXT_GIC_ID_EXTINT10,
331
- EXT_GIC_ID_EXTINT11,
332
- EXT_GIC_ID_EXTINT12,
333
- EXT_GIC_ID_EXTINT13,
334
- EXT_GIC_ID_EXTINT14,
335
- EXT_GIC_ID_EXTINT15
336
-};
337
-
338
-/*
339
- * External GIC sources which are not from External Interrupt Combiner or
340
- * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
341
- * which is INTG16 in Internal Interrupt Combiner.
342
- */
343
-
344
-static const uint32_t
345
-combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
346
- /* int combiner groups 16-19 */
347
- { }, { }, { }, { },
348
- /* int combiner group 20 */
349
- { 0, EXT_GIC_ID_MDMA_LCD0 },
350
- /* int combiner group 21 */
351
- { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
352
- /* int combiner group 22 */
353
- { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
354
- EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
355
- /* int combiner group 23 */
356
- { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
357
- /* int combiner group 24 */
358
- { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
359
- /* int combiner group 25 */
360
- { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
361
- /* int combiner group 26 */
362
- { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
363
- EXT_GIC_ID_UART4 },
364
- /* int combiner group 27 */
365
- { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
366
- EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
367
- EXT_GIC_ID_I2C7 },
368
- /* int combiner group 28 */
369
- { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
370
- /* int combiner group 29 */
371
- { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
372
- EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
373
- /* int combiner group 30 */
374
- { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
375
- /* int combiner group 31 */
376
- { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
377
- /* int combiner group 32 */
378
- { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
379
- /* int combiner group 33 */
380
- { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
381
- /* int combiner group 34 */
382
- { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
383
- /* int combiner group 35 */
384
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
385
- /* int combiner group 36 */
386
- { EXT_GIC_ID_MIXER },
387
- /* int combiner group 37 */
388
- { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
389
- EXT_GIC_ID_EXTINT7 },
390
- /* groups 38-50 */
391
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
392
- /* int combiner group 51 */
393
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
394
- /* group 52 */
395
- { },
396
- /* int combiner group 53 */
397
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
398
- /* groups 54-63 */
399
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
400
-};
401
-
402
#define EXYNOS4210_GIC_NIRQ 160
403
404
#define EXYNOS4210_EXT_GIC_CPU_REGION_SIZE 0x10000
405
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
406
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
407
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
408
409
-/*
410
- * Initialize board IRQs.
411
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
412
- */
413
-void exynos4210_init_board_irqs(Exynos4210State *s)
414
-{
415
- uint32_t grp, bit, irq_id, n;
416
- Exynos4210Irq *is = &s->irqs;
417
-
418
- for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
419
- irq_id = 0;
420
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
421
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
422
- /* MCT_G0 is passed to External GIC */
423
- irq_id = EXT_GIC_ID_MCT_G0;
424
- }
425
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
426
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
427
- /* MCT_G1 is passed to External and GIC */
428
- irq_id = EXT_GIC_ID_MCT_G1;
429
- }
430
- if (irq_id) {
431
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
432
- is->ext_gic_irq[irq_id - 32]);
433
- } else {
434
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
435
- is->ext_combiner_irq[n]);
436
- }
437
- }
438
- for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
439
- /* these IDs are passed to Internal Combiner and External GIC */
440
- grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
441
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
442
- irq_id = combiner_grp_to_gic_id[grp -
443
- EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
444
-
445
- if (irq_id) {
446
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
447
- is->ext_gic_irq[irq_id - 32]);
448
- }
449
- }
450
-}
451
-
452
-/*
453
- * Get IRQ number from exynos4210 IRQ subsystem stub.
454
- * To identify IRQ source use internal combiner group and bit number
455
- * grp - group number
456
- * bit - bit number inside group
457
- */
458
-uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
459
-{
460
- return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
461
-}
462
-
463
-/********* GIC part *********/
464
-
465
#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
466
OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
467
71
--
468
--
72
2.7.4
469
2.25.1
73
74
diff view generated by jsdifflib
1
Since milkymist-memcard is still using the legacy SD card API,
1
Switch the creation of the external GIC to the new-style "embedded in
2
the SD card created by sd_init() is not plugged into any bus.
2
state struct" approach, so we can easily refer to the object
3
This means that the controller has to reset it manually.
3
elsewhere during realize.
4
4
5
Failing to do this mostly didn't affect the guest since the
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
guest typically does a programmed SD card reset as part of
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
its SD controller driver initialization, but meant that
7
Message-id: 20220404154658.565020-9-peter.maydell@linaro.org
8
migration failed because it's only in sd_reset() that we
8
---
9
set up the wpgrps_size field.
9
include/hw/arm/exynos4210.h | 2 ++
10
include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++
11
hw/arm/exynos4210.c | 10 ++++----
12
hw/intc/exynos4210_gic.c | 17 ++-----------
13
MAINTAINERS | 2 +-
14
5 files changed, 53 insertions(+), 21 deletions(-)
15
create mode 100644 include/hw/intc/exynos4210_gic.h
10
16
11
Cc: qemu-stable@nongnu.org
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 1515506513-31961-3-git-send-email-peter.maydell@linaro.org
16
---
17
hw/sd/milkymist-memcard.c | 4 ++++
18
1 file changed, 4 insertions(+)
19
20
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/sd/milkymist-memcard.c
19
--- a/include/hw/arm/exynos4210.h
23
+++ b/hw/sd/milkymist-memcard.c
20
+++ b/include/hw/arm/exynos4210.h
24
@@ -XXX,XX +XXX,XX @@ static void milkymist_memcard_reset(DeviceState *d)
21
@@ -XXX,XX +XXX,XX @@
25
for (i = 0; i < R_MAX; i++) {
22
#include "hw/or-irq.h"
26
s->regs[i] = 0;
23
#include "hw/sysbus.h"
24
#include "hw/cpu/a9mpcore.h"
25
+#include "hw/intc/exynos4210_gic.h"
26
#include "target/arm/cpu-qom.h"
27
#include "qom/object.h"
28
29
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
30
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
31
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
32
A9MPPrivState a9mpcore;
33
+ Exynos4210GicState ext_gic;
34
};
35
36
#define TYPE_EXYNOS4210_SOC "exynos4210"
37
diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_gic.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Samsung exynos4210 GIC implementation. Based on hw/arm_gic.c
45
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
59
+ * See the GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+#ifndef HW_INTC_EXYNOS4210_GIC_H
65
+#define HW_INTC_EXYNOS4210_GIC_H
66
+
67
+#include "hw/sysbus.h"
68
+
69
+#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
70
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
71
+
72
+#define EXYNOS4210_GIC_NCPUS 2
73
+
74
+struct Exynos4210GicState {
75
+ SysBusDevice parent_obj;
76
+
77
+ MemoryRegion cpu_container;
78
+ MemoryRegion dist_container;
79
+ MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS];
80
+ MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS];
81
+ uint32_t num_cpu;
82
+ DeviceState *gic;
83
+};
84
+
85
+#endif
86
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/arm/exynos4210.c
89
+++ b/hw/arm/exynos4210.c
90
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
91
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
92
93
/* External GIC */
94
- dev = qdev_new("exynos4210.gic");
95
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
96
- busdev = SYS_BUS_DEVICE(dev);
97
- sysbus_realize_and_unref(busdev, &error_fatal);
98
+ qdev_prop_set_uint32(DEVICE(&s->ext_gic), "num-cpu", EXYNOS4210_NCPUS);
99
+ busdev = SYS_BUS_DEVICE(&s->ext_gic);
100
+ sysbus_realize(busdev, &error_fatal);
101
/* Map CPU interface */
102
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
103
/* Map Distributer interface */
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
27
}
106
}
28
+ /* Since we're still using the legacy SD API the card is not plugged
107
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
29
+ * into any bus, and we must reset it manually.
108
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
30
+ */
109
+ s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
31
+ device_reset(DEVICE(s->card));
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);
32
}
118
}
33
119
34
static int milkymist_memcard_init(SysBusDevice *dev)
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>
35
--
176
--
36
2.7.4
177
2.25.1
37
38
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
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The function exynos4210_combiner_get_gpioin() currently lives in
2
exynos4210_combiner.c, but it isn't really part of the combiner
3
device itself -- it is a function that implements the wiring up of
4
some interrupt sources to multiple combiner inputs. Move it to live
5
with the other SoC-level code in exynos4210.c, along with a few
6
macros previously defined in exynos4210.h which are now used only
7
in exynos4210.c.
2
8
3
running qtests:
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-11-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 11 -----
14
hw/arm/exynos4210.c | 82 +++++++++++++++++++++++++++++++++++
15
hw/intc/exynos4210_combiner.c | 77 --------------------------------
16
3 files changed, 82 insertions(+), 88 deletions(-)
4
17
5
$ make check-qtest-arm
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
6
GTESTER check-qtest-arm
7
SDHC rd_4b @0x44 not implemented
8
SDHC wr_4b @0x40 <- 0x89abcdef not implemented
9
SDHC wr_4b @0x44 <- 0x01234567 not implemented
10
11
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
13
Message-id: 20180115182436.2066-12-f4bug@amsat.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
include/hw/sd/sdhci.h | 4 ++--
17
hw/sd/sdhci.c | 23 +++++++++++++++++++----
18
2 files changed, 21 insertions(+), 6 deletions(-)
19
20
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/sd/sdhci.h
20
--- a/include/hw/arm/exynos4210.h
23
+++ b/include/hw/sd/sdhci.h
21
+++ b/include/hw/arm/exynos4210.h
24
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
22
@@ -XXX,XX +XXX,XX @@
25
uint64_t admasysaddr; /* ADMA System Address Register */
23
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
26
24
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
27
/* Read-only registers */
25
28
- uint32_t capareg; /* Capabilities Register */
26
-#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
29
- uint32_t maxcurr; /* Maximum Current Capabilities Register */
27
-#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
30
+ uint64_t capareg; /* Capabilities Register */
28
-#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
31
+ uint64_t maxcurr; /* Maximum Current Capabilities Register */
29
- ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
32
30
-
33
uint8_t *fifo_buffer; /* SD host i/o FIFO buffer */
31
/* IRQs number for external and internal GIC */
34
uint32_t buf_maxsz;
32
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
35
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
33
#define EXYNOS4210_INT_GIC_NIRQ 64
34
@@ -XXX,XX +XXX,XX @@ void exynos4210_write_secondary(ARMCPU *cpu,
35
* bit - bit number inside group */
36
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
37
38
-/*
39
- * Get Combiner input GPIO into irqs structure
40
- */
41
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
42
- int ext);
43
-
44
/*
45
* exynos4210 UART
46
*/
47
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
36
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/sd/sdhci.c
49
--- a/hw/arm/exynos4210.c
38
+++ b/hw/sd/sdhci.c
50
+++ b/hw/arm/exynos4210.c
39
@@ -XXX,XX +XXX,XX @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
51
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
40
ret = s->acmd12errsts;
52
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
41
break;
53
};
42
case SDHC_CAPAB:
54
43
- ret = s->capareg;
55
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
44
+ ret = (uint32_t)s->capareg;
56
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
45
+ break;
57
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
46
+ case SDHC_CAPAB + 4:
58
+ ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
47
+ ret = (uint32_t)(s->capareg >> 32);
59
+
48
break;
60
/*
49
case SDHC_MAXCURR:
61
* Initialize board IRQs.
50
- ret = s->maxcurr;
62
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
51
+ ret = (uint32_t)s->maxcurr;
63
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
52
+ break;
64
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
53
+ case SDHC_MAXCURR + 4:
65
}
54
+ ret = (uint32_t)(s->maxcurr >> 32);
66
55
break;
67
+/*
56
case SDHC_ADMAERR:
68
+ * Get Combiner input GPIO into irqs structure
57
ret = s->admaerr;
69
+ */
58
@@ -XXX,XX +XXX,XX @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
59
}
71
+ DeviceState *dev, int ext)
60
sdhci_update_irq(s);
72
+{
61
break;
73
+ int n;
62
+
74
+ int bit;
63
+ case SDHC_CAPAB:
75
+ int max;
64
+ case SDHC_CAPAB + 4:
76
+ qemu_irq *irq;
65
+ case SDHC_MAXCURR:
77
+
66
+ case SDHC_MAXCURR + 4:
78
+ max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
67
+ qemu_log_mask(LOG_GUEST_ERROR, "SDHC wr_%ub @0x%02" HWADDR_PRIx
79
+ EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
68
+ " <- 0x%08x read-only\n", size, offset, value >> shift);
80
+ irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
69
+ break;
81
+
70
+
82
+ /*
71
default:
83
+ * Some IRQs of Int/External Combiner are going to two Combiners groups,
72
qemu_log_mask(LOG_UNIMP, "SDHC wr_%ub @0x%02" HWADDR_PRIx " <- 0x%08x "
84
+ * so let split them.
73
"not implemented\n", size, offset, value >> shift);
85
+ */
74
@@ -XXX,XX +XXX,XX @@ static inline unsigned int sdhci_get_fifolen(SDHCIState *s)
86
+ for (n = 0; n < max; n++) {
75
#define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \
87
+
76
/* Capabilities registers provide information on supported features
88
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
77
* of this specific host controller implementation */ \
89
+
78
- DEFINE_PROP_UINT32("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \
90
+ switch (n) {
79
- DEFINE_PROP_UINT32("maxcurr", _state, maxcurr, 0)
91
+ /* MDNIE_LCD1 INTG1 */
80
+ DEFINE_PROP_UINT64("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \
92
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
81
+ DEFINE_PROP_UINT64("maxcurr", _state, maxcurr, 0)
93
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
82
94
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
83
static void sdhci_initfn(SDHCIState *s)
95
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
96
+ continue;
97
+
98
+ /* TMU INTG3 */
99
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
100
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
101
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
102
+ continue;
103
+
104
+ /* LCD1 INTG12 */
105
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
106
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
107
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
108
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
109
+ continue;
110
+
111
+ /* Multi-Core Timer INTG12 */
112
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
113
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
114
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
115
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
116
+ continue;
117
+
118
+ /* Multi-Core Timer INTG35 */
119
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
120
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
121
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
122
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
123
+ continue;
124
+
125
+ /* Multi-Core Timer INTG51 */
126
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
127
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
128
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
129
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
130
+ continue;
131
+
132
+ /* Multi-Core Timer INTG53 */
133
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
134
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
135
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
136
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
137
+ continue;
138
+ }
139
+
140
+ irq[n] = qdev_get_gpio_in(dev, n);
141
+ }
142
+}
143
+
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
145
0x09, 0x00, 0x00, 0x00 };
146
147
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/hw/intc/exynos4210_combiner.c
150
+++ b/hw/intc/exynos4210_combiner.c
151
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_exynos4210_combiner = {
152
}
153
};
154
155
-/*
156
- * Get Combiner input GPIO into irqs structure
157
- */
158
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
159
- int ext)
160
-{
161
- int n;
162
- int bit;
163
- int max;
164
- qemu_irq *irq;
165
-
166
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
167
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
168
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
169
-
170
- /*
171
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
172
- * so let split them.
173
- */
174
- for (n = 0; n < max; n++) {
175
-
176
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
177
-
178
- switch (n) {
179
- /* MDNIE_LCD1 INTG1 */
180
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
181
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
182
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
183
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
184
- continue;
185
-
186
- /* TMU INTG3 */
187
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
188
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
189
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
190
- continue;
191
-
192
- /* LCD1 INTG12 */
193
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
194
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
195
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
196
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
197
- continue;
198
-
199
- /* Multi-Core Timer INTG12 */
200
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
201
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
202
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
203
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
204
- continue;
205
-
206
- /* Multi-Core Timer INTG35 */
207
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
208
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
209
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
210
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
211
- continue;
212
-
213
- /* Multi-Core Timer INTG51 */
214
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
215
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
216
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
217
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
218
- continue;
219
-
220
- /* Multi-Core Timer INTG53 */
221
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
222
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
223
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
224
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
225
- continue;
226
- }
227
-
228
- irq[n] = qdev_get_gpio_in(dev, n);
229
- }
230
-}
231
-
232
static uint64_t
233
exynos4210_combiner_read(void *opaque, hwaddr offset, unsigned size)
84
{
234
{
85
--
235
--
86
2.7.4
236
2.25.1
87
88
diff view generated by jsdifflib
New patch
1
Delete a couple of #defines which are never used.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220404154658.565020-12-peter.maydell@linaro.org
6
---
7
include/hw/arm/exynos4210.h | 4 ----
8
1 file changed, 4 deletions(-)
9
10
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/include/hw/arm/exynos4210.h
13
+++ b/include/hw/arm/exynos4210.h
14
@@ -XXX,XX +XXX,XX @@
15
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
16
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
17
18
-/* IRQs number for external and internal GIC */
19
-#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
20
-#define EXYNOS4210_INT_GIC_NIRQ 64
21
-
22
#define EXYNOS4210_I2C_NUMBER 9
23
24
#define EXYNOS4210_NUM_DMA 3
25
--
26
2.25.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
2
instead of qemu_irq_split().
2
3
3
While SysBus devices can use the get_system_memory() address space,
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
PCI devices should use the bus master address space for DMA.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
7
---
8
include/hw/arm/exynos4210.h | 9 ++++++++
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
10
2 files changed, 42 insertions(+), 8 deletions(-)
5
11
6
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
12
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20180115182436.2066-14-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/sd/sdhci.h | 1 +
13
hw/sd/sdhci.c | 29 +++++++++++++++--------------
14
2 files changed, 16 insertions(+), 14 deletions(-)
15
16
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/sd/sdhci.h
14
--- a/include/hw/arm/exynos4210.h
19
+++ b/include/hw/sd/sdhci.h
15
+++ b/include/hw/arm/exynos4210.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
16
@@ -XXX,XX +XXX,XX @@
21
/*< public >*/
17
#include "hw/sysbus.h"
22
SDBus sdbus;
18
#include "hw/cpu/a9mpcore.h"
23
MemoryRegion iomem;
19
#include "hw/intc/exynos4210_gic.h"
24
+ AddressSpace *dma_as;
20
+#include "hw/core/split-irq.h"
25
21
#include "target/arm/cpu-qom.h"
26
QEMUTimer *insert_timer; /* timer for 'changing' sd card. */
22
#include "qom/object.h"
27
QEMUTimer *transfer_timer;
23
28
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
24
@@ -XXX,XX +XXX,XX @@
25
26
#define EXYNOS4210_NUM_DMA 3
27
28
+/*
29
+ * We need one splitter for every external combiner input, plus
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
32
+ */
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
34
+
35
typedef struct Exynos4210Irq {
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
37
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
38
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
39
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
40
A9MPPrivState a9mpcore;
41
Exynos4210GicState ext_gic;
42
+ SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
43
};
44
45
#define TYPE_EXYNOS4210_SOC "exynos4210"
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
29
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/sd/sdhci.c
48
--- a/hw/arm/exynos4210.c
31
+++ b/hw/sd/sdhci.c
49
+++ b/hw/arm/exynos4210.c
32
@@ -XXX,XX +XXX,XX @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
50
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
33
s->blkcnt--;
51
uint32_t grp, bit, irq_id, n;
34
}
52
Exynos4210Irq *is = &s->irqs;
35
}
53
DeviceState *extgicdev = DEVICE(&s->ext_gic);
36
- dma_memory_write(&address_space_memory, s->sdmasysad,
54
+ int splitcount = 0;
37
+ dma_memory_write(s->dma_as, s->sdmasysad,
55
+ DeviceState *splitter;
38
&s->fifo_buffer[begin], s->data_count - begin);
56
39
s->sdmasysad += s->data_count - begin;
57
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
40
if (s->data_count == block_size) {
58
irq_id = 0;
41
@@ -XXX,XX +XXX,XX @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
59
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
42
s->data_count = block_size;
60
/* MCT_G1 is passed to External and GIC */
43
boundary_count -= block_size - begin;
61
irq_id = EXT_GIC_ID_MCT_G1;
44
}
45
- dma_memory_read(&address_space_memory, s->sdmasysad,
46
+ dma_memory_read(s->dma_as, s->sdmasysad,
47
&s->fifo_buffer[begin], s->data_count - begin);
48
s->sdmasysad += s->data_count - begin;
49
if (s->data_count == block_size) {
50
@@ -XXX,XX +XXX,XX @@ static void sdhci_sdma_transfer_single_block(SDHCIState *s)
51
for (n = 0; n < datacnt; n++) {
52
s->fifo_buffer[n] = sdbus_read_data(&s->sdbus);
53
}
62
}
54
- dma_memory_write(&address_space_memory, s->sdmasysad, s->fifo_buffer,
63
+
55
- datacnt);
64
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
56
+ dma_memory_write(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt);
65
+ splitter = DEVICE(&s->splitter[splitcount]);
57
} else {
66
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
58
- dma_memory_read(&address_space_memory, s->sdmasysad, s->fifo_buffer,
67
+ qdev_realize(splitter, NULL, &error_abort);
59
- datacnt);
68
+ splitcount++;
60
+ dma_memory_read(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt);
69
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
61
for (n = 0; n < datacnt; n++) {
70
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
62
sdbus_write_data(&s->sdbus, s->fifo_buffer[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]);
63
}
81
}
64
@@ -XXX,XX +XXX,XX @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
82
}
65
hwaddr entry_addr = (hwaddr)s->admasysaddr;
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
66
switch (SDHC_DMA_TYPE(s->hostctl)) {
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
67
case SDHC_CTRL_ADMA2_32:
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
68
- dma_memory_read(&address_space_memory, entry_addr, (uint8_t *)&adma2,
86
69
+ dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma2,
87
if (irq_id) {
70
sizeof(adma2));
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
71
adma2 = le64_to_cpu(adma2);
89
- qdev_get_gpio_in(extgicdev,
72
/* The spec does not specify endianness of descriptor table.
90
- irq_id - 32));
73
@@ -XXX,XX +XXX,XX @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
74
dscr->incr = 8;
92
+ splitter = DEVICE(&s->splitter[splitcount]);
75
break;
93
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
76
case SDHC_CTRL_ADMA1_32:
94
+ qdev_realize(splitter, NULL, &error_abort);
77
- dma_memory_read(&address_space_memory, entry_addr, (uint8_t *)&adma1,
95
+ splitcount++;
78
+ dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma1,
96
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
79
sizeof(adma1));
97
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
80
adma1 = le32_to_cpu(adma1);
98
+ qdev_connect_gpio_out(splitter, 1,
81
dscr->addr = (hwaddr)(adma1 & 0xFFFFF000);
99
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
82
@@ -XXX,XX +XXX,XX @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
83
}
100
}
84
break;
101
}
85
case SDHC_CTRL_ADMA2_64:
102
+ /*
86
- dma_memory_read(&address_space_memory, entry_addr,
103
+ * We check this here to avoid a more obscure assert later when
87
+ dma_memory_read(s->dma_as, entry_addr,
104
+ * qdev_assert_realized_properly() checks that we realized every
88
(uint8_t *)(&dscr->attr), 1);
105
+ * child object we initialized.
89
- dma_memory_read(&address_space_memory, entry_addr + 2,
106
+ */
90
+ dma_memory_read(s->dma_as, entry_addr + 2,
107
+ assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
91
(uint8_t *)(&dscr->length), 2);
92
dscr->length = le16_to_cpu(dscr->length);
93
- dma_memory_read(&address_space_memory, entry_addr + 4,
94
+ dma_memory_read(s->dma_as, entry_addr + 4,
95
(uint8_t *)(&dscr->addr), 8);
96
dscr->attr = le64_to_cpu(dscr->attr);
97
dscr->attr &= 0xfffffff8;
98
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
99
s->data_count = block_size;
100
length -= block_size - begin;
101
}
102
- dma_memory_write(&address_space_memory, dscr.addr,
103
+ dma_memory_write(s->dma_as, dscr.addr,
104
&s->fifo_buffer[begin],
105
s->data_count - begin);
106
dscr.addr += s->data_count - begin;
107
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
108
s->data_count = block_size;
109
length -= block_size - begin;
110
}
111
- dma_memory_read(&address_space_memory, dscr.addr,
112
+ dma_memory_read(s->dma_as, dscr.addr,
113
&s->fifo_buffer[begin],
114
s->data_count - begin);
115
dscr.addr += s->data_count - begin;
116
@@ -XXX,XX +XXX,XX @@ static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
117
dev->config[PCI_CLASS_PROG] = 0x01; /* Standard Host supported DMA */
118
dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
119
s->irq = pci_allocate_irq(dev);
120
- pci_register_bar(dev, 0, 0, &s->iomem);
121
+ s->dma_as = pci_get_address_space(dev);
122
+ pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->iomem);
123
}
108
}
124
109
125
static void sdhci_pci_exit(PCIDevice *dev)
110
/*
126
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
127
return;
112
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
128
}
113
}
129
114
130
+ s->dma_as = &address_space_memory;
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
+ }
131
+
119
+
132
sysbus_init_irq(sbd, &s->irq);
120
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
133
sysbus_init_mmio(sbd, &s->iomem);
121
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
134
}
122
}
135
--
123
--
136
2.7.4
124
2.25.1
137
138
diff view generated by jsdifflib
New patch
1
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
2
are in a range that applies to the internal combiner only creates a
3
splitter for those interrupts which go to both the internal combiner
4
and to the external GIC, but it does nothing at all for the
5
interrupts which don't go to the external GIC, leaving the
6
irq_table[] array element empty for those. (This will result in
7
those interrupts simply being lost, not in a QEMU crash.)
1
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.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
24
---
25
hw/arm/exynos4210.c | 2 ++
26
1 file changed, 2 insertions(+)
27
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/exynos4210.c
31
+++ b/hw/arm/exynos4210.c
32
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
34
qdev_connect_gpio_out(splitter, 1,
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
36
+ } else {
37
+ s->irq_table[n] = is->int_combiner_irq[n];
38
}
39
}
40
/*
41
--
42
2.25.1
diff view generated by jsdifflib
1
For PMSAv7, the v7A/R Arm ARM defines that setting AP to 0b111
1
Currently for the interrupts MCT_G0 and MCT_G1 which are
2
is an UNPREDICTABLE reserved combination. However, for v7M
2
the only ones in the input range of the external combiner
3
this value is documented as having the same behaviour as 0b110:
3
and which are also wired to the external GIC, we connect
4
read-only for both privileged and unprivileged. Accept this
4
them only to the internal combiner and the external GIC.
5
value on an M profile core rather than treating it as a guest
5
This seems likely to be a bug, as all other interrupts
6
error and a no-access page.
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.)
7
10
8
Reported-by: Andy Gross <andy.gross@linaro.org>
11
Wire these interrupts up to both combiners, like the rest.
12
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 1512742402-31669-1-git-send-email-peter.maydell@linaro.org
15
Message-id: 20220404154658.565020-15-peter.maydell@linaro.org
12
---
16
---
13
target/arm/helper.c | 14 ++++++++++++++
17
hw/arm/exynos4210.c | 7 +++----
14
1 file changed, 14 insertions(+)
18
1 file changed, 3 insertions(+), 4 deletions(-)
15
19
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
22
--- a/hw/arm/exynos4210.c
19
+++ b/target/arm/helper.c
23
+++ b/hw/arm/exynos4210.c
20
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
21
case 6:
25
22
*prot |= PAGE_READ | PAGE_EXEC;
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
23
break;
27
splitter = DEVICE(&s->splitter[splitcount]);
24
+ case 7:
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
25
+ /* for v7M, same as 6; for R profile a reserved value */
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
26
+ if (arm_feature(env, ARM_FEATURE_M)) {
30
qdev_realize(splitter, NULL, &error_abort);
27
+ *prot |= PAGE_READ | PAGE_EXEC;
31
splitcount++;
28
+ break;
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
29
+ }
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
30
+ /* fall through */
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
31
default:
35
if (irq_id) {
32
qemu_log_mask(LOG_GUEST_ERROR,
36
- qdev_connect_gpio_out(splitter, 1,
33
"DRACR[%d]: Bad value for AP bits: 0x%"
37
+ qdev_connect_gpio_out(splitter, 2,
34
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
35
case 6:
39
- } else {
36
*prot |= PAGE_READ | PAGE_EXEC;
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
37
break;
41
}
38
+ case 7:
42
}
39
+ /* for v7M, same as 6; for R profile a reserved value */
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
40
+ if (arm_feature(env, ARM_FEATURE_M)) {
41
+ *prot |= PAGE_READ | PAGE_EXEC;
42
+ break;
43
+ }
44
+ /* fall through */
45
default:
46
qemu_log_mask(LOG_GUEST_ERROR,
47
"DRACR[%d]: Bad value for AP bits: 0x%"
48
--
44
--
49
2.7.4
45
2.25.1
50
51
diff view generated by jsdifflib
1
The Configurable Fault Status Register for ARMv7M and v8M is
1
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
2
supposed to be byte and halfword accessible, but we were only
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
3
implementing word accesses. Add support for the other access
3
connect multiple IRQs up to the same external GIC input, which
4
sizes, which are used by the Zephyr RTOS.
4
is not permitted. We do the same thing in the code in
5
exynos4210_init_board_irqs() because the conditionals selecting
6
an irq_id in the first loop match multiple interrupt IDs.
7
8
Overall we do this for interrupt IDs
9
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
10
and
11
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
12
13
These correspond to the cases for the multi-core timer that we are
14
wiring up to multiple inputs on the combiner in
15
exynos4210_combiner_get_gpioin(). That code already deals with all
16
these interrupt IDs being the same input source, so we don't need to
17
connect the external GIC interrupt for any of them except the first
18
(1, 4) and (1, 5). Remove the array entries and conditionals which
19
were incorrectly causing us to wire up extra lines.
20
21
This bug didn't cause any visible effects, because we only connect
22
up a device to the "primary" ID values (1, 4) and (1, 5), so the
23
extra lines would never be set to a level.
5
24
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reported-by: Andy Gross <andy.gross@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
27
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
9
Message-id: 1512742372-31517-1-git-send-email-peter.maydell@linaro.org
10
---
28
---
11
hw/intc/armv7m_nvic.c | 38 ++++++++++++++++++++++----------------
29
include/hw/arm/exynos4210.h | 2 +-
12
1 file changed, 22 insertions(+), 16 deletions(-)
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 uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
37
@@ -XXX,XX +XXX,XX @@
19
val |= (1 << 8);
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;
20
}
82
}
21
return val;
83
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
22
- case 0xd28: /* Configurable Fault Status. */
84
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
23
- /* The BFSR bits [15:8] are shared between security states
85
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
24
- * and we store them in the NS copy
86
/* MCT_G1 is passed to External and GIC */
25
- */
87
irq_id = EXT_GIC_ID_MCT_G1;
26
- val = cpu->env.v7m.cfsr[attrs.secure];
27
- val |= cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
28
- return val;
29
case 0xd2c: /* Hard Fault Status. */
30
return cpu->env.v7m.hfsr;
31
case 0xd30: /* Debug Fault Status. */
32
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
33
s->vectors[ARMV7M_EXCP_DEBUG].active = (value & (1 << 8)) != 0;
34
nvic_irq_update(s);
35
break;
36
- case 0xd28: /* Configurable Fault Status. */
37
- cpu->env.v7m.cfsr[attrs.secure] &= ~value; /* W1C */
38
- if (attrs.secure) {
39
- /* The BFSR bits [15:8] are shared between security states
40
- * and we store them in the NS copy.
41
- */
42
- cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
43
- }
44
- break;
45
case 0xd2c: /* Hard Fault Status. */
46
cpu->env.v7m.hfsr &= ~value; /* W1C */
47
break;
48
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
49
val = deposit32(val, i * 8, 8, get_prio(s, hdlidx, sbank));
50
}
88
}
51
break;
52
+ case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
53
+ /* The BFSR bits [15:8] are shared between security states
54
+ * and we store them in the NS copy
55
+ */
56
+ val = s->cpu->env.v7m.cfsr[attrs.secure];
57
+ val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
58
+ val = extract32(val, (offset - 0xd28) * 8, size * 8);
59
+ break;
60
case 0xfe0 ... 0xfff: /* ID. */
61
if (offset & 3) {
62
val = 0;
63
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
64
}
65
nvic_irq_update(s);
66
return MEMTX_OK;
67
+ case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
68
+ /* All bits are W1C, so construct 32 bit value with 0s in
69
+ * the parts not written by the access size
70
+ */
71
+ value <<= ((offset - 0xd28) * 8);
72
+
73
+ s->cpu->env.v7m.cfsr[attrs.secure] &= ~value;
74
+ if (attrs.secure) {
75
+ /* The BFSR bits [15:8] are shared between security states
76
+ * and we store them in the NS copy.
77
+ */
78
+ s->cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
79
+ }
80
+ return MEMTX_OK;
81
}
82
if (size == 4) {
83
nvic_writel(s, offset, value, attrs);
84
--
89
--
85
2.7.4
90
2.25.1
86
87
diff view generated by jsdifflib
1
Instead of ignoring the response from address_space_ld*()
1
At this point, the function exynos4210_init_board_irqs() splits input
2
(indicating an attempt to read a page table descriptor from
2
IRQ lines to connect them to the input combiner, output combiner and
3
an invalid physical address), use it to report the failure
3
external GIC. The function exynos4210_combiner_get_gpioin() splits
4
correctly.
4
some of the combiner input lines further to connect them to multiple
5
5
different inputs on the combiner.
6
Since this is another couple of locations where we need to
6
7
decide the value of the ARMMMUFaultInfo ea bit based on a
7
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
8
MemTxResult, we factor out that operation into a helper
8
configurable number of outputs, we can do all this in one place, by
9
function.
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.
10
38
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
41
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
12
---
42
---
13
target/arm/internals.h | 10 ++++++++++
43
include/hw/arm/exynos4210.h | 6 +-
14
target/arm/helper.c | 39 ++++++++++++++++++++++++++++++++++-----
44
hw/arm/exynos4210.c | 178 +++++++++++++++++++++++-------------
15
target/arm/op_helper.c | 7 +------
45
2 files changed, 119 insertions(+), 65 deletions(-)
16
3 files changed, 45 insertions(+), 11 deletions(-)
46
17
47
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/internals.h
49
--- a/include/hw/arm/exynos4210.h
21
+++ b/target/arm/internals.h
50
+++ b/include/hw/arm/exynos4210.h
22
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
51
@@ -XXX,XX +XXX,XX @@
23
return fsc;
52
24
}
53
/*
25
54
* We need one splitter for every external combiner input, plus
26
+static inline bool arm_extabort_type(MemTxResult result)
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)
27
+{
113
+{
28
+ /* The EA bit in syndromes and fault status registers is an
114
+ /*
29
+ * IMPDEF classification of external aborts. ARM implementations
115
+ * If the interrupt number passed in is the first entry in some
30
+ * usually use this to indicate AXI bus Decode error (0) or
116
+ * line of the combinermap, return a pointer to that line;
31
+ * Slave error (1); in QEMU we follow that.
117
+ * otherwise return NULL.
32
+ */
118
+ */
33
+ return result != MEMTX_DECODE_ERROR;
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;
34
+}
126
+}
35
+
127
+
36
/* Do a page table walk and add page to TLB if possible */
128
+static int mapline_size(const int *mapline)
37
bool arm_tlb_fill(CPUState *cpu, vaddr address,
129
+{
38
MMUAccessType access_type, int mmu_idx,
130
+ /* Return number of entries in this mapline in total */
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
131
+ int i = 0;
40
index XXXXXXX..XXXXXXX 100644
132
+
41
--- a/target/arm/helper.c
133
+ if (!mapline) {
42
+++ b/target/arm/helper.c
134
+ /* Not in the map? IRQ goes to exactly one combiner input */
43
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
135
+ return 1;
44
ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
136
+ }
45
&txattrs, &s2prot, &s2size, fi, NULL);
137
+ while (*mapline != IRQNONE) {
46
if (ret) {
138
+ mapline++;
47
+ assert(fi->type != ARMFault_None);
139
+ i++;
48
fi->s2addr = addr;
140
+ }
49
fi->stage2 = true;
141
+ return i;
50
fi->s1ptw = true;
142
+}
51
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
143
+
52
ARMCPU *cpu = ARM_CPU(cs);
144
/*
53
CPUARMState *env = &cpu->env;
145
* Initialize board IRQs.
54
MemTxAttrs attrs = {};
146
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
55
+ MemTxResult result = MEMTX_OK;
147
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
56
AddressSpace *as;
148
DeviceState *extgicdev = DEVICE(&s->ext_gic);
57
+ uint32_t data;
149
int splitcount = 0;
58
150
DeviceState *splitter;
59
attrs.secure = is_secure;
151
+ const int *mapline;
60
as = arm_addressspace(cs, attrs);
152
+ int numlines, splitin, in;
61
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
153
62
return 0;
154
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
155
irq_id = 0;
156
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
157
irq_id = EXT_GIC_ID_MCT_G1;
158
}
159
160
+ if (s->irq_table[n]) {
161
+ /*
162
+ * This must be some non-first entry in a combinermap line,
163
+ * and we've already filled it in.
164
+ */
165
+ continue;
166
+ }
167
+ mapline = combinermap_entry(n);
168
+ /*
169
+ * We need to connect the IRQ to multiple inputs on both combiners
170
+ * and possibly also to the external GIC.
171
+ */
172
+ numlines = 2 * mapline_size(mapline);
173
+ if (irq_id) {
174
+ numlines++;
175
+ }
176
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
177
splitter = DEVICE(&s->splitter[splitcount]);
178
- qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
179
+ qdev_prop_set_uint16(splitter, "num-lines", numlines);
180
qdev_realize(splitter, NULL, &error_abort);
181
splitcount++;
182
- s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
183
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
184
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
185
+
186
+ in = n;
187
+ splitin = 0;
188
+ for (;;) {
189
+ s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
190
+ qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
191
+ qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
192
+ splitin += 2;
193
+ if (!mapline) {
194
+ break;
195
+ }
196
+ mapline++;
197
+ in = *mapline;
198
+ if (in == IRQNONE) {
199
+ break;
200
+ }
201
+ }
202
if (irq_id) {
203
- qdev_connect_gpio_out(splitter, 2,
204
+ qdev_connect_gpio_out(splitter, splitin,
205
qdev_get_gpio_in(extgicdev, irq_id - 32));
206
}
63
}
207
}
64
if (regime_translation_big_endian(env, mmu_idx)) {
208
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
65
- return address_space_ldl_be(as, addr, attrs, NULL);
209
irq_id = combiner_grp_to_gic_id[grp -
66
+ data = address_space_ldl_be(as, addr, attrs, &result);
210
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
67
} else {
211
68
- return address_space_ldl_le(as, addr, attrs, NULL);
212
+ if (s->irq_table[n]) {
69
+ data = address_space_ldl_le(as, addr, attrs, &result);
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);
70
}
294
}
71
+ if (result == MEMTX_OK) {
72
+ return data;
73
+ }
74
+ fi->type = ARMFault_SyncExternalOnWalk;
75
+ fi->ea = arm_extabort_type(result);
76
+ return 0;
77
}
78
79
static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
80
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
81
ARMCPU *cpu = ARM_CPU(cs);
82
CPUARMState *env = &cpu->env;
83
MemTxAttrs attrs = {};
84
+ MemTxResult result = MEMTX_OK;
85
AddressSpace *as;
86
+ uint32_t data;
87
88
attrs.secure = is_secure;
89
as = arm_addressspace(cs, attrs);
90
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
91
return 0;
92
}
93
if (regime_translation_big_endian(env, mmu_idx)) {
94
- return address_space_ldq_be(as, addr, attrs, NULL);
95
+ data = address_space_ldq_be(as, addr, attrs, &result);
96
} else {
97
- return address_space_ldq_le(as, addr, attrs, NULL);
98
+ data = address_space_ldq_le(as, addr, attrs, &result);
99
+ }
100
+ if (result == MEMTX_OK) {
101
+ return data;
102
}
103
+ fi->type = ARMFault_SyncExternalOnWalk;
104
+ fi->ea = arm_extabort_type(result);
105
+ return 0;
106
}
107
108
static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
109
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
110
}
111
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
112
mmu_idx, fi);
113
+ if (fi->type != ARMFault_None) {
114
+ goto do_fault;
115
+ }
116
type = (desc & 3);
117
domain = (desc >> 5) & 0x0f;
118
if (regime_el(env, mmu_idx) == 1) {
119
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
120
}
121
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
122
mmu_idx, fi);
123
+ if (fi->type != ARMFault_None) {
124
+ goto do_fault;
125
+ }
126
switch (desc & 3) {
127
case 0: /* Page translation fault. */
128
fi->type = ARMFault_Translation;
129
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
130
}
131
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
132
mmu_idx, fi);
133
+ if (fi->type != ARMFault_None) {
134
+ goto do_fault;
135
+ }
136
type = (desc & 3);
137
if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) {
138
/* Section translation fault, or attempt to use the encoding
139
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
140
table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
141
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
142
mmu_idx, fi);
143
+ if (fi->type != ARMFault_None) {
144
+ goto do_fault;
145
+ }
146
ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
147
switch (desc & 3) {
148
case 0: /* Page translation fault. */
149
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
150
descaddr &= ~7ULL;
151
nstable = extract32(tableattrs, 4, 1);
152
descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fi);
153
- if (fi->s1ptw) {
154
+ if (fi->type != ARMFault_None) {
155
goto do_fault;
156
}
157
158
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/op_helper.c
161
+++ b/target/arm/op_helper.c
162
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
163
/* now we have a real cpu fault */
164
cpu_restore_state(cs, retaddr);
165
166
- /* The EA bit in syndromes and fault status registers is an
167
- * IMPDEF classification of external aborts. ARM implementations
168
- * usually use this to indicate AXI bus Decode error (0) or
169
- * Slave error (1); in QEMU we follow that.
170
- */
171
- fi.ea = (response != MEMTX_DECODE_ERROR);
172
+ fi.ea = arm_extabort_type(response);
173
fi.type = ARMFault_SyncExternal;
174
deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
175
}
295
}
176
--
296
--
177
2.7.4
297
2.25.1
178
179
diff view generated by jsdifflib
1
Since pl181 is still using the legacy SD card API, the SD
1
Switch the creation of the combiner devices to the new-style
2
card created by sd_init() is not plugged into any bus. This
2
"embedded in state struct" approach, so we can easily refer
3
means that the controller has to reset it manually.
3
to the object elsewhere during realize.
4
4
5
Failing to do this mostly didn't affect the guest since the
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
guest typically does a programmed SD card reset as part of
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
its SD controller driver initialization, but meant that
7
Message-id: 20220404154658.565020-18-peter.maydell@linaro.org
8
migration failed because it's only in sd_reset() that we
8
---
9
set up the wpgrps_size field.
9
include/hw/arm/exynos4210.h | 3 ++
10
include/hw/intc/exynos4210_combiner.h | 57 +++++++++++++++++++++++++++
11
hw/arm/exynos4210.c | 20 +++++-----
12
hw/intc/exynos4210_combiner.c | 31 +--------------
13
4 files changed, 72 insertions(+), 39 deletions(-)
14
create mode 100644 include/hw/intc/exynos4210_combiner.h
10
15
11
Cc: qemu-stable@nongnu.org
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
Fixes: https://bugs.launchpad.net/qemu/+bug/1739378
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 1515506513-31961-2-git-send-email-peter.maydell@linaro.org
17
---
18
hw/sd/pl181.c | 4 ++++
19
1 file changed, 4 insertions(+)
20
21
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/sd/pl181.c
18
--- a/include/hw/arm/exynos4210.h
24
+++ b/hw/sd/pl181.c
19
+++ b/include/hw/arm/exynos4210.h
25
@@ -XXX,XX +XXX,XX @@ static void pl181_reset(DeviceState *d)
20
@@ -XXX,XX +XXX,XX @@
26
21
#include "hw/sysbus.h"
27
/* We can assume our GPIO outputs have been wired up now */
22
#include "hw/cpu/a9mpcore.h"
28
sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1]);
23
#include "hw/intc/exynos4210_gic.h"
29
+ /* Since we're still using the legacy SD API the card is not plugged
24
+#include "hw/intc/exynos4210_combiner.h"
30
+ * into any bus, and we must reset it manually.
25
#include "hw/core/split-irq.h"
31
+ */
26
#include "target/arm/cpu-qom.h"
32
+ device_reset(DEVICE(s->card));
27
#include "qom/object.h"
28
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
29
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
30
A9MPPrivState a9mpcore;
31
Exynos4210GicState ext_gic;
32
+ Exynos4210CombinerState int_combiner;
33
+ Exynos4210CombinerState ext_combiner;
34
SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
35
};
36
37
diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_combiner.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Samsung exynos4210 Interrupt Combiner
45
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
59
+ * See the GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+
65
+#ifndef HW_INTC_EXYNOS4210_COMBINER
66
+#define HW_INTC_EXYNOS4210_COMBINER
67
+
68
+#include "hw/sysbus.h"
69
+
70
+/*
71
+ * State for each output signal of internal combiner
72
+ */
73
+typedef struct CombinerGroupState {
74
+ uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
75
+ uint8_t src_pending; /* Pending source interrupts before masking */
76
+} CombinerGroupState;
77
+
78
+#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
79
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
80
+
81
+/* Number of groups and total number of interrupts for the internal combiner */
82
+#define IIC_NGRP 64
83
+#define IIC_NIRQ (IIC_NGRP * 8)
84
+#define IIC_REGSET_SIZE 0x41
85
+
86
+struct Exynos4210CombinerState {
87
+ SysBusDevice parent_obj;
88
+
89
+ MemoryRegion iomem;
90
+
91
+ struct CombinerGroupState group[IIC_NGRP];
92
+ uint32_t reg_set[IIC_REGSET_SIZE];
93
+ uint32_t icipsr[2];
94
+ uint32_t external; /* 1 means that this combiner is external */
95
+
96
+ qemu_irq output_irq[IIC_NGRP];
97
+};
98
+
99
+#endif
100
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/arm/exynos4210.c
103
+++ b/hw/arm/exynos4210.c
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
}
106
107
/* Internal Interrupt Combiner */
108
- dev = qdev_new("exynos4210.combiner");
109
- busdev = SYS_BUS_DEVICE(dev);
110
- sysbus_realize_and_unref(busdev, &error_fatal);
111
+ busdev = SYS_BUS_DEVICE(&s->int_combiner);
112
+ sysbus_realize(busdev, &error_fatal);
113
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
114
sysbus_connect_irq(busdev, n,
115
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
116
}
117
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
118
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
119
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
120
121
/* External Interrupt Combiner */
122
- dev = qdev_new("exynos4210.combiner");
123
- qdev_prop_set_uint32(dev, "external", 1);
124
- busdev = SYS_BUS_DEVICE(dev);
125
- sysbus_realize_and_unref(busdev, &error_fatal);
126
+ qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
127
+ busdev = SYS_BUS_DEVICE(&s->ext_combiner);
128
+ sysbus_realize(busdev, &error_fatal);
129
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
130
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
131
}
132
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
133
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
134
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
135
136
/* Initialize board IRQs. */
137
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
138
139
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
140
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
141
+ object_initialize_child(obj, "int-combiner", &s->int_combiner,
142
+ TYPE_EXYNOS4210_COMBINER);
143
+ object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
144
+ TYPE_EXYNOS4210_COMBINER);
33
}
145
}
34
146
35
static void pl181_init(Object *obj)
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",
36
--
198
--
37
2.7.4
199
2.25.1
38
39
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The only time we use the int_combiner_irq[] and ext_combiner_irq[]
2
arrays in the Exynos4210Irq struct is during realize of the SoC -- we
3
initialize them with the input IRQs of the combiner devices, and then
4
connect those to outputs of other devices in
5
exynos4210_init_board_irqs(). Now that the combiner objects are
6
easily accessible as s->int_combiner and s->ext_combiner we can make
7
the connections directly from one device to the other without going
8
via these arrays.
2
9
3
Add common/sysbus/pci/sdbus comments to have clearer code blocks separation.
10
Since these are the only two remaining elements of Exynos4210Irq,
11
we can remove that struct entirely.
4
12
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20180115182436.2066-4-f4bug@amsat.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
9
---
16
---
10
include/hw/sd/sdhci.h | 4 +++-
17
include/hw/arm/exynos4210.h | 6 ------
11
hw/sd/sdhci.c | 25 +++++++++++++++++--------
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
12
2 files changed, 20 insertions(+), 9 deletions(-)
19
2 files changed, 8 insertions(+), 32 deletions(-)
13
20
14
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/sd/sdhci.h
23
--- a/include/hw/arm/exynos4210.h
17
+++ b/include/hw/sd/sdhci.h
24
+++ b/include/hw/arm/exynos4210.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
19
uint32_t buf_maxsz;
20
uint16_t data_count; /* current element in FIFO buffer */
21
uint8_t stopped_state;/* Current SDHC state */
22
- bool pending_insert_quirk;/* Quirk for Raspberry Pi card insert int */
23
bool pending_insert_state;
24
/* Buffer Data Port Register - virtual access point to R and W buffers */
25
/* Software Reset Register - always reads as 0 */
26
/* Force Event Auto CMD12 Error Interrupt Reg - write only */
27
/* Force Event Error Interrupt Register- write only */
28
/* RO Host Controller Version Register always reads as 0x2401 */
29
+
30
+ /* Configurable properties */
31
+ bool pending_insert_quirk; /* Quirk for Raspberry Pi card insert int */
32
} SDHCIState;
33
34
#define TYPE_PCI_SDHCI "sdhci-pci"
35
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/sd/sdhci.c
38
+++ b/hw/sd/sdhci.c
39
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
40
*/
26
*/
41
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
42
#include "qemu/osdep.h"
28
43
+#include "qapi/error.h"
29
-typedef struct Exynos4210Irq {
44
#include "hw/hw.h"
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
45
#include "sysemu/block-backend.h"
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
46
#include "sysemu/blockdev.h"
32
-} Exynos4210Irq;
47
@@ -XXX,XX +XXX,XX @@ static inline unsigned int sdhci_get_fifolen(SDHCIState *s)
33
-
34
struct Exynos4210State {
35
/*< private >*/
36
SysBusDevice parent_obj;
37
/*< public >*/
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
39
- Exynos4210Irq irqs;
40
qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
41
42
MemoryRegion chipid_mem;
43
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/arm/exynos4210.c
46
+++ b/hw/arm/exynos4210.c
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
48
static void exynos4210_init_board_irqs(Exynos4210State *s)
49
{
50
uint32_t grp, bit, irq_id, n;
51
- Exynos4210Irq *is = &s->irqs;
52
DeviceState *extgicdev = DEVICE(&s->ext_gic);
53
+ DeviceState *intcdev = DEVICE(&s->int_combiner);
54
+ DeviceState *extcdev = DEVICE(&s->ext_combiner);
55
int splitcount = 0;
56
DeviceState *splitter;
57
const int *mapline;
58
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
59
splitin = 0;
60
for (;;) {
61
s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
62
- qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
63
- qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
64
+ qdev_connect_gpio_out(splitter, splitin,
65
+ qdev_get_gpio_in(intcdev, in));
66
+ qdev_connect_gpio_out(splitter, splitin + 1,
67
+ qdev_get_gpio_in(extcdev, in));
68
splitin += 2;
69
if (!mapline) {
70
break;
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
72
qdev_realize(splitter, NULL, &error_abort);
73
splitcount++;
74
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
75
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
76
+ qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
77
qdev_connect_gpio_out(splitter, 1,
78
qdev_get_gpio_in(extgicdev, irq_id - 32));
79
} else {
80
- s->irq_table[n] = is->int_combiner_irq[n];
81
+ s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
82
}
48
}
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);
49
}
87
}
50
88
51
+/* --- qdev common --- */
89
-/*
52
+
90
- * Get Combiner input GPIO into irqs structure
53
+#define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \
91
- */
54
+ /* Capabilities registers provide information on supported features
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
55
+ * of this specific host controller implementation */ \
93
- DeviceState *dev, int ext)
56
+ DEFINE_PROP_UINT32("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \
94
-{
57
+ DEFINE_PROP_UINT32("maxcurr", _state, maxcurr, 0)
95
- int n;
58
+
96
- int max;
59
static void sdhci_initfn(SDHCIState *s)
97
- qemu_irq *irq;
60
{
98
-
61
qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
62
@@ -XXX,XX +XXX,XX @@ const VMStateDescription sdhci_vmstate = {
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
63
},
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
64
};
102
-
65
103
- for (n = 0; n < max; n++) {
66
-/* Capabilities registers provide information on supported features of this
104
- irq[n] = qdev_get_gpio_in(dev, n);
67
- * specific host controller implementation */
105
- }
68
+/* --- qdev PCI --- */
106
-}
69
+
107
-
70
static Property sdhci_pci_properties[] = {
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
71
- DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
109
0x09, 0x00, 0x00, 0x00 };
72
- SDHC_CAPAB_REG_DEFAULT),
110
73
- DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
74
+ DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState),
112
sysbus_connect_irq(busdev, n,
75
DEFINE_PROP_END_OF_LIST(),
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
76
};
114
}
77
115
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
78
@@ -XXX,XX +XXX,XX @@ static const TypeInfo sdhci_pci_info = {
116
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
79
},
117
80
};
118
/* External Interrupt Combiner */
81
119
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
82
+/* --- qdev SysBus --- */
120
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
83
+
121
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
84
static Property sdhci_sysbus_properties[] = {
122
}
85
- DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
123
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
86
- SDHC_CAPAB_REG_DEFAULT),
124
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
87
- DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
125
88
+ DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState),
126
/* Initialize board IRQs. */
89
DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk,
90
false),
91
DEFINE_PROP_END_OF_LIST(),
92
@@ -XXX,XX +XXX,XX @@ static const TypeInfo sdhci_sysbus_info = {
93
.class_init = sdhci_sysbus_class_init,
94
};
95
96
+/* --- qdev bus master --- */
97
+
98
static void sdhci_bus_class_init(ObjectClass *klass, void *data)
99
{
100
SDBusClass *sbc = SD_BUS_CLASS(klass);
101
--
127
--
102
2.7.4
128
2.25.1
103
104
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
Now both inherited classes appear as DEVICE_CATEGORY_STORAGE.
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
6
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
7
Message-id: 20180115182436.2066-5-f4bug@amsat.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
7
---
10
hw/sd/sdhci.c | 18 +++++++++++++-----
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
11
1 file changed, 13 insertions(+), 5 deletions(-)
9
1 file changed, 24 insertions(+), 9 deletions(-)
12
10
13
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/sd/sdhci.c
13
--- a/hw/arm/realview.c
16
+++ b/hw/sd/sdhci.c
14
+++ b/hw/arm/realview.c
17
@@ -XXX,XX +XXX,XX @@ const VMStateDescription sdhci_vmstate = {
15
@@ -XXX,XX +XXX,XX @@
18
},
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
19
};
29
};
20
30
21
+static void sdhci_common_class_init(ObjectClass *klass, void *data)
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
22
+{
32
+ qemu_irq out1, qemu_irq out2) {
23
+ DeviceClass *dc = DEVICE_CLASS(klass);
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
24
+
34
+
25
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
26
+ dc->vmsd = &sdhci_vmstate;
36
+
27
+ dc->reset = sdhci_poweron_reset;
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
38
+
39
+ qdev_connect_gpio_out(splitter, 0, out1);
40
+ qdev_connect_gpio_out(splitter, 1, out2);
41
+ qdev_connect_gpio_out_named(src, outname, 0,
42
+ qdev_get_gpio_in(splitter, 0));
28
+}
43
+}
29
+
44
+
30
/* --- qdev PCI --- */
45
static void realview_init(MachineState *machine,
31
46
enum realview_board_type board_type)
32
static Property sdhci_pci_properties[] = {
47
{
33
@@ -XXX,XX +XXX,XX @@ static void sdhci_pci_class_init(ObjectClass *klass, void *data)
48
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
34
k->vendor_id = PCI_VENDOR_ID_REDHAT;
49
DeviceState *dev, *sysctl, *gpio2, *pl041;
35
k->device_id = PCI_DEVICE_ID_REDHAT_SDHCI;
50
SysBusDevice *busdev;
36
k->class_id = PCI_CLASS_SYSTEM_SDHCI;
51
qemu_irq pic[64];
37
- set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
52
- qemu_irq mmc_irq[2];
38
- dc->vmsd = &sdhci_vmstate;
53
PCIBus *pci_bus = NULL;
39
dc->props = sdhci_pci_properties;
54
NICInfo *nd;
40
- dc->reset = sdhci_poweron_reset;
55
DriveInfo *dinfo;
56
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
57
* and the PL061 has them the other way about. Also the card
58
* detect line is inverted.
59
*/
60
- mmc_irq[0] = qemu_irq_split(
61
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
62
- qdev_get_gpio_in(gpio2, 1));
63
- mmc_irq[1] = qemu_irq_split(
64
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
65
- qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
66
- qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
67
- qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_irq[1]);
68
+ split_irq_from_named(dev, "card-read-only",
69
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
70
+ qdev_get_gpio_in(gpio2, 1));
41
+
71
+
42
+ sdhci_common_class_init(klass, data);
72
+ split_irq_from_named(dev, "card-inserted",
43
}
73
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
44
74
+ qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
45
static const TypeInfo sdhci_pci_info = {
46
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
47
{
48
DeviceClass *dc = DEVICE_CLASS(klass);
49
50
- dc->vmsd = &sdhci_vmstate;
51
dc->props = sdhci_sysbus_properties;
52
dc->realize = sdhci_sysbus_realize;
53
- dc->reset = sdhci_poweron_reset;
54
+
75
+
55
+ sdhci_common_class_init(klass, data);
76
dinfo = drive_get(IF_SD, 0, 0);
56
}
77
if (dinfo) {
57
78
DeviceState *card;
58
static const TypeInfo sdhci_sysbus_info = {
59
--
79
--
60
2.7.4
80
2.25.1
61
62
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180115182436.2066-11-f4bug@amsat.org
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
hw/sd/sdhci-internal.h | 2 +-
8
hw/arm/stellaris.c | 15 +++++++++++++--
9
hw/sd/sdhci.c | 2 +-
9
1 file changed, 13 insertions(+), 2 deletions(-)
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
10
12
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sdhci-internal.h
13
--- a/hw/arm/stellaris.c
15
+++ b/hw/sd/sdhci-internal.h
14
+++ b/hw/arm/stellaris.c
16
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@
17
#define SDHC_ACMD12ERRSTS 0x3C
16
18
17
#include "qemu/osdep.h"
19
/* HWInit Capabilities Register 0x05E80080 */
18
#include "qapi/error.h"
20
-#define SDHC_CAPAREG 0x40
19
+#include "hw/core/split-irq.h"
21
+#define SDHC_CAPAB 0x40
20
#include "hw/sysbus.h"
22
#define SDHC_CAN_DO_DMA 0x00400000
21
#include "hw/sd/sd.h"
23
#define SDHC_CAN_DO_ADMA2 0x00080000
22
#include "hw/ssi/ssi.h"
24
#define SDHC_CAN_DO_ADMA1 0x00100000
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
25
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
24
DeviceState *ssddev;
26
index XXXXXXX..XXXXXXX 100644
25
DriveInfo *dinfo;
27
--- a/hw/sd/sdhci.c
26
DeviceState *carddev;
28
+++ b/hw/sd/sdhci.c
27
+ DeviceState *gpio_d_splitter;
29
@@ -XXX,XX +XXX,XX @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
28
BlockBackend *blk;
30
case SDHC_ACMD12ERRSTS:
29
31
ret = s->acmd12errsts;
30
/*
32
break;
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
33
- case SDHC_CAPAREG:
32
&error_fatal);
34
+ case SDHC_CAPAB:
33
35
ret = s->capareg;
34
ssddev = ssi_create_peripheral(bus, "ssd0323");
36
break;
35
- gpio_out[GPIO_D][0] = qemu_irq_split(
37
case SDHC_MAXCURR:
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. */
38
--
52
--
39
2.7.4
53
2.25.1
40
41
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180115182436.2066-10-f4bug@amsat.org
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
---
8
hw/sd/sdhci-internal.h | 1 +
9
include/hw/irq.h | 5 -----
9
hw/sd/sdhci.c | 3 +--
10
hw/core/irq.c | 15 ---------------
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
2 files changed, 20 deletions(-)
11
12
12
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sdhci-internal.h
15
--- a/include/hw/irq.h
15
+++ b/hw/sd/sdhci-internal.h
16
+++ b/include/hw/irq.h
16
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
17
#define SDHC_TRNS_ACMD12 0x0004
18
/* Returns a new IRQ with opposite polarity. */
18
#define SDHC_TRNS_READ 0x0010
19
qemu_irq qemu_irq_invert(qemu_irq irq);
19
#define SDHC_TRNS_MULTI 0x0020
20
20
+#define SDHC_TRNMOD_MASK 0x0037
21
-/* Returns a new IRQ which feeds into both the passed IRQs.
21
22
- * It's probably better to use the TYPE_SPLIT_IRQ device instead.
22
/* R/W Command Register 0x0 */
23
- */
23
#define SDHC_CMDREG 0x0E
24
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
24
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
25
-
26
/* For internal use in qtest. Similar to qemu_irq_split, but operating
27
on an existing vector of qemu_irq. */
28
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
29
diff --git a/hw/core/irq.c b/hw/core/irq.c
25
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/sd/sdhci.c
31
--- a/hw/core/irq.c
27
+++ b/hw/sd/sdhci.c
32
+++ b/hw/core/irq.c
28
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_invert(qemu_irq irq)
29
(SDHC_CAPAB_BASECLKFREQ << 8) | (SDHC_CAPAB_TOUNIT << 7) | \
34
return qemu_allocate_irq(qemu_notirq, irq, 0);
30
(SDHC_CAPAB_TOCLKFREQ))
35
}
31
36
32
-#define MASK_TRNMOD 0x0037
37
-static void qemu_splitirq(void *opaque, int line, int level)
33
#define MASKED_WRITE(reg, mask, val) (reg = (reg & (mask)) | (val))
38
-{
34
39
- struct IRQState **irq = opaque;
35
static uint8_t sdhci_slotint(SDHCIState *s)
40
- irq[0]->handler(irq[0]->opaque, irq[0]->n, level);
36
@@ -XXX,XX +XXX,XX @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
41
- irq[1]->handler(irq[1]->opaque, irq[1]->n, level);
37
if (!(s->capareg & SDHC_CAN_DO_DMA)) {
42
-}
38
value &= ~SDHC_TRNS_DMA;
43
-
39
}
44
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
40
- MASKED_WRITE(s->trnmod, mask, value & MASK_TRNMOD);
45
-{
41
+ MASKED_WRITE(s->trnmod, mask, value & SDHC_TRNMOD_MASK);
46
- qemu_irq *s = g_new0(qemu_irq, 2);
42
MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);
47
- s[0] = irq1;
43
48
- s[1] = irq2;
44
/* Writing to the upper byte of CMDREG triggers SD command generation */
49
- return qemu_allocate_irq(qemu_splitirq, s, 0);
50
-}
51
-
52
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
53
{
54
int i;
45
--
55
--
46
2.7.4
56
2.25.1
47
48
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Describe that the gic-version influences the maximum number of CPUs.
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
5
Message-id: 20180115182436.2066-3-f4bug@amsat.org
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
7
[PMM: minor punctuation tweaks]
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
include/hw/sd/sdhci.h | 2 --
11
docs/system/arm/virt.rst | 4 ++--
9
hw/sd/sdhci.c | 2 --
12
1 file changed, 2 insertions(+), 2 deletions(-)
10
2 files changed, 4 deletions(-)
11
13
12
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/sd/sdhci.h
16
--- a/docs/system/arm/virt.rst
15
+++ b/include/hw/sd/sdhci.h
17
+++ b/docs/system/arm/virt.rst
16
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
18
@@ -XXX,XX +XXX,XX @@ gic-version
17
19
Valid values are:
18
QEMUTimer *insert_timer; /* timer for 'changing' sd card. */
20
19
QEMUTimer *transfer_timer;
21
``2``
20
- qemu_irq eject_cb;
22
- GICv2
21
- qemu_irq ro_cb;
23
+ GICv2. Note that this limits the number of CPUs to 8.
22
qemu_irq irq;
24
``3``
23
25
- GICv3
24
/* Registers cleared on reset */
26
+ GICv3. This allows up to 512 CPUs.
25
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
27
``host``
26
index XXXXXXX..XXXXXXX 100644
28
Use the same GIC version the host provides, when using KVM
27
--- a/hw/sd/sdhci.c
29
``max``
28
+++ b/hw/sd/sdhci.c
29
@@ -XXX,XX +XXX,XX @@ static void sdhci_uninitfn(SDHCIState *s)
30
timer_free(s->insert_timer);
31
timer_del(s->transfer_timer);
32
timer_free(s->transfer_timer);
33
- qemu_free_irq(s->eject_cb);
34
- qemu_free_irq(s->ro_cb);
35
36
g_free(s->fifo_buffer);
37
s->fifo_buffer = NULL;
38
--
30
--
39
2.7.4
31
2.25.1
40
41
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
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.
5
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Message-id: 20220411165842.3912945-2-wuhaotsh@google.com
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180110063337.21538-3-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/translate-a64.c | 5 +++++
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
9
1 file changed, 5 insertions(+)
13
1 file changed, 30 insertions(+)
10
14
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
17
--- a/include/hw/misc/npcm7xx_gcr.h
14
+++ b/target/arm/translate-a64.c
18
+++ b/include/hw/misc/npcm7xx_gcr.h
15
@@ -XXX,XX +XXX,XX @@ static uint64_t vfp_expand_imm(int size, uint8_t imm8)
19
@@ -XXX,XX +XXX,XX @@
16
(extract32(imm8, 0, 6) << 3);
20
#include "exec/memory.h"
17
imm <<= 16;
21
#include "hw/sysbus.h"
18
break;
22
19
+ case MO_16:
23
+/*
20
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
24
+ * NPCM7XX PWRON STRAP bit fields
21
+ (extract32(imm8, 6, 1) ? 0x3000 : 0x4000) |
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
22
+ (extract32(imm8, 0, 6) << 6);
26
+ * 11: System flash attached to BMC
23
+ break;
27
+ * 10: BSP alternative pins.
24
default:
28
+ * 9:8: Flash UART command route enabled.
25
g_assert_not_reached();
29
+ * 7: Security enabled.
26
}
30
+ * 6: HI-Z state control.
31
+ * 5: ECC disabled.
32
+ * 4: Reserved
33
+ * 3: JTAG2 enabled.
34
+ * 2:0: CPU and DRAM clock frequency.
35
+ */
36
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
37
+#define NPCM7XX_PWRON_STRAP_SFAB BIT(11)
38
+#define NPCM7XX_PWRON_STRAP_BSPA BIT(10)
39
+#define NPCM7XX_PWRON_STRAP_FUP(x) ((x) << 8)
40
+#define FUP_NORM_UART2 3
41
+#define FUP_PROG_UART3 2
42
+#define FUP_PROG_UART2 1
43
+#define FUP_NORM_UART3 0
44
+#define NPCM7XX_PWRON_STRAP_SECEN BIT(7)
45
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
46
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
47
+#define NPCM7XX_PWRON_STRAP_RESERVE1 BIT(4)
48
+#define NPCM7XX_PWRON_STRAP_J2EN BIT(3)
49
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x) (x)
50
+#define CKFRQ_SKIPINIT 0x000
51
+#define CKFRQ_DEFAULT 0x111
52
+
53
/*
54
* Number of registers in our device state structure. Don't change this without
55
* incrementing the version_id in the vmstate.
27
--
56
--
28
2.7.4
57
2.25.1
29
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
This patch uses the defined fields to describe PWRON STRAPs for
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
better readability.
5
Message-id: 20180115182436.2066-2-f4bug@amsat.org
5
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Message-id: 20220411165842.3912945-3-wuhaotsh@google.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
hw/sd/sdhci-internal.h | 4 ----
12
hw/arm/npcm7xx_boards.c | 24 +++++++++++++++++++-----
9
include/hw/sd/sdhci.h | 7 ++++++-
13
1 file changed, 19 insertions(+), 5 deletions(-)
10
hw/sd/sdhci.c | 1 +
11
3 files changed, 7 insertions(+), 5 deletions(-)
12
14
13
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/sd/sdhci-internal.h
17
--- a/hw/arm/npcm7xx_boards.c
16
+++ b/hw/sd/sdhci-internal.h
18
+++ b/hw/arm/npcm7xx_boards.c
17
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
18
#ifndef SDHCI_INTERNAL_H
20
#include "sysemu/sysemu.h"
19
#define SDHCI_INTERNAL_H
21
#include "sysemu/block-backend.h"
20
22
21
-#include "hw/sd/sdhci.h"
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
22
-
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
23
/* R/W SDMA System Address register 0x0 */
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
24
#define SDHC_SYSAD 0x00
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
25
27
-#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
26
@@ -XXX,XX +XXX,XX @@ enum {
28
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT ( \
27
sdhc_gap_write = 2 /* SDHC stopped at block gap during write operation */
29
+ NPCM7XX_PWRON_STRAP_SPI0F18 | \
28
};
30
+ NPCM7XX_PWRON_STRAP_SFAB | \
29
31
+ NPCM7XX_PWRON_STRAP_BSPA | \
30
-extern const VMStateDescription sdhci_vmstate;
32
+ NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) | \
31
-
33
+ NPCM7XX_PWRON_STRAP_SECEN | \
32
#endif
34
+ NPCM7XX_PWRON_STRAP_HIZ | \
33
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
35
+ NPCM7XX_PWRON_STRAP_ECC | \
34
index XXXXXXX..XXXXXXX 100644
36
+ NPCM7XX_PWRON_STRAP_RESERVE1 | \
35
--- a/include/hw/sd/sdhci.h
37
+ NPCM7XX_PWRON_STRAP_J2EN | \
36
+++ b/include/hw/sd/sdhci.h
38
+ NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))
37
@@ -XXX,XX +XXX,XX @@
38
#define SDHCI_H
39
40
#include "qemu-common.h"
41
-#include "hw/block/block.h"
42
#include "hw/pci/pci.h"
43
#include "hw/sysbus.h"
44
#include "hw/sd/sd.h"
45
46
/* SD/MMC host controller state */
47
typedef struct SDHCIState {
48
+ /*< private >*/
49
union {
50
PCIDevice pcidev;
51
SysBusDevice busdev;
52
};
53
+
39
+
54
+ /*< public >*/
40
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
55
SDBus sdbus;
41
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_J2EN)
56
MemoryRegion iomem;
42
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
57
43
+#define QUANTA_GBS_POWER_ON_STRAPS ( \
58
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
44
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_SFAB)
59
qemu_irq ro_cb;
45
+#define KUDO_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
60
qemu_irq irq;
46
+#define MORI_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
61
47
62
+ /* Registers cleared on reset */
48
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
63
uint32_t sdmasysad; /* SDMA System Address register */
64
uint16_t blksize; /* Host DMA Buff Boundary and Transfer BlkSize Reg */
65
uint16_t blkcnt; /* Blocks count for current transfer */
66
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
67
uint16_t acmd12errsts; /* Auto CMD12 error status register */
68
uint64_t admasysaddr; /* ADMA System Address Register */
69
70
+ /* Read-only registers */
71
uint32_t capareg; /* Capabilities Register */
72
uint32_t maxcurr; /* Maximum Current Capabilities Register */
73
+
74
uint8_t *fifo_buffer; /* SD host i/o FIFO buffer */
75
uint32_t buf_maxsz;
76
uint16_t data_count; /* current element in FIFO buffer */
77
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/sd/sdhci.c
80
+++ b/hw/sd/sdhci.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "sysemu/dma.h"
83
#include "qemu/timer.h"
84
#include "qemu/bitops.h"
85
+#include "hw/sd/sdhci.h"
86
#include "sdhci-internal.h"
87
#include "qemu/log.h"
88
49
89
--
50
--
90
2.7.4
51
2.25.1
91
92
diff view generated by jsdifflib