1
First arm pullreq of 5.0!
1
First arm pullreq for 7.1. The bulk of this is the qemu_split_irq
2
removal.
2
3
3
The following changes since commit 084a398bf8aa7634738e6c6c0103236ee1b3b72f:
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.
4
6
5
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2019-12-13 18:14:07 +0000)
7
thanks
8
-- PMM
9
10
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
11
12
Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700)
6
13
7
are available in the Git repository at:
14
are available in the Git repository at:
8
15
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191216-1
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220421
10
17
11
for you to fetch changes up to f80741d107673f162e3b097fc76a1590036cc9d1:
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
12
19
13
target/arm: ensure we use current exception state after SCR update (2019-12-16 10:52:58 +0000)
20
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs (2022-04-21 11:37:05 +0100)
14
21
15
----------------------------------------------------------------
22
----------------------------------------------------------------
16
target-arm queue:
23
target-arm queue:
17
* Add support for Cortex-M7 CPU
24
* hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
18
* exynos4210_gic: Suppress gcc9 format-truncation warnings
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
19
* aspeed: Various minor bug fixes and improvements
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
20
* aspeed: Add support for the tacoma-bmc board
27
* xlnx-zynqmp: Connect 4 TTC timers
21
* Honour HCR_EL32.TID1 and .TID2 trapping requirements
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
22
* Handle trapping to EL2 of AArch32 VMRS instructions
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
23
* Handle AArch32 CP15 trapping via HSTR_EL2
30
* stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
24
* Add support for missing Jazelle system registers
31
* hw/core/irq: remove unused 'qemu_irq_split' function
25
* arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on
32
* npcm7xx: use symbolic constants for PWRON STRAP bit fields
26
* Add support for DC CVAP & DC CVADP instructions
33
* virt: document impact of gic-version on max CPUs
27
* Fix assertion when SCR.NS is changed in Secure-SVC &c
28
* enable SHPC native hot plug in arm ACPI
29
34
30
----------------------------------------------------------------
35
----------------------------------------------------------------
31
Alex Bennée (1):
36
Edgar E. Iglesias (6):
32
target/arm: ensure we use current exception state after SCR update
37
timer: cadence_ttc: Break out header file to allow embedding
38
hw/arm/xlnx-zynqmp: Connect 4 TTC timers
39
hw/arm: versal: Create an APU CPU Cluster
40
hw/arm: versal: Add the Cortex-R5Fs
41
hw/misc: Add a model of the Xilinx Versal CRL
42
hw/arm: versal: Connect the CRL
33
43
34
Beata Michalska (4):
44
Hao Wu (2):
35
tcg: cputlb: Add probe_read
45
hw/misc: Add PWRON STRAP bit fields in GCR module
36
Memory: Enable writeback for given memory region
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
37
migration: ram: Switch to ram block writeback
38
target/arm: Add support for DC CVAP & DC CVADP ins
39
47
40
Christophe Lyon (1):
48
Heinrich Schuchardt (1):
41
target/arm: Add support for cortex-m7 CPU
49
hw/arm/virt: impact of gic-version on max CPUs
42
50
43
Cédric Le Goater (12):
51
Peter Maydell (19):
44
aspeed/i2c: Add support for pool buffer transfers
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
45
aspeed/i2c: Check SRAM enablement on AST2500
53
hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device
46
aspeed: Add a DRAM memory region at the SoC level
54
hw/intc/exynos4210_gic: Remove unused TYPE_EXYNOS4210_IRQ_GATE
47
aspeed/i2c: Add support for DMA transfers
55
hw/arm/exynos4210: Put a9mpcore device into state struct
48
aspeed/i2c: Add trace events
56
hw/arm/exynos4210: Drop int_gic_irq[] from Exynos4210Irq struct
49
aspeed/smc: Restore default AHB window mapping at reset
57
hw/arm/exynos4210: Coalesce board_irqs and irq_table
50
aspeed/smc: Do not map disabled segment on the AST2600
58
hw/arm/exynos4210: Fix code style nit in combiner_grp_to_gic_id[]
51
aspeed/smc: Add AST2600 timings registers
59
hw/arm/exynos4210: Move exynos4210_init_board_irqs() into exynos4210.c
52
aspeed: Remove AspeedBoardConfig array and use AspeedMachineClass
60
hw/arm/exynos4210: Put external GIC into state struct
53
aspeed: Add support for the tacoma-bmc board
61
hw/arm/exynos4210: Drop ext_gic_irq[] from Exynos4210Irq struct
54
aspeed: Change the "scu" property definition
62
hw/arm/exynos4210: Move exynos4210_combiner_get_gpioin() into exynos4210.c
55
aspeed: Change the "nic" property definition
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
56
71
57
David Gibson (1):
72
Zongyuan Li (3):
58
exynos4210_gic: Suppress gcc9 format-truncation warnings
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
75
hw/core/irq: remove unused 'qemu_irq_split' function
59
76
60
Heyi Guo (2):
77
docs/system/arm/virt.rst | 4 +-
61
hw/arm/acpi: simplify AML bit and/or statement
78
include/hw/arm/exynos4210.h | 50 ++--
62
hw/arm/acpi: enable SHPC native hot plug
79
include/hw/arm/xlnx-versal.h | 16 ++
63
80
include/hw/arm/xlnx-zynqmp.h | 4 +
64
Joel Stanley (4):
81
include/hw/intc/exynos4210_combiner.h | 57 +++++
65
aspeed/sdmc: Make ast2600 default 1G
82
include/hw/intc/exynos4210_gic.h | 43 ++++
66
aspeed/scu: Fix W1C behavior
83
include/hw/irq.h | 5 -
67
watchdog/aspeed: Improve watchdog timeout message
84
include/hw/misc/npcm7xx_gcr.h | 30 +++
68
watchdog/aspeed: Fix AST2600 frequency behaviour
85
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++++
69
86
include/hw/timer/cadence_ttc.h | 54 +++++
70
Marc Zyngier (5):
87
hw/arm/exynos4210.c | 430 ++++++++++++++++++++++++++++++----
71
target/arm: Honor HCR_EL2.TID2 trapping requirements
88
hw/arm/npcm7xx_boards.c | 24 +-
72
target/arm: Honor HCR_EL2.TID1 trapping requirements
89
hw/arm/realview.c | 33 ++-
73
target/arm: Handle trapping to EL2 of AArch32 VMRS instructions
90
hw/arm/stellaris.c | 15 +-
74
target/arm: Handle AArch32 CP15 trapping via HSTR_EL2
91
hw/arm/virt.c | 7 +
75
target/arm: Add support for missing Jazelle system registers
92
hw/arm/xlnx-versal-virt.c | 6 +-
76
93
hw/arm/xlnx-versal.c | 99 +++++++-
77
Niek Linnenbank (1):
94
hw/arm/xlnx-zynqmp.c | 22 ++
78
arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on()
95
hw/core/irq.c | 15 --
79
96
hw/intc/exynos4210_combiner.c | 108 +--------
80
PanNengyuan (1):
97
hw/intc/exynos4210_gic.c | 344 +--------------------------
81
gpio: fix memory leak in aspeed_gpio_init()
98
hw/misc/xlnx-versal-crl.c | 421 +++++++++++++++++++++++++++++++++
82
99
hw/timer/cadence_ttc.c | 32 +--
83
Philippe Mathieu-Daudé (2):
100
MAINTAINERS | 2 +-
84
hw/arm/sbsa-ref: Simplify by moving the gic in the machine state
101
hw/misc/meson.build | 1 +
85
hw/arm/virt: Simplify by moving the gic in the machine state
102
25 files changed, 1457 insertions(+), 600 deletions(-)
86
103
create mode 100644 include/hw/intc/exynos4210_combiner.h
87
include/exec/exec-all.h | 6 +
104
create mode 100644 include/hw/intc/exynos4210_gic.h
88
include/exec/memory.h | 6 +
105
create mode 100644 include/hw/misc/xlnx-versal-crl.h
89
include/exec/ram_addr.h | 8 +
106
create mode 100644 include/hw/timer/cadence_ttc.h
90
include/hw/arm/aspeed.h | 24 +--
107
create mode 100644 hw/misc/xlnx-versal-crl.c
91
include/hw/arm/aspeed_soc.h | 1 +
92
include/hw/arm/virt.h | 1 +
93
include/hw/i2c/aspeed_i2c.h | 16 ++
94
include/hw/ssi/aspeed_smc.h | 1 +
95
include/hw/watchdog/wdt_aspeed.h | 1 +
96
include/qemu/cutils.h | 1 +
97
target/arm/cpu.h | 20 +-
98
target/arm/helper.h | 3 +
99
target/arm/translate.h | 2 +
100
exec.c | 36 ++++
101
hw/arm/aspeed.c | 271 +++++++++++++----------
102
hw/arm/aspeed_ast2600.c | 25 ++-
103
hw/arm/aspeed_soc.c | 22 +-
104
hw/arm/sbsa-ref.c | 86 ++++----
105
hw/arm/virt-acpi-build.c | 21 +-
106
hw/arm/virt.c | 109 +++++-----
107
hw/gpio/aspeed_gpio.c | 1 +
108
hw/i2c/aspeed_i2c.c | 439 +++++++++++++++++++++++++++++++++++---
109
hw/intc/exynos4210_gic.c | 9 +-
110
hw/misc/aspeed_scu.c | 19 +-
111
hw/misc/aspeed_sdmc.c | 6 +-
112
hw/net/ftgmac100.c | 19 +-
113
hw/ssi/aspeed_smc.c | 63 ++++--
114
hw/timer/aspeed_timer.c | 17 +-
115
hw/watchdog/wdt_aspeed.c | 41 ++--
116
linux-user/elfload.c | 2 +
117
memory.c | 12 ++
118
migration/ram.c | 5 +-
119
target/arm/arm-powerctl.c | 3 +
120
target/arm/cpu.c | 33 +++
121
target/arm/cpu64.c | 1 +
122
target/arm/helper.c | 170 ++++++++++++++-
123
target/arm/op_helper.c | 22 ++
124
target/arm/translate-vfp.inc.c | 20 +-
125
target/arm/translate.c | 9 +-
126
target/arm/vfp_helper.c | 29 +++
127
util/cutils.c | 38 ++++
128
hw/i2c/trace-events | 9 +
129
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
130
tests/data/acpi/virt/DSDT.memhp | Bin 19807 -> 19799 bytes
131
tests/data/acpi/virt/DSDT.numamem | Bin 18470 -> 18462 bytes
132
45 files changed, 1273 insertions(+), 354 deletions(-)
133
diff view generated by jsdifflib
Deleted patch
1
From: Christophe Lyon <christophe.lyon@linaro.org>
2
1
3
This is derived from cortex-m4 description, adding DP support and FPv5
4
instructions with the corresponding flags in isar and mvfr2.
5
6
Checked that it could successfully execute
7
vrinta.f32 s15, s15
8
while cortex-m4 emulation rejects it with "illegal instruction".
9
10
Signed-off-by: Christophe Lyon <christophe.lyon@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20191025090841.10299-1-christophe.lyon@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/cpu.c | 33 +++++++++++++++++++++++++++++++++
17
1 file changed, 33 insertions(+)
18
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
24
cpu->isar.id_isar6 = 0x00000000;
25
}
26
27
+static void cortex_m7_initfn(Object *obj)
28
+{
29
+ ARMCPU *cpu = ARM_CPU(obj);
30
+
31
+ set_feature(&cpu->env, ARM_FEATURE_V7);
32
+ set_feature(&cpu->env, ARM_FEATURE_M);
33
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
34
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
35
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
36
+ cpu->midr = 0x411fc272; /* r1p2 */
37
+ cpu->pmsav7_dregion = 8;
38
+ cpu->isar.mvfr0 = 0x10110221;
39
+ cpu->isar.mvfr1 = 0x12000011;
40
+ cpu->isar.mvfr2 = 0x00000040;
41
+ cpu->id_pfr0 = 0x00000030;
42
+ cpu->id_pfr1 = 0x00000200;
43
+ cpu->id_dfr0 = 0x00100000;
44
+ cpu->id_afr0 = 0x00000000;
45
+ cpu->id_mmfr0 = 0x00100030;
46
+ cpu->id_mmfr1 = 0x00000000;
47
+ cpu->id_mmfr2 = 0x01000000;
48
+ cpu->id_mmfr3 = 0x00000000;
49
+ cpu->isar.id_isar0 = 0x01101110;
50
+ cpu->isar.id_isar1 = 0x02112000;
51
+ cpu->isar.id_isar2 = 0x20232231;
52
+ cpu->isar.id_isar3 = 0x01111131;
53
+ cpu->isar.id_isar4 = 0x01310132;
54
+ cpu->isar.id_isar5 = 0x00000000;
55
+ cpu->isar.id_isar6 = 0x00000000;
56
+}
57
+
58
static void cortex_m33_initfn(Object *obj)
59
{
60
ARMCPU *cpu = ARM_CPU(obj);
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
62
.class_init = arm_v7m_class_init },
63
{ .name = "cortex-m4", .initfn = cortex_m4_initfn,
64
.class_init = arm_v7m_class_init },
65
+ { .name = "cortex-m7", .initfn = cortex_m7_initfn,
66
+ .class_init = arm_v7m_class_init },
67
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
68
.class_init = arm_v7m_class_init },
69
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
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
3
Make the gic a field in the machine state, and instead of filling
7
$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none
4
an array of qemu_irq and passing it around, directly call
8
Unexpected error in object_property_find_err() at ../../qom/object.c:1304:
5
qdev_get_gpio_in() on the gic field.
9
qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found
10
Aborted
6
11
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Check for this combination of options and report an error, in the
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
13
same way we already do for attempts to give a KVM or HVF guest the
9
Message-id: 20191209090306.20433-1-philmd@redhat.com
14
Virtualization or MTE extensions. Now we will report:
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
11
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
12
---
22
---
13
include/hw/arm/virt.h | 1 +
23
hw/arm/virt.c | 7 +++++++
14
hw/arm/virt.c | 109 +++++++++++++++++++++---------------------
24
1 file changed, 7 insertions(+)
15
2 files changed, 55 insertions(+), 55 deletions(-)
16
25
17
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/virt.h
20
+++ b/include/hw/arm/virt.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
22
uint32_t iommu_phandle;
23
int psci_conduit;
24
hwaddr highest_gpa;
25
+ DeviceState *gic;
26
DeviceState *acpi_dev;
27
Notifier powerdown_notifier;
28
} VirtMachineState;
29
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
30
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/virt.c
28
--- a/hw/arm/virt.c
32
+++ b/hw/arm/virt.c
29
+++ b/hw/arm/virt.c
33
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
31
exit(1);
34
}
32
}
35
}
33
36
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
37
-static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
35
+ error_report("mach-virt: %s does not support providing "
38
+static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
36
+ "Security extensions (TrustZone) to the guest CPU",
39
{
37
+ kvm_enabled() ? "KVM" : "HVF");
40
DeviceState *dev;
38
+ exit(1);
41
MachineState *ms = MACHINE(vms);
39
+ }
42
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
40
+
43
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
44
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
42
error_report("mach-virt: %s does not support providing "
45
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
43
"Virtualization extensions to the guest CPU",
46
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
47
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
48
49
qdev_init_nofail(dev);
50
51
return dev;
52
}
53
54
-static void create_its(VirtMachineState *vms, DeviceState *gicdev)
55
+static void create_its(VirtMachineState *vms)
56
{
57
const char *itsclass = its_class_name();
58
DeviceState *dev;
59
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
60
61
dev = qdev_create(NULL, itsclass);
62
63
- object_property_set_link(OBJECT(dev), OBJECT(gicdev), "parent-gicv3",
64
+ object_property_set_link(OBJECT(dev), OBJECT(vms->gic), "parent-gicv3",
65
&error_abort);
66
qdev_init_nofail(dev);
67
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_ITS].base);
68
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
69
fdt_add_its_gic_node(vms);
70
}
71
72
-static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
73
+static void create_v2m(VirtMachineState *vms)
74
{
75
int i;
76
int irq = vms->irqmap[VIRT_GIC_V2M];
77
@@ -XXX,XX +XXX,XX @@ static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
78
qdev_init_nofail(dev);
79
80
for (i = 0; i < NUM_GICV2M_SPIS; i++) {
81
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
82
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
83
+ qdev_get_gpio_in(vms->gic, irq + i));
84
}
85
86
fdt_add_v2m_gic_node(vms);
87
}
88
89
-static void create_gic(VirtMachineState *vms, qemu_irq *pic)
90
+static void create_gic(VirtMachineState *vms)
91
{
92
MachineState *ms = MACHINE(vms);
93
/* We create a standalone GIC */
94
- DeviceState *gicdev;
95
SysBusDevice *gicbusdev;
96
const char *gictype;
97
int type = vms->gic_version, i;
98
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
99
100
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
101
102
- gicdev = qdev_create(NULL, gictype);
103
- qdev_prop_set_uint32(gicdev, "revision", type);
104
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
105
+ vms->gic = qdev_create(NULL, gictype);
106
+ qdev_prop_set_uint32(vms->gic, "revision", type);
107
+ qdev_prop_set_uint32(vms->gic, "num-cpu", smp_cpus);
108
/* Note that the num-irq property counts both internal and external
109
* interrupts; there are always 32 of the former (mandated by GIC spec).
110
*/
111
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
112
+ qdev_prop_set_uint32(vms->gic, "num-irq", NUM_IRQS + 32);
113
if (!kvm_irqchip_in_kernel()) {
114
- qdev_prop_set_bit(gicdev, "has-security-extensions", vms->secure);
115
+ qdev_prop_set_bit(vms->gic, "has-security-extensions", vms->secure);
116
}
117
118
if (type == 3) {
119
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
120
121
nb_redist_regions = virt_gicv3_redist_region_count(vms);
122
123
- qdev_prop_set_uint32(gicdev, "len-redist-region-count",
124
+ qdev_prop_set_uint32(vms->gic, "len-redist-region-count",
125
nb_redist_regions);
126
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
127
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[0]", redist0_count);
128
129
if (nb_redist_regions == 2) {
130
uint32_t redist1_capacity =
131
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
132
133
- qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
134
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[1]",
135
MIN(smp_cpus - redist0_count, redist1_capacity));
136
}
137
} else {
138
if (!kvm_irqchip_in_kernel()) {
139
- qdev_prop_set_bit(gicdev, "has-virtualization-extensions",
140
+ qdev_prop_set_bit(vms->gic, "has-virtualization-extensions",
141
vms->virt);
142
}
143
}
144
- qdev_init_nofail(gicdev);
145
- gicbusdev = SYS_BUS_DEVICE(gicdev);
146
+ qdev_init_nofail(vms->gic);
147
+ gicbusdev = SYS_BUS_DEVICE(vms->gic);
148
sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base);
149
if (type == 3) {
150
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
151
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
152
153
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
154
qdev_connect_gpio_out(cpudev, irq,
155
- qdev_get_gpio_in(gicdev,
156
+ qdev_get_gpio_in(vms->gic,
157
ppibase + timer_irq[irq]));
158
}
159
160
if (type == 3) {
161
- qemu_irq irq = qdev_get_gpio_in(gicdev,
162
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
163
ppibase + ARCH_GIC_MAINT_IRQ);
164
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
165
0, irq);
166
} else if (vms->virt) {
167
- qemu_irq irq = qdev_get_gpio_in(gicdev,
168
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
169
ppibase + ARCH_GIC_MAINT_IRQ);
170
sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
171
}
172
173
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
174
- qdev_get_gpio_in(gicdev, ppibase
175
+ qdev_get_gpio_in(vms->gic, ppibase
176
+ VIRTUAL_PMU_IRQ));
177
178
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
180
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
181
}
182
183
- for (i = 0; i < NUM_IRQS; i++) {
184
- pic[i] = qdev_get_gpio_in(gicdev, i);
185
- }
186
-
187
fdt_add_gic_node(vms);
188
189
if (type == 3 && vms->its) {
190
- create_its(vms, gicdev);
191
+ create_its(vms);
192
} else if (type == 2) {
193
- create_v2m(vms, pic);
194
+ create_v2m(vms);
195
}
196
}
197
198
-static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
199
+static void create_uart(const VirtMachineState *vms, int uart,
200
MemoryRegion *mem, Chardev *chr)
201
{
202
char *nodename;
203
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
204
qdev_init_nofail(dev);
205
memory_region_add_subregion(mem, base,
206
sysbus_mmio_get_region(s, 0));
207
- sysbus_connect_irq(s, 0, pic[irq]);
208
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
209
210
nodename = g_strdup_printf("/pl011@%" PRIx64, base);
211
qemu_fdt_add_subnode(vms->fdt, nodename);
212
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
213
g_free(nodename);
214
}
215
216
-static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
217
+static void create_rtc(const VirtMachineState *vms)
218
{
219
char *nodename;
220
hwaddr base = vms->memmap[VIRT_RTC].base;
221
@@ -XXX,XX +XXX,XX @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
222
int irq = vms->irqmap[VIRT_RTC];
223
const char compat[] = "arm,pl031\0arm,primecell";
224
225
- sysbus_create_simple("pl031", base, pic[irq]);
226
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(vms->gic, irq));
227
228
nodename = g_strdup_printf("/pl031@%" PRIx64, base);
229
qemu_fdt_add_subnode(vms->fdt, nodename);
230
@@ -XXX,XX +XXX,XX @@ static void virt_powerdown_req(Notifier *n, void *opaque)
231
}
232
}
233
234
-static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
235
+static void create_gpio(const VirtMachineState *vms)
236
{
237
char *nodename;
238
DeviceState *pl061_dev;
239
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
240
int irq = vms->irqmap[VIRT_GPIO];
241
const char compat[] = "arm,pl061\0arm,primecell";
242
243
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
244
+ pl061_dev = sysbus_create_simple("pl061", base,
245
+ qdev_get_gpio_in(vms->gic, irq));
246
247
uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
248
nodename = g_strdup_printf("/pl061@%" PRIx64, base);
249
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
250
g_free(nodename);
251
}
252
253
-static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
254
+static void create_virtio_devices(const VirtMachineState *vms)
255
{
256
int i;
257
hwaddr size = vms->memmap[VIRT_MMIO].size;
258
@@ -XXX,XX +XXX,XX @@ static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
259
int irq = vms->irqmap[VIRT_MMIO] + i;
260
hwaddr base = vms->memmap[VIRT_MMIO].base + i * size;
261
262
- sysbus_create_simple("virtio-mmio", base, pic[irq]);
263
+ sysbus_create_simple("virtio-mmio", base,
264
+ qdev_get_gpio_in(vms->gic, irq));
265
}
266
267
/* We add dtb nodes in reverse order so that they appear in the finished
268
@@ -XXX,XX +XXX,XX @@ static void create_pcie_irq_map(const VirtMachineState *vms,
269
0x7 /* PCI irq */);
270
}
271
272
-static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
273
+static void create_smmu(const VirtMachineState *vms,
274
PCIBus *bus)
275
{
276
char *node;
277
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
278
qdev_init_nofail(dev);
279
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
280
for (i = 0; i < NUM_SMMU_IRQS; i++) {
281
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
282
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
283
+ qdev_get_gpio_in(vms->gic, irq + i));
284
}
285
286
node = g_strdup_printf("/smmuv3@%" PRIx64, base);
287
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
288
g_free(node);
289
}
290
291
-static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
292
+static void create_pcie(VirtMachineState *vms)
293
{
294
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
295
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
296
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
297
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
298
299
for (i = 0; i < GPEX_NUM_IRQS; i++) {
300
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
301
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
302
+ qdev_get_gpio_in(vms->gic, irq + i));
303
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
304
}
305
306
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
307
if (vms->iommu) {
308
vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt);
309
310
- create_smmu(vms, pic, pci->bus);
311
+ create_smmu(vms, pci->bus);
312
313
qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map",
314
0x0, vms->iommu_phandle, 0x0, 0x10000);
315
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
316
g_free(nodename);
317
}
318
319
-static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
320
+static void create_platform_bus(VirtMachineState *vms)
321
{
322
DeviceState *dev;
323
SysBusDevice *s;
324
@@ -XXX,XX +XXX,XX @@ static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
325
326
s = SYS_BUS_DEVICE(dev);
327
for (i = 0; i < PLATFORM_BUS_NUM_IRQS; i++) {
328
- int irqn = vms->irqmap[VIRT_PLATFORM_BUS] + i;
329
- sysbus_connect_irq(s, i, pic[irqn]);
330
+ int irq = vms->irqmap[VIRT_PLATFORM_BUS] + i;
331
+ sysbus_connect_irq(s, i, qdev_get_gpio_in(vms->gic, irq));
332
}
333
334
memory_region_add_subregion(sysmem,
335
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
336
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
337
MachineClass *mc = MACHINE_GET_CLASS(machine);
338
const CPUArchIdList *possible_cpus;
339
- qemu_irq pic[NUM_IRQS];
340
MemoryRegion *sysmem = get_system_memory();
341
MemoryRegion *secure_sysmem = NULL;
342
int n, virt_max_cpus;
343
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
344
345
virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
346
347
- create_gic(vms, pic);
348
+ create_gic(vms);
349
350
fdt_add_pmu_nodes(vms);
351
352
- create_uart(vms, pic, VIRT_UART, sysmem, serial_hd(0));
353
+ create_uart(vms, VIRT_UART, sysmem, serial_hd(0));
354
355
if (vms->secure) {
356
create_secure_ram(vms, secure_sysmem);
357
- create_uart(vms, pic, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
358
+ create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
359
}
360
361
vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
362
363
- create_rtc(vms, pic);
364
+ create_rtc(vms);
365
366
- create_pcie(vms, pic);
367
+ create_pcie(vms);
368
369
if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
370
- vms->acpi_dev = create_acpi_ged(vms, pic);
371
+ vms->acpi_dev = create_acpi_ged(vms);
372
} else {
373
- create_gpio(vms, pic);
374
+ create_gpio(vms);
375
}
376
377
/* connect powerdown request */
378
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
379
* (which will be automatically plugged in to the transports). If
380
* no backend is created the transport will just sit harmlessly idle.
381
*/
382
- create_virtio_devices(vms, pic);
383
+ create_virtio_devices(vms);
384
385
vms->fw_cfg = create_fw_cfg(vms, &address_space_memory);
386
rom_set_fw(vms->fw_cfg);
387
388
- create_platform_bus(vms, pic);
389
+ create_platform_bus(vms);
390
391
vms->bootinfo.ram_size = machine->ram_size;
392
vms->bootinfo.nb_cpus = smp_cpus;
393
--
44
--
394
2.20.1
45
2.25.1
395
396
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
QEMU lacks the minimum Jazelle implementation that is required
3
Break out header file to allow embedding of the the TTC.
4
by the architecture (everything is RAZ or RAZ/WI). Add it
5
together with the HCR_EL2.TID0 trapping that goes with it.
6
4
7
Signed-off-by: Marc Zyngier <maz@kernel.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
10
Message-id: 20191201122018.25808-6-maz@kernel.org
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
11
[PMM: moved ARMCPRegInfo array to file scope, marked it
9
Message-id: 20220331222017.2914409-2-edgar.iglesias@gmail.com
12
'static global', moved new condition down in
13
register_cp_regs_for_features() to go with other feature
14
things rather than up with the v6/v7/v8 stuff]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
11
---
17
target/arm/helper.c | 27 +++++++++++++++++++++++++++
12
include/hw/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++
18
1 file changed, 27 insertions(+)
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
19
16
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/include/hw/timer/cadence_ttc.h b/include/hw/timer/cadence_ttc.h
21
index XXXXXXX..XXXXXXX 100644
18
new file mode 100644
22
--- a/target/arm/helper.c
19
index XXXXXXX..XXXXXXX
23
+++ b/target/arm/helper.c
20
--- /dev/null
24
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
21
+++ b/include/hw/timer/cadence_ttc.h
25
return CP_ACCESS_OK;
22
@@ -XXX,XX +XXX,XX @@
26
}
23
+/*
27
24
+ * Xilinx Zynq cadence TTC model
28
+static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
25
+ *
29
+ bool isread)
26
+ * Copyright (c) 2011 Xilinx Inc.
30
+{
27
+ * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@petalogix.com)
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID0)) {
28
+ * Copyright (c) 2012 PetaLogix Pty Ltd.
32
+ return CP_ACCESS_TRAP_EL2;
29
+ * Written By Haibing Ma
33
+ }
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
34
+
42
+
35
+ return CP_ACCESS_OK;
43
+#include "hw/sysbus.h"
36
+}
44
+#include "qemu/timer.h"
37
+
45
+
38
+static const ARMCPRegInfo jazelle_regs[] = {
46
+typedef struct {
39
+ { .name = "JIDR",
47
+ QEMUTimer *timer;
40
+ .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
48
+ int freq;
41
+ .access = PL1_R, .accessfn = access_jazelle,
49
+
42
+ .type = ARM_CP_CONST, .resetvalue = 0 },
50
+ uint32_t reg_clock;
43
+ { .name = "JOSCR",
51
+ uint32_t reg_count;
44
+ .cp = 14, .crn = 1, .crm = 0, .opc1 = 7, .opc2 = 0,
52
+ uint32_t reg_value;
45
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
53
+ uint16_t reg_interval;
46
+ { .name = "JMCR",
54
+ uint16_t reg_match[3];
47
+ .cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
55
+ uint32_t reg_intr;
48
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
56
+ uint32_t reg_intr_en;
49
+ REGINFO_SENTINEL
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];
50
+};
74
+};
51
+
75
+
52
void register_cp_regs_for_features(ARMCPU *cpu)
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)
53
{
125
{
54
/* Register all the coprocessor registers based on feature bits */
126
qemu_set_irq(s->irq, !!(s->reg_intr & s->reg_intr_en));
55
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
56
if (arm_feature(env, ARM_FEATURE_LPAE)) {
57
define_arm_cp_regs(cpu, lpae_cp_reginfo);
58
}
59
+ if (cpu_isar_feature(jazelle, cpu)) {
60
+ define_arm_cp_regs(cpu, jazelle_regs);
61
+ }
62
/* Slightly awkwardly, the OMAP and StrongARM cores need all of
63
* cp15 crn=0 to be writes-ignored, whereas for other cores they should
64
* be read-only (ie write causes UNDEF exception).
65
--
127
--
66
2.20.1
128
2.25.1
67
68
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
ARMv8.2 introduced support for Data Cache Clean instructions
3
Connect the 4 TTC timers on the ZynqMP.
4
to PoP (point-of-persistence) - DC CVAP and PoDP (point-of-deep-persistence)
5
- DV CVADP. Both specify conceptual points in a memory system where all writes
6
that are to reach them are considered persistent.
7
The support provided considers both to be actually the same so there is no
8
distinction between the two. If none is available (there is no backing store
9
for given memory) both will result in Data Cache Clean up to the point of
10
coherency. Otherwise sync for the specified range shall be performed.
11
4
12
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-id: 20191121000843.24844-5-beata.michalska@linaro.org
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
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
11
---
17
target/arm/cpu.h | 10 ++++++++
12
include/hw/arm/xlnx-zynqmp.h | 4 ++++
18
linux-user/elfload.c | 2 ++
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
19
target/arm/cpu64.c | 1 +
14
2 files changed, 26 insertions(+)
20
target/arm/helper.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
21
4 files changed, 69 insertions(+)
22
15
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
18
--- a/include/hw/arm/xlnx-zynqmp.h
26
+++ b/target/arm/cpu.h
19
+++ b/include/hw/arm/xlnx-zynqmp.h
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
20
@@ -XXX,XX +XXX,XX @@
28
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
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]);
29
}
61
}
30
62
31
+static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
32
+{
64
+{
33
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0;
65
+ SysBusDevice *sbd;
34
+}
66
+ int i, irq;
35
+
67
+
36
+static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
37
+{
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
38
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
70
+ TYPE_CADENCE_TTC);
39
+}
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
40
+
72
+
41
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
73
+ sysbus_realize(sbd, &error_fatal);
42
{
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
43
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
75
+ for (irq = 0; irq < 3; irq++) {
44
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
45
index XXXXXXX..XXXXXXX 100644
46
--- a/linux-user/elfload.c
47
+++ b/linux-user/elfload.c
48
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
49
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
50
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
51
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
52
+ GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
53
54
return hwcaps;
55
}
56
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
57
ARMCPU *cpu = ARM_CPU(thread_cpu);
58
uint32_t hwcaps = 0;
59
60
+ GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
61
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
62
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
63
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
cpu->isar.id_aa64isar0 = t;
70
71
t = cpu->isar.id_aa64isar1;
72
+ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
73
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
74
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
75
t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
76
diff --git a/target/arm/helper.c b/target/arm/helper.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/helper.c
79
+++ b/target/arm/helper.c
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo rndr_reginfo[] = {
81
.access = PL0_R, .readfn = rndr_readfn },
82
REGINFO_SENTINEL
83
};
84
+
85
+#ifndef CONFIG_USER_ONLY
86
+static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
87
+ uint64_t value)
88
+{
89
+ ARMCPU *cpu = env_archcpu(env);
90
+ /* CTR_EL0 System register -> DminLine, bits [19:16] */
91
+ uint64_t dline_size = 4 << ((cpu->ctr >> 16) & 0xF);
92
+ uint64_t vaddr_in = (uint64_t) value;
93
+ uint64_t vaddr = vaddr_in & ~(dline_size - 1);
94
+ void *haddr;
95
+ int mem_idx = cpu_mmu_index(env, false);
96
+
97
+ /* This won't be crossing page boundaries */
98
+ haddr = probe_read(env, vaddr, dline_size, mem_idx, GETPC());
99
+ if (haddr) {
100
+
101
+ ram_addr_t offset;
102
+ MemoryRegion *mr;
103
+
104
+ /* RCU lock is already being held */
105
+ mr = memory_region_from_host(haddr, &offset);
106
+
107
+ if (mr) {
108
+ memory_region_do_writeback(mr, offset, dline_size);
109
+ }
77
+ }
110
+ }
78
+ }
111
+}
79
+}
112
+
80
+
113
+static const ARMCPRegInfo dcpop_reg[] = {
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
114
+ { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
82
{
115
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
83
static const struct UnimpInfo {
116
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
117
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
85
xlnx_zynqmp_create_efuse(s, gic_spi);
118
+ REGINFO_SENTINEL
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
119
+};
87
xlnx_zynqmp_create_crf(s, gic_spi);
120
+
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
121
+static const ARMCPRegInfo dcpodp_reg[] = {
89
xlnx_zynqmp_create_unimp_mmio(s);
122
+ { .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
90
123
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
124
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
125
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
126
+ REGINFO_SENTINEL
127
+};
128
+#endif /*CONFIG_USER_ONLY*/
129
+
130
#endif
131
132
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
133
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
134
if (cpu_isar_feature(aa64_rndr, cpu)) {
135
define_arm_cp_regs(cpu, rndr_reginfo);
136
}
137
+#ifndef CONFIG_USER_ONLY
138
+ /* Data Cache clean instructions up to PoP */
139
+ if (cpu_isar_feature(aa64_dcpop, cpu)) {
140
+ define_one_arm_cp_reg(cpu, dcpop_reg);
141
+
142
+ if (cpu_isar_feature(aa64_dcpodp, cpu)) {
143
+ define_one_arm_cp_reg(cpu, dcpodp_reg);
144
+ }
145
+ }
146
+#endif /*CONFIG_USER_ONLY*/
147
#endif
148
149
/*
150
--
92
--
151
2.20.1
93
2.25.1
152
153
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
HSTR_EL2 offers a way to trap ranges of CP15 system register
3
Create an APU CPU Cluster. This is in preparation to add the RPU.
4
accesses to EL2, and it looks like this register is completely
5
ignored by QEMU.
6
4
7
To avoid adding extra .accessfn filters all over the place (which
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
8
would have a direct performance impact), let's add a new TB flag
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
9
that gets set whenever HSTR_EL2 is non-zero and that QEMU translates
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
10
a context where this trap has a chance to apply, and only generate
11
the extra access check if the hypervisor is actively using this feature.
12
13
Tested with a hand-crafted KVM guest accessing CBAR.
14
15
Signed-off-by: Marc Zyngier <maz@kernel.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20191201122018.25808-5-maz@kernel.org
18
[PMM: use is_a64(); fix comment syntax]
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
9
---
21
target/arm/cpu.h | 2 ++
10
include/hw/arm/xlnx-versal.h | 2 ++
22
target/arm/translate.h | 2 ++
11
hw/arm/xlnx-versal.c | 9 ++++++++-
23
target/arm/helper.c | 6 ++++++
12
2 files changed, 10 insertions(+), 1 deletion(-)
24
target/arm/op_helper.c | 22 ++++++++++++++++++++++
25
target/arm/translate.c | 3 ++-
26
5 files changed, 34 insertions(+), 1 deletion(-)
27
13
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
29
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
16
--- a/include/hw/arm/xlnx-versal.h
31
+++ b/target/arm/cpu.h
17
+++ b/include/hw/arm/xlnx-versal.h
32
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
18
@@ -XXX,XX +XXX,XX @@
33
FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Partially cached, minus FPEXC. */
19
34
FIELD(TBFLAG_A32, CONDEXEC, 8, 8) /* Not cached. */
20
#include "hw/sysbus.h"
35
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
21
#include "hw/arm/boot.h"
36
+FIELD(TBFLAG_A32, HSTR_ACTIVE, 17, 1)
22
+#include "hw/cpu/cluster.h"
23
#include "hw/or-irq.h"
24
#include "hw/sd/sdhci.h"
25
#include "hw/intc/arm_gicv3.h"
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
27
struct {
28
struct {
29
MemoryRegion mr;
30
+ CPUClusterState cluster;
31
ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
32
GICv3State gic;
33
} apu;
34
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/xlnx-versal.c
37
+++ b/hw/arm/xlnx-versal.c
38
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
39
{
40
int i;
41
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
43
+ TYPE_CPU_CLUSTER);
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
37
+
45
+
38
/* For M profile only, set if FPCCR.LSPACT is set */
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
39
FIELD(TBFLAG_A32, LSPACT, 18, 1) /* Not cached. */
47
Object *obj;
40
/* For M profile only, set if we must create a new FP context */
48
41
diff --git a/target/arm/translate.h b/target/arm/translate.h
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
42
index XXXXXXX..XXXXXXX 100644
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
43
--- a/target/arm/translate.h
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
44
+++ b/target/arm/translate.h
52
XLNX_VERSAL_ACPU_TYPE);
45
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
46
bool pauth_active;
54
if (i) {
47
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
48
bool bt;
56
&error_abort);
49
+ /* True if any CP15 access is trapped by HSTR_EL2 */
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
50
+ bool hstr_active;
51
/*
52
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
53
* < 0, set by the current instruction.
54
diff --git a/target/arm/helper.c b/target/arm/helper.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/helper.c
57
+++ b/target/arm/helper.c
58
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
59
if (arm_el_is_aa64(env, 1)) {
60
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
61
}
58
}
62
+
59
+
63
+ if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
60
+ qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
64
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
66
+ }
67
+
68
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
69
}
61
}
70
62
71
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
63
static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/op_helper.c
74
+++ b/target/arm/op_helper.c
75
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
76
raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
77
}
78
79
+ /*
80
+ * Check for an EL2 trap due to HSTR_EL2. We expect EL0 accesses
81
+ * to sysregs non accessible at EL0 to have UNDEF-ed already.
82
+ */
83
+ if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
84
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
85
+ uint32_t mask = 1 << ri->crn;
86
+
87
+ if (ri->type & ARM_CP_64BIT) {
88
+ mask = 1 << ri->crm;
89
+ }
90
+
91
+ /* T4 and T14 are RES0 */
92
+ mask &= ~((1 << 4) | (1 << 14));
93
+
94
+ if (env->cp15.hstr_el2 & mask) {
95
+ target_el = 2;
96
+ goto exept;
97
+ }
98
+ }
99
+
100
if (!ri->accessfn) {
101
return;
102
}
103
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
104
g_assert_not_reached();
105
}
106
107
+exept:
108
raise_exception(env, EXCP_UDEF, syndrome, target_el);
109
}
110
111
diff --git a/target/arm/translate.c b/target/arm/translate.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/translate.c
114
+++ b/target/arm/translate.c
115
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
116
return 1;
117
}
118
119
- if (ri->accessfn ||
120
+ if (s->hstr_active || ri->accessfn ||
121
(arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
122
/* Emit code to perform further access permissions checks at
123
* runtime; this may result in an exception.
124
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
125
!arm_el_is_aa64(env, 3);
126
dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
127
dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
128
+ dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
129
dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
130
condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
131
dc->condexec_mask = (condexec & 0xf) << 1;
132
--
64
--
133
2.20.1
65
2.25.1
134
135
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit)
4
an array of qemu_irq and passing it around, directly call
4
subsystem.
5
qdev_get_gpio_in() on the gic field.
6
5
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
8
Message-id: 20191206162303.30338-1-philmd@redhat.com
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/arm/sbsa-ref.c | 86 +++++++++++++++++++++++------------------------
11
include/hw/arm/xlnx-versal.h | 10 ++++++++++
13
1 file changed, 42 insertions(+), 44 deletions(-)
12
hw/arm/xlnx-versal-virt.c | 6 +++---
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
14
3 files changed, 49 insertions(+), 3 deletions(-)
14
15
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
18
--- a/include/hw/arm/xlnx-versal.h
18
+++ b/hw/arm/sbsa-ref.c
19
+++ b/include/hw/arm/xlnx-versal.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct {
20
@@ -XXX,XX +XXX,XX @@
20
void *fdt;
21
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
21
int fdt_size;
22
22
int psci_conduit;
23
#define XLNX_VERSAL_NR_ACPUS 2
23
+ DeviceState *gic;
24
+#define XLNX_VERSAL_NR_RCPUS 2
24
PFlashCFI01 *flash[2];
25
#define XLNX_VERSAL_NR_UARTS 2
25
} SBSAMachineState;
26
#define XLNX_VERSAL_NR_GEMS 2
26
27
#define XLNX_VERSAL_NR_ADMAS 8
27
@@ -XXX,XX +XXX,XX @@ static void create_secure_ram(SBSAMachineState *sms,
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
28
memory_region_add_subregion(secure_sysmem, base, secram);
29
VersalUsb2 usb;
30
} iou;
31
32
+ /* Real-time Processing Unit. */
33
+ struct {
34
+ MemoryRegion mr;
35
+ MemoryRegion mr_ps_alias;
36
+
37
+ CPUClusterState cluster;
38
+ ARMCPU cpu[XLNX_VERSAL_NR_RCPUS];
39
+ } rpu;
40
+
41
struct {
42
qemu_or_irq irq_orgate;
43
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
44
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal-virt.c
47
+++ b/hw/arm/xlnx-versal-virt.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
49
50
mc->desc = "Xilinx Versal Virtual development board";
51
mc->init = versal_virt_init;
52
- mc->min_cpus = XLNX_VERSAL_NR_ACPUS;
53
- mc->max_cpus = XLNX_VERSAL_NR_ACPUS;
54
- mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
55
+ mc->min_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
56
+ mc->max_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
57
+ mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
58
mc->no_cdrom = true;
59
mc->default_ram_id = "ddr";
29
}
60
}
30
61
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
31
-static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
62
index XXXXXXX..XXXXXXX 100644
32
+static void create_gic(SBSAMachineState *sms)
63
--- a/hw/arm/xlnx-versal.c
33
{
64
+++ b/hw/arm/xlnx-versal.c
34
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
65
@@ -XXX,XX +XXX,XX @@
35
- DeviceState *gicdev;
66
#include "hw/sysbus.h"
36
SysBusDevice *gicbusdev;
67
37
const char *gictype;
68
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
38
uint32_t redist0_capacity, redist0_count;
69
+#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
39
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
70
#define GEM_REVISION 0x40070106
40
71
41
gictype = gicv3_class_name();
72
#define VERSAL_NUM_PMC_APB_IRQS 3
42
73
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
43
- gicdev = qdev_create(NULL, gictype);
44
- qdev_prop_set_uint32(gicdev, "revision", 3);
45
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
46
+ sms->gic = qdev_create(NULL, gictype);
47
+ qdev_prop_set_uint32(sms->gic, "revision", 3);
48
+ qdev_prop_set_uint32(sms->gic, "num-cpu", smp_cpus);
49
/*
50
* Note that the num-irq property counts both internal and external
51
* interrupts; there are always 32 of the former (mandated by GIC spec).
52
*/
53
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
54
- qdev_prop_set_bit(gicdev, "has-security-extensions", true);
55
+ qdev_prop_set_uint32(sms->gic, "num-irq", NUM_IRQS + 32);
56
+ qdev_prop_set_bit(sms->gic, "has-security-extensions", true);
57
58
redist0_capacity =
59
sbsa_ref_memmap[SBSA_GIC_REDIST].size / GICV3_REDIST_SIZE;
60
redist0_count = MIN(smp_cpus, redist0_capacity);
61
62
- qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
63
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
64
+ qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1);
65
+ qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count);
66
67
- qdev_init_nofail(gicdev);
68
- gicbusdev = SYS_BUS_DEVICE(gicdev);
69
+ qdev_init_nofail(sms->gic);
70
+ gicbusdev = SYS_BUS_DEVICE(sms->gic);
71
sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base);
72
sysbus_mmio_map(gicbusdev, 1, sbsa_ref_memmap[SBSA_GIC_REDIST].base);
73
74
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
75
76
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
77
qdev_connect_gpio_out(cpudev, irq,
78
- qdev_get_gpio_in(gicdev,
79
+ qdev_get_gpio_in(sms->gic,
80
ppibase + timer_irq[irq]));
81
}
82
83
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
84
- qdev_get_gpio_in(gicdev, ppibase
85
+ qdev_get_gpio_in(sms->gic, ppibase
86
+ ARCH_GIC_MAINT_IRQ));
87
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
88
- qdev_get_gpio_in(gicdev, ppibase
89
+ qdev_get_gpio_in(sms->gic, ppibase
90
+ VIRTUAL_PMU_IRQ));
91
92
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
93
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
94
sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
95
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
96
}
97
-
98
- for (i = 0; i < NUM_IRQS; i++) {
99
- pic[i] = qdev_get_gpio_in(gicdev, i);
100
- }
101
}
102
103
-static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
104
+static void create_uart(const SBSAMachineState *sms, int uart,
105
MemoryRegion *mem, Chardev *chr)
106
{
107
hwaddr base = sbsa_ref_memmap[uart].base;
108
@@ -XXX,XX +XXX,XX @@ static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
109
qdev_init_nofail(dev);
110
memory_region_add_subregion(mem, base,
111
sysbus_mmio_get_region(s, 0));
112
- sysbus_connect_irq(s, 0, pic[irq]);
113
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(sms->gic, irq));
114
}
115
116
-static void create_rtc(const SBSAMachineState *sms, qemu_irq *pic)
117
+static void create_rtc(const SBSAMachineState *sms)
118
{
119
hwaddr base = sbsa_ref_memmap[SBSA_RTC].base;
120
int irq = sbsa_ref_irqmap[SBSA_RTC];
121
122
- sysbus_create_simple("pl031", base, pic[irq]);
123
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(sms->gic, irq));
124
}
125
126
static DeviceState *gpio_key_dev;
127
@@ -XXX,XX +XXX,XX @@ static Notifier sbsa_ref_powerdown_notifier = {
128
.notify = sbsa_ref_powerdown_req
129
};
130
131
-static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
132
+static void create_gpio(const SBSAMachineState *sms)
133
{
134
DeviceState *pl061_dev;
135
hwaddr base = sbsa_ref_memmap[SBSA_GPIO].base;
136
int irq = sbsa_ref_irqmap[SBSA_GPIO];
137
138
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
139
+ pl061_dev = sysbus_create_simple("pl061", base,
140
+ qdev_get_gpio_in(sms->gic, irq));
141
142
gpio_key_dev = sysbus_create_simple("gpio-key", -1,
143
qdev_get_gpio_in(pl061_dev, 3));
144
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
145
qemu_register_powerdown_notifier(&sbsa_ref_powerdown_notifier);
146
}
147
148
-static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
149
+static void create_ahci(const SBSAMachineState *sms)
150
{
151
hwaddr base = sbsa_ref_memmap[SBSA_AHCI].base;
152
int irq = sbsa_ref_irqmap[SBSA_AHCI];
153
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
154
qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS);
155
qdev_init_nofail(dev);
156
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
157
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
158
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
159
160
sysahci = SYSBUS_AHCI(dev);
161
ahci = &sysahci->ahci;
162
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
163
}
74
}
164
}
75
}
165
76
166
-static void create_ehci(const SBSAMachineState *sms, qemu_irq *pic)
77
+static void versal_create_rpu_cpus(Versal *s)
167
+static void create_ehci(const SBSAMachineState *sms)
78
+{
79
+ int i;
80
+
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
82
+ TYPE_CPU_CLUSTER);
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
84
+
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
86
+ Object *obj;
87
+
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
89
+ "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
90
+ XLNX_VERSAL_RCPU_TYPE);
91
+ obj = OBJECT(&s->lpd.rpu.cpu[i]);
92
+ object_property_set_bool(obj, "start-powered-off", true,
93
+ &error_abort);
94
+
95
+ object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
96
+ object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
97
+ &error_abort);
98
+ object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
99
+ &error_abort);
100
+ qdev_realize(DEVICE(obj), NULL, &error_fatal);
101
+ }
102
+
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
104
+}
105
+
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
168
{
107
{
169
hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
108
int i;
170
int irq = sbsa_ref_irqmap[SBSA_EHCI];
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
171
110
172
- sysbus_create_simple("platform-ehci-usb", base, pic[irq]);
111
versal_create_apu_cpus(s);
173
+ sysbus_create_simple("platform-ehci-usb", base,
112
versal_create_apu_gic(s, pic);
174
+ qdev_get_gpio_in(sms->gic, irq));
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);
175
}
123
}
176
124
177
-static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
125
static void versal_init(Object *obj)
178
- PCIBus *bus)
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
179
+static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
127
Versal *s = XLNX_VERSAL(obj);
180
{
128
181
hwaddr base = sbsa_ref_memmap[SBSA_SMMU].base;
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
182
int irq = sbsa_ref_irqmap[SBSA_SMMU];
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
183
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
184
qdev_init_nofail(dev);
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
185
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
186
for (i = 0; i < NUM_SMMU_IRQS; i++) {
187
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
188
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
189
+ qdev_get_gpio_in(sms->gic, irq + 1));
190
}
191
}
134
}
192
135
193
-static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
136
static Property versal_properties[] = {
194
+static void create_pcie(SBSAMachineState *sms)
195
{
196
hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base;
197
hwaddr size_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].size;
198
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
199
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
200
201
for (i = 0; i < GPEX_NUM_IRQS; i++) {
202
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
203
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
204
+ qdev_get_gpio_in(sms->gic, irq + 1));
205
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
206
}
207
208
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
209
210
pci_create_simple(pci->bus, -1, "VGA");
211
212
- create_smmu(sms, pic, pci->bus);
213
+ create_smmu(sms, pci->bus);
214
}
215
216
static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
217
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
218
bool firmware_loaded;
219
const CPUArchIdList *possible_cpus;
220
int n, sbsa_max_cpus;
221
- qemu_irq pic[NUM_IRQS];
222
223
if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) {
224
error_report("sbsa-ref: CPU type other than the built-in "
225
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
226
227
create_secure_ram(sms, secure_sysmem);
228
229
- create_gic(sms, pic);
230
+ create_gic(sms);
231
232
- create_uart(sms, pic, SBSA_UART, sysmem, serial_hd(0));
233
- create_uart(sms, pic, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
234
+ create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
235
+ create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
236
/* Second secure UART for RAS and MM from EL0 */
237
- create_uart(sms, pic, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
238
+ create_uart(sms, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
239
240
- create_rtc(sms, pic);
241
+ create_rtc(sms);
242
243
- create_gpio(sms, pic);
244
+ create_gpio(sms);
245
246
- create_ahci(sms, pic);
247
+ create_ahci(sms);
248
249
- create_ehci(sms, pic);
250
+ create_ehci(sms);
251
252
- create_pcie(sms, pic);
253
+ create_pcie(sms);
254
255
sms->bootinfo.ram_size = machine->ram_size;
256
sms->bootinfo.nb_cpus = smp_cpus;
257
--
137
--
258
2.20.1
138
2.25.1
259
260
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
The Aspeed I2C controller can operate in different transfer modes :
3
Add a model of the Xilinx Versal CRL.
4
4
5
- Byte Buffer mode, using a dedicated register to transfer a
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
byte. This is what the model supports today.
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
- Pool Buffer mode, using an internal SRAM to transfer multiple
8
Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com
9
bytes in the same command sequence.
10
11
Each SoC has different SRAM characteristics. On the AST2400, 2048
12
bytes of SRAM are available at offset 0x800 of the controller AHB
13
window. The pool buffer can be configured from 1 to 256 bytes per bus.
14
15
On the AST2500, the SRAM is at offset 0x200 and the pool buffer is of
16
16 bytes per bus.
17
18
On the AST2600, the SRAM is at offset 0xC00 and the pool buffer is of
19
32 bytes per bus. It can be splitted in two for TX and RX but the
20
current model does not add support for it as it it unused by known
21
drivers.
22
23
Signed-off-by: Cédric Le Goater <clg@kaod.org>
24
Reviewed-by: Joel Stanley <joel@jms.id.au>
25
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
26
Signed-off-by: Cédric Le Goater <clg@kaod.org>
27
Message-id: 20191119141211.25716-2-clg@kaod.org
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
10
---
30
include/hw/i2c/aspeed_i2c.h | 8 ++
11
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++
31
hw/i2c/aspeed_i2c.c | 197 ++++++++++++++++++++++++++++++++----
12
hw/misc/xlnx-versal-crl.c | 421 ++++++++++++++++++++++++++++++
32
2 files changed, 186 insertions(+), 19 deletions(-)
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
33
17
34
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
18
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
35
index XXXXXXX..XXXXXXX 100644
19
new file mode 100644
36
--- a/include/hw/i2c/aspeed_i2c.h
20
index XXXXXXX..XXXXXXX
37
+++ b/include/hw/i2c/aspeed_i2c.h
21
--- /dev/null
22
+++ b/include/hw/misc/xlnx-versal-crl.h
38
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
39
OBJECT_CHECK(AspeedI2CState, (obj), TYPE_ASPEED_I2C)
24
+/*
40
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
41
#define ASPEED_I2C_NR_BUSSES 16
26
+ *
42
+#define ASPEED_I2C_MAX_POOL_SIZE 0x800
27
+ * Copyright (c) 2022 Xilinx Inc.
43
28
+ * SPDX-License-Identifier: GPL-2.0-or-later
44
struct AspeedI2CState;
29
+ *
45
30
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
46
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
31
+ */
47
uint32_t intr_status;
32
+#ifndef HW_MISC_XLNX_VERSAL_CRL_H
48
uint32_t cmd;
33
+#define HW_MISC_XLNX_VERSAL_CRL_H
49
uint32_t buf;
34
+
50
+ uint32_t pool_ctrl;
35
+#include "hw/sysbus.h"
51
} AspeedI2CBus;
36
+#include "hw/register.h"
52
37
+#include "target/arm/cpu.h"
53
typedef struct AspeedI2CState {
38
+
54
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
39
+#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl"
55
qemu_irq irq;
40
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL)
56
41
+
57
uint32_t intr_status;
42
+REG32(ERR_CTRL, 0x0)
58
+ MemoryRegion pool_iomem;
43
+ FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
59
+ uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
44
+REG32(IR_STATUS, 0x4)
60
45
+ FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1)
61
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
46
+REG32(IR_MASK, 0x8)
62
} AspeedI2CState;
47
+ FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1)
63
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
48
+REG32(IR_ENABLE, 0xc)
64
uint8_t reg_size;
49
+ FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1)
65
uint8_t gap;
50
+REG32(IR_DISABLE, 0x10)
66
qemu_irq (*bus_get_irq)(AspeedI2CBus *);
51
+ FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1)
67
+
52
+REG32(WPROT, 0x1c)
68
+ uint64_t pool_size;
53
+ FIELD(WPROT, ACTIVE, 0, 1)
69
+ hwaddr pool_base;
54
+REG32(PLL_CLK_OTHER_DMN, 0x20)
70
+ uint8_t *(*bus_pool_base)(AspeedI2CBus *);
55
+ FIELD(PLL_CLK_OTHER_DMN, APLL_BYPASS, 0, 1)
71
} AspeedI2CClass;
56
+REG32(RPLL_CTRL, 0x40)
72
57
+ FIELD(RPLL_CTRL, POST_SRC, 24, 3)
73
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
58
+ FIELD(RPLL_CTRL, PRE_SRC, 20, 3)
74
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
59
+ FIELD(RPLL_CTRL, CLKOUTDIV, 16, 2)
75
index XXXXXXX..XXXXXXX 100644
60
+ FIELD(RPLL_CTRL, FBDIV, 8, 8)
76
--- a/hw/i2c/aspeed_i2c.c
61
+ FIELD(RPLL_CTRL, BYPASS, 3, 1)
77
+++ b/hw/i2c/aspeed_i2c.c
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
78
@@ -XXX,XX +XXX,XX @@
264
@@ -XXX,XX +XXX,XX @@
79
/* I2C Device (Bus) Register */
265
+/*
80
266
+ * QEMU model of the Clock-Reset-LPD (CRL).
81
#define I2CD_FUN_CTRL_REG 0x00 /* I2CD Function Control */
267
+ *
82
-#define I2CD_BUFF_SEL_MASK (0x7 << 20)
268
+ * Copyright (c) 2022 Advanced Micro Devices, Inc.
83
-#define I2CD_BUFF_SEL(x) (x << 20)
269
+ * SPDX-License-Identifier: GPL-2.0-or-later
84
+#define I2CD_POOL_PAGE_SEL(x) (((x) >> 20) & 0x7) /* AST2400 */
270
+ *
85
#define I2CD_M_SDA_LOCK_EN (0x1 << 16)
271
+ * Written by Edgar E. Iglesias <edgar.iglesias@amd.com>
86
#define I2CD_MULTI_MASTER_DIS (0x1 << 15)
272
+ */
87
#define I2CD_M_SCL_DRIVE_EN (0x1 << 14)
273
+
88
@@ -XXX,XX +XXX,XX @@
274
+#include "qemu/osdep.h"
89
#define I2CD_SCL_O_OUT_DIR (0x1 << 12)
275
+#include "qapi/error.h"
90
#define I2CD_BUS_RECOVER_CMD_EN (0x1 << 11)
276
+#include "qemu/log.h"
91
#define I2CD_S_ALT_EN (0x1 << 10)
277
+#include "qemu/bitops.h"
92
-#define I2CD_RX_DMA_ENABLE (0x1 << 9)
278
+#include "migration/vmstate.h"
93
-#define I2CD_TX_DMA_ENABLE (0x1 << 8)
279
+#include "hw/qdev-properties.h"
94
280
+#include "hw/sysbus.h"
95
/* Command Bit */
281
+#include "hw/irq.h"
96
+#define I2CD_RX_DMA_ENABLE (0x1 << 9)
282
+#include "hw/register.h"
97
+#define I2CD_TX_DMA_ENABLE (0x1 << 8)
283
+#include "hw/resettable.h"
98
+#define I2CD_RX_BUFF_ENABLE (0x1 << 7)
284
+
99
+#define I2CD_TX_BUFF_ENABLE (0x1 << 6)
285
+#include "target/arm/arm-powerctl.h"
100
#define I2CD_M_STOP_CMD (0x1 << 5)
286
+#include "hw/misc/xlnx-versal-crl.h"
101
#define I2CD_M_S_RX_CMD_LAST (0x1 << 4)
287
+
102
#define I2CD_M_RX_CMD (0x1 << 3)
288
+#ifndef XLNX_VERSAL_CRL_ERR_DEBUG
103
@@ -XXX,XX +XXX,XX @@
289
+#define XLNX_VERSAL_CRL_ERR_DEBUG 0
104
#define I2CD_M_START_CMD (0x1)
290
+#endif
105
291
+
106
#define I2CD_DEV_ADDR_REG 0x18 /* Slave Device Address */
292
+static void crl_update_irq(XlnxVersalCRL *s)
107
-#define I2CD_BUF_CTRL_REG 0x1c /* Pool Buffer Control */
293
+{
108
+#define I2CD_POOL_CTRL_REG 0x1c /* Pool Buffer Control */
294
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
109
+#define I2CD_POOL_RX_COUNT(x) (((x) >> 24) & 0xff)
295
+ qemu_set_irq(s->irq, pending);
110
+#define I2CD_POOL_RX_SIZE(x) ((((x) >> 16) & 0xff) + 1)
296
+}
111
+#define I2CD_POOL_TX_COUNT(x) ((((x) >> 8) & 0xff) + 1)
297
+
112
+#define I2CD_POOL_OFFSET(x) (((x) & 0x3f) << 2) /* AST2400 */
298
+static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
113
#define I2CD_BYTE_BUF_REG 0x20 /* Transmit/Receive Byte Buffer */
299
+{
114
#define I2CD_BYTE_BUF_TX_SHIFT 0
300
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
115
#define I2CD_BYTE_BUF_TX_MASK 0xff
301
+ crl_update_irq(s);
116
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
302
+}
117
return bus->intr_ctrl;
303
+
118
case I2CD_INTR_STS_REG:
304
+static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
119
return bus->intr_status;
305
+{
120
+ case I2CD_POOL_CTRL_REG:
306
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
121
+ return bus->pool_ctrl;
307
+ uint32_t val = val64;
122
case I2CD_BYTE_BUF_REG:
308
+
123
return bus->buf;
309
+ s->regs[R_IR_MASK] &= ~val;
124
case I2CD_CMD_REG:
310
+ crl_update_irq(s);
125
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
311
+ return 0;
126
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
312
+}
127
}
313
+
128
314
+static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
129
+static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
315
+{
130
+{
316
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
131
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
317
+ uint32_t val = val64;
132
+ int ret = -1;
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);
133
+ int i;
362
+ int i;
134
+
363
+
135
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
364
+ /* A single register fans out to all ADMA reset inputs. */
136
+ for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
365
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); i++) {
137
+ uint8_t *pool_base = aic->bus_pool_base(bus);
366
+ REGFIELD_RESET(dev, s, RST_ADMA, RESET, val64, s->cfg.adma[i]);
138
+
367
+ }
139
+ ret = i2c_send(bus->bus, pool_base[i]);
368
+ return val64;
140
+ if (ret) {
369
+}
141
+ break;
370
+
142
+ }
371
+static uint64_t crl_rst_uart0_prew(RegisterInfo *reg, uint64_t val64)
143
+ }
372
+{
144
+ bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
373
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
145
+ } else {
374
+
146
+ ret = i2c_send(bus->bus, bus->buf);
375
+ REGFIELD_RESET(dev, s, RST_UART0, RESET, val64, s->cfg.uart[0]);
147
+ }
376
+ return val64;
148
+
377
+}
149
+ return ret;
378
+
150
+}
379
+static uint64_t crl_rst_uart1_prew(RegisterInfo *reg, uint64_t val64)
151
+
380
+{
152
+static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
381
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
153
+{
382
+
154
+ AspeedI2CState *s = bus->controller;
383
+ REGFIELD_RESET(dev, s, RST_UART1, RESET, val64, s->cfg.uart[1]);
155
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
384
+ return val64;
156
+ uint8_t data;
385
+}
157
+ int i;
386
+
158
+
387
+static uint64_t crl_rst_gem0_prew(RegisterInfo *reg, uint64_t val64)
159
+ if (bus->cmd & I2CD_RX_BUFF_ENABLE) {
388
+{
160
+ uint8_t *pool_base = aic->bus_pool_base(bus);
389
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
161
+
390
+
162
+ for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
391
+ REGFIELD_RESET(dev, s, RST_GEM0, RESET, val64, s->cfg.gem[0]);
163
+ pool_base[i] = i2c_recv(bus->bus);
392
+ return val64;
164
+ }
393
+}
165
+
394
+
166
+ /* Update RX count */
395
+static uint64_t crl_rst_gem1_prew(RegisterInfo *reg, uint64_t val64)
167
+ bus->pool_ctrl &= ~(0xff << 24);
396
+{
168
+ bus->pool_ctrl |= (i & 0xff) << 24;
397
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
169
+ bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
398
+
170
+ } else {
399
+ REGFIELD_RESET(dev, s, RST_GEM1, RESET, val64, s->cfg.gem[1]);
171
+ data = i2c_recv(bus->bus);
400
+ return val64;
172
+ bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
401
+}
173
+ }
402
+
174
+}
403
+static uint64_t crl_rst_usb_prew(RegisterInfo *reg, uint64_t val64)
175
+
404
+{
176
static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
405
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
177
{
406
+
178
- uint8_t ret;
407
+ REGFIELD_RESET(dev, s, RST_USB0, RESET, val64, s->cfg.usb);
179
-
408
+ return val64;
180
aspeed_i2c_set_state(bus, I2CD_MRXD);
409
+}
181
- ret = i2c_recv(bus->bus);
410
+
182
+ aspeed_i2c_bus_recv(bus);
411
+static const RegisterAccessInfo crl_regs_info[] = {
183
bus->intr_status |= I2CD_INTR_RX_DONE;
412
+ { .name = "ERR_CTRL", .addr = A_ERR_CTRL,
184
- bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
413
+ },{ .name = "IR_STATUS", .addr = A_IR_STATUS,
185
if (bus->cmd & I2CD_M_S_RX_CMD_LAST) {
414
+ .w1c = 0x1,
186
i2c_nack(bus->bus);
415
+ .post_write = crl_status_postw,
187
}
416
+ },{ .name = "IR_MASK", .addr = A_IR_MASK,
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
417
+ .reset = 0x1,
189
aspeed_i2c_set_state(bus, I2CD_MACTIVE);
418
+ .ro = 0x1,
190
}
419
+ },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE,
191
420
+ .pre_write = crl_enable_prew,
192
+static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
421
+ },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE,
193
+{
422
+ .pre_write = crl_disable_prew,
194
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
423
+ },{ .name = "WPROT", .addr = A_WPROT,
195
+
424
+ },{ .name = "PLL_CLK_OTHER_DMN", .addr = A_PLL_CLK_OTHER_DMN,
196
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
425
+ .reset = 0x1,
197
+ uint8_t *pool_base = aic->bus_pool_base(bus);
426
+ .rsvd = 0xe,
198
+
427
+ },{ .name = "RPLL_CTRL", .addr = A_RPLL_CTRL,
199
+ return pool_base[0];
428
+ .reset = 0x24809,
200
+ } else {
429
+ .rsvd = 0xf88c00f6,
201
+ return bus->buf;
430
+ },{ .name = "RPLL_CFG", .addr = A_RPLL_CFG,
202
+ }
431
+ .reset = 0x2000000,
203
+}
432
+ .rsvd = 0x1801210,
204
+
433
+ },{ .name = "RPLL_FRAC_CFG", .addr = A_RPLL_FRAC_CFG,
205
/*
434
+ .rsvd = 0x7e330000,
206
* The state machine needs some refinement. It is only used to track
435
+ },{ .name = "PLL_STATUS", .addr = A_PLL_STATUS,
207
* invalid STOP commands for the moment.
436
+ .reset = R_PLL_STATUS_RPLL_STABLE_MASK |
208
*/
437
+ R_PLL_STATUS_RPLL_LOCK_MASK,
209
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
438
+ .rsvd = 0xfa,
210
{
439
+ .ro = 0x5,
211
+ uint8_t pool_start = 0;
440
+ },{ .name = "RPLL_TO_XPD_CTRL", .addr = A_RPLL_TO_XPD_CTRL,
212
+
441
+ .reset = 0x2000100,
213
bus->cmd &= ~0xFFFF;
442
+ .rsvd = 0xfdfc00ff,
214
bus->cmd |= value & 0xFFFF;
443
+ },{ .name = "LPD_TOP_SWITCH_CTRL", .addr = A_LPD_TOP_SWITCH_CTRL,
215
444
+ .reset = 0x6000300,
216
if (bus->cmd & I2CD_M_START_CMD) {
445
+ .rsvd = 0xf9fc00f8,
217
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
446
+ },{ .name = "LPD_LSBUS_CTRL", .addr = A_LPD_LSBUS_CTRL,
218
I2CD_MSTARTR : I2CD_MSTART;
447
+ .reset = 0x2000800,
219
+ uint8_t addr;
448
+ .rsvd = 0xfdfc00f8,
220
449
+ },{ .name = "CPU_R5_CTRL", .addr = A_CPU_R5_CTRL,
221
aspeed_i2c_set_state(bus, state);
450
+ .reset = 0xe000300,
222
451
+ .rsvd = 0xe1fc00f8,
223
- if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7),
452
+ },{ .name = "IOU_SWITCH_CTRL", .addr = A_IOU_SWITCH_CTRL,
224
- extract32(bus->buf, 0, 1))) {
453
+ .reset = 0x2000500,
225
+ addr = aspeed_i2c_get_addr(bus);
454
+ .rsvd = 0xfdfc00f8,
226
+
455
+ },{ .name = "GEM0_REF_CTRL", .addr = A_GEM0_REF_CTRL,
227
+ if (i2c_start_transfer(bus->bus, extract32(addr, 1, 7),
456
+ .reset = 0xe000a00,
228
+ extract32(addr, 0, 1))) {
457
+ .rsvd = 0xf1fc00f8,
229
bus->intr_status |= I2CD_INTR_TX_NAK;
458
+ },{ .name = "GEM1_REF_CTRL", .addr = A_GEM1_REF_CTRL,
230
} else {
459
+ .reset = 0xe000a00,
231
bus->intr_status |= I2CD_INTR_TX_ACK;
460
+ .rsvd = 0xf1fc00f8,
232
}
461
+ },{ .name = "GEM_TSU_REF_CTRL", .addr = A_GEM_TSU_REF_CTRL,
233
462
+ .reset = 0x300,
234
- /* START command is also a TX command, as the slave address is
463
+ .rsvd = 0xfdfc00f8,
235
- * sent on the bus */
464
+ },{ .name = "USB0_BUS_REF_CTRL", .addr = A_USB0_BUS_REF_CTRL,
236
- bus->cmd &= ~(I2CD_M_START_CMD | I2CD_M_TX_CMD);
465
+ .reset = 0x2001900,
237
+ bus->cmd &= ~I2CD_M_START_CMD;
466
+ .rsvd = 0xfdfc00f8,
238
+
467
+ },{ .name = "UART0_REF_CTRL", .addr = A_UART0_REF_CTRL,
239
+ /*
468
+ .reset = 0xc00,
240
+ * The START command is also a TX command, as the slave
469
+ .rsvd = 0xfdfc00f8,
241
+ * address is sent on the bus. Drop the TX flag if nothing
470
+ },{ .name = "UART1_REF_CTRL", .addr = A_UART1_REF_CTRL,
242
+ * else needs to be sent in this sequence.
471
+ .reset = 0xc00,
243
+ */
472
+ .rsvd = 0xfdfc00f8,
244
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
473
+ },{ .name = "SPI0_REF_CTRL", .addr = A_SPI0_REF_CTRL,
245
+ if (I2CD_POOL_TX_COUNT(bus->pool_ctrl) == 1) {
474
+ .reset = 0x600,
246
+ bus->cmd &= ~I2CD_M_TX_CMD;
475
+ .rsvd = 0xfdfc00f8,
247
+ } else {
476
+ },{ .name = "SPI1_REF_CTRL", .addr = A_SPI1_REF_CTRL,
248
+ /*
477
+ .reset = 0x600,
249
+ * Increase the start index in the TX pool buffer to
478
+ .rsvd = 0xfdfc00f8,
250
+ * skip the address byte.
479
+ },{ .name = "CAN0_REF_CTRL", .addr = A_CAN0_REF_CTRL,
251
+ */
480
+ .reset = 0xc00,
252
+ pool_start++;
481
+ .rsvd = 0xfdfc00f8,
253
+ }
482
+ },{ .name = "CAN1_REF_CTRL", .addr = A_CAN1_REF_CTRL,
254
+ } else {
483
+ .reset = 0xc00,
255
+ bus->cmd &= ~I2CD_M_TX_CMD;
484
+ .rsvd = 0xfdfc00f8,
256
+ }
485
+ },{ .name = "I2C0_REF_CTRL", .addr = A_I2C0_REF_CTRL,
257
486
+ .reset = 0xc00,
258
/* No slave found */
487
+ .rsvd = 0xfdfc00f8,
259
if (!i2c_bus_busy(bus->bus)) {
488
+ },{ .name = "I2C1_REF_CTRL", .addr = A_I2C1_REF_CTRL,
260
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
489
+ .reset = 0xc00,
261
490
+ .rsvd = 0xfdfc00f8,
262
if (bus->cmd & I2CD_M_TX_CMD) {
491
+ },{ .name = "DBG_LPD_CTRL", .addr = A_DBG_LPD_CTRL,
263
aspeed_i2c_set_state(bus, I2CD_MTXD);
492
+ .reset = 0x300,
264
- if (i2c_send(bus->bus, bus->buf)) {
493
+ .rsvd = 0xfdfc00f8,
265
+ if (aspeed_i2c_bus_send(bus, pool_start)) {
494
+ },{ .name = "TIMESTAMP_REF_CTRL", .addr = A_TIMESTAMP_REF_CTRL,
266
bus->intr_status |= (I2CD_INTR_TX_NAK);
495
+ .reset = 0x2000c00,
267
i2c_end_transfer(bus->bus);
496
+ .rsvd = 0xfdfc00f8,
268
} else {
497
+ },{ .name = "CRL_SAFETY_CHK", .addr = A_CRL_SAFETY_CHK,
269
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
498
+ },{ .name = "PSM_REF_CTRL", .addr = A_PSM_REF_CTRL,
270
qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
499
+ .reset = 0xf04,
271
__func__);
500
+ .rsvd = 0xfffc00f8,
272
break;
501
+ },{ .name = "DBG_TSTMP_CTRL", .addr = A_DBG_TSTMP_CTRL,
273
+ case I2CD_POOL_CTRL_REG:
502
+ .reset = 0x300,
274
+ bus->pool_ctrl &= ~0xffffff;
503
+ .rsvd = 0xfdfc00f8,
275
+ bus->pool_ctrl |= (value & 0xffffff);
504
+ },{ .name = "CPM_TOPSW_REF_CTRL", .addr = A_CPM_TOPSW_REF_CTRL,
276
+ break;
505
+ .reset = 0x300,
277
+
506
+ .rsvd = 0xfdfc00f8,
278
case I2CD_BYTE_BUF_REG:
507
+ },{ .name = "USB3_DUAL_REF_CTRL", .addr = A_USB3_DUAL_REF_CTRL,
279
bus->buf = (value & I2CD_BYTE_BUF_TX_MASK) << I2CD_BYTE_BUF_TX_SHIFT;
508
+ .reset = 0x3c00,
280
break;
509
+ .rsvd = 0xfdfc00f8,
281
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_ctrl_ops = {
510
+ },{ .name = "RST_CPU_R5", .addr = A_RST_CPU_R5,
282
.endianness = DEVICE_LITTLE_ENDIAN,
511
+ .reset = 0x17,
283
};
512
+ .rsvd = 0x8,
284
513
+ .pre_write = crl_rst_r5_prew,
285
+static uint64_t aspeed_i2c_pool_read(void *opaque, hwaddr offset,
514
+ },{ .name = "RST_ADMA", .addr = A_RST_ADMA,
286
+ unsigned size)
515
+ .reset = 0x1,
287
+{
516
+ .pre_write = crl_rst_adma_prew,
288
+ AspeedI2CState *s = opaque;
517
+ },{ .name = "RST_GEM0", .addr = A_RST_GEM0,
289
+ uint64_t ret = 0;
518
+ .reset = 0x1,
290
+ int i;
519
+ .pre_write = crl_rst_gem0_prew,
291
+
520
+ },{ .name = "RST_GEM1", .addr = A_RST_GEM1,
292
+ for (i = 0; i < size; i++) {
521
+ .reset = 0x1,
293
+ ret |= (uint64_t) s->pool[offset + i] << (8 * i);
522
+ .pre_write = crl_rst_gem1_prew,
294
+ }
523
+ },{ .name = "RST_SPARE", .addr = A_RST_SPARE,
295
+
524
+ .reset = 0x1,
296
+ return ret;
525
+ },{ .name = "RST_USB0", .addr = A_RST_USB0,
297
+}
526
+ .reset = 0x1,
298
+
527
+ .pre_write = crl_rst_usb_prew,
299
+static void aspeed_i2c_pool_write(void *opaque, hwaddr offset,
528
+ },{ .name = "RST_UART0", .addr = A_RST_UART0,
300
+ uint64_t value, unsigned size)
529
+ .reset = 0x1,
301
+{
530
+ .pre_write = crl_rst_uart0_prew,
302
+ AspeedI2CState *s = opaque;
531
+ },{ .name = "RST_UART1", .addr = A_RST_UART1,
303
+ int i;
532
+ .reset = 0x1,
304
+
533
+ .pre_write = crl_rst_uart1_prew,
305
+ for (i = 0; i < size; i++) {
534
+ },{ .name = "RST_SPI0", .addr = A_RST_SPI0,
306
+ s->pool[offset + i] = (value >> (8 * i)) & 0xFF;
535
+ .reset = 0x1,
307
+ }
536
+ },{ .name = "RST_SPI1", .addr = A_RST_SPI1,
308
+}
537
+ .reset = 0x1,
309
+
538
+ },{ .name = "RST_CAN0", .addr = A_RST_CAN0,
310
+static const MemoryRegionOps aspeed_i2c_pool_ops = {
539
+ .reset = 0x1,
311
+ .read = aspeed_i2c_pool_read,
540
+ },{ .name = "RST_CAN1", .addr = A_RST_CAN1,
312
+ .write = aspeed_i2c_pool_write,
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,
313
+ .endianness = DEVICE_LITTLE_ENDIAN,
587
+ .endianness = DEVICE_LITTLE_ENDIAN,
314
+ .valid = {
588
+ .valid = {
315
+ .min_access_size = 1,
589
+ .min_access_size = 4,
316
+ .max_access_size = 4,
590
+ .max_access_size = 4,
317
+ },
591
+ },
318
+};
592
+};
319
+
593
+
320
static const VMStateDescription aspeed_i2c_bus_vmstate = {
594
+static void crl_init(Object *obj)
321
.name = TYPE_ASPEED_I2C,
595
+{
322
- .version_id = 1,
596
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
323
- .minimum_version_id = 1,
597
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
324
+ .version_id = 2,
598
+ int i;
325
+ .minimum_version_id = 2,
599
+
326
.fields = (VMStateField[]) {
600
+ s->reg_array =
327
VMSTATE_UINT8(id, AspeedI2CBus),
601
+ register_init_block32(DEVICE(obj), crl_regs_info,
328
VMSTATE_UINT32(ctrl, AspeedI2CBus),
602
+ ARRAY_SIZE(crl_regs_info),
329
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
603
+ s->regs_info, s->regs,
330
VMSTATE_UINT32(intr_status, AspeedI2CBus),
604
+ &crl_ops,
331
VMSTATE_UINT32(cmd, AspeedI2CBus),
605
+ XLNX_VERSAL_CRL_ERR_DEBUG,
332
VMSTATE_UINT32(buf, AspeedI2CBus),
606
+ CRL_R_MAX * 4);
333
+ VMSTATE_UINT32(pool_ctrl, AspeedI2CBus),
607
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
334
VMSTATE_END_OF_LIST()
608
+ sysbus_init_irq(sbd, &s->irq);
335
}
609
+
336
};
610
+ for (i = 0; i < ARRAY_SIZE(s->cfg.cpu_r5); ++i) {
337
611
+ object_property_add_link(obj, "cpu_r5[*]", TYPE_ARM_CPU,
338
static const VMStateDescription aspeed_i2c_vmstate = {
612
+ (Object **)&s->cfg.cpu_r5[i],
339
.name = TYPE_ASPEED_I2C,
613
+ qdev_prop_allow_set_link_before_realize,
340
- .version_id = 1,
614
+ OBJ_PROP_LINK_STRONG);
341
- .minimum_version_id = 1,
615
+ }
342
+ .version_id = 2,
616
+
343
+ .minimum_version_id = 2,
617
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); ++i) {
344
.fields = (VMStateField[]) {
618
+ object_property_add_link(obj, "adma[*]", TYPE_DEVICE,
345
VMSTATE_UINT32(intr_status, AspeedI2CState),
619
+ (Object **)&s->cfg.adma[i],
346
VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState,
620
+ qdev_prop_allow_set_link_before_realize,
347
ASPEED_I2C_NR_BUSSES, 1, aspeed_i2c_bus_vmstate,
621
+ OBJ_PROP_LINK_STRONG);
348
AspeedI2CBus),
622
+ }
349
+ VMSTATE_UINT8_ARRAY(pool, AspeedI2CState, ASPEED_I2C_MAX_POOL_SIZE),
623
+
350
VMSTATE_END_OF_LIST()
624
+ for (i = 0; i < ARRAY_SIZE(s->cfg.uart); ++i) {
351
}
625
+ object_property_add_link(obj, "uart[*]", TYPE_DEVICE,
352
};
626
+ (Object **)&s->cfg.uart[i],
353
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
627
+ qdev_prop_allow_set_link_before_realize,
354
memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset),
628
+ OBJ_PROP_LINK_STRONG);
355
&s->busses[i].mr);
629
+ }
356
}
630
+
357
+
631
+ for (i = 0; i < ARRAY_SIZE(s->cfg.gem); ++i) {
358
+ memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
632
+ object_property_add_link(obj, "gem[*]", TYPE_DEVICE,
359
+ "aspeed.i2c-pool", aic->pool_size);
633
+ (Object **)&s->cfg.gem[i],
360
+ memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
634
+ qdev_prop_allow_set_link_before_realize,
361
}
635
+ OBJ_PROP_LINK_STRONG);
362
636
+ }
363
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
637
+
364
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CBus *bus)
638
+ object_property_add_link(obj, "usb", TYPE_DEVICE,
365
return bus->controller->irq;
639
+ (Object **)&s->cfg.gem[i],
366
}
640
+ qdev_prop_allow_set_link_before_realize,
367
641
+ OBJ_PROP_LINK_STRONG);
368
+static uint8_t *aspeed_2400_i2c_bus_pool_base(AspeedI2CBus *bus)
642
+}
369
+{
643
+
370
+ uint8_t *pool_page =
644
+static void crl_finalize(Object *obj)
371
+ &bus->controller->pool[I2CD_POOL_PAGE_SEL(bus->ctrl) * 0x100];
645
+{
372
+
646
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
373
+ return &pool_page[I2CD_POOL_OFFSET(bus->pool_ctrl)];
647
+ register_finalize_block(s->reg_array);
374
+}
648
+}
375
+
649
+
376
static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
650
+static const VMStateDescription vmstate_crl = {
377
{
651
+ .name = TYPE_XLNX_VERSAL_CRL,
378
DeviceClass *dc = DEVICE_CLASS(klass);
652
+ .version_id = 1,
379
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
653
+ .minimum_version_id = 1,
380
aic->reg_size = 0x40;
654
+ .fields = (VMStateField[]) {
381
aic->gap = 7;
655
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalCRL, CRL_R_MAX),
382
aic->bus_get_irq = aspeed_2400_i2c_bus_get_irq;
656
+ VMSTATE_END_OF_LIST(),
383
+ aic->pool_size = 0x800;
657
+ }
384
+ aic->pool_base = 0x800;
658
+};
385
+ aic->bus_pool_base = aspeed_2400_i2c_bus_pool_base;
659
+
386
}
660
+static void crl_class_init(ObjectClass *klass, void *data)
387
661
+{
388
static const TypeInfo aspeed_2400_i2c_info = {
662
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
389
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2500_i2c_bus_get_irq(AspeedI2CBus *bus)
663
+ DeviceClass *dc = DEVICE_CLASS(klass);
390
return bus->controller->irq;
664
+
391
}
665
+ dc->vmsd = &vmstate_crl;
392
666
+
393
+static uint8_t *aspeed_2500_i2c_bus_pool_base(AspeedI2CBus *bus)
667
+ rc->phases.enter = crl_reset_enter;
394
+{
668
+ rc->phases.hold = crl_reset_hold;
395
+ return &bus->controller->pool[bus->id * 0x10];
669
+}
396
+}
670
+
397
+
671
+static const TypeInfo crl_info = {
398
static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
672
+ .name = TYPE_XLNX_VERSAL_CRL,
399
{
673
+ .parent = TYPE_SYS_BUS_DEVICE,
400
DeviceClass *dc = DEVICE_CLASS(klass);
674
+ .instance_size = sizeof(XlnxVersalCRL),
401
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
675
+ .class_init = crl_class_init,
402
aic->reg_size = 0x40;
676
+ .instance_init = crl_init,
403
aic->gap = 7;
677
+ .instance_finalize = crl_finalize,
404
aic->bus_get_irq = aspeed_2500_i2c_bus_get_irq;
678
+};
405
+ aic->pool_size = 0x100;
679
+
406
+ aic->pool_base = 0x200;
680
+static void crl_register_types(void)
407
+ aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
681
+{
408
}
682
+ type_register_static(&crl_info);
409
683
+}
410
static const TypeInfo aspeed_2500_i2c_info = {
684
+
411
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus)
685
+type_init(crl_register_types)
412
return bus->irq;
686
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
413
}
687
index XXXXXXX..XXXXXXX 100644
414
688
--- a/hw/misc/meson.build
415
+static uint8_t *aspeed_2600_i2c_bus_pool_base(AspeedI2CBus *bus)
689
+++ b/hw/misc/meson.build
416
+{
690
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
417
+ return &bus->controller->pool[bus->id * 0x20];
691
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
418
+}
692
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-crf.c'))
419
+
693
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-apu-ctrl.c'))
420
static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
694
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
421
{
695
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
422
DeviceClass *dc = DEVICE_CLASS(klass);
696
'xlnx-versal-xramc.c',
423
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
697
'xlnx-versal-pmc-iou-slcr.c',
424
aic->reg_size = 0x80;
425
aic->gap = -1; /* no gap */
426
aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
427
+ aic->pool_size = 0x200;
428
+ aic->pool_base = 0xC00;
429
+ aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
430
}
431
432
static const TypeInfo aspeed_2600_i2c_info = {
433
--
698
--
434
2.20.1
699
2.25.1
435
436
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
The SRAM must be enabled before using the Buffer Pool mode or the DMA
3
Connect the CRL (Clock Reset LPD) to the Versal SoC.
4
mode. This is not required on other SoCs.
5
4
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
8
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com
10
Message-id: 20191119141211.25716-3-clg@kaod.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
include/hw/i2c/aspeed_i2c.h | 3 +++
11
include/hw/arm/xlnx-versal.h | 4 +++
14
hw/i2c/aspeed_i2c.c | 37 +++++++++++++++++++++++++++++++++++++
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
15
2 files changed, 40 insertions(+)
13
2 files changed, 56 insertions(+), 2 deletions(-)
16
14
17
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/i2c/aspeed_i2c.h
17
--- a/include/hw/arm/xlnx-versal.h
20
+++ b/include/hw/i2c/aspeed_i2c.h
18
+++ b/include/hw/arm/xlnx-versal.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
19
@@ -XXX,XX +XXX,XX @@
22
qemu_irq irq;
20
#include "hw/nvram/xlnx-versal-efuse.h"
23
21
#include "hw/ssi/xlnx-versal-ospi.h"
24
uint32_t intr_status;
22
#include "hw/dma/xlnx_csu_dma.h"
25
+ uint32_t ctrl_global;
23
+#include "hw/misc/xlnx-versal-crl.h"
26
MemoryRegion pool_iomem;
24
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
27
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
25
28
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
27
@@ -XXX,XX +XXX,XX @@ struct Versal {
30
uint64_t pool_size;
28
qemu_or_irq irq_orgate;
31
hwaddr pool_base;
29
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
32
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
30
} xram;
33
+ bool check_sram;
34
+
31
+
35
} AspeedI2CClass;
32
+ XlnxVersalCRL crl;
36
33
} lpd;
37
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
34
38
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
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
39
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/i2c/aspeed_i2c.c
46
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/i2c/aspeed_i2c.c
47
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@
48
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
43
#define I2C_CTRL_STATUS 0x00 /* Device Interrupt Status */
49
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
44
#define I2C_CTRL_ASSIGN 0x08 /* Device Interrupt Target
45
Assignment */
46
+#define I2C_CTRL_GLOBAL 0x0C /* Global Control Register */
47
+#define I2C_CTRL_SRAM_EN BIT(0)
48
49
/* I2C Device (Bus) Register */
50
51
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
52
}
53
}
50
}
54
51
55
+static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
56
+{
53
+{
57
+ AspeedI2CState *s = bus->controller;
54
+ SysBusDevice *sbd;
58
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
55
+ int i;
59
+
56
+
60
+ if (!aic->check_sram) {
57
+ object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
61
+ return true;
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);
62
+ }
67
+ }
63
+
68
+
64
+ /*
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
65
+ * AST2500: SRAM must be enabled before using the Buffer Pool or
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
66
+ * DMA mode.
71
+
67
+ */
72
+ object_property_set_link(OBJECT(&s->lpd.crl),
68
+ if (!(s->ctrl_global & I2C_CTRL_SRAM_EN) &&
73
+ name, OBJECT(&s->lpd.iou.gem[i]),
69
+ (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE |
74
+ &error_abort);
70
+ I2CD_RX_BUFF_ENABLE | I2CD_TX_BUFF_ENABLE))) {
71
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: SRAM is not enabled\n", __func__);
72
+ return false;
73
+ }
75
+ }
74
+
76
+
75
+ return true;
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]);
76
+}
101
+}
77
+
102
+
78
/*
103
/* This takes the board allocated linear DDR memory and creates aliases
79
* The state machine needs some refinement. It is only used to track
104
* for each split DDR range/aperture on the Versal address map.
80
* invalid STOP commands for the moment.
105
*/
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
106
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
82
bus->cmd &= ~0xFFFF;
107
83
bus->cmd |= value & 0xFFFF;
108
versal_unimp_area(s, "psm", &s->mr_ps,
84
109
MM_PSM_START, MM_PSM_END - MM_PSM_START);
85
+ if (!aspeed_i2c_check_sram(bus)) {
110
- versal_unimp_area(s, "crl", &s->mr_ps,
86
+ return;
111
- MM_CRL, MM_CRL_SIZE);
87
+ }
112
versal_unimp_area(s, "crf", &s->mr_ps,
88
+
113
MM_FPD_CRF, MM_FPD_CRF_SIZE);
89
if (bus->cmd & I2CD_M_START_CMD) {
114
versal_unimp_area(s, "apu", &s->mr_ps,
90
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
115
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
91
I2CD_MSTARTR : I2CD_MSTART;
116
versal_create_efuse(s, pic);
92
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
117
versal_create_pmc_iou_slcr(s, pic);
93
switch (offset) {
118
versal_create_ospi(s, pic);
94
case I2C_CTRL_STATUS:
119
+ versal_create_crl(s, pic);
95
return s->intr_status;
120
versal_map_ddr(s);
96
+ case I2C_CTRL_GLOBAL:
121
versal_unimp(s);
97
+ return s->ctrl_global;
122
98
default:
99
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
100
__func__, offset);
101
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
102
static void aspeed_i2c_ctrl_write(void *opaque, hwaddr offset,
103
uint64_t value, unsigned size)
104
{
105
+ AspeedI2CState *s = opaque;
106
+
107
switch (offset) {
108
+ case I2C_CTRL_GLOBAL:
109
+ s->ctrl_global = value;
110
+ break;
111
case I2C_CTRL_STATUS:
112
default:
113
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
114
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
115
aic->pool_size = 0x100;
116
aic->pool_base = 0x200;
117
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
118
+ aic->check_sram = true;
119
}
120
121
static const TypeInfo aspeed_2500_i2c_info = {
122
--
123
--
123
2.20.1
124
2.25.1
124
125
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.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
The Aspeed MII model has a link pointing to its associated FTGMAC100
6
(This is a migration compatibility break, but that is OK for this
4
NIC in the machine.
7
machine type.)
5
8
6
Change the "nic" property definition so that it explicitly sets the
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
pointer. The property isn't optional : not being able to set the link
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
is a bug and QEMU should rather abort than exit in this case.
11
Message-id: 20220404154658.565020-2-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 +
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
15
2 files changed, 17 insertions(+), 15 deletions(-)
9
16
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
11
Reviewed-by: Greg Kurz <groug@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-18-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/aspeed_ast2600.c | 5 ++---
18
hw/net/ftgmac100.c | 19 +++++++++----------
19
2 files changed, 11 insertions(+), 13 deletions(-)
20
21
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/aspeed_ast2600.c
19
--- a/include/hw/arm/exynos4210.h
24
+++ b/hw/arm/aspeed_ast2600.c
20
+++ b/include/hw/arm/exynos4210.h
25
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
26
22
MemoryRegion bootreg_mem;
27
sysbus_init_child_obj(obj, "mii[*]", &s->mii[i], sizeof(s->mii[i]),
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
28
TYPE_ASPEED_MII);
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
29
- object_property_add_const_link(OBJECT(&s->mii[i]), "nic",
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
30
- OBJECT(&s->ftgmac100[i]),
26
};
31
- &error_abort);
27
28
#define TYPE_EXYNOS4210_SOC "exynos4210"
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
{
35
Exynos4210State *s = EXYNOS4210_SOC(socdev);
36
MemoryRegion *system_mem = get_system_memory();
37
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
38
SysBusDevice *busdev;
39
DeviceState *dev, *uart[4], *pl330[3];
40
int i, n;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
42
43
/* IRQ Gate */
44
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
45
- dev = qdev_new("exynos4210.irq_gate");
46
- qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
47
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
48
- /* Get IRQ Gate input in gate_irq */
49
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
50
- gate_irq[i][n] = qdev_get_gpio_in(dev, n);
51
- }
52
- busdev = SYS_BUS_DEVICE(dev);
53
-
54
- /* Connect IRQ Gate output to CPU's IRQ line */
55
- sysbus_connect_irq(busdev, 0,
56
- qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
57
+ DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
58
+ object_property_set_int(OBJECT(orgate), "num-lines",
59
+ EXYNOS4210_IRQ_GATE_NINPUTS,
60
+ &error_abort);
61
+ qdev_realize(orgate, NULL, &error_abort);
62
+ qdev_connect_gpio_out(orgate, 0,
63
+ qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
32
}
64
}
33
65
34
sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
66
/* Private memory region and Internal GIC */
35
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
67
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
36
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
68
sysbus_realize_and_unref(busdev, &error_fatal);
37
aspeed_soc_get_irq(s, ASPEED_ETH1 + i));
69
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
38
70
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
39
+ object_property_set_link(OBJECT(&s->mii[i]), OBJECT(&s->ftgmac100[i]),
71
- sysbus_connect_irq(busdev, n, gate_irq[n][0]);
40
+ "nic", &error_abort);
72
+ sysbus_connect_irq(busdev, n,
41
object_property_set_bool(OBJECT(&s->mii[i]), true, "realized",
73
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
42
&err);
43
if (err) {
44
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/net/ftgmac100.c
47
+++ b/hw/net/ftgmac100.c
48
@@ -XXX,XX +XXX,XX @@ static void aspeed_mii_realize(DeviceState *dev, Error **errp)
49
{
50
AspeedMiiState *s = ASPEED_MII(dev);
51
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
52
- Object *obj;
53
- Error *local_err = NULL;
54
55
- obj = object_property_get_link(OBJECT(dev), "nic", &local_err);
56
- if (!obj) {
57
- error_propagate(errp, local_err);
58
- error_prepend(errp, "required link 'nic' not found: ");
59
- return;
60
- }
61
-
62
- s->nic = FTGMAC100(obj);
63
+ assert(s->nic);
64
65
memory_region_init_io(&s->iomem, OBJECT(dev), &aspeed_mii_ops, s,
66
TYPE_ASPEED_MII, 0x8);
67
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_mii = {
68
VMSTATE_END_OF_LIST()
69
}
74
}
70
};
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
}
71
+
91
+
72
+static Property aspeed_mii_properties[] = {
92
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
73
+ DEFINE_PROP_LINK("nic", AspeedMiiState, nic, TYPE_FTGMAC100,
93
+ g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
74
+ FTGMAC100State *),
94
+ object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
75
+ DEFINE_PROP_END_OF_LIST(),
95
+ }
76
+};
77
+
78
static void aspeed_mii_class_init(ObjectClass *klass, void *data)
79
{
80
DeviceClass *dc = DEVICE_CLASS(klass);
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_mii_class_init(ObjectClass *klass, void *data)
82
dc->reset = aspeed_mii_reset;
83
dc->realize = aspeed_mii_realize;
84
dc->desc = "Aspeed MII controller";
85
+ dc->props = aspeed_mii_properties;
86
}
96
}
87
97
88
static const TypeInfo aspeed_mii_info = {
98
static void exynos4210_class_init(ObjectClass *klass, void *data)
89
--
99
--
90
2.20.1
100
2.25.1
91
92
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Now we have removed the only use of TYPE_EXYNOS4210_IRQ_GATE we can
2
delete the device entirely.
2
3
3
A write to the SCR can change the effective EL by droppping the system
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
from secure to non-secure mode. However if we use a cached current_el
5
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
from before the change we'll rebuild the flags incorrectly. To fix
6
Message-id: 20220404154658.565020-3-peter.maydell@linaro.org
6
this we introduce the ARM_CP_NEWEL CP flag to indicate the new EL
7
---
7
should be used when recomputing the flags.
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
9
1 file changed, 107 deletions(-)
8
10
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
10
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20191212114734.6962-1-alex.bennee@linaro.org
13
Cc: Richard Henderson <richard.henderson@linaro.org>
14
Message-Id: <20191209143723.6368-1-alex.bennee@linaro.org>
15
Cc: qemu-stable@nongnu.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/cpu.h | 8 ++++++--
19
target/arm/helper.h | 1 +
20
target/arm/helper.c | 14 +++++++++++++-
21
target/arm/translate.c | 6 +++++-
22
4 files changed, 25 insertions(+), 4 deletions(-)
23
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu.h
13
--- a/hw/intc/exynos4210_gic.c
27
+++ b/target/arm/cpu.h
14
+++ b/hw/intc/exynos4210_gic.c
28
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
29
* RAISES_EXC is for when the read or write hook might raise an exception;
30
* the generated code will synchronize the CPU state before calling the hook
31
* so that it is safe for the hook to call raise_exception().
32
+ * NEWEL is for writes to registers that might change the exception
33
+ * level - typically on older ARM chips. For those cases we need to
34
+ * re-read the new el when recomputing the translation flags.
35
*/
36
#define ARM_CP_SPECIAL 0x0001
37
#define ARM_CP_CONST 0x0002
38
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
39
#define ARM_CP_SVE 0x2000
40
#define ARM_CP_NO_GDB 0x4000
41
#define ARM_CP_RAISES_EXC 0x8000
42
+#define ARM_CP_NEWEL 0x10000
43
/* Used only as a terminator for ARMCPRegInfo lists */
44
-#define ARM_CP_SENTINEL 0xffff
45
+#define ARM_CP_SENTINEL 0xfffff
46
/* Mask of only the flag bits in a type field */
47
-#define ARM_CP_FLAG_MASK 0xf0ff
48
+#define ARM_CP_FLAG_MASK 0x1f0ff
49
50
/* Valid values for ARMCPRegInfo state field, indicating which of
51
* the AArch32 and AArch64 execution states this register is visible in.
52
diff --git a/target/arm/helper.h b/target/arm/helper.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/helper.h
55
+++ b/target/arm/helper.h
56
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_user_reg, i32, env, i32)
57
DEF_HELPER_3(set_user_reg, void, env, i32, i32)
58
59
DEF_HELPER_FLAGS_2(rebuild_hflags_m32, TCG_CALL_NO_RWG, void, env, int)
60
+DEF_HELPER_FLAGS_1(rebuild_hflags_a32_newel, TCG_CALL_NO_RWG, void, env)
61
DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, int)
62
DEF_HELPER_FLAGS_2(rebuild_hflags_a64, TCG_CALL_NO_RWG, void, env, int)
63
64
diff --git a/target/arm/helper.c b/target/arm/helper.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/helper.c
67
+++ b/target/arm/helper.c
68
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
69
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
70
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
71
.resetvalue = 0, .writefn = scr_write },
72
- { .name = "SCR", .type = ARM_CP_ALIAS,
73
+ { .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
74
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
75
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
76
.fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
77
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
78
env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
79
}
16
}
80
17
81
+/*
18
type_init(exynos4210_gic_register_types)
82
+ * If we have triggered a EL state change we can't rely on the
19
-
83
+ * translator having passed it too us, we need to recompute.
20
-/* IRQ OR Gate struct.
84
+ */
21
- *
85
+void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
86
+{
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
87
+ int el = arm_current_el(env);
24
- * gpio inputs.
88
+ int fp_el = fp_exception_el(env, el);
25
- */
89
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
26
-
90
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
27
-#define TYPE_EXYNOS4210_IRQ_GATE "exynos4210.irq_gate"
91
+}
28
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210IRQGateState, EXYNOS4210_IRQ_GATE)
92
+
29
-
93
void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
30
-struct Exynos4210IRQGateState {
94
{
31
- SysBusDevice parent_obj;
95
int fp_el = fp_exception_el(env, el);
32
-
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
33
- uint32_t n_in; /* inputs amount */
97
index XXXXXXX..XXXXXXX 100644
34
- uint32_t *level; /* input levels */
98
--- a/target/arm/translate.c
35
- qemu_irq out; /* output IRQ */
99
+++ b/target/arm/translate.c
36
-};
100
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
37
-
101
if (arm_dc_feature(s, ARM_FEATURE_M)) {
38
-static Property exynos4210_irq_gate_properties[] = {
102
gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
39
- DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
103
} else {
40
- DEFINE_PROP_END_OF_LIST(),
104
- gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
41
-};
105
+ if (ri->type & ARM_CP_NEWEL) {
42
-
106
+ gen_helper_rebuild_hflags_a32_newel(cpu_env);
43
-static const VMStateDescription vmstate_exynos4210_irq_gate = {
107
+ } else {
44
- .name = "exynos4210.irq_gate",
108
+ gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
45
- .version_id = 2,
109
+ }
46
- .minimum_version_id = 2,
110
}
47
- .fields = (VMStateField[]) {
111
tcg_temp_free_i32(tcg_el);
48
- VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, n_in),
112
/*
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)
113
--
126
--
114
2.20.1
127
2.25.1
115
116
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
The exynos4210 SoC mostly creates its child devices as if it were
2
board code. This includes the a9mpcore object. Switch that to a
3
new-style "embedded in the state struct" creation, because in the
4
next commit we're going to want to refer to the object again further
5
down in the exynos4210_realize() function.
2
6
3
HCR_EL2.TID2 mandates that access from EL1 to CTR_EL0, CCSIDR_EL1,
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
CCSIDR2_EL1, CLIDR_EL1, CSSELR_EL1 are trapped to EL2, and QEMU
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
completely ignores it, making it impossible for hypervisors to
9
Message-id: 20220404154658.565020-4-peter.maydell@linaro.org
6
virtualize the cache hierarchy.
10
---
11
include/hw/arm/exynos4210.h | 2 ++
12
hw/arm/exynos4210.c | 11 ++++++-----
13
2 files changed, 8 insertions(+), 5 deletions(-)
7
14
8
Do the right thing by trapping to EL2 if HCR_EL2.TID2 is set.
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
9
10
Signed-off-by: Marc Zyngier <maz@kernel.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20191201122018.25808-2-maz@kernel.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/helper.c | 31 +++++++++++++++++++++++++++----
17
1 file changed, 27 insertions(+), 4 deletions(-)
18
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
17
--- a/include/hw/arm/exynos4210.h
22
+++ b/target/arm/helper.c
18
+++ b/include/hw/arm/exynos4210.h
23
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
19
@@ -XXX,XX +XXX,XX @@
24
raw_write(env, ri, value);
20
25
}
21
#include "hw/or-irq.h"
26
22
#include "hw/sysbus.h"
27
+static CPAccessResult access_aa64_tid2(CPUARMState *env,
23
+#include "hw/cpu/a9mpcore.h"
28
+ const ARMCPRegInfo *ri,
24
#include "target/arm/cpu-qom.h"
29
+ bool isread)
25
#include "qom/object.h"
30
+{
26
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID2)) {
27
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
32
+ return CP_ACCESS_TRAP_EL2;
28
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
33
+ }
29
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
34
+
30
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
35
+ return CP_ACCESS_OK;
31
+ A9MPPrivState a9mpcore;
36
+}
32
};
37
+
33
38
static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
34
#define TYPE_EXYNOS4210_SOC "exynos4210"
39
{
35
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
40
ARMCPU *cpu = env_archcpu(env);
36
index XXXXXXX..XXXXXXX 100644
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
37
--- a/hw/arm/exynos4210.c
42
.writefn = pmintenclr_write },
38
+++ b/hw/arm/exynos4210.c
43
{ .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
39
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
44
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
40
}
45
- .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
41
46
+ .access = PL1_R,
42
/* Private memory region and Internal GIC */
47
+ .accessfn = access_aa64_tid2,
43
- dev = qdev_new(TYPE_A9MPCORE_PRIV);
48
+ .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
44
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
49
{ .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
45
- busdev = SYS_BUS_DEVICE(dev);
50
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
46
- sysbus_realize_and_unref(busdev, &error_fatal);
51
- .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
47
+ qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
52
+ .access = PL1_RW,
48
+ busdev = SYS_BUS_DEVICE(&s->a9mpcore);
53
+ .accessfn = access_aa64_tid2,
49
+ sysbus_realize(busdev, &error_fatal);
54
+ .writefn = csselr_write, .resetvalue = 0,
50
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
55
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
51
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
56
offsetof(CPUARMState, cp15.csselr_ns) } },
52
sysbus_connect_irq(busdev, n,
57
/* Auxiliary ID register: this actually has an IMPDEF value but for now
53
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
58
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
54
}
59
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCT)) {
55
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
60
return CP_ACCESS_TRAP;
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);
61
}
64
}
62
+
65
+
63
+ if (arm_current_el(env) < 2 && arm_hcr_el2_eff(env) & HCR_TID2) {
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
64
+ return CP_ACCESS_TRAP_EL2;
65
+ }
66
+
67
return CP_ACCESS_OK;
68
}
67
}
69
68
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
71
ARMCPRegInfo clidr = {
72
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
73
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
74
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr
75
+ .access = PL1_R, .type = ARM_CP_CONST,
76
+ .accessfn = access_aa64_tid2,
77
+ .resetvalue = cpu->clidr
78
};
79
define_one_arm_cp_reg(cpu, &clidr);
80
define_arm_cp_regs(cpu, v7_cp_reginfo);
81
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
82
/* These are common to v8 and pre-v8 */
83
{ .name = "CTR",
84
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
85
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
86
+ .access = PL1_R, .accessfn = ctr_el0_access,
87
+ .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
88
{ .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
89
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
90
.access = PL0_R, .accessfn = ctr_el0_access,
91
--
70
--
92
2.20.1
71
2.25.1
93
94
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
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.
2
8
3
After the introduction of generic PCIe root port and PCIe-PCI bridge,
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
we will also have SHPC controller on ARM, so just enable SHPC native
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
hot plug.
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(-)
6
16
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
8
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
10
Cc: Peter Maydell <peter.maydell@linaro.org>
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
12
Cc: Igor Mammedov <imammedo@redhat.com>
13
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
16
Message-id: 20191209063719.23086-3-guoheyi@huawei.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
hw/arm/virt-acpi-build.c | 7 ++++++-
20
tests/data/acpi/virt/DSDT | Bin 18462 -> 18462 bytes
21
tests/data/acpi/virt/DSDT.memhp | Bin 19799 -> 19799 bytes
22
tests/data/acpi/virt/DSDT.numamem | Bin 18462 -> 18462 bytes
23
4 files changed, 6 insertions(+), 1 deletion(-)
24
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
26
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
19
--- a/include/hw/arm/exynos4210.h
28
+++ b/hw/arm/virt-acpi-build.c
20
+++ b/include/hw/arm/exynos4210.h
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
21
@@ -XXX,XX +XXX,XX @@
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
22
typedef struct Exynos4210Irq {
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
33
- aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
25
- qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
34
+
26
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
35
+ /*
27
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
36
+ * Allow OS control for all 5 features:
28
} Exynos4210Irq;
37
+ * PCIeHotplug SHPCHotplug PME AER PCIeCapability.
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
38
+ */
39
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F),
40
aml_name("CTRL")));
41
42
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
43
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
44
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
45
GIT binary patch
31
--- a/hw/arm/exynos4210.c
46
delta 28
32
+++ b/hw/arm/exynos4210.c
47
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
48
34
sysbus_connect_irq(busdev, n,
49
delta 28
35
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
50
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
36
}
51
37
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
52
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
38
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
53
index XXXXXXX..XXXXXXX 100644
39
- }
54
GIT binary patch
40
55
delta 28
41
/* Cache controller */
56
kcmcaUi}Cs_MlP3NmymE@1_mbija=*8809zbbeqQp0Eq|*2mk;8
42
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
57
43
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
58
delta 28
44
busdev = SYS_BUS_DEVICE(dev);
59
kcmcaUi}Cs_MlP3NmymE@1_ma@ja=*87-cu_beqQp0ErX{2mk;8
45
sysbus_realize_and_unref(busdev, &error_fatal);
60
46
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
61
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
47
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
62
index XXXXXXX..XXXXXXX 100644
48
+ sysbus_connect_irq(busdev, n,
63
GIT binary patch
49
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
64
delta 28
50
}
65
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
51
exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
66
52
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
67
delta 28
68
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
69
70
--
53
--
71
2.20.1
54
2.25.1
72
73
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
The exynos4210 code currently has two very similar arrays of IRQs:
2
2
3
Users benefit from knowing which watchdog timer has expired. The address
3
* board_irqs is a field of the Exynos4210Irq struct which is filled
4
of the watchdog's registers unambiguously indicates which has expired,
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
5
so log that.
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
6
10
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
11
The extra indirection through irq_table is unnecessary, so coalesce
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
these into a single irq_table[] array as a direct field in
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
13
Exynos4210State which exynos4210_init_board_irqs() fills in.
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
11
Message-id: 20191119141211.25716-9-clg@kaod.org
12
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
13
---
18
---
14
hw/watchdog/wdt_aspeed.c | 3 ++-
19
include/hw/arm/exynos4210.h | 8 ++------
15
1 file changed, 2 insertions(+), 1 deletion(-)
20
hw/arm/exynos4210.c | 6 +-----
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
22
3 files changed, 11 insertions(+), 35 deletions(-)
16
23
17
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/watchdog/wdt_aspeed.c
26
--- a/include/hw/arm/exynos4210.h
20
+++ b/hw/watchdog/wdt_aspeed.c
27
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_timer_expired(void *dev)
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
22
return;
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
33
} Exynos4210Irq;
34
35
struct Exynos4210State {
36
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
37
/*< public >*/
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
39
Exynos4210Irq irqs;
40
- qemu_irq *irq_table;
41
+ qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
42
43
MemoryRegion chipid_mem;
44
MemoryRegion iram_mem;
45
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
46
void exynos4210_write_secondary(ARMCPU *cpu,
47
const struct arm_boot_info *info);
48
49
-/* Initialize exynos4210 IRQ subsystem stub */
50
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
51
-
52
/* Initialize board IRQs.
53
* These IRQs contain splitted Int/External Combiner and External Gic IRQs */
54
-void exynos4210_init_board_irqs(Exynos4210Irq *s);
55
+void exynos4210_init_board_irqs(Exynos4210State *s);
56
57
/* Get IRQ number from exynos4210 IRQ subsystem stub.
58
* To identify IRQ source use internal combiner group and bit number
59
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/exynos4210.c
62
+++ b/hw/arm/exynos4210.c
63
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
64
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
23
}
65
}
24
66
25
- qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
67
- /*** IRQs ***/
26
+ qemu_log_mask(CPU_LOG_RESET, "Watchdog timer %" HWADDR_PRIx " expired.\n",
68
-
27
+ s->iomem.addr);
69
- s->irq_table = exynos4210_init_irq(&s->irqs);
28
watchdog_perform_action();
70
-
29
timer_del(s->timer);
71
/* IRQ Gate */
72
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
73
DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
74
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
75
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
76
77
/* Initialize board IRQs. */
78
- exynos4210_init_board_irqs(&s->irqs);
79
+ exynos4210_init_board_irqs(s);
80
81
/*** Memory ***/
82
83
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/intc/exynos4210_gic.c
86
+++ b/hw/intc/exynos4210_gic.c
87
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
88
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
89
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
90
91
-static void exynos4210_irq_handler(void *opaque, int irq, int level)
92
-{
93
- Exynos4210Irq *s = (Exynos4210Irq *)opaque;
94
-
95
- /* Bypass */
96
- qemu_set_irq(s->board_irqs[irq], level);
97
-}
98
-
99
-/*
100
- * Initialize exynos4210 IRQ subsystem stub.
101
- */
102
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *s)
103
-{
104
- return qemu_allocate_irqs(exynos4210_irq_handler, s,
105
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ);
106
-}
107
-
108
/*
109
* Initialize board IRQs.
110
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
111
*/
112
-void exynos4210_init_board_irqs(Exynos4210Irq *s)
113
+void exynos4210_init_board_irqs(Exynos4210State *s)
114
{
115
uint32_t grp, bit, irq_id, n;
116
+ Exynos4210Irq *is = &s->irqs;
117
118
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
119
irq_id = 0;
120
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
121
irq_id = EXT_GIC_ID_MCT_G1;
122
}
123
if (irq_id) {
124
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
125
- s->ext_gic_irq[irq_id-32]);
126
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
127
+ is->ext_gic_irq[irq_id - 32]);
128
} else {
129
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
130
- s->ext_combiner_irq[n]);
131
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
132
+ is->ext_combiner_irq[n]);
133
}
134
}
135
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
136
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
137
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
138
139
if (irq_id) {
140
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
141
- s->ext_gic_irq[irq_id-32]);
142
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
143
+ is->ext_gic_irq[irq_id - 32]);
144
}
145
}
30
}
146
}
31
--
147
--
32
2.20.1
148
2.25.1
33
34
diff view generated by jsdifflib
1
From: David Gibson <david@gibson.dropbear.id.au>
1
Fix a missing set of spaces around '-' in the definition of
2
combiner_grp_to_gic_id[]. We're about to move this code, so
3
fix the style issue first to keep checkpatch happy with the
4
code-motion patch.
2
5
3
exynos4210_gic_realize() prints the number of cpus into some temporary
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
buffers, but it only allows 3 bytes space for it. That's plenty:
5
existing machines will only ever set this value to EXYNOS4210_NCPUS
6
(2). But the compiler can't always figure that out, so some[*] gcc9
7
versions emit -Wformat-truncation warnings.
8
9
We can fix that by hinting the constraint to the compiler with a
10
suitably placed assert().
11
12
[*] The bizarre thing here, is that I've long gotten these warnings
13
compiling in a 32-bit x86 container as host - Fedora 30 with
14
gcc-9.2.1-1.fc30.i686 - but it compiles just fine on my normal
15
x86_64 host - Fedora 30 with and gcc-9.2.1-1.fc30.x86_64.
16
17
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
[PMM: deleted stray blank line]
8
Message-id: 20220404154658.565020-7-peter.maydell@linaro.org
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
9
---
23
hw/intc/exynos4210_gic.c | 9 ++++++++-
10
hw/intc/exynos4210_gic.c | 2 +-
24
1 file changed, 8 insertions(+), 1 deletion(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
25
12
26
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
27
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/exynos4210_gic.c
15
--- a/hw/intc/exynos4210_gic.c
29
+++ b/hw/intc/exynos4210_gic.c
16
+++ b/hw/intc/exynos4210_gic.c
30
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
31
char cpu_alias_name[sizeof(cpu_prefix) + 3];
18
*/
32
char dist_alias_name[sizeof(cpu_prefix) + 3];
19
33
SysBusDevice *gicbusdev;
20
static const uint32_t
34
+ uint32_t n = s->num_cpu;
21
-combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
35
uint32_t i;
22
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
36
23
/* int combiner groups 16-19 */
37
s->gic = qdev_create(NULL, "arm_gic");
24
{ }, { }, { }, { },
38
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
25
/* int combiner group 20 */
39
memory_region_init(&s->dist_container, obj, "exynos4210-dist-container",
40
EXYNOS4210_EXT_GIC_DIST_REGION_SIZE);
41
42
- for (i = 0; i < s->num_cpu; i++) {
43
+ /*
44
+ * This clues in gcc that our on-stack buffers do, in fact have
45
+ * enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
46
+ * doesn't figure this out, otherwise and gives spurious warnings.
47
+ */
48
+ assert(n <= EXYNOS4210_NCPUS);
49
+ for (i = 0; i < n; i++) {
50
/* Map CPU interface per SMP Core */
51
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
52
memory_region_init_alias(&s->cpu_alias[i], obj,
53
--
26
--
54
2.20.1
27
2.25.1
55
56
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
The function exynos4210_init_board_irqs() currently lives in
2
exynos4210_gic.c, but it isn't really part of the exynos4210.gic
3
device -- it is a function that implements (some of) the wiring up of
4
interrupts between the SoC's GIC and combiner components. This means
5
it fits better in exynos4210.c, which is the SoC-level code. Move it
6
there. Similarly, exynos4210_git_irq() is used almost only in the
7
SoC-level code, so move it too.
2
8
3
Add an option to trigger memory writeback to sync given memory region
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
with the corresponding backing store, case one is available.
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
This extends the support for persistent memory, allowing syncing on-demand.
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 4 -
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
16
3 files changed, 202 insertions(+), 208 deletions(-)
6
17
7
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20191121000843.24844-3-beata.michalska@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/exec/memory.h | 6 ++++++
13
include/exec/ram_addr.h | 8 ++++++++
14
include/qemu/cutils.h | 1 +
15
exec.c | 36 ++++++++++++++++++++++++++++++++++++
16
memory.c | 12 ++++++++++++
17
util/cutils.c | 38 ++++++++++++++++++++++++++++++++++++++
18
6 files changed, 101 insertions(+)
19
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/memory.h
20
--- a/include/hw/arm/exynos4210.h
23
+++ b/include/exec/memory.h
21
+++ b/include/hw/arm/exynos4210.h
24
@@ -XXX,XX +XXX,XX @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
25
*/
23
void exynos4210_write_secondary(ARMCPU *cpu,
26
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
24
const struct arm_boot_info *info);
27
Error **errp);
25
28
+/**
26
-/* Initialize board IRQs.
29
+ * memory_region_do_writeback: Trigger writeback for selected address range
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
30
+ * [addr, addr + size]
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
31
+ *
29
-
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
31
* To identify IRQ source use internal combiner group and bit number
32
* grp - group number
33
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/exynos4210.c
36
+++ b/hw/arm/exynos4210.c
37
@@ -XXX,XX +XXX,XX @@
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
40
41
+enum ExtGicId {
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
43
+ EXT_GIC_ID_PDMA0,
44
+ EXT_GIC_ID_PDMA1,
45
+ EXT_GIC_ID_TIMER0,
46
+ EXT_GIC_ID_TIMER1,
47
+ EXT_GIC_ID_TIMER2,
48
+ EXT_GIC_ID_TIMER3,
49
+ EXT_GIC_ID_TIMER4,
50
+ EXT_GIC_ID_MCT_L0,
51
+ EXT_GIC_ID_WDT,
52
+ EXT_GIC_ID_RTC_ALARM,
53
+ EXT_GIC_ID_RTC_TIC,
54
+ EXT_GIC_ID_GPIO_XB,
55
+ EXT_GIC_ID_GPIO_XA,
56
+ EXT_GIC_ID_MCT_L1,
57
+ EXT_GIC_ID_IEM_APC,
58
+ EXT_GIC_ID_IEM_IEC,
59
+ EXT_GIC_ID_NFC,
60
+ EXT_GIC_ID_UART0,
61
+ EXT_GIC_ID_UART1,
62
+ EXT_GIC_ID_UART2,
63
+ EXT_GIC_ID_UART3,
64
+ EXT_GIC_ID_UART4,
65
+ EXT_GIC_ID_MCT_G0,
66
+ EXT_GIC_ID_I2C0,
67
+ EXT_GIC_ID_I2C1,
68
+ EXT_GIC_ID_I2C2,
69
+ EXT_GIC_ID_I2C3,
70
+ EXT_GIC_ID_I2C4,
71
+ EXT_GIC_ID_I2C5,
72
+ EXT_GIC_ID_I2C6,
73
+ EXT_GIC_ID_I2C7,
74
+ EXT_GIC_ID_SPI0,
75
+ EXT_GIC_ID_SPI1,
76
+ EXT_GIC_ID_SPI2,
77
+ EXT_GIC_ID_MCT_G1,
78
+ EXT_GIC_ID_USB_HOST,
79
+ EXT_GIC_ID_USB_DEVICE,
80
+ EXT_GIC_ID_MODEMIF,
81
+ EXT_GIC_ID_HSMMC0,
82
+ EXT_GIC_ID_HSMMC1,
83
+ EXT_GIC_ID_HSMMC2,
84
+ EXT_GIC_ID_HSMMC3,
85
+ EXT_GIC_ID_SDMMC,
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
90
+ EXT_GIC_ID_ONENAND_AUDI,
91
+ EXT_GIC_ID_ROTATOR,
92
+ EXT_GIC_ID_FIMC0,
93
+ EXT_GIC_ID_FIMC1,
94
+ EXT_GIC_ID_FIMC2,
95
+ EXT_GIC_ID_FIMC3,
96
+ EXT_GIC_ID_JPEG,
97
+ EXT_GIC_ID_2D,
98
+ EXT_GIC_ID_PCIe,
99
+ EXT_GIC_ID_MIXER,
100
+ EXT_GIC_ID_HDMI,
101
+ EXT_GIC_ID_HDMI_I2C,
102
+ EXT_GIC_ID_MFC,
103
+ EXT_GIC_ID_TVENC,
104
+};
105
+
106
+enum ExtInt {
107
+ EXT_GIC_ID_EXTINT0 = 48,
108
+ EXT_GIC_ID_EXTINT1,
109
+ EXT_GIC_ID_EXTINT2,
110
+ EXT_GIC_ID_EXTINT3,
111
+ EXT_GIC_ID_EXTINT4,
112
+ EXT_GIC_ID_EXTINT5,
113
+ EXT_GIC_ID_EXTINT6,
114
+ EXT_GIC_ID_EXTINT7,
115
+ EXT_GIC_ID_EXTINT8,
116
+ EXT_GIC_ID_EXTINT9,
117
+ EXT_GIC_ID_EXTINT10,
118
+ EXT_GIC_ID_EXTINT11,
119
+ EXT_GIC_ID_EXTINT12,
120
+ EXT_GIC_ID_EXTINT13,
121
+ EXT_GIC_ID_EXTINT14,
122
+ EXT_GIC_ID_EXTINT15
123
+};
124
+
125
+/*
126
+ * External GIC sources which are not from External Interrupt Combiner or
127
+ * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
128
+ * which is INTG16 in Internal Interrupt Combiner.
32
+ */
129
+ */
33
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size);
130
+
34
131
+static const uint32_t
35
/**
132
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
36
* memory_region_set_log: Turn dirty logging on or off for a region.
133
+ /* int combiner groups 16-19 */
37
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
134
+ { }, { }, { }, { },
38
index XXXXXXX..XXXXXXX 100644
135
+ /* int combiner group 20 */
39
--- a/include/exec/ram_addr.h
136
+ { 0, EXT_GIC_ID_MDMA_LCD0 },
40
+++ b/include/exec/ram_addr.h
137
+ /* int combiner group 21 */
41
@@ -XXX,XX +XXX,XX @@ void qemu_ram_free(RAMBlock *block);
138
+ { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
42
139
+ /* int combiner group 22 */
43
int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
140
+ { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
44
141
+ EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
45
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length);
142
+ /* int combiner group 23 */
46
+
143
+ { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
47
+/* Clear whole block of mem */
144
+ /* int combiner group 24 */
48
+static inline void qemu_ram_block_writeback(RAMBlock *block)
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)
49
+{
194
+{
50
+ qemu_ram_writeback(block, 0, block->used_length);
195
+ uint32_t grp, bit, irq_id, n;
51
+}
196
+ Exynos4210Irq *is = &s->irqs;
52
+
197
+
53
#define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1)
198
+ for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
54
#define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE))
199
+ irq_id = 0;
55
200
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
56
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
201
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
57
index XXXXXXX..XXXXXXX 100644
202
+ /* MCT_G0 is passed to External GIC */
58
--- a/include/qemu/cutils.h
203
+ irq_id = EXT_GIC_ID_MCT_G0;
59
+++ b/include/qemu/cutils.h
204
+ }
60
@@ -XXX,XX +XXX,XX @@ const char *qemu_strchrnul(const char *s, int c);
205
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
61
#endif
206
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
62
time_t mktimegm(struct tm *tm);
207
+ /* MCT_G1 is passed to External and GIC */
63
int qemu_fdatasync(int fd);
208
+ irq_id = EXT_GIC_ID_MCT_G1;
64
+int qemu_msync(void *addr, size_t length, int fd);
209
+ }
65
int fcntl_setfl(int fd, int flag);
210
+ if (irq_id) {
66
int qemu_parse_fd(const char *param);
211
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
67
int qemu_strtoi(const char *nptr, const char **endptr, int base,
212
+ is->ext_gic_irq[irq_id - 32]);
68
diff --git a/exec.c b/exec.c
213
+ } else {
69
index XXXXXXX..XXXXXXX 100644
214
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
70
--- a/exec.c
215
+ is->ext_combiner_irq[n]);
71
+++ b/exec.c
216
+ }
72
@@ -XXX,XX +XXX,XX @@
73
#include "exec/ram_addr.h"
74
#include "exec/log.h"
75
76
+#include "qemu/pmem.h"
77
+
78
#include "migration/vmstate.h"
79
80
#include "qemu/range.h"
81
@@ -XXX,XX +XXX,XX @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
82
return 0;
83
}
84
85
+/*
86
+ * Trigger sync on the given ram block for range [start, start + length]
87
+ * with the backing store if one is available.
88
+ * Otherwise no-op.
89
+ * @Note: this is supposed to be a synchronous op.
90
+ */
91
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length)
92
+{
93
+ void *addr = ramblock_ptr(block, start);
94
+
95
+ /* The requested range should fit in within the block range */
96
+ g_assert((start + length) <= block->used_length);
97
+
98
+#ifdef CONFIG_LIBPMEM
99
+ /* The lack of support for pmem should not block the sync */
100
+ if (ramblock_is_pmem(block)) {
101
+ pmem_persist(addr, length);
102
+ return;
103
+ }
217
+ }
104
+#endif
218
+ for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
105
+ if (block->fd >= 0) {
219
+ /* these IDs are passed to Internal Combiner and External GIC */
106
+ /**
220
+ grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
107
+ * Case there is no support for PMEM or the memory has not been
221
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
108
+ * specified as persistent (or is not one) - use the msync.
222
+ irq_id = combiner_grp_to_gic_id[grp -
109
+ * Less optimal but still achieves the same goal
223
+ EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
110
+ */
224
+
111
+ if (qemu_msync(addr, length, block->fd)) {
225
+ if (irq_id) {
112
+ warn_report("%s: failed to sync memory range: start: "
226
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
113
+ RAM_ADDR_FMT " length: " RAM_ADDR_FMT,
227
+ is->ext_gic_irq[irq_id - 32]);
114
+ __func__, start, length);
115
+ }
228
+ }
116
+ }
229
+ }
117
+}
230
+}
118
+
231
+
119
/* Called with ram_list.mutex held */
232
+/*
120
static void dirty_memory_extend(ram_addr_t old_ram_size,
233
+ * Get IRQ number from exynos4210 IRQ subsystem stub.
121
ram_addr_t new_ram_size)
234
+ * To identify IRQ source use internal combiner group and bit number
122
diff --git a/memory.c b/memory.c
235
+ * grp - group number
236
+ * bit - bit number inside group
237
+ */
238
+uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
239
+{
240
+ return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
241
+}
242
+
243
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
244
0x09, 0x00, 0x00, 0x00 };
245
246
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
123
index XXXXXXX..XXXXXXX 100644
247
index XXXXXXX..XXXXXXX 100644
124
--- a/memory.c
248
--- a/hw/intc/exynos4210_gic.c
125
+++ b/memory.c
249
+++ b/hw/intc/exynos4210_gic.c
126
@@ -XXX,XX +XXX,XX @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
250
@@ -XXX,XX +XXX,XX @@
127
qemu_ram_resize(mr->ram_block, newsize, errp);
251
#include "hw/arm/exynos4210.h"
128
}
252
#include "qom/object.h"
129
253
130
+
254
-enum ExtGicId {
131
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
255
- EXT_GIC_ID_MDMA_LCD0 = 66,
132
+{
256
- EXT_GIC_ID_PDMA0,
133
+ /*
257
- EXT_GIC_ID_PDMA1,
134
+ * Might be extended case needed to cover
258
- EXT_GIC_ID_TIMER0,
135
+ * different types of memory regions
259
- EXT_GIC_ID_TIMER1,
136
+ */
260
- EXT_GIC_ID_TIMER2,
137
+ if (mr->ram_block && mr->dirty_log_mask) {
261
- EXT_GIC_ID_TIMER3,
138
+ qemu_ram_writeback(mr->ram_block, addr, size);
262
- EXT_GIC_ID_TIMER4,
139
+ }
263
- EXT_GIC_ID_MCT_L0,
140
+}
264
- EXT_GIC_ID_WDT,
141
+
265
- EXT_GIC_ID_RTC_ALARM,
142
/*
266
- EXT_GIC_ID_RTC_TIC,
143
* Call proper memory listeners about the change on the newly
267
- EXT_GIC_ID_GPIO_XB,
144
* added/removed CoalescedMemoryRange.
268
- EXT_GIC_ID_GPIO_XA,
145
diff --git a/util/cutils.c b/util/cutils.c
269
- EXT_GIC_ID_MCT_L1,
146
index XXXXXXX..XXXXXXX 100644
270
- EXT_GIC_ID_IEM_APC,
147
--- a/util/cutils.c
271
- EXT_GIC_ID_IEM_IEC,
148
+++ b/util/cutils.c
272
- EXT_GIC_ID_NFC,
149
@@ -XXX,XX +XXX,XX @@ int qemu_fdatasync(int fd)
273
- EXT_GIC_ID_UART0,
150
#endif
274
- EXT_GIC_ID_UART1,
151
}
275
- EXT_GIC_ID_UART2,
152
276
- EXT_GIC_ID_UART3,
153
+/**
277
- EXT_GIC_ID_UART4,
154
+ * Sync changes made to the memory mapped file back to the backing
278
- EXT_GIC_ID_MCT_G0,
155
+ * storage. For POSIX compliant systems this will fallback
279
- EXT_GIC_ID_I2C0,
156
+ * to regular msync call. Otherwise it will trigger whole file sync
280
- EXT_GIC_ID_I2C1,
157
+ * (including the metadata case there is no support to skip that otherwise)
281
- EXT_GIC_ID_I2C2,
158
+ *
282
- EXT_GIC_ID_I2C3,
159
+ * @addr - start of the memory area to be synced
283
- EXT_GIC_ID_I2C4,
160
+ * @length - length of the are to be synced
284
- EXT_GIC_ID_I2C5,
161
+ * @fd - file descriptor for the file to be synced
285
- EXT_GIC_ID_I2C6,
162
+ * (mandatory only for POSIX non-compliant systems)
286
- EXT_GIC_ID_I2C7,
163
+ */
287
- EXT_GIC_ID_SPI0,
164
+int qemu_msync(void *addr, size_t length, int fd)
288
- EXT_GIC_ID_SPI1,
165
+{
289
- EXT_GIC_ID_SPI2,
166
+#ifdef CONFIG_POSIX
290
- EXT_GIC_ID_MCT_G1,
167
+ size_t align_mask = ~(qemu_real_host_page_size - 1);
291
- EXT_GIC_ID_USB_HOST,
168
+
292
- EXT_GIC_ID_USB_DEVICE,
169
+ /**
293
- EXT_GIC_ID_MODEMIF,
170
+ * There are no strict reqs as per the length of mapping
294
- EXT_GIC_ID_HSMMC0,
171
+ * to be synced. Still the length needs to follow the address
295
- EXT_GIC_ID_HSMMC1,
172
+ * alignment changes. Additionally - round the size to the multiple
296
- EXT_GIC_ID_HSMMC2,
173
+ * of PAGE_SIZE
297
- EXT_GIC_ID_HSMMC3,
174
+ */
298
- EXT_GIC_ID_SDMMC,
175
+ length += ((uintptr_t)addr & (qemu_real_host_page_size - 1));
299
- EXT_GIC_ID_MIPI_CSI_4LANE,
176
+ length = (length + ~align_mask) & align_mask;
300
- EXT_GIC_ID_MIPI_DSI_4LANE,
177
+
301
- EXT_GIC_ID_MIPI_CSI_2LANE,
178
+ addr = (void *)((uintptr_t)addr & align_mask);
302
- EXT_GIC_ID_MIPI_DSI_2LANE,
179
+
303
- EXT_GIC_ID_ONENAND_AUDI,
180
+ return msync(addr, length, MS_SYNC);
304
- EXT_GIC_ID_ROTATOR,
181
+#else /* CONFIG_POSIX */
305
- EXT_GIC_ID_FIMC0,
182
+ /**
306
- EXT_GIC_ID_FIMC1,
183
+ * Perform the sync based on the file descriptor
307
- EXT_GIC_ID_FIMC2,
184
+ * The sync range will most probably be wider than the one
308
- EXT_GIC_ID_FIMC3,
185
+ * requested - but it will still get the job done
309
- EXT_GIC_ID_JPEG,
186
+ */
310
- EXT_GIC_ID_2D,
187
+ return qemu_fdatasync(fd);
311
- EXT_GIC_ID_PCIe,
188
+#endif /* CONFIG_POSIX */
312
- EXT_GIC_ID_MIXER,
189
+}
313
- EXT_GIC_ID_HDMI,
190
+
314
- EXT_GIC_ID_HDMI_I2C,
191
#ifndef _WIN32
315
- EXT_GIC_ID_MFC,
192
/* Sets a specific flag */
316
- EXT_GIC_ID_TVENC,
193
int fcntl_setfl(int fd, int flag)
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
194
--
468
--
195
2.20.1
469
2.25.1
196
197
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
Switch the creation of the external GIC to the new-style "embedded in
2
state struct" approach, so we can easily refer to the object
3
elsewhere during realize.
2
4
3
Add probe_read alongside the write probing equivalent.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-9-peter.maydell@linaro.org
8
---
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
4
16
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20191121000843.24844-2-beata.michalska@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/exec/exec-all.h | 6 ++++++
12
1 file changed, 6 insertions(+)
13
14
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/exec-all.h
19
--- a/include/hw/arm/exynos4210.h
17
+++ b/include/exec/exec-all.h
20
+++ b/include/hw/arm/exynos4210.h
18
@@ -XXX,XX +XXX,XX @@ static inline void *probe_write(CPUArchState *env, target_ulong addr, int size,
21
@@ -XXX,XX +XXX,XX @@
19
return probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
22
#include "hw/or-irq.h"
23
#include "hw/sysbus.h"
24
#include "hw/cpu/a9mpcore.h"
25
+#include "hw/intc/exynos4210_gic.h"
26
#include "target/arm/cpu-qom.h"
27
#include "qom/object.h"
28
29
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
30
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
31
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
32
A9MPPrivState a9mpcore;
33
+ Exynos4210GicState ext_gic;
34
};
35
36
#define TYPE_EXYNOS4210_SOC "exynos4210"
37
diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_gic.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Samsung exynos4210 GIC implementation. Based on hw/arm_gic.c
45
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
59
+ * See the GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+#ifndef HW_INTC_EXYNOS4210_GIC_H
65
+#define HW_INTC_EXYNOS4210_GIC_H
66
+
67
+#include "hw/sysbus.h"
68
+
69
+#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
70
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
71
+
72
+#define EXYNOS4210_GIC_NCPUS 2
73
+
74
+struct Exynos4210GicState {
75
+ SysBusDevice parent_obj;
76
+
77
+ MemoryRegion cpu_container;
78
+ MemoryRegion dist_container;
79
+ MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS];
80
+ MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS];
81
+ uint32_t num_cpu;
82
+ DeviceState *gic;
83
+};
84
+
85
+#endif
86
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/arm/exynos4210.c
89
+++ b/hw/arm/exynos4210.c
90
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
91
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
92
93
/* External GIC */
94
- dev = qdev_new("exynos4210.gic");
95
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
96
- busdev = SYS_BUS_DEVICE(dev);
97
- sysbus_realize_and_unref(busdev, &error_fatal);
98
+ qdev_prop_set_uint32(DEVICE(&s->ext_gic), "num-cpu", EXYNOS4210_NCPUS);
99
+ busdev = SYS_BUS_DEVICE(&s->ext_gic);
100
+ sysbus_realize(busdev, &error_fatal);
101
/* Map CPU interface */
102
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
103
/* Map Distributer interface */
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
106
}
107
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
108
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
109
+ s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
110
}
111
112
/* Internal Interrupt Combiner */
113
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
114
}
115
116
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
117
+ object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
20
}
118
}
21
119
22
+static inline void *probe_read(CPUArchState *env, target_ulong addr, int size,
120
static void exynos4210_class_init(ObjectClass *klass, void *data)
23
+ int mmu_idx, uintptr_t retaddr)
121
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
24
+{
122
index XXXXXXX..XXXXXXX 100644
25
+ return probe_access(env, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
123
--- a/hw/intc/exynos4210_gic.c
26
+}
124
+++ b/hw/intc/exynos4210_gic.c
27
+
125
@@ -XXX,XX +XXX,XX @@
28
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
126
#include "qemu/module.h"
29
127
#include "hw/irq.h"
30
/* Estimated block size for TB allocation. */
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>
31
--
176
--
32
2.20.1
177
2.25.1
33
34
diff view generated by jsdifflib
1
From: PanNengyuan <pannengyuan@huawei.com>
1
The only time we use the ext_gic_irq[] array in the Exynos4210Irq
2
struct is during realize of the SoC -- we initialize it with the
3
input IRQs of the external GIC device, and then connect those to
4
outputs of other devices further on in realize (including in the
5
exynos4210_init_board_irqs() function). Now that the ext_gic object
6
is easily accessible as s->ext_gic we can make the connections
7
directly from one device to the other without going via this array.
2
8
3
Address Sanitizer shows memory leak in hw/gpio/aspeed_gpio.c:875
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(-)
4
16
5
Reported-by: Euler Robot <euler.robot@huawei.com>
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
6
Signed-off-by: PanNengyuan <pannengyuan@huawei.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-16-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/gpio/aspeed_gpio.c | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/gpio/aspeed_gpio.c
19
--- a/include/hw/arm/exynos4210.h
18
+++ b/hw/gpio/aspeed_gpio.c
20
+++ b/include/hw/arm/exynos4210.h
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_init(Object *obj)
21
@@ -XXX,XX +XXX,XX @@
20
pin_idx % GPIOS_PER_GROUP);
22
typedef struct Exynos4210Irq {
21
object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
22
aspeed_gpio_set_pin, NULL, NULL, NULL);
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
23
+ g_free(name);
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
}
24
}
59
}
25
}
60
}
26
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);
27
--
80
--
28
2.20.1
81
2.25.1
29
30
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
The function exynos4210_combiner_get_gpioin() currently lives in
2
exynos4210_combiner.c, but it isn't really part of the combiner
3
device itself -- it is a function that implements the wiring up of
4
some interrupt sources to multiple combiner inputs. Move it to live
5
with the other SoC-level code in exynos4210.c, along with a few
6
macros previously defined in exynos4210.h which are now used only
7
in exynos4210.c.
2
8
3
The AST2600 control register sneakily changed the meaning of bit 4
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
without anyone noticing. It no longer controls the 1MHz vs APB clock
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
select, and instead always runs at 1MHz.
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(-)
6
17
7
The AST2500 was always 1MHz too, but it retained bit 4, making it read
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
8
only. We can model both using the same fixed 1MHz calculation.
9
10
Fixes: 6b2b2a703cad ("hw: wdt_aspeed: Add AST2600 support")
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Joel Stanley <joel@jms.id.au>
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Message-id: 20191119141211.25716-10-clg@kaod.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
include/hw/watchdog/wdt_aspeed.h | 1 +
19
hw/watchdog/wdt_aspeed.c | 21 +++++++++++++++++----
20
2 files changed, 18 insertions(+), 4 deletions(-)
21
22
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
23
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/watchdog/wdt_aspeed.h
20
--- a/include/hw/arm/exynos4210.h
25
+++ b/include/hw/watchdog/wdt_aspeed.h
21
+++ b/include/hw/arm/exynos4210.h
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedWDTClass {
22
@@ -XXX,XX +XXX,XX @@
27
uint32_t ext_pulse_width_mask;
23
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
28
uint32_t reset_ctrl_reg;
24
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
29
void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
25
30
+ void (*wdt_reload)(AspeedWDTState *s);
26
-#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
31
} AspeedWDTClass;
27
-#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
32
28
-#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
33
#endif /* WDT_ASPEED_H */
29
- ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
34
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
30
-
31
/* IRQs number for external and internal GIC */
32
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
33
#define EXYNOS4210_INT_GIC_NIRQ 64
34
@@ -XXX,XX +XXX,XX @@ void exynos4210_write_secondary(ARMCPU *cpu,
35
* bit - bit number inside group */
36
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
37
38
-/*
39
- * Get Combiner input GPIO into irqs structure
40
- */
41
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
42
- int ext);
43
-
44
/*
45
* exynos4210 UART
46
*/
47
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
35
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/watchdog/wdt_aspeed.c
49
--- a/hw/arm/exynos4210.c
37
+++ b/hw/watchdog/wdt_aspeed.c
50
+++ b/hw/arm/exynos4210.c
38
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_wdt_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] = {
39
52
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
53
};
54
55
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
56
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
57
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
58
+ ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
59
+
60
/*
61
* Initialize board IRQs.
62
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
63
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
64
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
40
}
65
}
41
66
42
-static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
67
+/*
43
+static void aspeed_wdt_reload(AspeedWDTState *s)
68
+ * Get Combiner input GPIO into irqs structure
44
{
69
+ */
45
uint64_t reload;
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
46
71
+ DeviceState *dev, int ext)
47
- if (pclk) {
48
+ if (!(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK)) {
49
reload = muldiv64(s->regs[WDT_RELOAD_VALUE], NANOSECONDS_PER_SECOND,
50
s->pclk_freq);
51
} else {
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
53
}
54
}
55
56
+static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
57
+{
72
+{
58
+ uint64_t reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL;
73
+ int n;
59
+
74
+ int bit;
60
+ if (aspeed_wdt_is_enabled(s)) {
75
+ int max;
61
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
76
+ qemu_irq *irq;
77
+
78
+ max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
79
+ EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
80
+ irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
81
+
82
+ /*
83
+ * Some IRQs of Int/External Combiner are going to two Combiners groups,
84
+ * so let split them.
85
+ */
86
+ for (n = 0; n < max; n++) {
87
+
88
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
89
+
90
+ switch (n) {
91
+ /* MDNIE_LCD1 INTG1 */
92
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
93
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
94
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
95
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
96
+ continue;
97
+
98
+ /* TMU INTG3 */
99
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
100
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
101
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
102
+ continue;
103
+
104
+ /* LCD1 INTG12 */
105
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
106
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
107
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
108
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
109
+ continue;
110
+
111
+ /* Multi-Core Timer INTG12 */
112
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
113
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
114
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
115
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
116
+ continue;
117
+
118
+ /* Multi-Core Timer INTG35 */
119
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
120
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
121
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
122
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
123
+ continue;
124
+
125
+ /* Multi-Core Timer INTG51 */
126
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
127
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
128
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
129
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
130
+ continue;
131
+
132
+ /* Multi-Core Timer INTG53 */
133
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
134
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
135
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
136
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
137
+ continue;
138
+ }
139
+
140
+ irq[n] = qdev_get_gpio_in(dev, n);
62
+ }
141
+ }
63
+}
142
+}
64
+
143
+
65
+
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
66
static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
145
0x09, 0x00, 0x00, 0x00 };
67
unsigned size)
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)
68
{
234
{
69
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
70
case WDT_RESTART:
71
if ((data & 0xFFFF) == WDT_RESTART_MAGIC) {
72
s->regs[WDT_STATUS] = s->regs[WDT_RELOAD_VALUE];
73
- aspeed_wdt_reload(s, !(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK));
74
+ awc->wdt_reload(s);
75
}
76
break;
77
case WDT_CTRL:
78
if (enable && !aspeed_wdt_is_enabled(s)) {
79
s->regs[WDT_CTRL] = data;
80
- aspeed_wdt_reload(s, !(data & WDT_CTRL_1MHZ_CLK));
81
+ awc->wdt_reload(s);
82
} else if (!enable && aspeed_wdt_is_enabled(s)) {
83
s->regs[WDT_CTRL] = data;
84
timer_del(s->timer);
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data)
86
awc->offset = 0x20;
87
awc->ext_pulse_width_mask = 0xff;
88
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
89
+ awc->wdt_reload = aspeed_wdt_reload;
90
}
91
92
static const TypeInfo aspeed_2400_wdt_info = {
93
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
94
awc->ext_pulse_width_mask = 0xfffff;
95
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
96
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
97
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
98
}
99
100
static const TypeInfo aspeed_2500_wdt_info = {
101
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
102
awc->ext_pulse_width_mask = 0xfffff; /* TODO */
103
awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
104
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
105
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
106
}
107
108
static const TypeInfo aspeed_2600_wdt_info = {
109
--
235
--
110
2.20.1
236
2.25.1
111
112
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
Delete a couple of #defines which are never used.
2
2
3
The last argument of AML bit and/or statement is the target variable,
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
so we don't need to use a NULL target and then an additional store
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
operation; using just aml_and() or aml_or() statement is enough.
5
Message-id: 20220404154658.565020-12-peter.maydell@linaro.org
6
---
7
include/hw/arm/exynos4210.h | 4 ----
8
1 file changed, 4 deletions(-)
6
9
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
10
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
8
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
10
Cc: Peter Maydell <peter.maydell@linaro.org>
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
12
Cc: Igor Mammedov <imammedo@redhat.com>
13
Suggested-by: Igor Mammedov <imammedo@redhat.com>
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
16
Message-id: 20191209063719.23086-2-guoheyi@huawei.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
hw/arm/virt-acpi-build.c | 16 ++++++++--------
20
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
21
tests/data/acpi/virt/DSDT.memhp | Bin 19807 -> 19799 bytes
22
tests/data/acpi/virt/DSDT.numamem | Bin 18470 -> 18462 bytes
23
4 files changed, 8 insertions(+), 8 deletions(-)
24
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
26
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
12
--- a/include/hw/arm/exynos4210.h
28
+++ b/hw/arm/virt-acpi-build.c
13
+++ b/include/hw/arm/exynos4210.h
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
14
@@ -XXX,XX +XXX,XX @@
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
15
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
16
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
17
33
- aml_append(ifctx, aml_store(aml_and(aml_name("CTRL"), aml_int(0x1D), NULL),
18
-/* IRQs number for external and internal GIC */
34
- aml_name("CTRL")));
19
-#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
35
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
20
-#define EXYNOS4210_INT_GIC_NIRQ 64
36
+ aml_name("CTRL")));
21
-
37
22
#define EXYNOS4210_I2C_NUMBER 9
38
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
23
39
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x08), NULL),
24
#define EXYNOS4210_NUM_DMA 3
40
- aml_name("CDW1")));
41
+ aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
42
+ aml_name("CDW1")));
43
aml_append(ifctx, ifctx1);
44
45
ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), aml_name("CTRL"))));
46
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x10), NULL),
47
- aml_name("CDW1")));
48
+ aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10),
49
+ aml_name("CDW1")));
50
aml_append(ifctx, ifctx1);
51
52
aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3")));
53
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
54
aml_append(method, ifctx);
55
56
elsectx = aml_else();
57
- aml_append(elsectx, aml_store(aml_or(aml_name("CDW1"), aml_int(4), NULL),
58
- aml_name("CDW1")));
59
+ aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4),
60
+ aml_name("CDW1")));
61
aml_append(elsectx, aml_return(aml_arg(3)));
62
aml_append(method, elsectx);
63
aml_append(dev, method);
64
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
65
index XXXXXXX..XXXXXXX 100644
66
GIT binary patch
67
delta 133
68
zcmZ2BfpOjhMlP3Nmk>D*1_q|2iCof5o%I{lJ2{y;?{412x!p#<jWgaq*qNm(o59&7
69
z+;D-%<VrV7_iE>mARjJS5V=5L(&S9WT970c2Uv;Nq{%?q7$gZ1761tsfcPNsCD{x4
70
MAmS{W8QoPG0j8@bzW@LL
71
72
delta 141
73
zcmbO?fpOUcMlP3Nmk>1%1_q`n6S<_B8XGpMcXBc{-rKy1bGwazA7{LOuro_nHiNTE
74
zxZwi7$(3%F{sq;}AwfP|vJ4<<fzYJMnT!RsAbBnhh%$*ulYv}gkTg_604z}e5&_99
75
R$zCV`m0@An{L@X95dZ+BD!u>!
76
77
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
78
index XXXXXXX..XXXXXXX 100644
79
GIT binary patch
80
delta 132
81
zcmcaVi}Cs_MlP3NmymE@1_ma@iCof*O&is^IGH-{Zr;SX-A2HTGu}VgnWZb6!PzC;
82
zaDm6<N;gaQYUhw3A1+xCxj<mj<V?m|kR%reSc%xA$w1l|Bnc4~00|d>_#p8m*$ep~
83
L;w+mP-Q(B*s{AMU
84
85
delta 140
86
zcmcaUi}C&}MlP3Nmymd01_maViCof*T^rT9IGGynZQjJW-A2HVGu}VgnWZb6!PzC;
87
zaDm_CN;gaYf@<fGARjJS1`xGCXwu|N#)4XqJQoK<nZ%^YK&~-J8Y&?GmM8#;fMk|r
88
QFBE{vurO@?=@!QZ00dYn_y7O^
89
90
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
91
index XXXXXXX..XXXXXXX 100644
92
GIT binary patch
93
delta 133
94
zcmZ2BfpOjhMlP3Nmk>D*1_q|2iCof5o%I{lJ2{y;?{412x!p#<jWgaq*qNm(o59&7
95
z+;D-%<VrV7_iE>mARjJS5V=5L(&S9WT970c2Uv;Nq{%?q7$gZ1761tsfcPNsCD{x4
96
MAmS{W8QoPG0j8@bzW@LL
97
98
delta 141
99
zcmbO?fpOUcMlP3Nmk>1%1_q`n6S<_B8XGpMcXBc{-rKy1bGwazA7{LOuro_nHiNTE
100
zxZwi7$(3%F{sq;}AwfP|vJ4<<fzYJMnT!RsAbBnhh%$*ulYv}gkTg_604z}e5&_99
101
R$zCV`m0@An{L@X95dZ+BD!u>!
102
103
--
25
--
104
2.20.1
26
2.25.1
105
106
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
2
instead of qemu_irq_split().
2
3
3
Signed-off-by: Cédric Le Goater <clg@kaod.org>
4
Reviewed-by: Joel Stanley <joel@jms.id.au>
5
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20191119141211.25716-6-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
10
---
7
---
11
hw/i2c/aspeed_i2c.c | 93 ++++++++++++++++++++++++++++++++++++++-------
8
include/hw/arm/exynos4210.h | 9 ++++++++
12
hw/i2c/trace-events | 9 +++++
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
13
2 files changed, 89 insertions(+), 13 deletions(-)
10
2 files changed, 42 insertions(+), 8 deletions(-)
14
11
15
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
12
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/i2c/aspeed_i2c.c
14
--- a/include/hw/arm/exynos4210.h
18
+++ b/hw/i2c/aspeed_i2c.c
15
+++ b/include/hw/arm/exynos4210.h
19
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
20
#include "hw/i2c/aspeed_i2c.h"
17
#include "hw/sysbus.h"
21
#include "hw/irq.h"
18
#include "hw/cpu/a9mpcore.h"
22
#include "hw/qdev-properties.h"
19
#include "hw/intc/exynos4210_gic.h"
23
+#include "trace.h"
20
+#include "hw/core/split-irq.h"
24
21
#include "target/arm/cpu-qom.h"
25
/* I2C Global Register */
22
#include "qom/object.h"
26
23
27
@@ -XXX,XX +XXX,XX @@ static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
24
@@ -XXX,XX +XXX,XX @@
28
{
25
29
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
26
#define EXYNOS4210_NUM_DMA 3
30
27
31
+ trace_aspeed_i2c_bus_raise_interrupt(bus->intr_status,
28
+/*
32
+ bus->intr_status & I2CD_INTR_TX_NAK ? "nak|" : "",
29
+ * We need one splitter for every external combiner input, plus
33
+ bus->intr_status & I2CD_INTR_TX_ACK ? "ack|" : "",
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
34
+ bus->intr_status & I2CD_INTR_RX_DONE ? "done|" : "",
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
35
+ bus->intr_status & I2CD_INTR_NORMAL_STOP ? "normal|" : "",
32
+ */
36
+ bus->intr_status & I2CD_INTR_ABNORMAL ? "abnormal" : "");
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
37
+
34
+
38
bus->intr_status &= bus->intr_ctrl;
35
typedef struct Exynos4210Irq {
39
if (bus->intr_status) {
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
40
bus->controller->intr_status |= 1 << bus->id;
37
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
41
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
38
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
42
{
39
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
43
AspeedI2CBus *bus = opaque;
40
A9MPPrivState a9mpcore;
44
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
41
Exynos4210GicState ext_gic;
45
+ uint64_t value = -1;
42
+ SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
46
43
};
47
switch (offset) {
44
48
case I2CD_FUN_CTRL_REG:
45
#define TYPE_EXYNOS4210_SOC "exynos4210"
49
- return bus->ctrl;
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
50
+ value = bus->ctrl;
47
index XXXXXXX..XXXXXXX 100644
51
+ break;
48
--- a/hw/arm/exynos4210.c
52
case I2CD_AC_TIMING_REG1:
49
+++ b/hw/arm/exynos4210.c
53
- return bus->timing[0];
50
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
54
+ value = bus->timing[0];
51
uint32_t grp, bit, irq_id, n;
55
+ break;
52
Exynos4210Irq *is = &s->irqs;
56
case I2CD_AC_TIMING_REG2:
53
DeviceState *extgicdev = DEVICE(&s->ext_gic);
57
- return bus->timing[1];
54
+ int splitcount = 0;
58
+ value = bus->timing[1];
55
+ DeviceState *splitter;
59
+ break;
56
60
case I2CD_INTR_CTRL_REG:
57
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
61
- return bus->intr_ctrl;
58
irq_id = 0;
62
+ value = bus->intr_ctrl;
59
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
63
+ break;
60
/* MCT_G1 is passed to External and GIC */
64
case I2CD_INTR_STS_REG:
61
irq_id = EXT_GIC_ID_MCT_G1;
65
- return bus->intr_status;
66
+ value = bus->intr_status;
67
+ break;
68
case I2CD_POOL_CTRL_REG:
69
- return bus->pool_ctrl;
70
+ value = bus->pool_ctrl;
71
+ break;
72
case I2CD_BYTE_BUF_REG:
73
- return bus->buf;
74
+ value = bus->buf;
75
+ break;
76
case I2CD_CMD_REG:
77
- return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
78
+ value = bus->cmd | (i2c_bus_busy(bus->bus) << 16);
79
+ break;
80
case I2CD_DMA_ADDR:
81
if (!aic->has_dma) {
82
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
83
- return -1;
84
+ break;
85
}
62
}
86
- return bus->dma_addr;
63
+
87
+ value = bus->dma_addr;
64
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
88
+ break;
65
+ splitter = DEVICE(&s->splitter[splitcount]);
89
case I2CD_DMA_LEN:
66
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
90
if (!aic->has_dma) {
67
+ qdev_realize(splitter, NULL, &error_abort);
91
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
68
+ splitcount++;
92
- return -1;
69
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
93
+ break;
70
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
71
if (irq_id) {
72
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
73
- qdev_get_gpio_in(extgicdev,
74
- irq_id - 32));
75
+ qdev_connect_gpio_out(splitter, 1,
76
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
77
} else {
78
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
79
- is->ext_combiner_irq[n]);
80
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
94
}
81
}
95
- return bus->dma_len;
96
+ value = bus->dma_len;
97
+ break;
98
+
99
default:
100
qemu_log_mask(LOG_GUEST_ERROR,
101
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
102
- return -1;
103
+ value = -1;
104
+ break;
105
}
82
}
106
+
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
107
+ trace_aspeed_i2c_bus_read(bus->id, offset, size, value);
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
108
+ return value;
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
86
87
if (irq_id) {
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
89
- qdev_get_gpio_in(extgicdev,
90
- irq_id - 32));
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
92
+ splitter = DEVICE(&s->splitter[splitcount]);
93
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
94
+ qdev_realize(splitter, NULL, &error_abort);
95
+ splitcount++;
96
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
97
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
98
+ qdev_connect_gpio_out(splitter, 1,
99
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
100
}
101
}
102
+ /*
103
+ * We check this here to avoid a more obscure assert later when
104
+ * qdev_assert_realized_properly() checks that we realized every
105
+ * child object we initialized.
106
+ */
107
+ assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
109
}
108
}
110
109
111
static void aspeed_i2c_set_state(AspeedI2CBus *bus, uint8_t state)
110
/*
112
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
113
for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
112
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
114
uint8_t *pool_base = aic->bus_pool_base(bus);
115
116
+ trace_aspeed_i2c_bus_send("BUF", i + 1,
117
+ I2CD_POOL_TX_COUNT(bus->pool_ctrl),
118
+ pool_base[i]);
119
ret = i2c_send(bus->bus, pool_base[i]);
120
if (ret) {
121
break;
122
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
123
while (bus->dma_len) {
124
uint8_t data;
125
aspeed_i2c_dma_read(bus, &data);
126
+ trace_aspeed_i2c_bus_send("DMA", bus->dma_len, bus->dma_len, data);
127
ret = i2c_send(bus->bus, data);
128
if (ret) {
129
break;
130
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
131
}
132
bus->cmd &= ~I2CD_TX_DMA_ENABLE;
133
} else {
134
+ trace_aspeed_i2c_bus_send("BYTE", pool_start, 1, bus->buf);
135
ret = i2c_send(bus->bus, bus->buf);
136
}
113
}
137
114
138
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
115
+ for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
139
116
+ g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
140
for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
117
+ object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
141
pool_base[i] = i2c_recv(bus->bus);
142
+ trace_aspeed_i2c_bus_recv("BUF", i + 1,
143
+ I2CD_POOL_RX_SIZE(bus->pool_ctrl),
144
+ pool_base[i]);
145
}
146
147
/* Update RX count */
148
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
149
MemTxResult result;
150
151
data = i2c_recv(bus->bus);
152
+ trace_aspeed_i2c_bus_recv("DMA", bus->dma_len, bus->dma_len, data);
153
result = address_space_write(&s->dram_as, bus->dma_addr,
154
MEMTXATTRS_UNSPECIFIED, &data, 1);
155
if (result != MEMTX_OK) {
156
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
157
bus->cmd &= ~I2CD_RX_DMA_ENABLE;
158
} else {
159
data = i2c_recv(bus->bus);
160
+ trace_aspeed_i2c_bus_recv("BYTE", 1, 1, bus->buf);
161
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
162
}
163
}
164
@@ -XXX,XX +XXX,XX @@ static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
165
return true;
166
}
167
168
+static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
169
+{
170
+ g_autofree char *cmd_flags;
171
+ uint32_t count;
172
+
173
+ if (bus->cmd & (I2CD_RX_BUFF_ENABLE | I2CD_RX_BUFF_ENABLE)) {
174
+ count = I2CD_POOL_TX_COUNT(bus->pool_ctrl);
175
+ } else if (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_RX_DMA_ENABLE)) {
176
+ count = bus->dma_len;
177
+ } else { /* BYTE mode */
178
+ count = 1;
179
+ }
118
+ }
180
+
119
+
181
+ cmd_flags = g_strdup_printf("%s%s%s%s%s%s%s%s%s",
120
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
182
+ bus->cmd & I2CD_M_START_CMD ? "start|" : "",
121
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
183
+ bus->cmd & I2CD_RX_DMA_ENABLE ? "rxdma|" : "",
122
}
184
+ bus->cmd & I2CD_TX_DMA_ENABLE ? "txdma|" : "",
185
+ bus->cmd & I2CD_RX_BUFF_ENABLE ? "rxbuf|" : "",
186
+ bus->cmd & I2CD_TX_BUFF_ENABLE ? "txbuf|" : "",
187
+ bus->cmd & I2CD_M_TX_CMD ? "tx|" : "",
188
+ bus->cmd & I2CD_M_RX_CMD ? "rx|" : "",
189
+ bus->cmd & I2CD_M_S_RX_CMD_LAST ? "last|" : "",
190
+ bus->cmd & I2CD_M_STOP_CMD ? "stop" : "");
191
+
192
+ trace_aspeed_i2c_bus_cmd(bus->cmd, cmd_flags, count, bus->intr_status);
193
+}
194
+
195
/*
196
* The state machine needs some refinement. It is only used to track
197
* invalid STOP commands for the moment.
198
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
199
return;
200
}
201
202
+ if (trace_event_get_state_backends(TRACE_ASPEED_I2C_BUS_CMD)) {
203
+ aspeed_i2c_bus_cmd_dump(bus);
204
+ }
205
+
206
if (bus->cmd & I2CD_M_START_CMD) {
207
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
208
I2CD_MSTARTR : I2CD_MSTART;
209
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
210
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
211
bool handle_rx;
212
213
+ trace_aspeed_i2c_bus_write(bus->id, offset, size, value);
214
+
215
switch (offset) {
216
case I2CD_FUN_CTRL_REG:
217
if (value & I2CD_SLAVE_EN) {
218
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/i2c/trace-events
221
+++ b/hw/i2c/trace-events
222
@@ -XXX,XX +XXX,XX @@
223
i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)"
224
i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x"
225
i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
226
+
227
+# aspeed_i2c.c
228
+
229
+aspeed_i2c_bus_cmd(uint32_t cmd, const char *cmd_flags, uint32_t count, uint32_t intr_status) "handling cmd=0x%x %s count=%d intr=0x%x"
230
+aspeed_i2c_bus_raise_interrupt(uint32_t intr_status, const char *str1, const char *str2, const char *str3, const char *str4, const char *str5) "handled intr=0x%x %s%s%s%s%s"
231
+aspeed_i2c_bus_read(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
232
+aspeed_i2c_bus_write(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
233
+aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s send %d/%d 0x%02x"
234
+aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s recv %d/%d 0x%02x"
235
--
123
--
236
2.20.1
124
2.25.1
237
238
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
2
are in a range that applies to the internal combiner only creates a
3
splitter for those interrupts which go to both the internal combiner
4
and to the external GIC, but it does nothing at all for the
5
interrupts which don't go to the external GIC, leaving the
6
irq_table[] array element empty for those. (This will result in
7
those interrupts simply being lost, not in a QEMU crash.)
2
8
3
Switch to ram block writeback for pmem migration.
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.)
4
16
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
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>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
23
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
8
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
9
Message-id: 20191121000843.24844-4-beata.michalska@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
24
---
12
migration/ram.c | 5 +----
25
hw/arm/exynos4210.c | 2 ++
13
1 file changed, 1 insertion(+), 4 deletions(-)
26
1 file changed, 2 insertions(+)
14
27
15
diff --git a/migration/ram.c b/migration/ram.c
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
16
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
17
--- a/migration/ram.c
30
--- a/hw/arm/exynos4210.c
18
+++ b/migration/ram.c
31
+++ b/hw/arm/exynos4210.c
19
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
20
#include "qemu/bitops.h"
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
21
#include "qemu/bitmap.h"
34
qdev_connect_gpio_out(splitter, 1,
22
#include "qemu/main-loop.h"
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
23
-#include "qemu/pmem.h"
36
+ } else {
24
#include "xbzrle.h"
37
+ s->irq_table[n] = is->int_combiner_irq[n];
25
#include "ram.h"
38
}
26
#include "migration.h"
27
@@ -XXX,XX +XXX,XX @@ static int ram_load_cleanup(void *opaque)
28
RAMBlock *rb;
29
30
RAMBLOCK_FOREACH_NOT_IGNORED(rb) {
31
- if (ramblock_is_pmem(rb)) {
32
- pmem_persist(rb->host, rb->used_length);
33
- }
34
+ qemu_ram_block_writeback(rb);
35
}
39
}
36
40
/*
37
xbzrle_load_cleanup();
38
--
41
--
39
2.20.1
42
2.25.1
40
41
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
Currently for the interrupts MCT_G0 and MCT_G1 which are
2
the only ones in the input range of the external combiner
3
and which are also wired to the external GIC, we connect
4
them only to the internal combiner and the external GIC.
5
This seems likely to be a bug, as all other interrupts
6
which are in the input range of both combiners are
7
connected to both combiners. (The fact that the code in
8
exynos4210_combiner_get_gpioin() is also trying to wire
9
up these inputs on both combiners also suggests this.)
2
10
3
HCR_EL2.TID3 requires that AArch32 reads of MVFR[012] are trapped to
11
Wire these interrupts up to both combiners, like the rest.
4
EL2, and HCR_EL2.TID0 does the same for reads of FPSID.
5
In order to handle this, introduce a new TCG helper function that
6
checks for these control bits before executing the VMRC instruction.
7
12
8
Tested with a hacked-up version of KVM/arm64 that sets the control
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
bits for 32bit guests.
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-15-peter.maydell@linaro.org
16
---
17
hw/arm/exynos4210.c | 7 +++----
18
1 file changed, 3 insertions(+), 4 deletions(-)
10
19
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-4-maz@kernel.org
15
[PMM: move helper declaration to helper.h; make it
16
TCG_CALL_NO_WG]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
target/arm/helper.h | 2 ++
20
target/arm/translate-vfp.inc.c | 20 ++++++++++++++++----
21
target/arm/vfp_helper.c | 29 +++++++++++++++++++++++++++++
22
3 files changed, 47 insertions(+), 4 deletions(-)
23
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
22
--- a/hw/arm/exynos4210.c
27
+++ b/target/arm/helper.h
23
+++ b/hw/arm/exynos4210.c
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG, f64, f64, ptr)
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
29
DEF_HELPER_FLAGS_2(vjcvt, TCG_CALL_NO_RWG, i32, f64, env)
25
30
DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
31
27
splitter = DEVICE(&s->splitter[splitcount]);
32
+DEF_HELPER_FLAGS_3(check_hcr_el2_trap, TCG_CALL_NO_WG, void, env, i32, i32)
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
33
+
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
34
/* neon_helper.c */
30
qdev_realize(splitter, NULL, &error_abort);
35
DEF_HELPER_FLAGS_3(neon_qadd_u8, TCG_CALL_NO_RWG, i32, env, i32, i32)
31
splitcount++;
36
DEF_HELPER_FLAGS_3(neon_qadd_s8, TCG_CALL_NO_RWG, i32, env, i32, i32)
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
37
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
38
index XXXXXXX..XXXXXXX 100644
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
39
--- a/target/arm/translate-vfp.inc.c
35
if (irq_id) {
40
+++ b/target/arm/translate-vfp.inc.c
36
- qdev_connect_gpio_out(splitter, 1,
41
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
37
+ qdev_connect_gpio_out(splitter, 2,
42
if (a->l) {
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
43
/* VMRS, move VFP special register to gp register */
39
- } else {
44
switch (a->reg) {
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
45
- case ARM_VFP_FPSID:
41
}
46
- case ARM_VFP_FPEXC:
42
}
47
- case ARM_VFP_FPINST:
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
48
- case ARM_VFP_FPINST2:
49
case ARM_VFP_MVFR0:
50
case ARM_VFP_MVFR1:
51
case ARM_VFP_MVFR2:
52
+ case ARM_VFP_FPSID:
53
+ if (s->current_el == 1) {
54
+ TCGv_i32 tcg_reg, tcg_rt;
55
+
56
+ gen_set_condexec(s);
57
+ gen_set_pc_im(s, s->pc_curr);
58
+ tcg_reg = tcg_const_i32(a->reg);
59
+ tcg_rt = tcg_const_i32(a->rt);
60
+ gen_helper_check_hcr_el2_trap(cpu_env, tcg_rt, tcg_reg);
61
+ tcg_temp_free_i32(tcg_reg);
62
+ tcg_temp_free_i32(tcg_rt);
63
+ }
64
+ /* fall through */
65
+ case ARM_VFP_FPEXC:
66
+ case ARM_VFP_FPINST:
67
+ case ARM_VFP_FPINST2:
68
tmp = load_cpu_field(vfp.xregs[a->reg]);
69
break;
70
case ARM_VFP_FPSCR:
71
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/vfp_helper.c
74
+++ b/target/arm/vfp_helper.c
75
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frint64_d)(float64 f, void *fpst)
76
return frint_d(f, fpst, 64);
77
}
78
79
+void HELPER(check_hcr_el2_trap)(CPUARMState *env, uint32_t rt, uint32_t reg)
80
+{
81
+ uint32_t syndrome;
82
+
83
+ switch (reg) {
84
+ case ARM_VFP_MVFR0:
85
+ case ARM_VFP_MVFR1:
86
+ case ARM_VFP_MVFR2:
87
+ if (!(arm_hcr_el2_eff(env) & HCR_TID3)) {
88
+ return;
89
+ }
90
+ break;
91
+ case ARM_VFP_FPSID:
92
+ if (!(arm_hcr_el2_eff(env) & HCR_TID0)) {
93
+ return;
94
+ }
95
+ break;
96
+ default:
97
+ g_assert_not_reached();
98
+ }
99
+
100
+ syndrome = ((EC_FPIDTRAP << ARM_EL_EC_SHIFT)
101
+ | ARM_EL_IL
102
+ | (1 << 24) | (0xe << 20) | (7 << 14)
103
+ | (reg << 10) | (rt << 5) | 1);
104
+
105
+ raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
106
+}
107
+
108
#endif
109
--
44
--
110
2.20.1
45
2.25.1
111
112
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
3
connect multiple IRQs up to the same external GIC input, which
4
is not permitted. We do the same thing in the code in
5
exynos4210_init_board_irqs() because the conditionals selecting
6
an irq_id in the first loop match multiple interrupt IDs.
2
7
3
HCR_EL2.TID1 mandates that access from EL1 to REVIDR_EL1, AIDR_EL1
8
Overall we do this for interrupt IDs
4
(and their 32bit equivalents) as well as TCMTR, TLBTR are trapped
9
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
5
to EL2. QEMU ignores it, making it harder for a hypervisor to
10
and
6
virtualize the HW (though to be fair, no known hypervisor actually
11
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
7
cares).
8
12
9
Do the right thing by trapping to EL2 if HCR_EL2.TID1 is set.
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.
10
20
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
21
This bug didn't cause any visible effects, because we only connect
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
22
up a device to the "primary" ID values (1, 4) and (1, 5), so the
23
extra lines would never be set to a level.
24
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-3-maz@kernel.org
27
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
28
---
17
target/arm/helper.c | 36 ++++++++++++++++++++++++++++++++----
29
include/hw/arm/exynos4210.h | 2 +-
18
1 file changed, 32 insertions(+), 4 deletions(-)
30
hw/arm/exynos4210.c | 12 +++++-------
31
2 files changed, 6 insertions(+), 8 deletions(-)
19
32
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
21
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
35
--- a/include/hw/arm/exynos4210.h
23
+++ b/target/arm/helper.c
36
+++ b/include/hw/arm/exynos4210.h
24
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
37
@@ -XXX,XX +XXX,XX @@
25
return ret;
38
* one for every non-zero entry in combiner_grp_to_gic_id[].
26
}
39
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
27
40
*/
28
+static CPAccessResult access_aa64_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
41
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
29
+ bool isread)
42
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
30
+{
43
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID1)) {
44
typedef struct Exynos4210Irq {
32
+ return CP_ACCESS_TRAP_EL2;
45
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
33
+ }
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
34
+
47
index XXXXXXX..XXXXXXX 100644
35
+ return CP_ACCESS_OK;
48
--- a/hw/arm/exynos4210.c
36
+}
49
+++ b/hw/arm/exynos4210.c
37
+
50
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
38
+static CPAccessResult access_aa32_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
51
/* int combiner group 34 */
39
+ bool isread)
52
{ EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
40
+{
53
/* int combiner group 35 */
41
+ if (arm_feature(env, ARM_FEATURE_V8)) {
54
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
42
+ return access_aa64_tid1(env, ri, isread);
55
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
43
+ }
56
/* int combiner group 36 */
44
+
57
{ EXT_GIC_ID_MIXER },
45
+ return CP_ACCESS_OK;
58
/* int combiner group 37 */
46
+}
59
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
47
+
60
/* groups 38-50 */
48
static const ARMCPRegInfo v7_cp_reginfo[] = {
61
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
49
/* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */
62
/* int combiner group 51 */
50
{ .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
63
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
51
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
64
+ { EXT_GIC_ID_MCT_L0 },
52
*/
65
/* group 52 */
53
{ .name = "AIDR", .state = ARM_CP_STATE_BOTH,
66
{ },
54
.opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7,
67
/* int combiner group 53 */
55
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
68
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
56
+ .access = PL1_R, .type = ARM_CP_CONST,
69
+ { EXT_GIC_ID_WDT },
57
+ .accessfn = access_aa64_tid1,
70
/* groups 54-63 */
58
+ .resetvalue = 0 },
71
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
59
/* Auxiliary fault status registers: these also are IMPDEF, and we
72
};
60
* choose to RAZ/WI for all cores.
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
61
*/
74
62
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
75
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
63
.access = PL1_R, .resetvalue = cpu->midr },
76
irq_id = 0;
64
{ .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,
77
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
65
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
78
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
66
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
79
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
67
+ .access = PL1_R,
80
/* MCT_G0 is passed to External GIC */
68
+ .accessfn = access_aa64_tid1,
81
irq_id = EXT_GIC_ID_MCT_G0;
69
+ .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
82
}
70
REGINFO_SENTINEL
83
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
71
};
84
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
72
ARMCPRegInfo id_cp_reginfo[] = {
85
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
86
/* MCT_G1 is passed to External and GIC */
74
/* TCMTR and TLBTR exist in v8 but have no 64-bit versions */
87
irq_id = EXT_GIC_ID_MCT_G1;
75
{ .name = "TCMTR",
88
}
76
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2,
77
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
78
+ .access = PL1_R,
79
+ .accessfn = access_aa32_tid1,
80
+ .type = ARM_CP_CONST, .resetvalue = 0 },
81
REGINFO_SENTINEL
82
};
83
/* TLBTR is specific to VMSA */
84
ARMCPRegInfo id_tlbtr_reginfo = {
85
.name = "TLBTR",
86
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3,
87
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0,
88
+ .access = PL1_R,
89
+ .accessfn = access_aa32_tid1,
90
+ .type = ARM_CP_CONST, .resetvalue = 0,
91
};
92
/* MPUIR is specific to PMSA V6+ */
93
ARMCPRegInfo id_mpuir_reginfo = {
94
--
89
--
95
2.20.1
90
2.25.1
96
97
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
At this point, the function exynos4210_init_board_irqs() splits input
2
2
IRQ lines to connect them to the input combiner, output combiner and
3
The I2C controller of the Aspeed AST2500 and AST2600 SoCs supports DMA
3
external GIC. The function exynos4210_combiner_get_gpioin() splits
4
transfers to and from DRAM.
4
some of the combiner input lines further to connect them to multiple
5
5
different inputs on the combiner.
6
A pair of registers defines the buffer address and the length of the
6
7
DMA transfer. The address should be aligned on 4 bytes and the maximum
7
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
8
length should not exceed 4K. The receive or transmit DMA transfer can
8
configurable number of outputs, we can do all this in one place, by
9
then be initiated with specific bits in the Command/Status register of
9
making exynos4210_init_board_irqs() add extra outputs to the splitter
10
the controller.
10
device when it must be connected to more than one input on each
11
11
combiner.
12
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
13
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
We do this with a new data structure, the combinermap, which is an
14
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
14
array each of whose elements is a list of the interrupt IDs on the
15
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
combiner which must be tied together. As we loop through each
16
Message-id: 20191119141211.25716-5-clg@kaod.org
16
interrupt ID, if we find that it is the first one in one of these
17
lists, we configure the splitter device with eonugh extra outputs and
18
wire them up to the other interrupt IDs in the list.
19
20
Conveniently, for all the cases where this is necessary, the
21
lowest-numbered interrupt ID in each group is in the range of the
22
external combiner, so we only need to code for this in the first of
23
the two loops in exynos4210_init_board_irqs().
24
25
The old code in exynos4210_combiner_get_gpioin() which is being
26
deleted here had several problems which don't exist in the new code
27
in its handling of the multi-core timer interrupts:
28
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
29
exist; these should have been 4 ... 7
30
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
31
multiple times as the input of several different splitters,
32
which isn't allowed
33
(3) in an apparent cut-and-paste error, the cases for all the
34
multi-core timer inputs used "bit + 4" even though the
35
bit range for the case was (intended to be) 4 ... 7, which
36
meant it was looking at non-existent bits 8 ... 11.
37
None of these exist in the new code.
38
17
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
18
---
42
---
19
include/hw/i2c/aspeed_i2c.h | 5 ++
43
include/hw/arm/exynos4210.h | 6 +-
20
hw/arm/aspeed_ast2600.c | 5 ++
44
hw/arm/exynos4210.c | 178 +++++++++++++++++++++++-------------
21
hw/arm/aspeed_soc.c | 5 ++
45
2 files changed, 119 insertions(+), 65 deletions(-)
22
hw/i2c/aspeed_i2c.c | 126 +++++++++++++++++++++++++++++++++++-
46
23
4 files changed, 138 insertions(+), 3 deletions(-)
47
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
24
25
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
26
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/i2c/aspeed_i2c.h
49
--- a/include/hw/arm/exynos4210.h
28
+++ b/include/hw/i2c/aspeed_i2c.h
50
+++ b/include/hw/arm/exynos4210.h
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
51
@@ -XXX,XX +XXX,XX @@
30
uint32_t cmd;
52
31
uint32_t buf;
53
/*
32
uint32_t pool_ctrl;
54
* We need one splitter for every external combiner input, plus
33
+ uint32_t dma_addr;
55
- * one for every non-zero entry in combiner_grp_to_gic_id[].
34
+ uint32_t dma_len;
56
+ * one for every non-zero entry in combiner_grp_to_gic_id[],
35
} AspeedI2CBus;
57
+ * minus one for every external combiner ID in second or later
36
58
+ * places in a combinermap[] line.
37
typedef struct AspeedI2CState {
59
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
38
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
60
*/
39
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
61
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
40
62
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
41
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
63
42
+ MemoryRegion *dram_mr;
64
typedef struct Exynos4210Irq {
43
+ AddressSpace dram_as;
65
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
44
} AspeedI2CState;
66
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
45
46
#define ASPEED_I2C_CLASS(klass) \
47
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
48
hwaddr pool_base;
49
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
50
bool check_sram;
51
+ bool has_dma;
52
53
} AspeedI2CClass;
54
55
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
56
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/aspeed_ast2600.c
68
--- a/hw/arm/exynos4210.c
58
+++ b/hw/arm/aspeed_ast2600.c
69
+++ b/hw/arm/exynos4210.c
59
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
70
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
60
}
71
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
61
72
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
62
/* I2C */
73
63
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
74
+/*
64
+ if (err) {
75
+ * Some interrupt lines go to multiple combiner inputs.
65
+ error_propagate(errp, err);
76
+ * This data structure defines those: each array element is
66
+ return;
77
+ * a list of combiner inputs which are connected together;
78
+ * the one with the smallest interrupt ID value must be first.
79
+ * As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
80
+ * wired to anything so we can use 0 as a terminator.
81
+ */
82
+#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
83
+#define IRQNONE 0
84
+
85
+#define COMBINERMAP_SIZE 16
86
+
87
+static const int combinermap[COMBINERMAP_SIZE][6] = {
88
+ /* MDNIE_LCD1 */
89
+ { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
90
+ { IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
91
+ { IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
92
+ { IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
93
+ /* TMU */
94
+ { IRQNO(2, 4), IRQNO(3, 4), IRQNONE },
95
+ { IRQNO(2, 5), IRQNO(3, 5), IRQNONE },
96
+ { IRQNO(2, 6), IRQNO(3, 6), IRQNONE },
97
+ { IRQNO(2, 7), IRQNO(3, 7), IRQNONE },
98
+ /* LCD1 */
99
+ { IRQNO(11, 4), IRQNO(12, 0), IRQNONE },
100
+ { IRQNO(11, 5), IRQNO(12, 1), IRQNONE },
101
+ { IRQNO(11, 6), IRQNO(12, 2), IRQNONE },
102
+ { IRQNO(11, 7), IRQNO(12, 3), IRQNONE },
103
+ /* Multi-core timer */
104
+ { IRQNO(1, 4), IRQNO(12, 4), IRQNO(35, 4), IRQNO(51, 4), IRQNO(53, 4), IRQNONE },
105
+ { IRQNO(1, 5), IRQNO(12, 5), IRQNO(35, 5), IRQNO(51, 5), IRQNO(53, 5), IRQNONE },
106
+ { IRQNO(1, 6), IRQNO(12, 6), IRQNO(35, 6), IRQNO(51, 6), IRQNO(53, 6), IRQNONE },
107
+ { IRQNO(1, 7), IRQNO(12, 7), IRQNO(35, 7), IRQNO(51, 7), IRQNO(53, 7), IRQNONE },
108
+};
109
+
110
+#undef IRQNO
111
+
112
+static const int *combinermap_entry(int irq)
113
+{
114
+ /*
115
+ * If the interrupt number passed in is the first entry in some
116
+ * line of the combinermap, return a pointer to that line;
117
+ * otherwise return NULL.
118
+ */
119
+ int i;
120
+ for (i = 0; i < COMBINERMAP_SIZE; i++) {
121
+ if (combinermap[i][0] == irq) {
122
+ return combinermap[i];
123
+ }
67
+ }
124
+ }
68
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
125
+ return NULL;
69
if (err) {
126
+}
70
error_propagate(errp, err);
127
+
71
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
128
+static int mapline_size(const int *mapline)
72
index XXXXXXX..XXXXXXX 100644
129
+{
73
--- a/hw/arm/aspeed_soc.c
130
+ /* Return number of entries in this mapline in total */
74
+++ b/hw/arm/aspeed_soc.c
131
+ int i = 0;
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
132
+
76
}
133
+ if (!mapline) {
77
134
+ /* Not in the map? IRQ goes to exactly one combiner input */
78
/* I2C */
135
+ return 1;
79
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
80
+ if (err) {
81
+ error_propagate(errp, err);
82
+ return;
83
+ }
136
+ }
84
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
137
+ while (*mapline != IRQNONE) {
85
if (err) {
138
+ mapline++;
86
error_propagate(errp, err);
139
+ i++;
87
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/i2c/aspeed_i2c.c
90
+++ b/hw/i2c/aspeed_i2c.c
91
@@ -XXX,XX +XXX,XX @@
92
#include "migration/vmstate.h"
93
#include "qemu/log.h"
94
#include "qemu/module.h"
95
+#include "qemu/error-report.h"
96
+#include "qapi/error.h"
97
#include "hw/i2c/aspeed_i2c.h"
98
#include "hw/irq.h"
99
+#include "hw/qdev-properties.h"
100
101
/* I2C Global Register */
102
103
@@ -XXX,XX +XXX,XX @@
104
#define I2CD_BYTE_BUF_TX_MASK 0xff
105
#define I2CD_BYTE_BUF_RX_SHIFT 8
106
#define I2CD_BYTE_BUF_RX_MASK 0xff
107
-
108
+#define I2CD_DMA_ADDR 0x24 /* DMA Buffer Address */
109
+#define I2CD_DMA_LEN 0x28 /* DMA Transfer Length < 4KB */
110
111
static inline bool aspeed_i2c_bus_is_master(AspeedI2CBus *bus)
112
{
113
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
114
unsigned size)
115
{
116
AspeedI2CBus *bus = opaque;
117
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
118
119
switch (offset) {
120
case I2CD_FUN_CTRL_REG:
121
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
122
return bus->buf;
123
case I2CD_CMD_REG:
124
return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
125
+ case I2CD_DMA_ADDR:
126
+ if (!aic->has_dma) {
127
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
128
+ return -1;
129
+ }
130
+ return bus->dma_addr;
131
+ case I2CD_DMA_LEN:
132
+ if (!aic->has_dma) {
133
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
134
+ return -1;
135
+ }
136
+ return bus->dma_len;
137
default:
138
qemu_log_mask(LOG_GUEST_ERROR,
139
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
140
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
141
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
142
}
143
144
+static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data)
145
+{
146
+ MemTxResult result;
147
+ AspeedI2CState *s = bus->controller;
148
+
149
+ result = address_space_read(&s->dram_as, bus->dma_addr,
150
+ MEMTXATTRS_UNSPECIFIED, data, 1);
151
+ if (result != MEMTX_OK) {
152
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n",
153
+ __func__, bus->dma_addr);
154
+ return -1;
155
+ }
140
+ }
156
+
141
+ return i;
157
+ bus->dma_addr++;
158
+ bus->dma_len--;
159
+ return 0;
160
+}
142
+}
161
+
143
+
162
static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
144
/*
163
{
145
* Initialize board IRQs.
164
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
146
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
165
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
147
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
166
}
148
DeviceState *extgicdev = DEVICE(&s->ext_gic);
149
int splitcount = 0;
150
DeviceState *splitter;
151
+ const int *mapline;
152
+ int numlines, splitin, in;
153
154
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
155
irq_id = 0;
156
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
157
irq_id = EXT_GIC_ID_MCT_G1;
167
}
158
}
168
bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
159
169
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
160
+ if (s->irq_table[n]) {
170
+ while (bus->dma_len) {
161
+ /*
171
+ uint8_t data;
162
+ * This must be some non-first entry in a combinermap line,
172
+ aspeed_i2c_dma_read(bus, &data);
163
+ * and we've already filled it in.
173
+ ret = i2c_send(bus->bus, data);
164
+ */
174
+ if (ret) {
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) {
175
+ break;
194
+ break;
176
+ }
195
+ }
177
+ }
196
+ mapline++;
178
+ bus->cmd &= ~I2CD_TX_DMA_ENABLE;
197
+ in = *mapline;
179
} else {
198
+ if (in == IRQNONE) {
180
ret = i2c_send(bus->bus, bus->buf);
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
}
181
}
207
}
182
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
208
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
183
bus->pool_ctrl &= ~(0xff << 24);
209
irq_id = combiner_grp_to_gic_id[grp -
184
bus->pool_ctrl |= (i & 0xff) << 24;
210
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
185
bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
211
186
+ } else if (bus->cmd & I2CD_RX_DMA_ENABLE) {
212
+ if (s->irq_table[n]) {
187
+ uint8_t data;
213
+ /*
188
+
214
+ * This must be some non-first entry in a combinermap line,
189
+ while (bus->dma_len) {
215
+ * and we've already filled it in.
190
+ MemTxResult result;
216
+ */
191
+
217
+ continue;
192
+ data = i2c_recv(bus->bus);
218
+ }
193
+ result = address_space_write(&s->dram_as, bus->dma_addr,
219
+
194
+ MEMTXATTRS_UNSPECIFIED, &data, 1);
220
if (irq_id) {
195
+ if (result != MEMTX_OK) {
221
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
196
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
222
splitter = DEVICE(&s->splitter[splitcount]);
197
+ __func__, bus->dma_addr);
223
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
198
+ return;
224
DeviceState *dev, int ext)
199
+ }
225
{
200
+ bus->dma_addr++;
226
int n;
201
+ bus->dma_len--;
227
- int bit;
202
+ }
228
int max;
203
+ bus->cmd &= ~I2CD_RX_DMA_ENABLE;
229
qemu_irq *irq;
204
} else {
230
205
data = i2c_recv(bus->bus);
231
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
206
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
232
EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
207
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
233
irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
208
uint8_t *pool_base = aic->bus_pool_base(bus);
234
209
235
- /*
210
return pool_base[0];
236
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
211
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
237
- * so let split them.
212
+ uint8_t data;
238
- */
213
+
239
for (n = 0; n < max; n++) {
214
+ aspeed_i2c_dma_read(bus, &data);
240
-
215
+ return data;
241
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
216
} else {
242
-
217
return bus->buf;
243
- switch (n) {
218
}
244
- /* MDNIE_LCD1 INTG1 */
219
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
245
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
220
*/
246
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
221
pool_start++;
247
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
222
}
248
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
223
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
249
- continue;
224
+ if (bus->dma_len == 0) {
250
-
225
+ bus->cmd &= ~I2CD_M_TX_CMD;
251
- /* TMU INTG3 */
226
+ }
252
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
227
} else {
253
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
228
bus->cmd &= ~I2CD_M_TX_CMD;
254
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
229
}
255
- continue;
230
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
256
-
231
break;
257
- /* LCD1 INTG12 */
232
}
258
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
233
259
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
234
+ if (!aic->has_dma &&
260
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
235
+ value & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE)) {
261
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
236
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
262
- continue;
237
+ break;
263
-
238
+ }
264
- /* Multi-Core Timer INTG12 */
239
+
265
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
240
aspeed_i2c_bus_handle_cmd(bus, value);
266
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
241
aspeed_i2c_bus_raise_interrupt(bus);
267
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
242
break;
268
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
243
+ case I2CD_DMA_ADDR:
269
- continue;
244
+ if (!aic->has_dma) {
270
-
245
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
271
- /* Multi-Core Timer INTG35 */
246
+ break;
272
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
247
+ }
273
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
248
+
274
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
249
+ bus->dma_addr = value & 0xfffffffc;
275
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
250
+ break;
276
- continue;
251
+
277
-
252
+ case I2CD_DMA_LEN:
278
- /* Multi-Core Timer INTG51 */
253
+ if (!aic->has_dma) {
279
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
254
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
280
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
255
+ break;
281
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
256
+ }
282
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
257
+
283
- continue;
258
+ bus->dma_len = value & 0xfff;
284
-
259
+ if (!bus->dma_len) {
285
- /* Multi-Core Timer INTG53 */
260
+ qemu_log_mask(LOG_UNIMP, "%s: invalid DMA length\n", __func__);
286
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
261
+ }
287
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
262
+ break;
288
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
263
289
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
264
default:
290
- continue;
265
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
291
- }
266
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_pool_ops = {
292
-
267
293
irq[n] = qdev_get_gpio_in(dev, n);
268
static const VMStateDescription aspeed_i2c_bus_vmstate = {
269
.name = TYPE_ASPEED_I2C,
270
- .version_id = 2,
271
- .minimum_version_id = 2,
272
+ .version_id = 3,
273
+ .minimum_version_id = 3,
274
.fields = (VMStateField[]) {
275
VMSTATE_UINT8(id, AspeedI2CBus),
276
VMSTATE_UINT32(ctrl, AspeedI2CBus),
277
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
278
VMSTATE_UINT32(cmd, AspeedI2CBus),
279
VMSTATE_UINT32(buf, AspeedI2CBus),
280
VMSTATE_UINT32(pool_ctrl, AspeedI2CBus),
281
+ VMSTATE_UINT32(dma_addr, AspeedI2CBus),
282
+ VMSTATE_UINT32(dma_len, AspeedI2CBus),
283
VMSTATE_END_OF_LIST()
284
}
285
};
286
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_reset(DeviceState *dev)
287
s->busses[i].intr_status = 0;
288
s->busses[i].cmd = 0;
289
s->busses[i].buf = 0;
290
+ s->busses[i].dma_addr = 0;
291
+ s->busses[i].dma_len = 0;
292
i2c_end_transfer(s->busses[i].bus);
293
}
294
}
294
}
295
}
295
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
296
memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
297
"aspeed.i2c-pool", aic->pool_size);
298
memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
299
+
300
+ if (aic->has_dma) {
301
+ if (!s->dram_mr) {
302
+ error_setg(errp, TYPE_ASPEED_I2C ": 'dram' link not set");
303
+ return;
304
+ }
305
+
306
+ address_space_init(&s->dram_as, s->dram_mr, "dma-dram");
307
+ }
308
}
309
310
+static Property aspeed_i2c_properties[] = {
311
+ DEFINE_PROP_LINK("dram", AspeedI2CState, dram_mr,
312
+ TYPE_MEMORY_REGION, MemoryRegion *),
313
+ DEFINE_PROP_END_OF_LIST(),
314
+};
315
+
316
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
317
{
318
DeviceClass *dc = DEVICE_CLASS(klass);
319
320
dc->vmsd = &aspeed_i2c_vmstate;
321
dc->reset = aspeed_i2c_reset;
322
+ dc->props = aspeed_i2c_properties;
323
dc->realize = aspeed_i2c_realize;
324
dc->desc = "Aspeed I2C Controller";
325
}
326
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
327
aic->pool_base = 0x200;
328
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
329
aic->check_sram = true;
330
+ aic->has_dma = true;
331
}
332
333
static const TypeInfo aspeed_2500_i2c_info = {
334
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
335
aic->pool_size = 0x200;
336
aic->pool_base = 0xC00;
337
aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
338
+ aic->has_dma = true;
339
}
340
341
static const TypeInfo aspeed_2600_i2c_info = {
342
--
296
--
343
2.20.1
297
2.25.1
344
345
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Switch the creation of the combiner devices to the new-style
2
"embedded in state struct" approach, so we can easily refer
3
to the object elsewhere during realize.
2
4
3
The Aspeed Watchdog and Timer models have a link pointing to the SCU
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
controller model of the machine.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-18-peter.maydell@linaro.org
8
---
9
include/hw/arm/exynos4210.h | 3 ++
10
include/hw/intc/exynos4210_combiner.h | 57 +++++++++++++++++++++++++++
11
hw/arm/exynos4210.c | 20 +++++-----
12
hw/intc/exynos4210_combiner.c | 31 +--------------
13
4 files changed, 72 insertions(+), 39 deletions(-)
14
create mode 100644 include/hw/intc/exynos4210_combiner.h
5
15
6
Change the "scu" property definition so that it explicitly sets the
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
7
pointer. The property isn't optional : not being able to set the link
8
is a bug and QEMU should rather abort than exit in this case.
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Greg Kurz <groug@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-17-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/aspeed_ast2600.c | 8 ++++----
18
hw/arm/aspeed_soc.c | 8 ++++----
19
hw/timer/aspeed_timer.c | 17 +++++++++--------
20
hw/watchdog/wdt_aspeed.c | 17 ++++++++---------
21
4 files changed, 25 insertions(+), 25 deletions(-)
22
23
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/aspeed_ast2600.c
18
--- a/include/hw/arm/exynos4210.h
26
+++ b/hw/arm/aspeed_ast2600.c
19
+++ b/include/hw/arm/exynos4210.h
27
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
28
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
29
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
30
sizeof(s->timerctrl), typename);
31
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
32
- OBJECT(&s->scu), &error_abort);
33
34
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
35
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
37
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
38
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
39
sizeof(s->wdt[i]), typename);
40
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
41
- OBJECT(&s->scu), &error_abort);
42
}
43
44
for (i = 0; i < sc->macs_num; i++) {
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
46
aspeed_soc_get_irq(s, ASPEED_RTC));
47
48
/* Timer */
49
+ object_property_set_link(OBJECT(&s->timerctrl),
50
+ OBJECT(&s->scu), "scu", &error_abort);
51
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
52
if (err) {
53
error_propagate(errp, err);
54
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
55
for (i = 0; i < sc->wdts_num; i++) {
56
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
57
58
+ object_property_set_link(OBJECT(&s->wdt[i]),
59
+ OBJECT(&s->scu), "scu", &error_abort);
60
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
61
if (err) {
62
error_propagate(errp, err);
63
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/aspeed_soc.c
66
+++ b/hw/arm/aspeed_soc.c
67
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
68
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
69
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
70
sizeof(s->timerctrl), typename);
71
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
72
- OBJECT(&s->scu), &error_abort);
73
74
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
75
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
76
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
77
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
78
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
79
sizeof(s->wdt[i]), typename);
80
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
81
- OBJECT(&s->scu), &error_abort);
82
}
83
84
for (i = 0; i < sc->macs_num; i++) {
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
86
aspeed_soc_get_irq(s, ASPEED_RTC));
87
88
/* Timer */
89
+ object_property_set_link(OBJECT(&s->timerctrl),
90
+ OBJECT(&s->scu), "scu", &error_abort);
91
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
92
if (err) {
93
error_propagate(errp, err);
94
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
95
for (i = 0; i < sc->wdts_num; i++) {
96
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
97
98
+ object_property_set_link(OBJECT(&s->wdt[i]),
99
+ OBJECT(&s->scu), "scu", &error_abort);
100
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
101
if (err) {
102
error_propagate(errp, err);
103
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/hw/timer/aspeed_timer.c
106
+++ b/hw/timer/aspeed_timer.c
107
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
108
#include "qemu/timer.h"
21
#include "hw/sysbus.h"
109
#include "qemu/log.h"
22
#include "hw/cpu/a9mpcore.h"
110
#include "qemu/module.h"
23
#include "hw/intc/exynos4210_gic.h"
111
+#include "hw/qdev-properties.h"
24
+#include "hw/intc/exynos4210_combiner.h"
112
#include "trace.h"
25
#include "hw/core/split-irq.h"
113
26
#include "target/arm/cpu-qom.h"
114
#define TIMER_NR_REGS 4
27
#include "qom/object.h"
115
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_realize(DeviceState *dev, Error **errp)
28
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
116
int i;
29
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
117
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
30
A9MPPrivState a9mpcore;
118
AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
31
Exynos4210GicState ext_gic;
119
- Object *obj;
32
+ Exynos4210CombinerState int_combiner;
120
- Error *err = NULL;
33
+ Exynos4210CombinerState ext_combiner;
121
34
SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
122
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
123
- if (!obj) {
124
- error_propagate_prepend(errp, err, "required link 'scu' not found: ");
125
- return;
126
- }
127
- s->scu = ASPEED_SCU(obj);
128
+ assert(s->scu);
129
130
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
131
aspeed_init_one_timer(s, i);
132
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_timer_state = {
133
}
134
};
35
};
135
36
136
+static Property aspeed_timer_properties[] = {
37
diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h
137
+ DEFINE_PROP_LINK("scu", AspeedTimerCtrlState, scu, TYPE_ASPEED_SCU,
38
new file mode 100644
138
+ AspeedSCUState *),
39
index XXXXXXX..XXXXXXX
139
+ DEFINE_PROP_END_OF_LIST(),
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];
140
+};
97
+};
141
+
98
+
142
static void timer_class_init(ObjectClass *klass, void *data)
99
+#endif
143
{
100
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
144
DeviceClass *dc = DEVICE_CLASS(klass);
101
index XXXXXXX..XXXXXXX 100644
145
@@ -XXX,XX +XXX,XX @@ static void timer_class_init(ObjectClass *klass, void *data)
102
--- a/hw/arm/exynos4210.c
146
dc->reset = aspeed_timer_reset;
103
+++ b/hw/arm/exynos4210.c
147
dc->desc = "ASPEED Timer";
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
148
dc->vmsd = &vmstate_aspeed_timer_state;
105
}
149
+ dc->props = aspeed_timer_properties;
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);
150
}
145
}
151
146
152
static const TypeInfo aspeed_timer_info = {
147
static void exynos4210_class_init(ObjectClass *klass, void *data)
153
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
148
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
154
index XXXXXXX..XXXXXXX 100644
149
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/watchdog/wdt_aspeed.c
150
--- a/hw/intc/exynos4210_combiner.c
156
+++ b/hw/watchdog/wdt_aspeed.c
151
+++ b/hw/intc/exynos4210_combiner.c
157
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
152
@@ -XXX,XX +XXX,XX @@
158
{
153
#include "hw/sysbus.h"
159
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
154
#include "migration/vmstate.h"
160
AspeedWDTState *s = ASPEED_WDT(dev);
155
#include "qemu/module.h"
161
- Error *err = NULL;
156
-
162
- Object *obj;
157
+#include "hw/intc/exynos4210_combiner.h"
163
158
#include "hw/arm/exynos4210.h"
164
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
159
#include "hw/hw.h"
165
- if (!obj) {
160
#include "hw/irq.h"
166
- error_propagate(errp, err);
161
@@ -XXX,XX +XXX,XX @@
167
- error_prepend(errp, "required link 'scu' not found: ");
162
#define DPRINTF(fmt, ...) do {} while (0)
168
- return;
163
#endif
169
- }
164
170
- s->scu = ASPEED_SCU(obj);
165
-#define IIC_NGRP 64 /* Internal Interrupt Combiner
171
+ assert(s->scu);
166
- Groups number */
172
167
-#define IIC_NIRQ (IIC_NGRP * 8)/* Internal Interrupt Combiner
173
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, aspeed_wdt_timer_expired, dev);
168
- Interrupts number */
174
169
#define IIC_REGION_SIZE 0x108 /* Size of memory mapped region */
175
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
170
-#define IIC_REGSET_SIZE 0x41
176
sysbus_init_mmio(sbd, &s->iomem);
171
-
177
}
172
-/*
178
173
- * State for each output signal of internal combiner
179
+static Property aspeed_wdt_properties[] = {
174
- */
180
+ DEFINE_PROP_LINK("scu", AspeedWDTState, scu, TYPE_ASPEED_SCU,
175
-typedef struct CombinerGroupState {
181
+ AspeedSCUState *),
176
- uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
182
+ DEFINE_PROP_END_OF_LIST(),
177
- uint8_t src_pending; /* Pending source interrupts before masking */
183
+};
178
-} CombinerGroupState;
184
+
179
-
185
static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
180
-#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
186
{
181
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
187
DeviceClass *dc = DEVICE_CLASS(klass);
182
-
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
183
-struct Exynos4210CombinerState {
189
dc->reset = aspeed_wdt_reset;
184
- SysBusDevice parent_obj;
190
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
185
-
191
dc->vmsd = &vmstate_aspeed_wdt;
186
- MemoryRegion iomem;
192
+ dc->props = aspeed_wdt_properties;
187
-
193
}
188
- struct CombinerGroupState group[IIC_NGRP];
194
189
- uint32_t reg_set[IIC_REGSET_SIZE];
195
static const TypeInfo aspeed_wdt_info = {
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",
196
--
198
--
197
2.20.1
199
2.25.1
198
199
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.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
The segments can be disabled on the AST2600 (zero register value).
10
Since these are the only two remaining elements of Exynos4210Irq,
4
CS0 is open by default but not the other CS. This is closing the
11
we can remove that struct entirely.
5
access to the flash device in user mode and forbids scanning.
6
12
7
In the model, check the segment size and disable the associated region
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
when the value is zero.
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
16
---
17
include/hw/arm/exynos4210.h | 6 ------
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
19
2 files changed, 8 insertions(+), 32 deletions(-)
9
20
10
Fixes: bcaa8ddd081c ("aspeed/smc: Add AST2600 support")
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-12-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/ssi/aspeed_smc.c | 16 +++++++++++-----
18
1 file changed, 11 insertions(+), 5 deletions(-)
19
20
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/ssi/aspeed_smc.c
23
--- a/include/hw/arm/exynos4210.h
23
+++ b/hw/ssi/aspeed_smc.c
24
+++ b/include/hw/arm/exynos4210.h
24
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
25
@@ -XXX,XX +XXX,XX @@
25
uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
26
*/
26
uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
27
28
28
- seg->addr = s->ctrl->flash_window_base + start_offset;
29
-typedef struct Exynos4210Irq {
29
- seg->size = end_offset + MiB - start_offset;
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
30
+ if (reg) {
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
31
+ seg->addr = s->ctrl->flash_window_base + start_offset;
32
-} Exynos4210Irq;
32
+ seg->size = end_offset + MiB - start_offset;
33
-
33
+ } else {
34
struct Exynos4210State {
34
+ seg->addr = s->ctrl->flash_window_base;
35
/*< private >*/
35
+ seg->size = 0;
36
SysBusDevice parent_obj;
36
+ }
37
/*< public >*/
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
39
- Exynos4210Irq irqs;
40
qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
41
42
MemoryRegion chipid_mem;
43
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/arm/exynos4210.c
46
+++ b/hw/arm/exynos4210.c
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
48
static void exynos4210_init_board_irqs(Exynos4210State *s)
49
{
50
uint32_t grp, bit, irq_id, n;
51
- Exynos4210Irq *is = &s->irqs;
52
DeviceState *extgicdev = DEVICE(&s->ext_gic);
53
+ DeviceState *intcdev = DEVICE(&s->int_combiner);
54
+ DeviceState *extcdev = DEVICE(&s->ext_combiner);
55
int splitcount = 0;
56
DeviceState *splitter;
57
const int *mapline;
58
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
59
splitin = 0;
60
for (;;) {
61
s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
62
- qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
63
- qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
64
+ qdev_connect_gpio_out(splitter, splitin,
65
+ qdev_get_gpio_in(intcdev, in));
66
+ qdev_connect_gpio_out(splitter, splitin + 1,
67
+ qdev_get_gpio_in(extcdev, in));
68
splitin += 2;
69
if (!mapline) {
70
break;
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
72
qdev_realize(splitter, NULL, &error_abort);
73
splitcount++;
74
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
75
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
76
+ qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
77
qdev_connect_gpio_out(splitter, 1,
78
qdev_get_gpio_in(extgicdev, irq_id - 32));
79
} else {
80
- s->irq_table[n] = is->int_combiner_irq[n];
81
+ s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
82
}
83
}
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);
37
}
87
}
38
88
39
static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
89
-/*
40
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
90
- * Get Combiner input GPIO into irqs structure
41
memory_region_transaction_begin();
91
- */
42
memory_region_set_size(&fl->mmio, seg.size);
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
43
memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
93
- DeviceState *dev, int ext)
44
- memory_region_set_enabled(&fl->mmio, true);
94
-{
45
+ memory_region_set_enabled(&fl->mmio, !!seg.size);
95
- int n;
46
memory_region_transaction_commit();
96
- int max;
47
97
- qemu_irq *irq;
48
s->regs[R_SEG_ADDR0 + cs] = regval;
98
-
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
102
-
103
- for (n = 0; n < max; n++) {
104
- irq[n] = qdev_get_gpio_in(dev, n);
105
- }
106
-}
107
-
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
109
0x09, 0x00, 0x00, 0x00 };
110
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
112
sysbus_connect_irq(busdev, n,
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
50
}
114
}
51
115
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
52
/* Keep the segment in the overall flash window */
116
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
53
- if (seg.addr + seg.size <= s->ctrl->flash_window_base ||
117
54
- seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size) {
118
/* External Interrupt Combiner */
55
+ if (seg.size &&
119
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
56
+ (seg.addr + seg.size <= s->ctrl->flash_window_base ||
120
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
57
+ seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size)) {
121
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
58
qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : "
122
}
59
"[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
123
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
60
s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
124
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
125
126
/* Initialize board IRQs. */
61
--
127
--
62
2.20.1
128
2.25.1
63
64
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
The current model only restores the Segment Register values but leaves
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
the previous CS mapping behind. Introduce a helper setting the
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
register value and mapping the region at the requested address. Use
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
6
this helper when a Segment register is set and at reset.
7
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-11-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
7
---
14
hw/ssi/aspeed_smc.c | 32 +++++++++++++++++++++-----------
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
15
1 file changed, 21 insertions(+), 11 deletions(-)
9
1 file changed, 24 insertions(+), 9 deletions(-)
16
10
17
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/ssi/aspeed_smc.c
13
--- a/hw/arm/realview.c
20
+++ b/hw/ssi/aspeed_smc.c
14
+++ b/hw/arm/realview.c
21
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
15
@@ -XXX,XX +XXX,XX @@
22
return false;
16
#include "hw/sysbus.h"
23
}
17
#include "hw/arm/boot.h"
24
18
#include "hw/arm/primecell.h"
25
+static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
19
+#include "hw/core/split-irq.h"
26
+ uint64_t regval)
20
#include "hw/net/lan9118.h"
27
+{
21
#include "hw/net/smc91c111.h"
28
+ AspeedSMCFlash *fl = &s->flashes[cs];
22
#include "hw/pci/pci.h"
29
+ AspeedSegments seg;
23
+#include "hw/qdev-core.h"
24
#include "net/net.h"
25
#include "sysemu/sysemu.h"
26
#include "hw/boards.h"
27
@@ -XXX,XX +XXX,XX @@ static const int realview_board_id[] = {
28
0x76d
29
};
30
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
32
+ qemu_irq out1, qemu_irq out2) {
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
30
+
34
+
31
+ s->ctrl->reg_to_segment(s, regval, &seg);
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
32
+
36
+
33
+ memory_region_transaction_begin();
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
34
+ memory_region_set_size(&fl->mmio, seg.size);
35
+ memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
36
+ memory_region_set_enabled(&fl->mmio, true);
37
+ memory_region_transaction_commit();
38
+
38
+
39
+ s->regs[R_SEG_ADDR0 + cs] = regval;
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));
40
+}
43
+}
41
+
44
+
42
static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
45
static void realview_init(MachineState *machine,
43
uint64_t new)
46
enum realview_board_type board_type)
44
{
47
{
45
- AspeedSMCFlash *fl = &s->flashes[cs];
48
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
46
AspeedSegments seg;
49
DeviceState *dev, *sysctl, *gpio2, *pl041;
47
50
SysBusDevice *busdev;
48
s->ctrl->reg_to_segment(s, new, &seg);
51
qemu_irq pic[64];
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
52
- qemu_irq mmc_irq[2];
50
aspeed_smc_flash_overlap(s, &seg, cs);
53
PCIBus *pci_bus = NULL;
51
54
NICInfo *nd;
52
/* All should be fine now to move the region */
55
DriveInfo *dinfo;
53
- memory_region_transaction_begin();
56
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
54
- memory_region_set_size(&fl->mmio, seg.size);
57
* and the PL061 has them the other way about. Also the card
55
- memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
58
* detect line is inverted.
56
- memory_region_set_enabled(&fl->mmio, true);
59
*/
57
- memory_region_transaction_commit();
60
- mmc_irq[0] = qemu_irq_split(
58
-
61
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
59
- s->regs[R_SEG_ADDR0 + cs] = new;
62
- qdev_get_gpio_in(gpio2, 1));
60
+ aspeed_smc_flash_set_segment_region(s, cs, new);
63
- mmc_irq[1] = qemu_irq_split(
61
}
64
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
62
65
- qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
63
static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
66
- qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
64
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
67
- qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_irq[1]);
65
qemu_set_irq(s->cs_lines[i], true);
68
+ split_irq_from_named(dev, "card-read-only",
66
}
69
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
67
70
+ qdev_get_gpio_in(gpio2, 1));
68
- /* setup default segment register values for all */
71
+
69
+ /* setup the default segment register values and regions for all */
72
+ split_irq_from_named(dev, "card-inserted",
70
for (i = 0; i < s->ctrl->max_slaves; ++i) {
73
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
71
- s->regs[R_SEG_ADDR0 + i] =
74
+ qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
72
- s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]);
75
+
73
+ aspeed_smc_flash_set_segment_region(s, i,
76
dinfo = drive_get(IF_SD, 0, 0);
74
+ s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]));
77
if (dinfo) {
75
}
78
DeviceState *card;
76
77
/* HW strapping flash type for the AST2600 controllers */
78
--
79
--
79
2.20.1
80
2.25.1
80
81
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
Each CS has its own Read Timing Compensation Register on newer SoCs.
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
6
Reviewed-by: Joel Stanley <joel@jms.id.au>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20191119141211.25716-13-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
7
---
11
include/hw/ssi/aspeed_smc.h | 1 +
8
hw/arm/stellaris.c | 15 +++++++++++++--
12
hw/ssi/aspeed_smc.c | 17 ++++++++++++++---
9
1 file changed, 13 insertions(+), 2 deletions(-)
13
2 files changed, 15 insertions(+), 3 deletions(-)
14
10
15
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/aspeed_smc.h
13
--- a/hw/arm/stellaris.c
18
+++ b/include/hw/ssi/aspeed_smc.h
14
+++ b/hw/arm/stellaris.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCController {
20
uint8_t r_ce_ctrl;
21
uint8_t r_ctrl0;
22
uint8_t r_timings;
23
+ uint8_t nregs_timings;
24
uint8_t conf_enable_w0;
25
uint8_t max_slaves;
26
const AspeedSegments *segments;
27
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/ssi/aspeed_smc.c
30
+++ b/hw/ssi/aspeed_smc.c
31
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@
32
/* Checksum Calculation Result */
16
33
#define R_DMA_CHECKSUM (0x90 / 4)
17
#include "qemu/osdep.h"
34
18
#include "qapi/error.h"
35
-/* Misc Control Register #2 */
19
+#include "hw/core/split-irq.h"
36
+/* Read Timing Compensation Register */
20
#include "hw/sysbus.h"
37
#define R_TIMINGS (0x94 / 4)
21
#include "hw/sd/sd.h"
38
22
#include "hw/ssi/ssi.h"
39
/* SPI controller registers and bits (AST2400) */
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
40
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
24
DeviceState *ssddev;
41
.r_ce_ctrl = R_CE_CTRL,
25
DriveInfo *dinfo;
42
.r_ctrl0 = R_CTRL0,
26
DeviceState *carddev;
43
.r_timings = R_TIMINGS,
27
+ DeviceState *gpio_d_splitter;
44
+ .nregs_timings = 1,
28
BlockBackend *blk;
45
.conf_enable_w0 = CONF_ENABLE_W0,
29
46
.max_slaves = 5,
30
/*
47
.segments = aspeed_segments_legacy,
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
48
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
32
&error_fatal);
49
.r_ce_ctrl = R_CE_CTRL,
33
50
.r_ctrl0 = R_CTRL0,
34
ssddev = ssi_create_peripheral(bus, "ssd0323");
51
.r_timings = R_TIMINGS,
35
- gpio_out[GPIO_D][0] = qemu_irq_split(
52
+ .nregs_timings = 1,
36
- qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
53
.conf_enable_w0 = CONF_ENABLE_W0,
37
+
54
.max_slaves = 5,
38
+ gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
55
.segments = aspeed_segments_fmc,
39
+ qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
56
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
40
+ qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
57
.r_ce_ctrl = 0xff,
41
+ qdev_connect_gpio_out(
58
.r_ctrl0 = R_SPI_CTRL0,
42
+ gpio_d_splitter, 0,
59
.r_timings = R_SPI_TIMINGS,
43
+ qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0));
60
+ .nregs_timings = 1,
44
+ qdev_connect_gpio_out(
61
.conf_enable_w0 = SPI_CONF_ENABLE_W0,
45
+ gpio_d_splitter, 1,
62
.max_slaves = 1,
46
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
63
.segments = aspeed_segments_spi,
47
+ gpio_out[GPIO_D][0] = qdev_get_gpio_in(gpio_d_splitter, 0);
64
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
48
+
65
.r_ce_ctrl = R_CE_CTRL,
49
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
66
.r_ctrl0 = R_CTRL0,
50
67
.r_timings = R_TIMINGS,
51
/* Make sure the select pin is high. */
68
+ .nregs_timings = 1,
69
.conf_enable_w0 = CONF_ENABLE_W0,
70
.max_slaves = 3,
71
.segments = aspeed_segments_ast2500_fmc,
72
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
73
.r_ce_ctrl = R_CE_CTRL,
74
.r_ctrl0 = R_CTRL0,
75
.r_timings = R_TIMINGS,
76
+ .nregs_timings = 1,
77
.conf_enable_w0 = CONF_ENABLE_W0,
78
.max_slaves = 2,
79
.segments = aspeed_segments_ast2500_spi1,
80
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
81
.r_ce_ctrl = R_CE_CTRL,
82
.r_ctrl0 = R_CTRL0,
83
.r_timings = R_TIMINGS,
84
+ .nregs_timings = 1,
85
.conf_enable_w0 = CONF_ENABLE_W0,
86
.max_slaves = 2,
87
.segments = aspeed_segments_ast2500_spi2,
88
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
89
.r_ce_ctrl = R_CE_CTRL,
90
.r_ctrl0 = R_CTRL0,
91
.r_timings = R_TIMINGS,
92
+ .nregs_timings = 1,
93
.conf_enable_w0 = CONF_ENABLE_W0,
94
.max_slaves = 3,
95
.segments = aspeed_segments_ast2600_fmc,
96
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
97
.r_ce_ctrl = R_CE_CTRL,
98
.r_ctrl0 = R_CTRL0,
99
.r_timings = R_TIMINGS,
100
+ .nregs_timings = 2,
101
.conf_enable_w0 = CONF_ENABLE_W0,
102
.max_slaves = 2,
103
.segments = aspeed_segments_ast2600_spi1,
104
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
105
.r_ce_ctrl = R_CE_CTRL,
106
.r_ctrl0 = R_CTRL0,
107
.r_timings = R_TIMINGS,
108
+ .nregs_timings = 3,
109
.conf_enable_w0 = CONF_ENABLE_W0,
110
.max_slaves = 3,
111
.segments = aspeed_segments_ast2600_spi2,
112
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
113
addr >>= 2;
114
115
if (addr == s->r_conf ||
116
- addr == s->r_timings ||
117
+ (addr >= s->r_timings &&
118
+ addr < s->r_timings + s->ctrl->nregs_timings) ||
119
addr == s->r_ce_ctrl ||
120
addr == R_INTR_CTRL ||
121
addr == R_DUMMY_DATA ||
122
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
123
addr >>= 2;
124
125
if (addr == s->r_conf ||
126
- addr == s->r_timings ||
127
+ (addr >= s->r_timings &&
128
+ addr < s->r_timings + s->ctrl->nregs_timings) ||
129
addr == s->r_ce_ctrl) {
130
s->regs[addr] = value;
131
} else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
132
--
52
--
133
2.20.1
53
2.25.1
134
135
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
AspeedBoardConfig is a redundant way to define class attributes and it
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
complexifies the machine definition and initialization.
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-14-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
include/hw/arm/aspeed.h | 24 ++--
9
include/hw/irq.h | 5 -----
13
hw/arm/aspeed.c | 243 ++++++++++++++++++++++------------------
10
hw/core/irq.c | 15 ---------------
14
2 files changed, 143 insertions(+), 124 deletions(-)
11
2 files changed, 20 deletions(-)
15
12
16
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/aspeed.h
15
--- a/include/hw/irq.h
19
+++ b/include/hw/arm/aspeed.h
16
+++ b/include/hw/irq.h
20
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
21
18
/* Returns a new IRQ with opposite polarity. */
22
typedef struct AspeedBoardState AspeedBoardState;
19
qemu_irq qemu_irq_invert(qemu_irq irq);
23
20
24
-typedef struct AspeedBoardConfig {
21
-/* Returns a new IRQ which feeds into both the passed IRQs.
25
- const char *name;
22
- * It's probably better to use the TYPE_SPLIT_IRQ device instead.
26
- const char *desc;
23
- */
27
- const char *soc_name;
24
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
28
- uint32_t hw_strap1;
29
- uint32_t hw_strap2;
30
- const char *fmc_model;
31
- const char *spi_model;
32
- uint32_t num_cs;
33
- void (*i2c_init)(AspeedBoardState *bmc);
34
- uint32_t ram;
35
-} AspeedBoardConfig;
36
-
25
-
37
#define TYPE_ASPEED_MACHINE MACHINE_TYPE_NAME("aspeed")
26
/* For internal use in qtest. Similar to qemu_irq_split, but operating
38
#define ASPEED_MACHINE(obj) \
27
on an existing vector of qemu_irq. */
39
OBJECT_CHECK(AspeedMachine, (obj), TYPE_ASPEED_MACHINE)
28
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
40
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedMachine {
29
diff --git a/hw/core/irq.c b/hw/core/irq.c
41
42
typedef struct AspeedMachineClass {
43
MachineClass parent_obj;
44
- const AspeedBoardConfig *board;
45
+
46
+ const char *name;
47
+ const char *desc;
48
+ const char *soc_name;
49
+ uint32_t hw_strap1;
50
+ uint32_t hw_strap2;
51
+ const char *fmc_model;
52
+ const char *spi_model;
53
+ uint32_t num_cs;
54
+ void (*i2c_init)(AspeedBoardState *bmc);
55
} AspeedMachineClass;
56
57
58
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
59
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/arm/aspeed.c
31
--- a/hw/core/irq.c
61
+++ b/hw/arm/aspeed.c
32
+++ b/hw/core/irq.c
62
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
33
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_invert(qemu_irq irq)
63
}
34
return qemu_allocate_irq(qemu_notirq, irq, 0);
64
}
35
}
65
36
66
-static void aspeed_board_init(MachineState *machine,
37
-static void qemu_splitirq(void *opaque, int line, int level)
67
- const AspeedBoardConfig *cfg)
68
+static void aspeed_machine_init(MachineState *machine)
69
{
70
AspeedBoardState *bmc;
71
+ AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
72
AspeedSoCClass *sc;
73
DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
74
ram_addr_t max_ram_size;
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
76
UINT32_MAX);
77
78
object_initialize_child(OBJECT(machine), "soc", &bmc->soc,
79
- (sizeof(bmc->soc)), cfg->soc_name, &error_abort,
80
+ (sizeof(bmc->soc)), amc->soc_name, &error_abort,
81
NULL);
82
83
sc = ASPEED_SOC_GET_CLASS(&bmc->soc);
84
85
object_property_set_uint(OBJECT(&bmc->soc), ram_size, "ram-size",
86
&error_abort);
87
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1",
88
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap1, "hw-strap1",
89
&error_abort);
90
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap2, "hw-strap2",
91
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap2, "hw-strap2",
92
&error_abort);
93
- object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs",
94
+ object_property_set_int(OBJECT(&bmc->soc), amc->num_cs, "num-cs",
95
&error_abort);
96
object_property_set_int(OBJECT(&bmc->soc), machine->smp.cpus, "num-cpus",
97
&error_abort);
98
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
99
"max_ram", max_ram_size - ram_size);
100
memory_region_add_subregion(&bmc->ram_container, ram_size, &bmc->max_ram);
101
102
- aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort);
103
- aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort);
104
+ aspeed_board_init_flashes(&bmc->soc.fmc, amc->fmc_model, &error_abort);
105
+ aspeed_board_init_flashes(&bmc->soc.spi[0], amc->spi_model, &error_abort);
106
107
/* Install first FMC flash content as a boot rom. */
108
if (drive0) {
109
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
110
aspeed_board_binfo.loader_start = sc->memmap[ASPEED_SDRAM];
111
aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus;
112
113
- if (cfg->i2c_init) {
114
- cfg->i2c_init(bmc);
115
+ if (amc->i2c_init) {
116
+ amc->i2c_init(bmc);
117
}
118
119
for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
120
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
121
0x60);
122
}
123
124
-static void aspeed_machine_init(MachineState *machine)
125
-{
38
-{
126
- AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
39
- struct IRQState **irq = opaque;
127
-
40
- irq[0]->handler(irq[0]->opaque, irq[0]->n, level);
128
- aspeed_board_init(machine, amc->board);
41
- irq[1]->handler(irq[1]->opaque, irq[1]->n, level);
129
-}
42
-}
130
-
43
-
131
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
44
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
45
-{
46
- qemu_irq *s = g_new0(qemu_irq, 2);
47
- s[0] = irq1;
48
- s[1] = irq2;
49
- return qemu_allocate_irq(qemu_splitirq, s, 0);
50
-}
51
-
52
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
132
{
53
{
133
MachineClass *mc = MACHINE_CLASS(oc);
54
int i;
134
- AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
135
- const AspeedBoardConfig *board = data;
136
137
- mc->desc = board->desc;
138
mc->init = aspeed_machine_init;
139
mc->max_cpus = ASPEED_CPUS_NUM;
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->no_parallel = 1;
143
- if (board->ram) {
144
- mc->default_ram_size = board->ram;
145
- }
146
- amc->board = board;
147
}
148
149
-static const TypeInfo aspeed_machine_type = {
150
- .name = TYPE_ASPEED_MACHINE,
151
- .parent = TYPE_MACHINE,
152
- .instance_size = sizeof(AspeedMachine),
153
- .class_size = sizeof(AspeedMachineClass),
154
- .abstract = true,
155
-};
156
-
157
-static const AspeedBoardConfig aspeed_boards[] = {
158
- {
159
- .name = MACHINE_TYPE_NAME("palmetto-bmc"),
160
- .desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)",
161
- .soc_name = "ast2400-a1",
162
- .hw_strap1 = PALMETTO_BMC_HW_STRAP1,
163
- .fmc_model = "n25q256a",
164
- .spi_model = "mx25l25635e",
165
- .num_cs = 1,
166
- .i2c_init = palmetto_bmc_i2c_init,
167
- .ram = 256 * MiB,
168
- }, {
169
- .name = MACHINE_TYPE_NAME("ast2500-evb"),
170
- .desc = "Aspeed AST2500 EVB (ARM1176)",
171
- .soc_name = "ast2500-a1",
172
- .hw_strap1 = AST2500_EVB_HW_STRAP1,
173
- .fmc_model = "w25q256",
174
- .spi_model = "mx25l25635e",
175
- .num_cs = 1,
176
- .i2c_init = ast2500_evb_i2c_init,
177
- .ram = 512 * MiB,
178
- }, {
179
- .name = MACHINE_TYPE_NAME("romulus-bmc"),
180
- .desc = "OpenPOWER Romulus BMC (ARM1176)",
181
- .soc_name = "ast2500-a1",
182
- .hw_strap1 = ROMULUS_BMC_HW_STRAP1,
183
- .fmc_model = "n25q256a",
184
- .spi_model = "mx66l1g45g",
185
- .num_cs = 2,
186
- .i2c_init = romulus_bmc_i2c_init,
187
- .ram = 512 * MiB,
188
- }, {
189
- .name = MACHINE_TYPE_NAME("swift-bmc"),
190
- .desc = "OpenPOWER Swift BMC (ARM1176)",
191
- .soc_name = "ast2500-a1",
192
- .hw_strap1 = SWIFT_BMC_HW_STRAP1,
193
- .fmc_model = "mx66l1g45g",
194
- .spi_model = "mx66l1g45g",
195
- .num_cs = 2,
196
- .i2c_init = swift_bmc_i2c_init,
197
- .ram = 512 * MiB,
198
- }, {
199
- .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
200
- .desc = "OpenPOWER Witherspoon BMC (ARM1176)",
201
- .soc_name = "ast2500-a1",
202
- .hw_strap1 = WITHERSPOON_BMC_HW_STRAP1,
203
- .fmc_model = "mx25l25635e",
204
- .spi_model = "mx66l1g45g",
205
- .num_cs = 2,
206
- .i2c_init = witherspoon_bmc_i2c_init,
207
- .ram = 512 * MiB,
208
- }, {
209
- .name = MACHINE_TYPE_NAME("ast2600-evb"),
210
- .desc = "Aspeed AST2600 EVB (Cortex A7)",
211
- .soc_name = "ast2600-a0",
212
- .hw_strap1 = AST2600_EVB_HW_STRAP1,
213
- .hw_strap2 = AST2600_EVB_HW_STRAP2,
214
- .fmc_model = "w25q512jv",
215
- .spi_model = "mx66u51235f",
216
- .num_cs = 1,
217
- .i2c_init = ast2600_evb_i2c_init,
218
- .ram = 1 * GiB,
219
- },
220
-};
221
-
222
-static void aspeed_machine_types(void)
223
+static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data)
224
{
225
- int i;
226
+ MachineClass *mc = MACHINE_CLASS(oc);
227
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
228
229
- type_register_static(&aspeed_machine_type);
230
- for (i = 0; i < ARRAY_SIZE(aspeed_boards); ++i) {
231
- TypeInfo ti = {
232
- .name = aspeed_boards[i].name,
233
- .parent = TYPE_ASPEED_MACHINE,
234
- .class_init = aspeed_machine_class_init,
235
- .class_data = (void *)&aspeed_boards[i],
236
- };
237
- type_register(&ti);
238
+ mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)";
239
+ amc->soc_name = "ast2400-a1";
240
+ amc->hw_strap1 = PALMETTO_BMC_HW_STRAP1;
241
+ amc->fmc_model = "n25q256a";
242
+ amc->spi_model = "mx25l25635e";
243
+ amc->num_cs = 1;
244
+ amc->i2c_init = palmetto_bmc_i2c_init;
245
+ mc->default_ram_size = 256 * MiB;
246
+};
247
+
248
+static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data)
249
+{
250
+ MachineClass *mc = MACHINE_CLASS(oc);
251
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
252
+
253
+ mc->desc = "Aspeed AST2500 EVB (ARM1176)";
254
+ amc->soc_name = "ast2500-a1";
255
+ amc->hw_strap1 = AST2500_EVB_HW_STRAP1;
256
+ amc->fmc_model = "w25q256";
257
+ amc->spi_model = "mx25l25635e";
258
+ amc->num_cs = 1;
259
+ amc->i2c_init = ast2500_evb_i2c_init;
260
+ mc->default_ram_size = 512 * MiB;
261
+};
262
+
263
+static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data)
264
+{
265
+ MachineClass *mc = MACHINE_CLASS(oc);
266
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
267
+
268
+ mc->desc = "OpenPOWER Romulus BMC (ARM1176)";
269
+ amc->soc_name = "ast2500-a1";
270
+ amc->hw_strap1 = ROMULUS_BMC_HW_STRAP1;
271
+ amc->fmc_model = "n25q256a";
272
+ amc->spi_model = "mx66l1g45g";
273
+ amc->num_cs = 2;
274
+ amc->i2c_init = romulus_bmc_i2c_init;
275
+ mc->default_ram_size = 512 * MiB;
276
+};
277
+
278
+static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data)
279
+{
280
+ MachineClass *mc = MACHINE_CLASS(oc);
281
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
282
+
283
+ mc->desc = "OpenPOWER Swift BMC (ARM1176)";
284
+ amc->soc_name = "ast2500-a1";
285
+ amc->hw_strap1 = SWIFT_BMC_HW_STRAP1;
286
+ amc->fmc_model = "mx66l1g45g";
287
+ amc->spi_model = "mx66l1g45g";
288
+ amc->num_cs = 2;
289
+ amc->i2c_init = swift_bmc_i2c_init;
290
+ mc->default_ram_size = 512 * MiB;
291
+};
292
+
293
+static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data)
294
+{
295
+ MachineClass *mc = MACHINE_CLASS(oc);
296
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
297
+
298
+ mc->desc = "OpenPOWER Witherspoon BMC (ARM1176)";
299
+ amc->soc_name = "ast2500-a1";
300
+ amc->hw_strap1 = WITHERSPOON_BMC_HW_STRAP1;
301
+ amc->fmc_model = "mx25l25635e";
302
+ amc->spi_model = "mx66l1g45g";
303
+ amc->num_cs = 2;
304
+ amc->i2c_init = witherspoon_bmc_i2c_init;
305
+ mc->default_ram_size = 512 * MiB;
306
+};
307
+
308
+static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
309
+{
310
+ MachineClass *mc = MACHINE_CLASS(oc);
311
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
312
+
313
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
314
+ amc->soc_name = "ast2600-a0";
315
+ amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
316
+ amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
317
+ amc->fmc_model = "w25q512jv";
318
+ amc->spi_model = "mx66u51235f";
319
+ amc->num_cs = 1;
320
+ amc->i2c_init = ast2600_evb_i2c_init;
321
+ mc->default_ram_size = 1 * GiB;
322
+};
323
+
324
+static const TypeInfo aspeed_machine_types[] = {
325
+ {
326
+ .name = MACHINE_TYPE_NAME("palmetto-bmc"),
327
+ .parent = TYPE_ASPEED_MACHINE,
328
+ .class_init = aspeed_machine_palmetto_class_init,
329
+ }, {
330
+ .name = MACHINE_TYPE_NAME("ast2500-evb"),
331
+ .parent = TYPE_ASPEED_MACHINE,
332
+ .class_init = aspeed_machine_ast2500_evb_class_init,
333
+ }, {
334
+ .name = MACHINE_TYPE_NAME("romulus-bmc"),
335
+ .parent = TYPE_ASPEED_MACHINE,
336
+ .class_init = aspeed_machine_romulus_class_init,
337
+ }, {
338
+ .name = MACHINE_TYPE_NAME("swift-bmc"),
339
+ .parent = TYPE_ASPEED_MACHINE,
340
+ .class_init = aspeed_machine_swift_class_init,
341
+ }, {
342
+ .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
343
+ .parent = TYPE_ASPEED_MACHINE,
344
+ .class_init = aspeed_machine_witherspoon_class_init,
345
+ }, {
346
+ .name = MACHINE_TYPE_NAME("ast2600-evb"),
347
+ .parent = TYPE_ASPEED_MACHINE,
348
+ .class_init = aspeed_machine_ast2600_evb_class_init,
349
+ }, {
350
+ .name = TYPE_ASPEED_MACHINE,
351
+ .parent = TYPE_MACHINE,
352
+ .instance_size = sizeof(AspeedMachine),
353
+ .class_size = sizeof(AspeedMachineClass),
354
+ .class_init = aspeed_machine_class_init,
355
+ .abstract = true,
356
}
357
-}
358
+};
359
360
-type_init(aspeed_machine_types)
361
+DEFINE_TYPES(aspeed_machine_types)
362
--
55
--
363
2.20.1
56
2.25.1
364
365
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
2
2
3
This change ensures that the FPU can be accessed in Non-Secure mode
3
Describe that the gic-version influences the maximum number of CPUs.
4
when the CPU core is reset using the arm_set_cpu_on() function call.
5
The NSACR.{CP11,CP10} bits define the exception level required to
6
access the FPU in Non-Secure mode. Without these bits set, the CPU
7
will give an undefined exception trap on the first FPU access for the
8
secondary cores under Linux.
9
4
10
This is necessary because in this power-control codepath QEMU
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
11
is effectively emulating a bit of EL3 firmware, and has to set
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
12
the CPU up as the EL3 firmware would.
7
[PMM: minor punctuation tweaks]
13
14
Fixes: fc1120a7f5
15
Cc: qemu-stable@nongnu.org
16
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
17
[PMM: added clarifying para to commit message]
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
10
---
21
target/arm/arm-powerctl.c | 3 +++
11
docs/system/arm/virt.rst | 4 ++--
22
1 file changed, 3 insertions(+)
12
1 file changed, 2 insertions(+), 2 deletions(-)
23
13
24
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/arm-powerctl.c
16
--- a/docs/system/arm/virt.rst
27
+++ b/target/arm/arm-powerctl.c
17
+++ b/docs/system/arm/virt.rst
28
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
18
@@ -XXX,XX +XXX,XX @@ gic-version
29
/* Processor is not in secure mode */
19
Valid values are:
30
target_cpu->env.cp15.scr_el3 |= SCR_NS;
20
31
21
``2``
32
+ /* Set NSACR.{CP11,CP10} so NS can access the FPU */
22
- GICv2
33
+ target_cpu->env.cp15.nsacr |= 3 << 10;
23
+ GICv2. Note that this limits the number of CPUs to 8.
34
+
24
``3``
35
/*
25
- GICv3
36
* If QEMU is providing the equivalent of EL3 firmware, then we need
26
+ GICv3. This allows up to 512 CPUs.
37
* to make sure a CPU targeting EL2 comes out of reset with a
27
``host``
28
Use the same GIC version the host provides, when using KVM
29
``max``
38
--
30
--
39
2.20.1
31
2.25.1
40
41
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
The Tacoma BMC board is replacement board for the BMC of the OpenPOWER
3
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
4
Witherspoon system. It uses a AST2600 SoC instead of a AST2500 and the
4
the PWRON STRAP fields in their corresponding module for NPCM7XX.
5
I2C layout is the same as it controls the same main board. Used for HW
6
bringup.
7
5
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Patrick Venture <venture@google.com>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20220411165842.3912945-2-wuhaotsh@google.com
11
Message-id: 20191119141211.25716-15-clg@kaod.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
hw/arm/aspeed.c | 28 ++++++++++++++++++++++++++++
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
15
1 file changed, 28 insertions(+)
13
1 file changed, 30 insertions(+)
16
14
17
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/aspeed.c
17
--- a/include/hw/misc/npcm7xx_gcr.h
20
+++ b/hw/arm/aspeed.c
18
+++ b/include/hw/misc/npcm7xx_gcr.h
21
@@ -XXX,XX +XXX,XX @@ struct AspeedBoardState {
19
@@ -XXX,XX +XXX,XX @@
22
#define AST2600_EVB_HW_STRAP1 0x000000C0
20
#include "exec/memory.h"
23
#define AST2600_EVB_HW_STRAP2 0x00000003
21
#include "hw/sysbus.h"
24
22
25
+/* Tacoma hardware value */
23
+/*
26
+#define TACOMA_BMC_HW_STRAP1 0x00000000
24
+ * NPCM7XX PWRON STRAP bit fields
27
+#define TACOMA_BMC_HW_STRAP2 0x00000000
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
26
+ * 11: System flash attached to BMC
27
+ * 10: BSP alternative pins.
28
+ * 9:8: Flash UART command route enabled.
29
+ * 7: Security enabled.
30
+ * 6: HI-Z state control.
31
+ * 5: ECC disabled.
32
+ * 4: Reserved
33
+ * 3: JTAG2 enabled.
34
+ * 2:0: CPU and DRAM clock frequency.
35
+ */
36
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
37
+#define NPCM7XX_PWRON_STRAP_SFAB BIT(11)
38
+#define NPCM7XX_PWRON_STRAP_BSPA BIT(10)
39
+#define NPCM7XX_PWRON_STRAP_FUP(x) ((x) << 8)
40
+#define FUP_NORM_UART2 3
41
+#define FUP_PROG_UART3 2
42
+#define FUP_PROG_UART2 1
43
+#define FUP_NORM_UART3 0
44
+#define NPCM7XX_PWRON_STRAP_SECEN BIT(7)
45
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
46
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
47
+#define NPCM7XX_PWRON_STRAP_RESERVE1 BIT(4)
48
+#define NPCM7XX_PWRON_STRAP_J2EN BIT(3)
49
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x) (x)
50
+#define CKFRQ_SKIPINIT 0x000
51
+#define CKFRQ_DEFAULT 0x111
28
+
52
+
29
/*
53
/*
30
* The max ram region is for firmwares that scan the address space
54
* Number of registers in our device state structure. Don't change this without
31
* with load/store to guess how much RAM the SoC has.
55
* incrementing the version_id in the vmstate.
32
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
33
AspeedSoCState *soc = &bmc->soc;
34
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
35
36
+ /* Bus 3: TODO bmp280@77 */
37
+ /* Bus 3: TODO max31785@52 */
38
+ /* Bus 3: TODO dps310@76 */
39
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
40
0x60);
41
42
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
43
eeprom_buf);
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
45
0x60);
46
+ /* Bus 11: TODO ucd90160@64 */
47
}
48
49
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
50
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
51
mc->default_ram_size = 1 * GiB;
52
};
53
54
+static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
55
+{
56
+ MachineClass *mc = MACHINE_CLASS(oc);
57
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
58
+
59
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
60
+ amc->soc_name = "ast2600-a0";
61
+ amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
62
+ amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
63
+ amc->fmc_model = "mx66l1g45g";
64
+ amc->spi_model = "mx66l1g45g";
65
+ amc->num_cs = 2;
66
+ amc->i2c_init = witherspoon_bmc_i2c_init; /* Same board layout */
67
+ mc->default_ram_size = 1 * GiB;
68
+};
69
+
70
static const TypeInfo aspeed_machine_types[] = {
71
{
72
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
73
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
74
.name = MACHINE_TYPE_NAME("ast2600-evb"),
75
.parent = TYPE_ASPEED_MACHINE,
76
.class_init = aspeed_machine_ast2600_evb_class_init,
77
+ }, {
78
+ .name = MACHINE_TYPE_NAME("tacoma-bmc"),
79
+ .parent = TYPE_ASPEED_MACHINE,
80
+ .class_init = aspeed_machine_tacoma_class_init,
81
}, {
82
.name = TYPE_ASPEED_MACHINE,
83
.parent = TYPE_MACHINE,
84
--
56
--
85
2.20.1
57
2.25.1
86
87
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
Currently, we link the DRAM memory region to the FMC model (for DMAs)
3
This patch uses the defined fields to describe PWRON STRAPs for
4
through a property alias at the SoC level. The I2C model will need a
4
better readability.
5
similar region for DMA support, add a DRAM region property at the SoC
6
level for both model to use.
7
5
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Patrick Venture <venture@google.com>
10
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
8
Message-id: 20220411165842.3912945-3-wuhaotsh@google.com
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20191119141211.25716-4-clg@kaod.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
include/hw/arm/aspeed_soc.h | 1 +
12
hw/arm/npcm7xx_boards.c | 24 +++++++++++++++++++-----
16
hw/arm/aspeed_ast2600.c | 7 +++++--
13
1 file changed, 19 insertions(+), 5 deletions(-)
17
hw/arm/aspeed_soc.c | 9 +++++++--
18
3 files changed, 13 insertions(+), 4 deletions(-)
19
14
20
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/aspeed_soc.h
17
--- a/hw/arm/npcm7xx_boards.c
23
+++ b/include/hw/arm/aspeed_soc.h
18
+++ b/hw/arm/npcm7xx_boards.c
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
19
@@ -XXX,XX +XXX,XX @@
25
ARMCPU cpu[ASPEED_CPUS_NUM];
20
#include "sysemu/sysemu.h"
26
uint32_t num_cpus;
21
#include "sysemu/block-backend.h"
27
A15MPPrivState a7mpcore;
22
28
+ MemoryRegion *dram_mr;
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
29
MemoryRegion sram;
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
30
AspeedVICState vic;
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
31
AspeedRtcState rtc;
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
32
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
27
-#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
33
index XXXXXXX..XXXXXXX 100644
28
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT ( \
34
--- a/hw/arm/aspeed_ast2600.c
29
+ NPCM7XX_PWRON_STRAP_SPI0F18 | \
35
+++ b/hw/arm/aspeed_ast2600.c
30
+ NPCM7XX_PWRON_STRAP_SFAB | \
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
31
+ NPCM7XX_PWRON_STRAP_BSPA | \
37
typename);
32
+ NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) | \
38
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
33
+ NPCM7XX_PWRON_STRAP_SECEN | \
39
&error_abort);
34
+ NPCM7XX_PWRON_STRAP_HIZ | \
40
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
35
+ NPCM7XX_PWRON_STRAP_ECC | \
41
- &error_abort);
36
+ NPCM7XX_PWRON_STRAP_RESERVE1 | \
42
37
+ NPCM7XX_PWRON_STRAP_J2EN | \
43
for (i = 0; i < sc->spis_num; i++) {
38
+ NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))
44
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
39
+
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
40
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
46
}
41
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_J2EN)
47
42
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
48
/* FMC, The number of CS is set at the board level */
43
+#define QUANTA_GBS_POWER_ON_STRAPS ( \
49
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
44
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_SFAB)
50
+ if (err) {
45
+#define KUDO_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
51
+ error_propagate(errp, err);
46
+#define MORI_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
52
+ return;
47
53
+ }
48
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
54
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
55
"sdram-base", &err);
56
if (err) {
57
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/aspeed_soc.c
60
+++ b/hw/arm/aspeed_soc.c
61
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
62
typename);
63
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
64
&error_abort);
65
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
66
- &error_abort);
67
68
for (i = 0; i < sc->spis_num; i++) {
69
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
70
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
71
aspeed_soc_get_irq(s, ASPEED_I2C));
72
73
/* FMC, The number of CS is set at the board level */
74
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
75
+ if (err) {
76
+ error_propagate(errp, err);
77
+ return;
78
+ }
79
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
80
"sdram-base", &err);
81
if (err) {
82
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
83
}
84
static Property aspeed_soc_properties[] = {
85
DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
86
+ DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
87
+ MemoryRegion *),
88
DEFINE_PROP_END_OF_LIST(),
89
};
90
49
91
--
50
--
92
2.20.1
51
2.25.1
93
94
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
Most boards have this much.
4
5
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-7-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/misc/aspeed_sdmc.c | 6 +++---
13
1 file changed, 3 insertions(+), 3 deletions(-)
14
15
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/aspeed_sdmc.c
18
+++ b/hw/misc/aspeed_sdmc.c
19
@@ -XXX,XX +XXX,XX @@ static int ast2600_rambits(AspeedSDMCState *s)
20
}
21
22
/* use a common default */
23
- warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M",
24
+ warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 1024M",
25
s->ram_size);
26
- s->ram_size = 512 << 20;
27
- return ASPEED_SDMC_AST2600_512MB;
28
+ s->ram_size = 1024 << 20;
29
+ return ASPEED_SDMC_AST2600_1024MB;
30
}
31
32
static void aspeed_sdmc_reset(DeviceState *dev)
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
This models the clock write one to clear registers, and fixes up some
4
incorrect behavior in all of the write to clear registers.
5
6
There was also a typo in one of the register definitions.
7
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Joel Stanley <joel@jms.id.au>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-id: 20191119141211.25716-8-clg@kaod.org
13
[clg: checkpatch.pl fixes ]
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/misc/aspeed_scu.c | 19 ++++++++++++++-----
18
1 file changed, 14 insertions(+), 5 deletions(-)
19
20
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/aspeed_scu.c
23
+++ b/hw/misc/aspeed_scu.c
24
@@ -XXX,XX +XXX,XX @@
25
#define AST2600_CLK_STOP_CTRL TO_REG(0x80)
26
#define AST2600_CLK_STOP_CTRL_CLR TO_REG(0x84)
27
#define AST2600_CLK_STOP_CTRL2 TO_REG(0x90)
28
-#define AST2600_CLK_STOP_CTR2L_CLR TO_REG(0x94)
29
+#define AST2600_CLK_STOP_CTRL2_CLR TO_REG(0x94)
30
#define AST2600_SDRAM_HANDSHAKE TO_REG(0x100)
31
#define AST2600_HPLL_PARAM TO_REG(0x200)
32
#define AST2600_HPLL_EXT TO_REG(0x204)
33
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_ast2600_scu_read(void *opaque, hwaddr offset,
34
return s->regs[reg];
35
}
36
37
-static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
38
- unsigned size)
39
+static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
40
+ uint64_t data64, unsigned size)
41
{
42
AspeedSCUState *s = ASPEED_SCU(opaque);
43
int reg = TO_REG(offset);
44
+ /* Truncate here so bitwise operations below behave as expected */
45
+ uint32_t data = data64;
46
47
if (reg >= ASPEED_AST2600_SCU_NR_REGS) {
48
qemu_log_mask(LOG_GUEST_ERROR,
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
50
/* fall through */
51
case AST2600_SYS_RST_CTRL:
52
case AST2600_SYS_RST_CTRL2:
53
+ case AST2600_CLK_STOP_CTRL:
54
+ case AST2600_CLK_STOP_CTRL2:
55
/* W1S (Write 1 to set) registers */
56
s->regs[reg] |= data;
57
return;
58
case AST2600_SYS_RST_CTRL_CLR:
59
case AST2600_SYS_RST_CTRL2_CLR:
60
+ case AST2600_CLK_STOP_CTRL_CLR:
61
+ case AST2600_CLK_STOP_CTRL2_CLR:
62
case AST2600_HW_STRAP1_CLR:
63
case AST2600_HW_STRAP2_CLR:
64
- /* W1C (Write 1 to clear) registers */
65
- s->regs[reg] &= ~data;
66
+ /*
67
+ * W1C (Write 1 to clear) registers are offset by one address from
68
+ * the data register
69
+ */
70
+ s->regs[reg - 1] &= ~data;
71
return;
72
73
case AST2600_RNG_DATA:
74
--
75
2.20.1
76
77
diff view generated by jsdifflib