1
First arm pullreq of 5.0!
1
Small pile of bug fixes for rc1. I've included my patches to get
2
our docs building with Sphinx 3, just for convenience...
2
3
3
The following changes since commit 084a398bf8aa7634738e6c6c0103236ee1b3b72f:
4
-- PMM
4
5
5
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2019-12-13 18:14:07 +0000)
6
The following changes since commit b149dea55cce97cb226683d06af61984a1c11e96:
7
8
Merge remote-tracking branch 'remotes/cschoenebeck/tags/pull-9p-20201102' into staging (2020-11-02 10:57:48 +0000)
6
9
7
are available in the Git repository at:
10
are available in the Git repository at:
8
11
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191216-1
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201102
10
13
11
for you to fetch changes up to f80741d107673f162e3b097fc76a1590036cc9d1:
14
for you to fetch changes up to ffb4fbf90a2f63c9cb33e4bb9f854c79bf04ca4a:
12
15
13
target/arm: ensure we use current exception state after SCR update (2019-12-16 10:52:58 +0000)
16
tests/qtest/npcm7xx_rng-test: Disable randomness tests (2020-11-02 16:52:18 +0000)
14
17
15
----------------------------------------------------------------
18
----------------------------------------------------------------
16
target-arm queue:
19
target-arm queue:
17
* Add support for Cortex-M7 CPU
20
* target/arm: Fix Neon emulation bugs on big-endian hosts
18
* exynos4210_gic: Suppress gcc9 format-truncation warnings
21
* target/arm: fix handling of HCR.FB
19
* aspeed: Various minor bug fixes and improvements
22
* target/arm: fix LORID_EL1 access check
20
* aspeed: Add support for the tacoma-bmc board
23
* disas/capstone: Fix monitor disassembly of >32 bytes
21
* Honour HCR_EL32.TID1 and .TID2 trapping requirements
24
* hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
22
* Handle trapping to EL2 of AArch32 VMRS instructions
25
* hw/arm/boot: fix SVE for EL3 direct kernel boot
23
* Handle AArch32 CP15 trapping via HSTR_EL2
26
* hw/display/omap_lcdc: Fix potential NULL pointer dereference
24
* Add support for missing Jazelle system registers
27
* hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
25
* arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on
28
* target/arm: Get correct MMU index for other-security-state
26
* Add support for DC CVAP & DC CVADP instructions
29
* configure: Test that gio libs from pkg-config work
27
* Fix assertion when SCR.NS is changed in Secure-SVC &c
30
* hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
28
* enable SHPC native hot plug in arm ACPI
31
* docs: Fix building with Sphinx 3
32
* tests/qtest/npcm7xx_rng-test: Disable randomness tests
29
33
30
----------------------------------------------------------------
34
----------------------------------------------------------------
31
Alex Bennée (1):
35
AlexChen (2):
32
target/arm: ensure we use current exception state after SCR update
36
hw/display/omap_lcdc: Fix potential NULL pointer dereference
37
hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
33
38
34
Beata Michalska (4):
39
Peter Maydell (9):
35
tcg: cputlb: Add probe_read
40
target/arm: Fix float16 pairwise Neon ops on big-endian hosts
36
Memory: Enable writeback for given memory region
41
target/arm: Fix VUDOT/VSDOT (scalar) on big-endian hosts
37
migration: ram: Switch to ram block writeback
42
disas/capstone: Fix monitor disassembly of >32 bytes
38
target/arm: Add support for DC CVAP & DC CVADP ins
43
target/arm: Get correct MMU index for other-security-state
44
configure: Test that gio libs from pkg-config work
45
hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
46
scripts/kerneldoc: For Sphinx 3 use c:macro for macros with arguments
47
qemu-option-trace.rst.inc: Don't use option:: markup
48
tests/qtest/npcm7xx_rng-test: Disable randomness tests
39
49
40
Christophe Lyon (1):
50
Philippe Mathieu-Daudé (1):
41
target/arm: Add support for cortex-m7 CPU
51
hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
42
52
43
Cédric Le Goater (12):
53
Richard Henderson (11):
44
aspeed/i2c: Add support for pool buffer transfers
54
target/arm: Introduce neon_full_reg_offset
45
aspeed/i2c: Check SRAM enablement on AST2500
55
target/arm: Move neon_element_offset to translate.c
46
aspeed: Add a DRAM memory region at the SoC level
56
target/arm: Use neon_element_offset in neon_load/store_reg
47
aspeed/i2c: Add support for DMA transfers
57
target/arm: Use neon_element_offset in vfp_reg_offset
48
aspeed/i2c: Add trace events
58
target/arm: Add read/write_neon_element32
49
aspeed/smc: Restore default AHB window mapping at reset
59
target/arm: Expand read/write_neon_element32 to all MemOp
50
aspeed/smc: Do not map disabled segment on the AST2600
60
target/arm: Rename neon_load_reg32 to vfp_load_reg32
51
aspeed/smc: Add AST2600 timings registers
61
target/arm: Add read/write_neon_element64
52
aspeed: Remove AspeedBoardConfig array and use AspeedMachineClass
62
target/arm: Rename neon_load_reg64 to vfp_load_reg64
53
aspeed: Add support for the tacoma-bmc board
63
target/arm: Simplify do_long_3d and do_2scalar_long
54
aspeed: Change the "scu" property definition
64
target/arm: Improve do_prewiden_3d
55
aspeed: Change the "nic" property definition
56
65
57
David Gibson (1):
66
Rémi Denis-Courmont (3):
58
exynos4210_gic: Suppress gcc9 format-truncation warnings
67
target/arm: fix handling of HCR.FB
68
target/arm: fix LORID_EL1 access check
69
hw/arm/boot: fix SVE for EL3 direct kernel boot
59
70
60
Heyi Guo (2):
71
docs/qemu-option-trace.rst.inc | 6 +-
61
hw/arm/acpi: simplify AML bit and/or statement
72
configure | 10 +-
62
hw/arm/acpi: enable SHPC native hot plug
73
include/hw/intc/arm_gicv3_common.h | 1 -
74
disas/capstone.c | 2 +-
75
hw/arm/boot.c | 3 +
76
hw/arm/smmuv3.c | 3 +-
77
hw/display/exynos4210_fimd.c | 4 +-
78
hw/display/omap_lcdc.c | 10 +-
79
hw/intc/arm_gicv3_cpuif.c | 5 +-
80
target/arm/helper.c | 24 +-
81
target/arm/m_helper.c | 3 +-
82
target/arm/translate.c | 153 +++++++++---
83
target/arm/vec_helper.c | 12 +-
84
tests/qtest/npcm7xx_rng-test.c | 14 +-
85
scripts/kernel-doc | 18 +-
86
target/arm/translate-neon.c.inc | 472 ++++++++++++++++++++-----------------
87
target/arm/translate-vfp.c.inc | 341 +++++++++++----------------
88
17 files changed, 588 insertions(+), 493 deletions(-)
63
89
64
Joel Stanley (4):
65
aspeed/sdmc: Make ast2600 default 1G
66
aspeed/scu: Fix W1C behavior
67
watchdog/aspeed: Improve watchdog timeout message
68
watchdog/aspeed: Fix AST2600 frequency behaviour
69
70
Marc Zyngier (5):
71
target/arm: Honor HCR_EL2.TID2 trapping requirements
72
target/arm: Honor HCR_EL2.TID1 trapping requirements
73
target/arm: Handle trapping to EL2 of AArch32 VMRS instructions
74
target/arm: Handle AArch32 CP15 trapping via HSTR_EL2
75
target/arm: Add support for missing Jazelle system registers
76
77
Niek Linnenbank (1):
78
arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on()
79
80
PanNengyuan (1):
81
gpio: fix memory leak in aspeed_gpio_init()
82
83
Philippe Mathieu-Daudé (2):
84
hw/arm/sbsa-ref: Simplify by moving the gic in the machine state
85
hw/arm/virt: Simplify by moving the gic in the machine state
86
87
include/exec/exec-all.h | 6 +
88
include/exec/memory.h | 6 +
89
include/exec/ram_addr.h | 8 +
90
include/hw/arm/aspeed.h | 24 +--
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
Deleted patch
1
From: David Gibson <david@gibson.dropbear.id.au>
2
1
3
exynos4210_gic_realize() prints the number of cpus into some temporary
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>
20
[PMM: deleted stray blank line]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
hw/intc/exynos4210_gic.c | 9 ++++++++-
24
1 file changed, 8 insertions(+), 1 deletion(-)
25
26
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/exynos4210_gic.c
29
+++ b/hw/intc/exynos4210_gic.c
30
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
31
char cpu_alias_name[sizeof(cpu_prefix) + 3];
32
char dist_alias_name[sizeof(cpu_prefix) + 3];
33
SysBusDevice *gicbusdev;
34
+ uint32_t n = s->num_cpu;
35
uint32_t i;
36
37
s->gic = qdev_create(NULL, "arm_gic");
38
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
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
--
54
2.20.1
55
56
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The current model only restores the Segment Register values but leaves
3
This function makes it clear that we're talking about the whole
4
the previous CS mapping behind. Introduce a helper setting the
4
register, and not the 32-bit piece at index 0. This fixes a bug
5
register value and mapping the region at the requested address. Use
5
when running on a big-endian host.
6
this helper when a Segment register is set and at reset.
7
6
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20201030022618.785675-2-richard.henderson@linaro.org
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20191119141211.25716-11-clg@kaod.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/ssi/aspeed_smc.c | 32 +++++++++++++++++++++-----------
12
target/arm/translate.c | 8 ++++++
15
1 file changed, 21 insertions(+), 11 deletions(-)
13
target/arm/translate-neon.c.inc | 44 ++++++++++++++++-----------------
14
target/arm/translate-vfp.c.inc | 2 +-
15
3 files changed, 31 insertions(+), 23 deletions(-)
16
16
17
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/ssi/aspeed_smc.c
19
--- a/target/arm/translate.c
20
+++ b/hw/ssi/aspeed_smc.c
20
+++ b/target/arm/translate.c
21
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
21
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
22
return false;
22
unallocated_encoding(s);
23
}
23
}
24
24
25
+static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
25
+/*
26
+ uint64_t regval)
26
+ * Return the offset of a "full" NEON Dreg.
27
+ */
28
+static long neon_full_reg_offset(unsigned reg)
27
+{
29
+{
28
+ AspeedSMCFlash *fl = &s->flashes[cs];
30
+ return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
29
+ AspeedSegments seg;
30
+
31
+ s->ctrl->reg_to_segment(s, regval, &seg);
32
+
33
+ memory_region_transaction_begin();
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
+
39
+ s->regs[R_SEG_ADDR0 + cs] = regval;
40
+}
31
+}
41
+
32
+
42
static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
33
static inline long vfp_reg_offset(bool dp, unsigned reg)
43
uint64_t new)
44
{
34
{
45
- AspeedSMCFlash *fl = &s->flashes[cs];
35
if (dp) {
46
AspeedSegments seg;
36
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
47
37
index XXXXXXX..XXXXXXX 100644
48
s->ctrl->reg_to_segment(s, new, &seg);
38
--- a/target/arm/translate-neon.c.inc
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
39
+++ b/target/arm/translate-neon.c.inc
50
aspeed_smc_flash_overlap(s, &seg, cs);
40
@@ -XXX,XX +XXX,XX @@ neon_element_offset(int reg, int element, MemOp size)
51
41
ofs ^= 8 - element_size;
52
/* All should be fine now to move the region */
42
}
53
- memory_region_transaction_begin();
43
#endif
54
- memory_region_set_size(&fl->mmio, seg.size);
44
- return neon_reg_offset(reg, 0) + ofs;
55
- memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
45
+ return neon_full_reg_offset(reg) + ofs;
56
- memory_region_set_enabled(&fl->mmio, true);
57
- memory_region_transaction_commit();
58
-
59
- s->regs[R_SEG_ADDR0 + cs] = new;
60
+ aspeed_smc_flash_set_segment_region(s, cs, new);
61
}
46
}
62
47
63
static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
48
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
64
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
65
qemu_set_irq(s->cs_lines[i], true);
50
* We cannot write 16 bytes at once because the
51
* destination is unaligned.
52
*/
53
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
54
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
55
8, 8, tmp);
56
- tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
57
- neon_reg_offset(vd, 0), 8, 8);
58
+ tcg_gen_gvec_mov(0, neon_full_reg_offset(vd + 1),
59
+ neon_full_reg_offset(vd), 8, 8);
60
} else {
61
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
62
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
63
vec_size, vec_size, tmp);
64
}
65
tcg_gen_addi_i32(addr, addr, 1 << size);
66
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
67
static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
68
{
69
int vec_size = a->q ? 16 : 8;
70
- int rd_ofs = neon_reg_offset(a->vd, 0);
71
- int rn_ofs = neon_reg_offset(a->vn, 0);
72
- int rm_ofs = neon_reg_offset(a->vm, 0);
73
+ int rd_ofs = neon_full_reg_offset(a->vd);
74
+ int rn_ofs = neon_full_reg_offset(a->vn);
75
+ int rm_ofs = neon_full_reg_offset(a->vm);
76
77
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
78
return false;
79
@@ -XXX,XX +XXX,XX @@ static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)
80
{
81
/* Handle a 2-reg-shift insn which can be vectorized. */
82
int vec_size = a->q ? 16 : 8;
83
- int rd_ofs = neon_reg_offset(a->vd, 0);
84
- int rm_ofs = neon_reg_offset(a->vm, 0);
85
+ int rd_ofs = neon_full_reg_offset(a->vd);
86
+ int rm_ofs = neon_full_reg_offset(a->vm);
87
88
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
89
return false;
90
@@ -XXX,XX +XXX,XX @@ static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
91
{
92
/* FP operations in 2-reg-and-shift group */
93
int vec_size = a->q ? 16 : 8;
94
- int rd_ofs = neon_reg_offset(a->vd, 0);
95
- int rm_ofs = neon_reg_offset(a->vm, 0);
96
+ int rd_ofs = neon_full_reg_offset(a->vd);
97
+ int rm_ofs = neon_full_reg_offset(a->vm);
98
TCGv_ptr fpst;
99
100
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
101
@@ -XXX,XX +XXX,XX @@ static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
102
return true;
66
}
103
}
67
104
68
- /* setup default segment register values for all */
105
- reg_ofs = neon_reg_offset(a->vd, 0);
69
+ /* setup the default segment register values and regions for all */
106
+ reg_ofs = neon_full_reg_offset(a->vd);
70
for (i = 0; i < s->ctrl->max_slaves; ++i) {
107
vec_size = a->q ? 16 : 8;
71
- s->regs[R_SEG_ADDR0 + i] =
108
imm = asimd_imm_const(a->imm, a->cmode, a->op);
72
- s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]);
109
73
+ aspeed_smc_flash_set_segment_region(s, i,
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMULL_P_3d(DisasContext *s, arg_3diff *a)
74
+ s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]));
111
return true;
75
}
112
}
76
113
77
/* HW strapping flash type for the AST2600 controllers */
114
- tcg_gen_gvec_3_ool(neon_reg_offset(a->vd, 0),
115
- neon_reg_offset(a->vn, 0),
116
- neon_reg_offset(a->vm, 0),
117
+ tcg_gen_gvec_3_ool(neon_full_reg_offset(a->vd),
118
+ neon_full_reg_offset(a->vn),
119
+ neon_full_reg_offset(a->vm),
120
16, 16, 0, fn_gvec);
121
return true;
122
}
123
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
124
{
125
/* Two registers and a scalar, using gvec */
126
int vec_size = a->q ? 16 : 8;
127
- int rd_ofs = neon_reg_offset(a->vd, 0);
128
- int rn_ofs = neon_reg_offset(a->vn, 0);
129
+ int rd_ofs = neon_full_reg_offset(a->vd);
130
+ int rn_ofs = neon_full_reg_offset(a->vn);
131
int rm_ofs;
132
int idx;
133
TCGv_ptr fpstatus;
134
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
135
/* a->vm is M:Vm, which encodes both register and index */
136
idx = extract32(a->vm, a->size + 2, 2);
137
a->vm = extract32(a->vm, 0, a->size + 2);
138
- rm_ofs = neon_reg_offset(a->vm, 0);
139
+ rm_ofs = neon_full_reg_offset(a->vm);
140
141
fpstatus = fpstatus_ptr(a->size == 1 ? FPST_STD_F16 : FPST_STD);
142
tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, fpstatus,
143
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
144
return true;
145
}
146
147
- tcg_gen_gvec_dup_mem(a->size, neon_reg_offset(a->vd, 0),
148
+ tcg_gen_gvec_dup_mem(a->size, neon_full_reg_offset(a->vd),
149
neon_element_offset(a->vm, a->index, a->size),
150
a->q ? 16 : 8, a->q ? 16 : 8);
151
return true;
152
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
153
static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn)
154
{
155
int vec_size = a->q ? 16 : 8;
156
- int rd_ofs = neon_reg_offset(a->vd, 0);
157
- int rm_ofs = neon_reg_offset(a->vm, 0);
158
+ int rd_ofs = neon_full_reg_offset(a->vd);
159
+ int rm_ofs = neon_full_reg_offset(a->vm);
160
161
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
return false;
163
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/arm/translate-vfp.c.inc
166
+++ b/target/arm/translate-vfp.c.inc
167
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
168
}
169
170
tmp = load_reg(s, a->rt);
171
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(a->vn, 0),
172
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(a->vn),
173
vec_size, vec_size, tmp);
174
tcg_temp_free_i32(tmp);
175
78
--
176
--
79
2.20.1
177
2.20.1
80
178
81
179
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
ARMv8.2 introduced support for Data Cache Clean instructions
3
This will shortly have users outside of translate-neon.c.inc.
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: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-3-richard.henderson@linaro.org
14
Message-id: 20191121000843.24844-5-beata.michalska@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
9
---
17
target/arm/cpu.h | 10 ++++++++
10
target/arm/translate.c | 20 ++++++++++++++++++++
18
linux-user/elfload.c | 2 ++
11
target/arm/translate-neon.c.inc | 19 -------------------
19
target/arm/cpu64.c | 1 +
12
2 files changed, 20 insertions(+), 19 deletions(-)
20
target/arm/helper.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
21
4 files changed, 69 insertions(+)
22
13
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
16
--- a/target/arm/translate.c
26
+++ b/target/arm/cpu.h
17
+++ b/target/arm/translate.c
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
18
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
28
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
19
return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
29
}
20
}
30
21
31
+static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
22
+/*
23
+ * Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
24
+ * where 0 is the least significant end of the register.
25
+ */
26
+static long neon_element_offset(int reg, int element, MemOp size)
32
+{
27
+{
33
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0;
28
+ int element_size = 1 << size;
29
+ int ofs = element * element_size;
30
+#ifdef HOST_WORDS_BIGENDIAN
31
+ /*
32
+ * Calculate the offset assuming fully little-endian,
33
+ * then XOR to account for the order of the 8-byte units.
34
+ */
35
+ if (element_size < 8) {
36
+ ofs ^= 8 - element_size;
37
+ }
38
+#endif
39
+ return neon_full_reg_offset(reg) + ofs;
34
+}
40
+}
35
+
41
+
36
+static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
42
static inline long vfp_reg_offset(bool dp, unsigned reg)
37
+{
38
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
39
+}
40
+
41
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
42
{
43
{
43
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
44
if (dp) {
44
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
45
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
45
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
46
--- a/linux-user/elfload.c
47
--- a/target/arm/translate-neon.c.inc
47
+++ b/linux-user/elfload.c
48
+++ b/target/arm/translate-neon.c.inc
48
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
49
@@ -XXX,XX +XXX,XX @@ static inline int neon_3same_fp_size(DisasContext *s, int x)
49
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
50
#include "decode-neon-ls.c.inc"
50
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
51
#include "decode-neon-shared.c.inc"
51
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
52
52
+ GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
53
-/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
53
54
- * where 0 is the least significant end of the register.
54
return hwcaps;
55
- */
55
}
56
-static inline long
56
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
57
-neon_element_offset(int reg, int element, MemOp size)
57
ARMCPU *cpu = ARM_CPU(thread_cpu);
58
-{
58
uint32_t hwcaps = 0;
59
- int element_size = 1 << size;
59
60
- int ofs = element * element_size;
60
+ GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
61
-#ifdef HOST_WORDS_BIGENDIAN
61
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
62
- /* Calculate the offset assuming fully little-endian,
62
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
63
- * then XOR to account for the order of the 8-byte units.
63
64
- */
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
- if (element_size < 8) {
65
index XXXXXXX..XXXXXXX 100644
66
- ofs ^= 8 - element_size;
66
--- a/target/arm/cpu64.c
67
- }
67
+++ b/target/arm/cpu64.c
68
-#endif
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
- return neon_full_reg_offset(reg) + ofs;
69
cpu->isar.id_aa64isar0 = t;
70
-}
70
71
-
71
t = cpu->isar.id_aa64isar1;
72
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
72
+ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
73
{
73
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
74
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
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
+ }
110
+ }
111
+}
112
+
113
+static const ARMCPRegInfo dcpop_reg[] = {
114
+ { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
115
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
116
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
117
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
118
+ REGINFO_SENTINEL
119
+};
120
+
121
+static const ARMCPRegInfo dcpodp_reg[] = {
122
+ { .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
123
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
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
--
75
--
151
2.20.1
76
2.20.1
152
77
153
78
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
AspeedBoardConfig is a redundant way to define class attributes and it
3
These are the only users of neon_reg_offset, so remove that.
4
complexifies the machine definition and initialization.
5
4
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
6
Message-id: 20201030022618.785675-4-richard.henderson@linaro.org
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20191119141211.25716-14-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
include/hw/arm/aspeed.h | 24 ++--
10
target/arm/translate.c | 14 ++------------
13
hw/arm/aspeed.c | 243 ++++++++++++++++++++++------------------
11
1 file changed, 2 insertions(+), 12 deletions(-)
14
2 files changed, 143 insertions(+), 124 deletions(-)
15
12
16
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/aspeed.h
15
--- a/target/arm/translate.c
19
+++ b/include/hw/arm/aspeed.h
16
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static inline long vfp_reg_offset(bool dp, unsigned reg)
21
22
typedef struct AspeedBoardState AspeedBoardState;
23
24
-typedef struct AspeedBoardConfig {
25
- const char *name;
26
- const char *desc;
27
- const char *soc_name;
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
-
37
#define TYPE_ASPEED_MACHINE MACHINE_TYPE_NAME("aspeed")
38
#define ASPEED_MACHINE(obj) \
39
OBJECT_CHECK(AspeedMachine, (obj), TYPE_ASPEED_MACHINE)
40
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedMachine {
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
60
--- a/hw/arm/aspeed.c
61
+++ b/hw/arm/aspeed.c
62
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
63
}
18
}
64
}
19
}
65
20
66
-static void aspeed_board_init(MachineState *machine,
21
-/* Return the offset of a 32-bit piece of a NEON register.
67
- const AspeedBoardConfig *cfg)
22
- zero is the least significant end of the register. */
68
+static void aspeed_machine_init(MachineState *machine)
23
-static inline long
69
{
24
-neon_reg_offset (int reg, int n)
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
-{
25
-{
126
- AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
26
- int sreg;
127
-
27
- sreg = reg * 2 + n;
128
- aspeed_board_init(machine, amc->board);
28
- return vfp_reg_offset(0, sreg);
129
-}
29
-}
130
-
30
-
131
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
31
static TCGv_i32 neon_load_reg(int reg, int pass)
132
{
32
{
133
MachineClass *mc = MACHINE_CLASS(oc);
33
TCGv_i32 tmp = tcg_temp_new_i32();
134
- AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
34
- tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
135
- const AspeedBoardConfig *board = data;
35
+ tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
136
36
return tmp;
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
}
37
}
148
38
149
-static const TypeInfo aspeed_machine_type = {
39
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
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
{
40
{
225
- int i;
41
- tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
226
+ MachineClass *mc = MACHINE_CLASS(oc);
42
+ tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
227
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
43
tcg_temp_free_i32(var);
228
44
}
229
- type_register_static(&aspeed_machine_type);
45
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
--
46
--
363
2.20.1
47
2.20.1
364
48
365
49
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The AST2600 control register sneakily changed the meaning of bit 4
3
This seems a bit more readable than using offsetof CPU_DoubleU.
4
without anyone noticing. It no longer controls the 1MHz vs APB clock
5
select, and instead always runs at 1MHz.
6
4
7
The AST2500 was always 1MHz too, but it retained bit 4, making it read
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
only. We can model both using the same fixed 1MHz calculation.
6
Message-id: 20201030022618.785675-5-richard.henderson@linaro.org
9
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
9
---
18
include/hw/watchdog/wdt_aspeed.h | 1 +
10
target/arm/translate.c | 13 ++++---------
19
hw/watchdog/wdt_aspeed.c | 21 +++++++++++++++++----
11
1 file changed, 4 insertions(+), 9 deletions(-)
20
2 files changed, 18 insertions(+), 4 deletions(-)
21
12
22
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
23
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/watchdog/wdt_aspeed.h
15
--- a/target/arm/translate.c
25
+++ b/include/hw/watchdog/wdt_aspeed.h
16
+++ b/target/arm/translate.c
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedWDTClass {
17
@@ -XXX,XX +XXX,XX @@ static long neon_element_offset(int reg, int element, MemOp size)
27
uint32_t ext_pulse_width_mask;
18
return neon_full_reg_offset(reg) + ofs;
28
uint32_t reset_ctrl_reg;
29
void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
30
+ void (*wdt_reload)(AspeedWDTState *s);
31
} AspeedWDTClass;
32
33
#endif /* WDT_ASPEED_H */
34
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/watchdog/wdt_aspeed.c
37
+++ b/hw/watchdog/wdt_aspeed.c
38
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
39
40
}
19
}
41
20
42
-static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
21
-static inline long vfp_reg_offset(bool dp, unsigned reg)
43
+static void aspeed_wdt_reload(AspeedWDTState *s)
22
+/* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
23
+static long vfp_reg_offset(bool dp, unsigned reg)
44
{
24
{
45
uint64_t reload;
25
if (dp) {
46
26
- return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
47
- if (pclk) {
27
+ return neon_element_offset(reg, 0, MO_64);
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 {
28
} else {
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
29
- long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
30
- if (reg & 1) {
31
- ofs += offsetof(CPU_DoubleU, l.upper);
32
- } else {
33
- ofs += offsetof(CPU_DoubleU, l.lower);
34
- }
35
- return ofs;
36
+ return neon_element_offset(reg >> 1, reg & 1, MO_32);
53
}
37
}
54
}
38
}
55
39
56
+static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
57
+{
58
+ uint64_t reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL;
59
+
60
+ if (aspeed_wdt_is_enabled(s)) {
61
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
62
+ }
63
+}
64
+
65
+
66
static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
67
unsigned size)
68
{
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
--
40
--
110
2.20.1
41
2.20.1
111
42
112
43
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
HCR_EL2.TID3 requires that AArch32 reads of MVFR[012] are trapped to
3
Model these off the aa64 read/write_vec_element functions.
4
EL2, and HCR_EL2.TID0 does the same for reads of FPSID.
4
Use it within translate-neon.c.inc. The new functions do
5
In order to handle this, introduce a new TCG helper function that
5
not allocate or free temps, so this rearranges the calling
6
checks for these control bits before executing the VMRC instruction.
6
code a bit.
7
7
8
Tested with a hacked-up version of KVM/arm64 that sets the control
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
bits for 32bit guests.
9
Message-id: 20201030022618.785675-6-richard.henderson@linaro.org
10
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
12
---
19
target/arm/helper.h | 2 ++
13
target/arm/translate.c | 26 ++++
20
target/arm/translate-vfp.inc.c | 20 ++++++++++++++++----
14
target/arm/translate-neon.c.inc | 256 ++++++++++++++++++++------------
21
target/arm/vfp_helper.c | 29 +++++++++++++++++++++++++++++
15
2 files changed, 183 insertions(+), 99 deletions(-)
22
3 files changed, 47 insertions(+), 4 deletions(-)
23
16
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
25
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
19
--- a/target/arm/translate.c
27
+++ b/target/arm/helper.h
20
+++ b/target/arm/translate.c
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG, f64, f64, ptr)
21
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
29
DEF_HELPER_FLAGS_2(vjcvt, TCG_CALL_NO_RWG, i32, f64, env)
22
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
30
DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
23
}
31
24
32
+DEF_HELPER_FLAGS_3(check_hcr_el2_trap, TCG_CALL_NO_WG, void, env, i32, i32)
25
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
33
+
34
/* neon_helper.c */
35
DEF_HELPER_FLAGS_3(neon_qadd_u8, TCG_CALL_NO_RWG, i32, env, i32, i32)
36
DEF_HELPER_FLAGS_3(neon_qadd_s8, TCG_CALL_NO_RWG, i32, env, i32, i32)
37
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-vfp.inc.c
40
+++ b/target/arm/translate-vfp.inc.c
41
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
42
if (a->l) {
43
/* VMRS, move VFP special register to gp register */
44
switch (a->reg) {
45
- case ARM_VFP_FPSID:
46
- case ARM_VFP_FPEXC:
47
- case ARM_VFP_FPINST:
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
+{
26
+{
81
+ uint32_t syndrome;
27
+ long off = neon_element_offset(reg, ele, size);
82
+
28
+
83
+ switch (reg) {
29
+ switch (size) {
84
+ case ARM_VFP_MVFR0:
30
+ case MO_32:
85
+ case ARM_VFP_MVFR1:
31
+ tcg_gen_ld_i32(dest, cpu_env, off);
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;
32
+ break;
96
+ default:
33
+ default:
97
+ g_assert_not_reached();
34
+ g_assert_not_reached();
98
+ }
35
+ }
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
+}
36
+}
107
+
37
+
108
#endif
38
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
39
+{
40
+ long off = neon_element_offset(reg, ele, size);
41
+
42
+ switch (size) {
43
+ case MO_32:
44
+ tcg_gen_st_i32(src, cpu_env, off);
45
+ break;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
+}
50
+
51
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
52
{
53
TCGv_ptr ret = tcg_temp_new_ptr();
54
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/translate-neon.c.inc
57
+++ b/target/arm/translate-neon.c.inc
58
@@ -XXX,XX +XXX,XX @@ static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
59
* early. Since Q is 0 there are always just two passes, so instead
60
* of a complicated loop over each pass we just unroll.
61
*/
62
- tmp = neon_load_reg(a->vn, 0);
63
- tmp2 = neon_load_reg(a->vn, 1);
64
+ tmp = tcg_temp_new_i32();
65
+ tmp2 = tcg_temp_new_i32();
66
+ tmp3 = tcg_temp_new_i32();
67
+
68
+ read_neon_element32(tmp, a->vn, 0, MO_32);
69
+ read_neon_element32(tmp2, a->vn, 1, MO_32);
70
fn(tmp, tmp, tmp2);
71
- tcg_temp_free_i32(tmp2);
72
73
- tmp3 = neon_load_reg(a->vm, 0);
74
- tmp2 = neon_load_reg(a->vm, 1);
75
+ read_neon_element32(tmp3, a->vm, 0, MO_32);
76
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
77
fn(tmp3, tmp3, tmp2);
78
- tcg_temp_free_i32(tmp2);
79
80
- neon_store_reg(a->vd, 0, tmp);
81
- neon_store_reg(a->vd, 1, tmp3);
82
+ write_neon_element32(tmp, a->vd, 0, MO_32);
83
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
84
+
85
+ tcg_temp_free_i32(tmp);
86
+ tcg_temp_free_i32(tmp2);
87
+ tcg_temp_free_i32(tmp3);
88
return true;
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
92
* 2-reg-and-shift operations, size < 3 case, where the
93
* helper needs to be passed cpu_env.
94
*/
95
- TCGv_i32 constimm;
96
+ TCGv_i32 constimm, tmp;
97
int pass;
98
99
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
100
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
101
* by immediate using the variable shift operations.
102
*/
103
constimm = tcg_const_i32(dup_const(a->size, a->shift));
104
+ tmp = tcg_temp_new_i32();
105
106
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
107
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
108
+ read_neon_element32(tmp, a->vm, pass, MO_32);
109
fn(tmp, cpu_env, tmp, constimm);
110
- neon_store_reg(a->vd, pass, tmp);
111
+ write_neon_element32(tmp, a->vd, pass, MO_32);
112
}
113
+ tcg_temp_free_i32(tmp);
114
tcg_temp_free_i32(constimm);
115
return true;
116
}
117
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
118
constimm = tcg_const_i64(-a->shift);
119
rm1 = tcg_temp_new_i64();
120
rm2 = tcg_temp_new_i64();
121
+ rd = tcg_temp_new_i32();
122
123
/* Load both inputs first to avoid potential overwrite if rm == rd */
124
neon_load_reg64(rm1, a->vm);
125
neon_load_reg64(rm2, a->vm + 1);
126
127
shiftfn(rm1, rm1, constimm);
128
- rd = tcg_temp_new_i32();
129
narrowfn(rd, cpu_env, rm1);
130
- neon_store_reg(a->vd, 0, rd);
131
+ write_neon_element32(rd, a->vd, 0, MO_32);
132
133
shiftfn(rm2, rm2, constimm);
134
- rd = tcg_temp_new_i32();
135
narrowfn(rd, cpu_env, rm2);
136
- neon_store_reg(a->vd, 1, rd);
137
+ write_neon_element32(rd, a->vd, 1, MO_32);
138
139
+ tcg_temp_free_i32(rd);
140
tcg_temp_free_i64(rm1);
141
tcg_temp_free_i64(rm2);
142
tcg_temp_free_i64(constimm);
143
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
144
constimm = tcg_const_i32(imm);
145
146
/* Load all inputs first to avoid potential overwrite */
147
- rm1 = neon_load_reg(a->vm, 0);
148
- rm2 = neon_load_reg(a->vm, 1);
149
- rm3 = neon_load_reg(a->vm + 1, 0);
150
- rm4 = neon_load_reg(a->vm + 1, 1);
151
+ rm1 = tcg_temp_new_i32();
152
+ rm2 = tcg_temp_new_i32();
153
+ rm3 = tcg_temp_new_i32();
154
+ rm4 = tcg_temp_new_i32();
155
+ read_neon_element32(rm1, a->vm, 0, MO_32);
156
+ read_neon_element32(rm2, a->vm, 1, MO_32);
157
+ read_neon_element32(rm3, a->vm, 2, MO_32);
158
+ read_neon_element32(rm4, a->vm, 3, MO_32);
159
rtmp = tcg_temp_new_i64();
160
161
shiftfn(rm1, rm1, constimm);
162
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
163
tcg_temp_free_i32(rm2);
164
165
narrowfn(rm1, cpu_env, rtmp);
166
- neon_store_reg(a->vd, 0, rm1);
167
+ write_neon_element32(rm1, a->vd, 0, MO_32);
168
+ tcg_temp_free_i32(rm1);
169
170
shiftfn(rm3, rm3, constimm);
171
shiftfn(rm4, rm4, constimm);
172
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
173
174
narrowfn(rm3, cpu_env, rtmp);
175
tcg_temp_free_i64(rtmp);
176
- neon_store_reg(a->vd, 1, rm3);
177
+ write_neon_element32(rm3, a->vd, 1, MO_32);
178
+ tcg_temp_free_i32(rm3);
179
return true;
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
183
widen_mask = dup_const(a->size + 1, widen_mask);
184
}
185
186
- rm0 = neon_load_reg(a->vm, 0);
187
- rm1 = neon_load_reg(a->vm, 1);
188
+ rm0 = tcg_temp_new_i32();
189
+ rm1 = tcg_temp_new_i32();
190
+ read_neon_element32(rm0, a->vm, 0, MO_32);
191
+ read_neon_element32(rm1, a->vm, 1, MO_32);
192
tmp = tcg_temp_new_i64();
193
194
widenfn(tmp, rm0);
195
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
196
if (src1_wide) {
197
neon_load_reg64(rn0_64, a->vn);
198
} else {
199
- TCGv_i32 tmp = neon_load_reg(a->vn, 0);
200
+ TCGv_i32 tmp = tcg_temp_new_i32();
201
+ read_neon_element32(tmp, a->vn, 0, MO_32);
202
widenfn(rn0_64, tmp);
203
tcg_temp_free_i32(tmp);
204
}
205
- rm = neon_load_reg(a->vm, 0);
206
+ rm = tcg_temp_new_i32();
207
+ read_neon_element32(rm, a->vm, 0, MO_32);
208
209
widenfn(rm_64, rm);
210
tcg_temp_free_i32(rm);
211
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
212
if (src1_wide) {
213
neon_load_reg64(rn1_64, a->vn + 1);
214
} else {
215
- TCGv_i32 tmp = neon_load_reg(a->vn, 1);
216
+ TCGv_i32 tmp = tcg_temp_new_i32();
217
+ read_neon_element32(tmp, a->vn, 1, MO_32);
218
widenfn(rn1_64, tmp);
219
tcg_temp_free_i32(tmp);
220
}
221
- rm = neon_load_reg(a->vm, 1);
222
+ rm = tcg_temp_new_i32();
223
+ read_neon_element32(rm, a->vm, 1, MO_32);
224
225
neon_store_reg64(rn0_64, a->vd);
226
227
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
228
229
narrowfn(rd1, rn_64);
230
231
- neon_store_reg(a->vd, 0, rd0);
232
- neon_store_reg(a->vd, 1, rd1);
233
+ write_neon_element32(rd0, a->vd, 0, MO_32);
234
+ write_neon_element32(rd1, a->vd, 1, MO_32);
235
236
+ tcg_temp_free_i32(rd0);
237
+ tcg_temp_free_i32(rd1);
238
tcg_temp_free_i64(rn_64);
239
tcg_temp_free_i64(rm_64);
240
241
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
242
rd0 = tcg_temp_new_i64();
243
rd1 = tcg_temp_new_i64();
244
245
- rn = neon_load_reg(a->vn, 0);
246
- rm = neon_load_reg(a->vm, 0);
247
+ rn = tcg_temp_new_i32();
248
+ rm = tcg_temp_new_i32();
249
+ read_neon_element32(rn, a->vn, 0, MO_32);
250
+ read_neon_element32(rm, a->vm, 0, MO_32);
251
opfn(rd0, rn, rm);
252
- tcg_temp_free_i32(rn);
253
- tcg_temp_free_i32(rm);
254
255
- rn = neon_load_reg(a->vn, 1);
256
- rm = neon_load_reg(a->vm, 1);
257
+ read_neon_element32(rn, a->vn, 1, MO_32);
258
+ read_neon_element32(rm, a->vm, 1, MO_32);
259
opfn(rd1, rn, rm);
260
tcg_temp_free_i32(rn);
261
tcg_temp_free_i32(rm);
262
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
263
264
static inline TCGv_i32 neon_get_scalar(int size, int reg)
265
{
266
- TCGv_i32 tmp;
267
- if (size == 1) {
268
- tmp = neon_load_reg(reg & 7, reg >> 4);
269
+ TCGv_i32 tmp = tcg_temp_new_i32();
270
+ if (size == MO_16) {
271
+ read_neon_element32(tmp, reg & 7, reg >> 4, MO_32);
272
if (reg & 8) {
273
gen_neon_dup_high16(tmp);
274
} else {
275
gen_neon_dup_low16(tmp);
276
}
277
} else {
278
- tmp = neon_load_reg(reg & 15, reg >> 4);
279
+ read_neon_element32(tmp, reg & 15, reg >> 4, MO_32);
280
}
281
return tmp;
282
}
283
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
284
* perform an accumulation operation of that result into the
285
* destination.
286
*/
287
- TCGv_i32 scalar;
288
+ TCGv_i32 scalar, tmp;
289
int pass;
290
291
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
292
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
293
}
294
295
scalar = neon_get_scalar(a->size, a->vm);
296
+ tmp = tcg_temp_new_i32();
297
298
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
299
- TCGv_i32 tmp = neon_load_reg(a->vn, pass);
300
+ read_neon_element32(tmp, a->vn, pass, MO_32);
301
opfn(tmp, tmp, scalar);
302
if (accfn) {
303
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
304
+ TCGv_i32 rd = tcg_temp_new_i32();
305
+ read_neon_element32(rd, a->vd, pass, MO_32);
306
accfn(tmp, rd, tmp);
307
tcg_temp_free_i32(rd);
308
}
309
- neon_store_reg(a->vd, pass, tmp);
310
+ write_neon_element32(tmp, a->vd, pass, MO_32);
311
}
312
+ tcg_temp_free_i32(tmp);
313
tcg_temp_free_i32(scalar);
314
return true;
315
}
316
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
317
* performs a kind of fused op-then-accumulate using a helper
318
* function that takes all of rd, rn and the scalar at once.
319
*/
320
- TCGv_i32 scalar;
321
+ TCGv_i32 scalar, rn, rd;
322
int pass;
323
324
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
325
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
326
}
327
328
scalar = neon_get_scalar(a->size, a->vm);
329
+ rn = tcg_temp_new_i32();
330
+ rd = tcg_temp_new_i32();
331
332
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
333
- TCGv_i32 rn = neon_load_reg(a->vn, pass);
334
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
335
+ read_neon_element32(rn, a->vn, pass, MO_32);
336
+ read_neon_element32(rd, a->vd, pass, MO_32);
337
opfn(rd, cpu_env, rn, scalar, rd);
338
- tcg_temp_free_i32(rn);
339
- neon_store_reg(a->vd, pass, rd);
340
+ write_neon_element32(rd, a->vd, pass, MO_32);
341
}
342
+ tcg_temp_free_i32(rn);
343
+ tcg_temp_free_i32(rd);
344
tcg_temp_free_i32(scalar);
345
346
return true;
347
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
348
scalar = neon_get_scalar(a->size, a->vm);
349
350
/* Load all inputs before writing any outputs, in case of overlap */
351
- rn = neon_load_reg(a->vn, 0);
352
+ rn = tcg_temp_new_i32();
353
+ read_neon_element32(rn, a->vn, 0, MO_32);
354
rn0_64 = tcg_temp_new_i64();
355
opfn(rn0_64, rn, scalar);
356
- tcg_temp_free_i32(rn);
357
358
- rn = neon_load_reg(a->vn, 1);
359
+ read_neon_element32(rn, a->vn, 1, MO_32);
360
rn1_64 = tcg_temp_new_i64();
361
opfn(rn1_64, rn, scalar);
362
tcg_temp_free_i32(rn);
363
@@ -XXX,XX +XXX,XX @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
364
return false;
365
}
366
n <<= 3;
367
+ tmp = tcg_temp_new_i32();
368
if (a->op) {
369
- tmp = neon_load_reg(a->vd, 0);
370
+ read_neon_element32(tmp, a->vd, 0, MO_32);
371
} else {
372
- tmp = tcg_temp_new_i32();
373
tcg_gen_movi_i32(tmp, 0);
374
}
375
- tmp2 = neon_load_reg(a->vm, 0);
376
+ tmp2 = tcg_temp_new_i32();
377
+ read_neon_element32(tmp2, a->vm, 0, MO_32);
378
ptr1 = vfp_reg_ptr(true, a->vn);
379
tmp4 = tcg_const_i32(n);
380
gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp4);
381
- tcg_temp_free_i32(tmp);
382
+
383
if (a->op) {
384
- tmp = neon_load_reg(a->vd, 1);
385
+ read_neon_element32(tmp, a->vd, 1, MO_32);
386
} else {
387
- tmp = tcg_temp_new_i32();
388
tcg_gen_movi_i32(tmp, 0);
389
}
390
- tmp3 = neon_load_reg(a->vm, 1);
391
+ tmp3 = tcg_temp_new_i32();
392
+ read_neon_element32(tmp3, a->vm, 1, MO_32);
393
gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp4);
394
+ tcg_temp_free_i32(tmp);
395
tcg_temp_free_i32(tmp4);
396
tcg_temp_free_ptr(ptr1);
397
- neon_store_reg(a->vd, 0, tmp2);
398
- neon_store_reg(a->vd, 1, tmp3);
399
- tcg_temp_free_i32(tmp);
400
+
401
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
402
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
403
+ tcg_temp_free_i32(tmp2);
404
+ tcg_temp_free_i32(tmp3);
405
return true;
406
}
407
408
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
409
static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
410
{
411
int pass, half;
412
+ TCGv_i32 tmp[2];
413
414
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
415
return false;
416
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
417
return true;
418
}
419
420
- for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
421
- TCGv_i32 tmp[2];
422
+ tmp[0] = tcg_temp_new_i32();
423
+ tmp[1] = tcg_temp_new_i32();
424
425
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
426
for (half = 0; half < 2; half++) {
427
- tmp[half] = neon_load_reg(a->vm, pass * 2 + half);
428
+ read_neon_element32(tmp[half], a->vm, pass * 2 + half, MO_32);
429
switch (a->size) {
430
case 0:
431
tcg_gen_bswap32_i32(tmp[half], tmp[half]);
432
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
433
g_assert_not_reached();
434
}
435
}
436
- neon_store_reg(a->vd, pass * 2, tmp[1]);
437
- neon_store_reg(a->vd, pass * 2 + 1, tmp[0]);
438
+ write_neon_element32(tmp[1], a->vd, pass * 2, MO_32);
439
+ write_neon_element32(tmp[0], a->vd, pass * 2 + 1, MO_32);
440
}
441
+
442
+ tcg_temp_free_i32(tmp[0]);
443
+ tcg_temp_free_i32(tmp[1]);
444
return true;
445
}
446
447
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
448
rm0_64 = tcg_temp_new_i64();
449
rm1_64 = tcg_temp_new_i64();
450
rd_64 = tcg_temp_new_i64();
451
- tmp = neon_load_reg(a->vm, pass * 2);
452
+
453
+ tmp = tcg_temp_new_i32();
454
+ read_neon_element32(tmp, a->vm, pass * 2, MO_32);
455
widenfn(rm0_64, tmp);
456
- tcg_temp_free_i32(tmp);
457
- tmp = neon_load_reg(a->vm, pass * 2 + 1);
458
+ read_neon_element32(tmp, a->vm, pass * 2 + 1, MO_32);
459
widenfn(rm1_64, tmp);
460
tcg_temp_free_i32(tmp);
461
+
462
opfn(rd_64, rm0_64, rm1_64);
463
tcg_temp_free_i64(rm0_64);
464
tcg_temp_free_i64(rm1_64);
465
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
466
narrowfn(rd0, cpu_env, rm);
467
neon_load_reg64(rm, a->vm + 1);
468
narrowfn(rd1, cpu_env, rm);
469
- neon_store_reg(a->vd, 0, rd0);
470
- neon_store_reg(a->vd, 1, rd1);
471
+ write_neon_element32(rd0, a->vd, 0, MO_32);
472
+ write_neon_element32(rd1, a->vd, 1, MO_32);
473
+ tcg_temp_free_i32(rd0);
474
+ tcg_temp_free_i32(rd1);
475
tcg_temp_free_i64(rm);
476
return true;
477
}
478
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
479
}
480
481
rd = tcg_temp_new_i64();
482
+ rm0 = tcg_temp_new_i32();
483
+ rm1 = tcg_temp_new_i32();
484
485
- rm0 = neon_load_reg(a->vm, 0);
486
- rm1 = neon_load_reg(a->vm, 1);
487
+ read_neon_element32(rm0, a->vm, 0, MO_32);
488
+ read_neon_element32(rm1, a->vm, 1, MO_32);
489
490
widenfn(rd, rm0);
491
tcg_gen_shli_i64(rd, rd, 8 << a->size);
492
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
493
494
fpst = fpstatus_ptr(FPST_STD);
495
ahp = get_ahp_flag();
496
- tmp = neon_load_reg(a->vm, 0);
497
+ tmp = tcg_temp_new_i32();
498
+ read_neon_element32(tmp, a->vm, 0, MO_32);
499
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
500
- tmp2 = neon_load_reg(a->vm, 1);
501
+ tmp2 = tcg_temp_new_i32();
502
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
503
gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
504
tcg_gen_shli_i32(tmp2, tmp2, 16);
505
tcg_gen_or_i32(tmp2, tmp2, tmp);
506
- tcg_temp_free_i32(tmp);
507
- tmp = neon_load_reg(a->vm, 2);
508
+ read_neon_element32(tmp, a->vm, 2, MO_32);
509
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
510
- tmp3 = neon_load_reg(a->vm, 3);
511
- neon_store_reg(a->vd, 0, tmp2);
512
+ tmp3 = tcg_temp_new_i32();
513
+ read_neon_element32(tmp3, a->vm, 3, MO_32);
514
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
515
+ tcg_temp_free_i32(tmp2);
516
gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
517
tcg_gen_shli_i32(tmp3, tmp3, 16);
518
tcg_gen_or_i32(tmp3, tmp3, tmp);
519
- neon_store_reg(a->vd, 1, tmp3);
520
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
521
+ tcg_temp_free_i32(tmp3);
522
tcg_temp_free_i32(tmp);
523
tcg_temp_free_i32(ahp);
524
tcg_temp_free_ptr(fpst);
525
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
526
fpst = fpstatus_ptr(FPST_STD);
527
ahp = get_ahp_flag();
528
tmp3 = tcg_temp_new_i32();
529
- tmp = neon_load_reg(a->vm, 0);
530
- tmp2 = neon_load_reg(a->vm, 1);
531
+ tmp2 = tcg_temp_new_i32();
532
+ tmp = tcg_temp_new_i32();
533
+ read_neon_element32(tmp, a->vm, 0, MO_32);
534
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
535
tcg_gen_ext16u_i32(tmp3, tmp);
536
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
537
- neon_store_reg(a->vd, 0, tmp3);
538
+ write_neon_element32(tmp3, a->vd, 0, MO_32);
539
tcg_gen_shri_i32(tmp, tmp, 16);
540
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
541
- neon_store_reg(a->vd, 1, tmp);
542
- tmp3 = tcg_temp_new_i32();
543
+ write_neon_element32(tmp, a->vd, 1, MO_32);
544
+ tcg_temp_free_i32(tmp);
545
tcg_gen_ext16u_i32(tmp3, tmp2);
546
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
547
- neon_store_reg(a->vd, 2, tmp3);
548
+ write_neon_element32(tmp3, a->vd, 2, MO_32);
549
+ tcg_temp_free_i32(tmp3);
550
tcg_gen_shri_i32(tmp2, tmp2, 16);
551
gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
552
- neon_store_reg(a->vd, 3, tmp2);
553
+ write_neon_element32(tmp2, a->vd, 3, MO_32);
554
+ tcg_temp_free_i32(tmp2);
555
tcg_temp_free_i32(ahp);
556
tcg_temp_free_ptr(fpst);
557
558
@@ -XXX,XX +XXX,XX @@ DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
559
560
static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
561
{
562
+ TCGv_i32 tmp;
563
int pass;
564
565
/* Handle a 2-reg-misc operation by iterating 32 bits at a time */
566
@@ -XXX,XX +XXX,XX @@ static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
567
return true;
568
}
569
570
+ tmp = tcg_temp_new_i32();
571
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
572
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
573
+ read_neon_element32(tmp, a->vm, pass, MO_32);
574
fn(tmp, tmp);
575
- neon_store_reg(a->vd, pass, tmp);
576
+ write_neon_element32(tmp, a->vd, pass, MO_32);
577
}
578
+ tcg_temp_free_i32(tmp);
579
580
return true;
581
}
582
@@ -XXX,XX +XXX,XX @@ static bool trans_VTRN(DisasContext *s, arg_2misc *a)
583
return true;
584
}
585
586
- if (a->size == 2) {
587
+ tmp = tcg_temp_new_i32();
588
+ tmp2 = tcg_temp_new_i32();
589
+ if (a->size == MO_32) {
590
for (pass = 0; pass < (a->q ? 4 : 2); pass += 2) {
591
- tmp = neon_load_reg(a->vm, pass);
592
- tmp2 = neon_load_reg(a->vd, pass + 1);
593
- neon_store_reg(a->vm, pass, tmp2);
594
- neon_store_reg(a->vd, pass + 1, tmp);
595
+ read_neon_element32(tmp, a->vm, pass, MO_32);
596
+ read_neon_element32(tmp2, a->vd, pass + 1, MO_32);
597
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
598
+ write_neon_element32(tmp, a->vd, pass + 1, MO_32);
599
}
600
} else {
601
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
602
- tmp = neon_load_reg(a->vm, pass);
603
- tmp2 = neon_load_reg(a->vd, pass);
604
- if (a->size == 0) {
605
+ read_neon_element32(tmp, a->vm, pass, MO_32);
606
+ read_neon_element32(tmp2, a->vd, pass, MO_32);
607
+ if (a->size == MO_8) {
608
gen_neon_trn_u8(tmp, tmp2);
609
} else {
610
gen_neon_trn_u16(tmp, tmp2);
611
}
612
- neon_store_reg(a->vm, pass, tmp2);
613
- neon_store_reg(a->vd, pass, tmp);
614
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
615
+ write_neon_element32(tmp, a->vd, pass, MO_32);
616
}
617
}
618
+ tcg_temp_free_i32(tmp);
619
+ tcg_temp_free_i32(tmp2);
620
return true;
621
}
109
--
622
--
110
2.20.1
623
2.20.1
111
624
112
625
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
A write to the SCR can change the effective EL by droppping the system
3
We can then use this to improve VMOV (scalar to gp) and
4
from secure to non-secure mode. However if we use a cached current_el
4
VMOV (gp to scalar) so that we simply perform the memory
5
from before the change we'll rebuild the flags incorrectly. To fix
5
operation that we wanted, rather than inserting or
6
this we introduce the ARM_CP_NEWEL CP flag to indicate the new EL
6
extracting from a 32-bit quantity.
7
should be used when recomputing the flags.
7
8
8
These were the last uses of neon_load/store_reg, so remove them.
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
9
10
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20201030022618.785675-7-richard.henderson@linaro.org
12
Message-id: 20191212114734.6962-1-alex.bennee@linaro.org
12
Reviewed-by: Peter Maydell <peter.maydell@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>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
14
---
18
target/arm/cpu.h | 8 ++++++--
15
target/arm/translate.c | 50 +++++++++++++-----------
19
target/arm/helper.h | 1 +
16
target/arm/translate-vfp.c.inc | 71 +++++-----------------------------
20
target/arm/helper.c | 14 +++++++++++++-
17
2 files changed, 37 insertions(+), 84 deletions(-)
21
target/arm/translate.c | 6 +++++-
18
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
26
--- a/target/arm/cpu.h
27
+++ b/target/arm/cpu.h
28
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
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
}
80
81
+/*
82
+ * If we have triggered a EL state change we can't rely on the
83
+ * translator having passed it too us, we need to recompute.
84
+ */
85
+void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
86
+{
87
+ int el = arm_current_el(env);
88
+ int fp_el = fp_exception_el(env, el);
89
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
90
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
91
+}
92
+
93
void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
94
{
95
int fp_el = fp_exception_el(env, el);
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
21
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
22
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
23
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
101
if (arm_dc_feature(s, ARM_FEATURE_M)) {
24
* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
102
gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
25
* where 0 is the least significant end of the register.
103
} else {
26
*/
104
- gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
27
-static long neon_element_offset(int reg, int element, MemOp size)
105
+ if (ri->type & ARM_CP_NEWEL) {
28
+static long neon_element_offset(int reg, int element, MemOp memop)
106
+ gen_helper_rebuild_hflags_a32_newel(cpu_env);
29
{
107
+ } else {
30
- int element_size = 1 << size;
108
+ gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
31
+ int element_size = 1 << (memop & MO_SIZE);
109
+ }
32
int ofs = element * element_size;
110
}
33
#ifdef HOST_WORDS_BIGENDIAN
111
tcg_temp_free_i32(tcg_el);
34
/*
112
/*
35
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
36
}
37
}
38
39
-static TCGv_i32 neon_load_reg(int reg, int pass)
40
-{
41
- TCGv_i32 tmp = tcg_temp_new_i32();
42
- tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
43
- return tmp;
44
-}
45
-
46
-static void neon_store_reg(int reg, int pass, TCGv_i32 var)
47
-{
48
- tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
49
- tcg_temp_free_i32(var);
50
-}
51
-
52
static inline void neon_load_reg64(TCGv_i64 var, int reg)
53
{
54
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
55
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
56
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
57
}
58
59
-static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
60
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
61
{
62
- long off = neon_element_offset(reg, ele, size);
63
+ long off = neon_element_offset(reg, ele, memop);
64
65
- switch (size) {
66
- case MO_32:
67
+ switch (memop) {
68
+ case MO_SB:
69
+ tcg_gen_ld8s_i32(dest, cpu_env, off);
70
+ break;
71
+ case MO_UB:
72
+ tcg_gen_ld8u_i32(dest, cpu_env, off);
73
+ break;
74
+ case MO_SW:
75
+ tcg_gen_ld16s_i32(dest, cpu_env, off);
76
+ break;
77
+ case MO_UW:
78
+ tcg_gen_ld16u_i32(dest, cpu_env, off);
79
+ break;
80
+ case MO_UL:
81
+ case MO_SL:
82
tcg_gen_ld_i32(dest, cpu_env, off);
83
break;
84
default:
85
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
86
}
87
}
88
89
-static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
90
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
91
{
92
- long off = neon_element_offset(reg, ele, size);
93
+ long off = neon_element_offset(reg, ele, memop);
94
95
- switch (size) {
96
+ switch (memop) {
97
+ case MO_8:
98
+ tcg_gen_st8_i32(src, cpu_env, off);
99
+ break;
100
+ case MO_16:
101
+ tcg_gen_st16_i32(src, cpu_env, off);
102
+ break;
103
case MO_32:
104
tcg_gen_st_i32(src, cpu_env, off);
105
break;
106
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-vfp.c.inc
109
+++ b/target/arm/translate-vfp.c.inc
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
111
{
112
/* VMOV scalar to general purpose register */
113
TCGv_i32 tmp;
114
- int pass;
115
- uint32_t offset;
116
117
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
118
- if (a->size == 2
119
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
120
+ if (a->size == MO_32
121
? !dc_isar_feature(aa32_fpsp_v2, s)
122
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
123
return false;
124
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
125
return false;
126
}
127
128
- offset = a->index << a->size;
129
- pass = extract32(offset, 2, 1);
130
- offset = extract32(offset, 0, 2) * 8;
131
-
132
if (!vfp_access_check(s)) {
133
return true;
134
}
135
136
- tmp = neon_load_reg(a->vn, pass);
137
- switch (a->size) {
138
- case 0:
139
- if (offset) {
140
- tcg_gen_shri_i32(tmp, tmp, offset);
141
- }
142
- if (a->u) {
143
- gen_uxtb(tmp);
144
- } else {
145
- gen_sxtb(tmp);
146
- }
147
- break;
148
- case 1:
149
- if (a->u) {
150
- if (offset) {
151
- tcg_gen_shri_i32(tmp, tmp, 16);
152
- } else {
153
- gen_uxth(tmp);
154
- }
155
- } else {
156
- if (offset) {
157
- tcg_gen_sari_i32(tmp, tmp, 16);
158
- } else {
159
- gen_sxth(tmp);
160
- }
161
- }
162
- break;
163
- case 2:
164
- break;
165
- }
166
+ tmp = tcg_temp_new_i32();
167
+ read_neon_element32(tmp, a->vn, a->index, a->size | (a->u ? 0 : MO_SIGN));
168
store_reg(s, a->rt, tmp);
169
170
return true;
171
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
172
static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
173
{
174
/* VMOV general purpose register to scalar */
175
- TCGv_i32 tmp, tmp2;
176
- int pass;
177
- uint32_t offset;
178
+ TCGv_i32 tmp;
179
180
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
181
- if (a->size == 2
182
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
183
+ if (a->size == MO_32
184
? !dc_isar_feature(aa32_fpsp_v2, s)
185
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
186
return false;
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
188
return false;
189
}
190
191
- offset = a->index << a->size;
192
- pass = extract32(offset, 2, 1);
193
- offset = extract32(offset, 0, 2) * 8;
194
-
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
199
tmp = load_reg(s, a->rt);
200
- switch (a->size) {
201
- case 0:
202
- tmp2 = neon_load_reg(a->vn, pass);
203
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
204
- tcg_temp_free_i32(tmp2);
205
- break;
206
- case 1:
207
- tmp2 = neon_load_reg(a->vn, pass);
208
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
209
- tcg_temp_free_i32(tmp2);
210
- break;
211
- case 2:
212
- break;
213
- }
214
- neon_store_reg(a->vn, pass, tmp);
215
+ write_neon_element32(tmp, a->vn, a->index, a->size);
216
+ tcg_temp_free_i32(tmp);
217
218
return true;
219
}
113
--
220
--
114
2.20.1
221
2.20.1
115
222
116
223
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
HSTR_EL2 offers a way to trap ranges of CP15 system register
3
The only uses of this function are for loading VFP
4
accesses to EL2, and it looks like this register is completely
4
single-precision values, and nothing to do with NEON.
5
ignored by QEMU.
6
5
7
To avoid adding extra .accessfn filters all over the place (which
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
would have a direct performance impact), let's add a new TB flag
7
Message-id: 20201030022618.785675-8-richard.henderson@linaro.org
9
that gets set whenever HSTR_EL2 is non-zero and that QEMU translates
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
10
---
21
target/arm/cpu.h | 2 ++
11
target/arm/translate.c | 4 +-
22
target/arm/translate.h | 2 ++
12
target/arm/translate-vfp.c.inc | 184 ++++++++++++++++-----------------
23
target/arm/helper.c | 6 ++++++
13
2 files changed, 94 insertions(+), 94 deletions(-)
24
target/arm/op_helper.c | 22 ++++++++++++++++++++++
25
target/arm/translate.c | 3 ++-
26
5 files changed, 34 insertions(+), 1 deletion(-)
27
14
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
33
FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Partially cached, minus FPEXC. */
34
FIELD(TBFLAG_A32, CONDEXEC, 8, 8) /* Not cached. */
35
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
36
+FIELD(TBFLAG_A32, HSTR_ACTIVE, 17, 1)
37
+
38
/* For M profile only, set if FPCCR.LSPACT is set */
39
FIELD(TBFLAG_A32, LSPACT, 18, 1) /* Not cached. */
40
/* For M profile only, set if we must create a new FP context */
41
diff --git a/target/arm/translate.h b/target/arm/translate.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/translate.h
44
+++ b/target/arm/translate.h
45
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
46
bool pauth_active;
47
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
48
bool bt;
49
+ /* True if any CP15 access is trapped by HSTR_EL2 */
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
}
62
+
63
+ if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
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
}
70
71
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
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
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
112
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/translate.c
17
--- a/target/arm/translate.c
114
+++ b/target/arm/translate.c
18
+++ b/target/arm/translate.c
115
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg64(TCGv_i64 var, int reg)
116
return 1;
20
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
117
}
21
}
118
22
119
- if (ri->accessfn ||
23
-static inline void neon_load_reg32(TCGv_i32 var, int reg)
120
+ if (s->hstr_active || ri->accessfn ||
24
+static inline void vfp_load_reg32(TCGv_i32 var, int reg)
121
(arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
25
{
122
/* Emit code to perform further access permissions checks at
26
tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
123
* runtime; this may result in an exception.
27
}
124
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
28
125
!arm_el_is_aa64(env, 3);
29
-static inline void neon_store_reg32(TCGv_i32 var, int reg)
126
dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
30
+static inline void vfp_store_reg32(TCGv_i32 var, int reg)
127
dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
31
{
128
+ dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
32
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
129
dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
33
}
130
condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
34
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
131
dc->condexec_mask = (condexec & 0xf) << 1;
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-vfp.c.inc
37
+++ b/target/arm/translate-vfp.c.inc
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
39
frn = tcg_temp_new_i32();
40
frm = tcg_temp_new_i32();
41
dest = tcg_temp_new_i32();
42
- neon_load_reg32(frn, rn);
43
- neon_load_reg32(frm, rm);
44
+ vfp_load_reg32(frn, rn);
45
+ vfp_load_reg32(frm, rm);
46
switch (a->cc) {
47
case 0: /* eq: Z */
48
tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
50
if (sz == 1) {
51
tcg_gen_andi_i32(dest, dest, 0xffff);
52
}
53
- neon_store_reg32(dest, rd);
54
+ vfp_store_reg32(dest, rd);
55
tcg_temp_free_i32(frn);
56
tcg_temp_free_i32(frm);
57
tcg_temp_free_i32(dest);
58
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
59
TCGv_i32 tcg_res;
60
tcg_op = tcg_temp_new_i32();
61
tcg_res = tcg_temp_new_i32();
62
- neon_load_reg32(tcg_op, rm);
63
+ vfp_load_reg32(tcg_op, rm);
64
if (sz == 1) {
65
gen_helper_rinth(tcg_res, tcg_op, fpst);
66
} else {
67
gen_helper_rints(tcg_res, tcg_op, fpst);
68
}
69
- neon_store_reg32(tcg_res, rd);
70
+ vfp_store_reg32(tcg_res, rd);
71
tcg_temp_free_i32(tcg_op);
72
tcg_temp_free_i32(tcg_res);
73
}
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
75
gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
76
}
77
tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
78
- neon_store_reg32(tcg_tmp, rd);
79
+ vfp_store_reg32(tcg_tmp, rd);
80
tcg_temp_free_i32(tcg_tmp);
81
tcg_temp_free_i64(tcg_res);
82
tcg_temp_free_i64(tcg_double);
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
84
TCGv_i32 tcg_single, tcg_res;
85
tcg_single = tcg_temp_new_i32();
86
tcg_res = tcg_temp_new_i32();
87
- neon_load_reg32(tcg_single, rm);
88
+ vfp_load_reg32(tcg_single, rm);
89
if (sz == 1) {
90
if (is_signed) {
91
gen_helper_vfp_toslh(tcg_res, tcg_single, tcg_shift, fpst);
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
93
gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
94
}
95
}
96
- neon_store_reg32(tcg_res, rd);
97
+ vfp_store_reg32(tcg_res, rd);
98
tcg_temp_free_i32(tcg_res);
99
tcg_temp_free_i32(tcg_single);
100
}
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_half(DisasContext *s, arg_VMOV_single *a)
102
if (a->l) {
103
/* VFP to general purpose register */
104
tmp = tcg_temp_new_i32();
105
- neon_load_reg32(tmp, a->vn);
106
+ vfp_load_reg32(tmp, a->vn);
107
tcg_gen_andi_i32(tmp, tmp, 0xffff);
108
store_reg(s, a->rt, tmp);
109
} else {
110
/* general purpose register to VFP */
111
tmp = load_reg(s, a->rt);
112
tcg_gen_andi_i32(tmp, tmp, 0xffff);
113
- neon_store_reg32(tmp, a->vn);
114
+ vfp_store_reg32(tmp, a->vn);
115
tcg_temp_free_i32(tmp);
116
}
117
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
119
if (a->l) {
120
/* VFP to general purpose register */
121
tmp = tcg_temp_new_i32();
122
- neon_load_reg32(tmp, a->vn);
123
+ vfp_load_reg32(tmp, a->vn);
124
if (a->rt == 15) {
125
/* Set the 4 flag bits in the CPSR. */
126
gen_set_nzcv(tmp);
127
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
128
} else {
129
/* general purpose register to VFP */
130
tmp = load_reg(s, a->rt);
131
- neon_store_reg32(tmp, a->vn);
132
+ vfp_store_reg32(tmp, a->vn);
133
tcg_temp_free_i32(tmp);
134
}
135
136
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
137
if (a->op) {
138
/* fpreg to gpreg */
139
tmp = tcg_temp_new_i32();
140
- neon_load_reg32(tmp, a->vm);
141
+ vfp_load_reg32(tmp, a->vm);
142
store_reg(s, a->rt, tmp);
143
tmp = tcg_temp_new_i32();
144
- neon_load_reg32(tmp, a->vm + 1);
145
+ vfp_load_reg32(tmp, a->vm + 1);
146
store_reg(s, a->rt2, tmp);
147
} else {
148
/* gpreg to fpreg */
149
tmp = load_reg(s, a->rt);
150
- neon_store_reg32(tmp, a->vm);
151
+ vfp_store_reg32(tmp, a->vm);
152
tcg_temp_free_i32(tmp);
153
tmp = load_reg(s, a->rt2);
154
- neon_store_reg32(tmp, a->vm + 1);
155
+ vfp_store_reg32(tmp, a->vm + 1);
156
tcg_temp_free_i32(tmp);
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
160
if (a->op) {
161
/* fpreg to gpreg */
162
tmp = tcg_temp_new_i32();
163
- neon_load_reg32(tmp, a->vm * 2);
164
+ vfp_load_reg32(tmp, a->vm * 2);
165
store_reg(s, a->rt, tmp);
166
tmp = tcg_temp_new_i32();
167
- neon_load_reg32(tmp, a->vm * 2 + 1);
168
+ vfp_load_reg32(tmp, a->vm * 2 + 1);
169
store_reg(s, a->rt2, tmp);
170
} else {
171
/* gpreg to fpreg */
172
tmp = load_reg(s, a->rt);
173
- neon_store_reg32(tmp, a->vm * 2);
174
+ vfp_store_reg32(tmp, a->vm * 2);
175
tcg_temp_free_i32(tmp);
176
tmp = load_reg(s, a->rt2);
177
- neon_store_reg32(tmp, a->vm * 2 + 1);
178
+ vfp_store_reg32(tmp, a->vm * 2 + 1);
179
tcg_temp_free_i32(tmp);
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
183
tmp = tcg_temp_new_i32();
184
if (a->l) {
185
gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
186
- neon_store_reg32(tmp, a->vd);
187
+ vfp_store_reg32(tmp, a->vd);
188
} else {
189
- neon_load_reg32(tmp, a->vd);
190
+ vfp_load_reg32(tmp, a->vd);
191
gen_aa32_st16(s, tmp, addr, get_mem_index(s));
192
}
193
tcg_temp_free_i32(tmp);
194
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
195
tmp = tcg_temp_new_i32();
196
if (a->l) {
197
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
198
- neon_store_reg32(tmp, a->vd);
199
+ vfp_store_reg32(tmp, a->vd);
200
} else {
201
- neon_load_reg32(tmp, a->vd);
202
+ vfp_load_reg32(tmp, a->vd);
203
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
204
}
205
tcg_temp_free_i32(tmp);
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
207
if (a->l) {
208
/* load */
209
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
210
- neon_store_reg32(tmp, a->vd + i);
211
+ vfp_store_reg32(tmp, a->vd + i);
212
} else {
213
/* store */
214
- neon_load_reg32(tmp, a->vd + i);
215
+ vfp_load_reg32(tmp, a->vd + i);
216
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
217
}
218
tcg_gen_addi_i32(addr, addr, offset);
219
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
220
fd = tcg_temp_new_i32();
221
fpst = fpstatus_ptr(FPST_FPCR);
222
223
- neon_load_reg32(f0, vn);
224
- neon_load_reg32(f1, vm);
225
+ vfp_load_reg32(f0, vn);
226
+ vfp_load_reg32(f1, vm);
227
228
for (;;) {
229
if (reads_vd) {
230
- neon_load_reg32(fd, vd);
231
+ vfp_load_reg32(fd, vd);
232
}
233
fn(fd, f0, f1, fpst);
234
- neon_store_reg32(fd, vd);
235
+ vfp_store_reg32(fd, vd);
236
237
if (veclen == 0) {
238
break;
239
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
240
veclen--;
241
vd = vfp_advance_sreg(vd, delta_d);
242
vn = vfp_advance_sreg(vn, delta_d);
243
- neon_load_reg32(f0, vn);
244
+ vfp_load_reg32(f0, vn);
245
if (delta_m) {
246
vm = vfp_advance_sreg(vm, delta_m);
247
- neon_load_reg32(f1, vm);
248
+ vfp_load_reg32(f1, vm);
249
}
250
}
251
252
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_hp(DisasContext *s, VFPGen3OpSPFn *fn,
253
fd = tcg_temp_new_i32();
254
fpst = fpstatus_ptr(FPST_FPCR_F16);
255
256
- neon_load_reg32(f0, vn);
257
- neon_load_reg32(f1, vm);
258
+ vfp_load_reg32(f0, vn);
259
+ vfp_load_reg32(f1, vm);
260
261
if (reads_vd) {
262
- neon_load_reg32(fd, vd);
263
+ vfp_load_reg32(fd, vd);
264
}
265
fn(fd, f0, f1, fpst);
266
- neon_store_reg32(fd, vd);
267
+ vfp_store_reg32(fd, vd);
268
269
tcg_temp_free_i32(f0);
270
tcg_temp_free_i32(f1);
271
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
272
f0 = tcg_temp_new_i32();
273
fd = tcg_temp_new_i32();
274
275
- neon_load_reg32(f0, vm);
276
+ vfp_load_reg32(f0, vm);
277
278
for (;;) {
279
fn(fd, f0);
280
- neon_store_reg32(fd, vd);
281
+ vfp_store_reg32(fd, vd);
282
283
if (veclen == 0) {
284
break;
285
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
286
/* single source one-many */
287
while (veclen--) {
288
vd = vfp_advance_sreg(vd, delta_d);
289
- neon_store_reg32(fd, vd);
290
+ vfp_store_reg32(fd, vd);
291
}
292
break;
293
}
294
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
295
veclen--;
296
vd = vfp_advance_sreg(vd, delta_d);
297
vm = vfp_advance_sreg(vm, delta_m);
298
- neon_load_reg32(f0, vm);
299
+ vfp_load_reg32(f0, vm);
300
}
301
302
tcg_temp_free_i32(f0);
303
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_hp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
304
}
305
306
f0 = tcg_temp_new_i32();
307
- neon_load_reg32(f0, vm);
308
+ vfp_load_reg32(f0, vm);
309
fn(f0, f0);
310
- neon_store_reg32(f0, vd);
311
+ vfp_store_reg32(f0, vd);
312
tcg_temp_free_i32(f0);
313
314
return true;
315
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_hp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
316
vm = tcg_temp_new_i32();
317
vd = tcg_temp_new_i32();
318
319
- neon_load_reg32(vn, a->vn);
320
- neon_load_reg32(vm, a->vm);
321
+ vfp_load_reg32(vn, a->vn);
322
+ vfp_load_reg32(vm, a->vm);
323
if (neg_n) {
324
/* VFNMS, VFMS */
325
gen_helper_vfp_negh(vn, vn);
326
}
327
- neon_load_reg32(vd, a->vd);
328
+ vfp_load_reg32(vd, a->vd);
329
if (neg_d) {
330
/* VFNMA, VFNMS */
331
gen_helper_vfp_negh(vd, vd);
332
}
333
fpst = fpstatus_ptr(FPST_FPCR_F16);
334
gen_helper_vfp_muladdh(vd, vn, vm, vd, fpst);
335
- neon_store_reg32(vd, a->vd);
336
+ vfp_store_reg32(vd, a->vd);
337
338
tcg_temp_free_ptr(fpst);
339
tcg_temp_free_i32(vn);
340
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
341
vm = tcg_temp_new_i32();
342
vd = tcg_temp_new_i32();
343
344
- neon_load_reg32(vn, a->vn);
345
- neon_load_reg32(vm, a->vm);
346
+ vfp_load_reg32(vn, a->vn);
347
+ vfp_load_reg32(vm, a->vm);
348
if (neg_n) {
349
/* VFNMS, VFMS */
350
gen_helper_vfp_negs(vn, vn);
351
}
352
- neon_load_reg32(vd, a->vd);
353
+ vfp_load_reg32(vd, a->vd);
354
if (neg_d) {
355
/* VFNMA, VFNMS */
356
gen_helper_vfp_negs(vd, vd);
357
}
358
fpst = fpstatus_ptr(FPST_FPCR);
359
gen_helper_vfp_muladds(vd, vn, vm, vd, fpst);
360
- neon_store_reg32(vd, a->vd);
361
+ vfp_store_reg32(vd, a->vd);
362
363
tcg_temp_free_ptr(fpst);
364
tcg_temp_free_i32(vn);
365
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_hp(DisasContext *s, arg_VMOV_imm_sp *a)
366
}
367
368
fd = tcg_const_i32(vfp_expand_imm(MO_16, a->imm));
369
- neon_store_reg32(fd, a->vd);
370
+ vfp_store_reg32(fd, a->vd);
371
tcg_temp_free_i32(fd);
372
return true;
373
}
374
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
375
fd = tcg_const_i32(vfp_expand_imm(MO_32, a->imm));
376
377
for (;;) {
378
- neon_store_reg32(fd, vd);
379
+ vfp_store_reg32(fd, vd);
380
381
if (veclen == 0) {
382
break;
383
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a)
384
vd = tcg_temp_new_i32();
385
vm = tcg_temp_new_i32();
386
387
- neon_load_reg32(vd, a->vd);
388
+ vfp_load_reg32(vd, a->vd);
389
if (a->z) {
390
tcg_gen_movi_i32(vm, 0);
391
} else {
392
- neon_load_reg32(vm, a->vm);
393
+ vfp_load_reg32(vm, a->vm);
394
}
395
396
if (a->e) {
397
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
398
vd = tcg_temp_new_i32();
399
vm = tcg_temp_new_i32();
400
401
- neon_load_reg32(vd, a->vd);
402
+ vfp_load_reg32(vd, a->vd);
403
if (a->z) {
404
tcg_gen_movi_i32(vm, 0);
405
} else {
406
- neon_load_reg32(vm, a->vm);
407
+ vfp_load_reg32(vm, a->vm);
408
}
409
410
if (a->e) {
411
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f32_f16(DisasContext *s, arg_VCVT_f32_f16 *a)
412
/* The T bit tells us if we want the low or high 16 bits of Vm */
413
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
414
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp_mode);
415
- neon_store_reg32(tmp, a->vd);
416
+ vfp_store_reg32(tmp, a->vd);
417
tcg_temp_free_i32(ahp_mode);
418
tcg_temp_free_ptr(fpst);
419
tcg_temp_free_i32(tmp);
420
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f32(DisasContext *s, arg_VCVT_f16_f32 *a)
421
ahp_mode = get_ahp_flag();
422
tmp = tcg_temp_new_i32();
423
424
- neon_load_reg32(tmp, a->vm);
425
+ vfp_load_reg32(tmp, a->vm);
426
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp_mode);
427
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
428
tcg_temp_free_i32(ahp_mode);
429
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_hp(DisasContext *s, arg_VRINTR_sp *a)
430
}
431
432
tmp = tcg_temp_new_i32();
433
- neon_load_reg32(tmp, a->vm);
434
+ vfp_load_reg32(tmp, a->vm);
435
fpst = fpstatus_ptr(FPST_FPCR_F16);
436
gen_helper_rinth(tmp, tmp, fpst);
437
- neon_store_reg32(tmp, a->vd);
438
+ vfp_store_reg32(tmp, a->vd);
439
tcg_temp_free_ptr(fpst);
440
tcg_temp_free_i32(tmp);
441
return true;
442
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a)
443
}
444
445
tmp = tcg_temp_new_i32();
446
- neon_load_reg32(tmp, a->vm);
447
+ vfp_load_reg32(tmp, a->vm);
448
fpst = fpstatus_ptr(FPST_FPCR);
449
gen_helper_rints(tmp, tmp, fpst);
450
- neon_store_reg32(tmp, a->vd);
451
+ vfp_store_reg32(tmp, a->vd);
452
tcg_temp_free_ptr(fpst);
453
tcg_temp_free_i32(tmp);
454
return true;
455
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_hp(DisasContext *s, arg_VRINTZ_sp *a)
456
}
457
458
tmp = tcg_temp_new_i32();
459
- neon_load_reg32(tmp, a->vm);
460
+ vfp_load_reg32(tmp, a->vm);
461
fpst = fpstatus_ptr(FPST_FPCR_F16);
462
tcg_rmode = tcg_const_i32(float_round_to_zero);
463
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
464
gen_helper_rinth(tmp, tmp, fpst);
465
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
466
- neon_store_reg32(tmp, a->vd);
467
+ vfp_store_reg32(tmp, a->vd);
468
tcg_temp_free_ptr(fpst);
469
tcg_temp_free_i32(tcg_rmode);
470
tcg_temp_free_i32(tmp);
471
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
472
}
473
474
tmp = tcg_temp_new_i32();
475
- neon_load_reg32(tmp, a->vm);
476
+ vfp_load_reg32(tmp, a->vm);
477
fpst = fpstatus_ptr(FPST_FPCR);
478
tcg_rmode = tcg_const_i32(float_round_to_zero);
479
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
480
gen_helper_rints(tmp, tmp, fpst);
481
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
482
- neon_store_reg32(tmp, a->vd);
483
+ vfp_store_reg32(tmp, a->vd);
484
tcg_temp_free_ptr(fpst);
485
tcg_temp_free_i32(tcg_rmode);
486
tcg_temp_free_i32(tmp);
487
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_hp(DisasContext *s, arg_VRINTX_sp *a)
488
}
489
490
tmp = tcg_temp_new_i32();
491
- neon_load_reg32(tmp, a->vm);
492
+ vfp_load_reg32(tmp, a->vm);
493
fpst = fpstatus_ptr(FPST_FPCR_F16);
494
gen_helper_rinth_exact(tmp, tmp, fpst);
495
- neon_store_reg32(tmp, a->vd);
496
+ vfp_store_reg32(tmp, a->vd);
497
tcg_temp_free_ptr(fpst);
498
tcg_temp_free_i32(tmp);
499
return true;
500
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_sp(DisasContext *s, arg_VRINTX_sp *a)
501
}
502
503
tmp = tcg_temp_new_i32();
504
- neon_load_reg32(tmp, a->vm);
505
+ vfp_load_reg32(tmp, a->vm);
506
fpst = fpstatus_ptr(FPST_FPCR);
507
gen_helper_rints_exact(tmp, tmp, fpst);
508
- neon_store_reg32(tmp, a->vd);
509
+ vfp_store_reg32(tmp, a->vd);
510
tcg_temp_free_ptr(fpst);
511
tcg_temp_free_i32(tmp);
512
return true;
513
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
514
515
vm = tcg_temp_new_i32();
516
vd = tcg_temp_new_i64();
517
- neon_load_reg32(vm, a->vm);
518
+ vfp_load_reg32(vm, a->vm);
519
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
520
neon_store_reg64(vd, a->vd);
521
tcg_temp_free_i32(vm);
522
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
523
vm = tcg_temp_new_i64();
524
neon_load_reg64(vm, a->vm);
525
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
526
- neon_store_reg32(vd, a->vd);
527
+ vfp_store_reg32(vd, a->vd);
528
tcg_temp_free_i32(vd);
529
tcg_temp_free_i64(vm);
530
return true;
531
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
532
}
533
534
vm = tcg_temp_new_i32();
535
- neon_load_reg32(vm, a->vm);
536
+ vfp_load_reg32(vm, a->vm);
537
fpst = fpstatus_ptr(FPST_FPCR_F16);
538
if (a->s) {
539
/* i32 -> f16 */
540
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
541
/* u32 -> f16 */
542
gen_helper_vfp_uitoh(vm, vm, fpst);
543
}
544
- neon_store_reg32(vm, a->vd);
545
+ vfp_store_reg32(vm, a->vd);
546
tcg_temp_free_i32(vm);
547
tcg_temp_free_ptr(fpst);
548
return true;
549
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
550
}
551
552
vm = tcg_temp_new_i32();
553
- neon_load_reg32(vm, a->vm);
554
+ vfp_load_reg32(vm, a->vm);
555
fpst = fpstatus_ptr(FPST_FPCR);
556
if (a->s) {
557
/* i32 -> f32 */
558
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
559
/* u32 -> f32 */
560
gen_helper_vfp_uitos(vm, vm, fpst);
561
}
562
- neon_store_reg32(vm, a->vd);
563
+ vfp_store_reg32(vm, a->vd);
564
tcg_temp_free_i32(vm);
565
tcg_temp_free_ptr(fpst);
566
return true;
567
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
568
569
vm = tcg_temp_new_i32();
570
vd = tcg_temp_new_i64();
571
- neon_load_reg32(vm, a->vm);
572
+ vfp_load_reg32(vm, a->vm);
573
fpst = fpstatus_ptr(FPST_FPCR);
574
if (a->s) {
575
/* i32 -> f64 */
576
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
577
vd = tcg_temp_new_i32();
578
neon_load_reg64(vm, a->vm);
579
gen_helper_vjcvt(vd, vm, cpu_env);
580
- neon_store_reg32(vd, a->vd);
581
+ vfp_store_reg32(vd, a->vd);
582
tcg_temp_free_i64(vm);
583
tcg_temp_free_i32(vd);
584
return true;
585
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
586
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
587
588
vd = tcg_temp_new_i32();
589
- neon_load_reg32(vd, a->vd);
590
+ vfp_load_reg32(vd, a->vd);
591
592
fpst = fpstatus_ptr(FPST_FPCR_F16);
593
shift = tcg_const_i32(frac_bits);
594
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
595
g_assert_not_reached();
596
}
597
598
- neon_store_reg32(vd, a->vd);
599
+ vfp_store_reg32(vd, a->vd);
600
tcg_temp_free_i32(vd);
601
tcg_temp_free_i32(shift);
602
tcg_temp_free_ptr(fpst);
603
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
604
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
605
606
vd = tcg_temp_new_i32();
607
- neon_load_reg32(vd, a->vd);
608
+ vfp_load_reg32(vd, a->vd);
609
610
fpst = fpstatus_ptr(FPST_FPCR);
611
shift = tcg_const_i32(frac_bits);
612
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
613
g_assert_not_reached();
614
}
615
616
- neon_store_reg32(vd, a->vd);
617
+ vfp_store_reg32(vd, a->vd);
618
tcg_temp_free_i32(vd);
619
tcg_temp_free_i32(shift);
620
tcg_temp_free_ptr(fpst);
621
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
622
623
fpst = fpstatus_ptr(FPST_FPCR_F16);
624
vm = tcg_temp_new_i32();
625
- neon_load_reg32(vm, a->vm);
626
+ vfp_load_reg32(vm, a->vm);
627
628
if (a->s) {
629
if (a->rz) {
630
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
631
gen_helper_vfp_touih(vm, vm, fpst);
632
}
633
}
634
- neon_store_reg32(vm, a->vd);
635
+ vfp_store_reg32(vm, a->vd);
636
tcg_temp_free_i32(vm);
637
tcg_temp_free_ptr(fpst);
638
return true;
639
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
640
641
fpst = fpstatus_ptr(FPST_FPCR);
642
vm = tcg_temp_new_i32();
643
- neon_load_reg32(vm, a->vm);
644
+ vfp_load_reg32(vm, a->vm);
645
646
if (a->s) {
647
if (a->rz) {
648
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
649
gen_helper_vfp_touis(vm, vm, fpst);
650
}
651
}
652
- neon_store_reg32(vm, a->vd);
653
+ vfp_store_reg32(vm, a->vd);
654
tcg_temp_free_i32(vm);
655
tcg_temp_free_ptr(fpst);
656
return true;
657
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
658
gen_helper_vfp_touid(vd, vm, fpst);
659
}
660
}
661
- neon_store_reg32(vd, a->vd);
662
+ vfp_store_reg32(vd, a->vd);
663
tcg_temp_free_i32(vd);
664
tcg_temp_free_i64(vm);
665
tcg_temp_free_ptr(fpst);
666
@@ -XXX,XX +XXX,XX @@ static bool trans_VINS(DisasContext *s, arg_VINS *a)
667
/* Insert low half of Vm into high half of Vd */
668
rm = tcg_temp_new_i32();
669
rd = tcg_temp_new_i32();
670
- neon_load_reg32(rm, a->vm);
671
- neon_load_reg32(rd, a->vd);
672
+ vfp_load_reg32(rm, a->vm);
673
+ vfp_load_reg32(rd, a->vd);
674
tcg_gen_deposit_i32(rd, rd, rm, 16, 16);
675
- neon_store_reg32(rd, a->vd);
676
+ vfp_store_reg32(rd, a->vd);
677
tcg_temp_free_i32(rm);
678
tcg_temp_free_i32(rd);
679
return true;
680
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOVX(DisasContext *s, arg_VINS *a)
681
682
/* Set Vd to high half of Vm */
683
rm = tcg_temp_new_i32();
684
- neon_load_reg32(rm, a->vm);
685
+ vfp_load_reg32(rm, a->vm);
686
tcg_gen_shri_i32(rm, rm, 16);
687
- neon_store_reg32(rm, a->vd);
688
+ vfp_store_reg32(rm, a->vd);
689
tcg_temp_free_i32(rm);
690
return true;
691
}
132
--
692
--
133
2.20.1
693
2.20.1
134
694
135
695
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add an option to trigger memory writeback to sync given memory region
3
Replace all uses of neon_load/store_reg64 within translate-neon.c.inc.
4
with the corresponding backing store, case one is available.
4
5
This extends the support for persistent memory, allowing syncing on-demand.
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
6
Message-id: 20201030022618.785675-9-richard.henderson@linaro.org
7
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
include/exec/memory.h | 6 ++++++
10
target/arm/translate.c | 26 +++++++++
13
include/exec/ram_addr.h | 8 ++++++++
11
target/arm/translate-neon.c.inc | 94 ++++++++++++++++-----------------
14
include/qemu/cutils.h | 1 +
12
2 files changed, 73 insertions(+), 47 deletions(-)
15
exec.c | 36 ++++++++++++++++++++++++++++++++++++
13
16
memory.c | 12 ++++++++++++
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
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
15
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/memory.h
16
--- a/target/arm/translate.c
23
+++ b/include/exec/memory.h
17
+++ b/target/arm/translate.c
24
@@ -XXX,XX +XXX,XX @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
18
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
25
*/
19
}
26
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
20
}
27
Error **errp);
21
28
+/**
22
+static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
29
+ * memory_region_do_writeback: Trigger writeback for selected address range
23
+{
30
+ * [addr, addr + size]
24
+ long off = neon_element_offset(reg, ele, memop);
31
+ *
32
+ */
33
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size);
34
35
/**
36
* memory_region_set_log: Turn dirty logging on or off for a region.
37
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/exec/ram_addr.h
40
+++ b/include/exec/ram_addr.h
41
@@ -XXX,XX +XXX,XX @@ void qemu_ram_free(RAMBlock *block);
42
43
int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
44
45
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length);
46
+
25
+
47
+/* Clear whole block of mem */
26
+ switch (memop) {
48
+static inline void qemu_ram_block_writeback(RAMBlock *block)
27
+ case MO_Q:
49
+{
28
+ tcg_gen_ld_i64(dest, cpu_env, off);
50
+ qemu_ram_writeback(block, 0, block->used_length);
29
+ break;
51
+}
30
+ default:
52
+
31
+ g_assert_not_reached();
53
#define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1)
54
#define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE))
55
56
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/include/qemu/cutils.h
59
+++ b/include/qemu/cutils.h
60
@@ -XXX,XX +XXX,XX @@ const char *qemu_strchrnul(const char *s, int c);
61
#endif
62
time_t mktimegm(struct tm *tm);
63
int qemu_fdatasync(int fd);
64
+int qemu_msync(void *addr, size_t length, int fd);
65
int fcntl_setfl(int fd, int flag);
66
int qemu_parse_fd(const char *param);
67
int qemu_strtoi(const char *nptr, const char **endptr, int base,
68
diff --git a/exec.c b/exec.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/exec.c
71
+++ b/exec.c
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
+ }
104
+#endif
105
+ if (block->fd >= 0) {
106
+ /**
107
+ * Case there is no support for PMEM or the memory has not been
108
+ * specified as persistent (or is not one) - use the msync.
109
+ * Less optimal but still achieves the same goal
110
+ */
111
+ if (qemu_msync(addr, length, block->fd)) {
112
+ warn_report("%s: failed to sync memory range: start: "
113
+ RAM_ADDR_FMT " length: " RAM_ADDR_FMT,
114
+ __func__, start, length);
115
+ }
116
+ }
32
+ }
117
+}
33
+}
118
+
34
+
119
/* Called with ram_list.mutex held */
35
static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
120
static void dirty_memory_extend(ram_addr_t old_ram_size,
36
{
121
ram_addr_t new_ram_size)
37
long off = neon_element_offset(reg, ele, memop);
122
diff --git a/memory.c b/memory.c
38
@@ -XXX,XX +XXX,XX @@ static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
123
index XXXXXXX..XXXXXXX 100644
39
}
124
--- a/memory.c
125
+++ b/memory.c
126
@@ -XXX,XX +XXX,XX @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
127
qemu_ram_resize(mr->ram_block, newsize, errp);
128
}
40
}
129
41
42
+static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
43
+{
44
+ long off = neon_element_offset(reg, ele, memop);
130
+
45
+
131
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
46
+ switch (memop) {
132
+{
47
+ case MO_64:
133
+ /*
48
+ tcg_gen_st_i64(src, cpu_env, off);
134
+ * Might be extended case needed to cover
49
+ break;
135
+ * different types of memory regions
50
+ default:
136
+ */
51
+ g_assert_not_reached();
137
+ if (mr->ram_block && mr->dirty_log_mask) {
138
+ qemu_ram_writeback(mr->ram_block, addr, size);
139
+ }
52
+ }
140
+}
53
+}
141
+
54
+
142
/*
55
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
143
* Call proper memory listeners about the change on the newly
56
{
144
* added/removed CoalescedMemoryRange.
57
TCGv_ptr ret = tcg_temp_new_ptr();
145
diff --git a/util/cutils.c b/util/cutils.c
58
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
146
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
147
--- a/util/cutils.c
60
--- a/target/arm/translate-neon.c.inc
148
+++ b/util/cutils.c
61
+++ b/target/arm/translate-neon.c.inc
149
@@ -XXX,XX +XXX,XX @@ int qemu_fdatasync(int fd)
62
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_64(DisasContext *s, arg_2reg_shift *a,
150
#endif
63
for (pass = 0; pass < a->q + 1; pass++) {
64
TCGv_i64 tmp = tcg_temp_new_i64();
65
66
- neon_load_reg64(tmp, a->vm + pass);
67
+ read_neon_element64(tmp, a->vm, pass, MO_64);
68
fn(tmp, cpu_env, tmp, constimm);
69
- neon_store_reg64(tmp, a->vd + pass);
70
+ write_neon_element64(tmp, a->vd, pass, MO_64);
71
tcg_temp_free_i64(tmp);
72
}
73
tcg_temp_free_i64(constimm);
74
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
75
rd = tcg_temp_new_i32();
76
77
/* Load both inputs first to avoid potential overwrite if rm == rd */
78
- neon_load_reg64(rm1, a->vm);
79
- neon_load_reg64(rm2, a->vm + 1);
80
+ read_neon_element64(rm1, a->vm, 0, MO_64);
81
+ read_neon_element64(rm2, a->vm, 1, MO_64);
82
83
shiftfn(rm1, rm1, constimm);
84
narrowfn(rd, cpu_env, rm1);
85
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
86
tcg_gen_shli_i64(tmp, tmp, a->shift);
87
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
88
}
89
- neon_store_reg64(tmp, a->vd);
90
+ write_neon_element64(tmp, a->vd, 0, MO_64);
91
92
widenfn(tmp, rm1);
93
tcg_temp_free_i32(rm1);
94
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
95
tcg_gen_shli_i64(tmp, tmp, a->shift);
96
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
97
}
98
- neon_store_reg64(tmp, a->vd + 1);
99
+ write_neon_element64(tmp, a->vd, 1, MO_64);
100
tcg_temp_free_i64(tmp);
101
return true;
151
}
102
}
152
103
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
153
+/**
104
rm_64 = tcg_temp_new_i64();
154
+ * Sync changes made to the memory mapped file back to the backing
105
155
+ * storage. For POSIX compliant systems this will fallback
106
if (src1_wide) {
156
+ * to regular msync call. Otherwise it will trigger whole file sync
107
- neon_load_reg64(rn0_64, a->vn);
157
+ * (including the metadata case there is no support to skip that otherwise)
108
+ read_neon_element64(rn0_64, a->vn, 0, MO_64);
158
+ *
109
} else {
159
+ * @addr - start of the memory area to be synced
110
TCGv_i32 tmp = tcg_temp_new_i32();
160
+ * @length - length of the are to be synced
111
read_neon_element32(tmp, a->vn, 0, MO_32);
161
+ * @fd - file descriptor for the file to be synced
112
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
162
+ * (mandatory only for POSIX non-compliant systems)
113
* avoid incorrect results if a narrow input overlaps with the result.
163
+ */
114
*/
164
+int qemu_msync(void *addr, size_t length, int fd)
115
if (src1_wide) {
165
+{
116
- neon_load_reg64(rn1_64, a->vn + 1);
166
+#ifdef CONFIG_POSIX
117
+ read_neon_element64(rn1_64, a->vn, 1, MO_64);
167
+ size_t align_mask = ~(qemu_real_host_page_size - 1);
118
} else {
168
+
119
TCGv_i32 tmp = tcg_temp_new_i32();
169
+ /**
120
read_neon_element32(tmp, a->vn, 1, MO_32);
170
+ * There are no strict reqs as per the length of mapping
121
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
171
+ * to be synced. Still the length needs to follow the address
122
rm = tcg_temp_new_i32();
172
+ * alignment changes. Additionally - round the size to the multiple
123
read_neon_element32(rm, a->vm, 1, MO_32);
173
+ * of PAGE_SIZE
124
174
+ */
125
- neon_store_reg64(rn0_64, a->vd);
175
+ length += ((uintptr_t)addr & (qemu_real_host_page_size - 1));
126
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
176
+ length = (length + ~align_mask) & align_mask;
127
177
+
128
widenfn(rm_64, rm);
178
+ addr = (void *)((uintptr_t)addr & align_mask);
129
tcg_temp_free_i32(rm);
179
+
130
opfn(rn1_64, rn1_64, rm_64);
180
+ return msync(addr, length, MS_SYNC);
131
- neon_store_reg64(rn1_64, a->vd + 1);
181
+#else /* CONFIG_POSIX */
132
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
182
+ /**
133
183
+ * Perform the sync based on the file descriptor
134
tcg_temp_free_i64(rn0_64);
184
+ * The sync range will most probably be wider than the one
135
tcg_temp_free_i64(rn1_64);
185
+ * requested - but it will still get the job done
136
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
186
+ */
137
rd0 = tcg_temp_new_i32();
187
+ return qemu_fdatasync(fd);
138
rd1 = tcg_temp_new_i32();
188
+#endif /* CONFIG_POSIX */
139
189
+}
140
- neon_load_reg64(rn_64, a->vn);
190
+
141
- neon_load_reg64(rm_64, a->vm);
191
#ifndef _WIN32
142
+ read_neon_element64(rn_64, a->vn, 0, MO_64);
192
/* Sets a specific flag */
143
+ read_neon_element64(rm_64, a->vm, 0, MO_64);
193
int fcntl_setfl(int fd, int flag)
144
145
opfn(rn_64, rn_64, rm_64);
146
147
narrowfn(rd0, rn_64);
148
149
- neon_load_reg64(rn_64, a->vn + 1);
150
- neon_load_reg64(rm_64, a->vm + 1);
151
+ read_neon_element64(rn_64, a->vn, 1, MO_64);
152
+ read_neon_element64(rm_64, a->vm, 1, MO_64);
153
154
opfn(rn_64, rn_64, rm_64);
155
156
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
157
/* Don't store results until after all loads: they might overlap */
158
if (accfn) {
159
tmp = tcg_temp_new_i64();
160
- neon_load_reg64(tmp, a->vd);
161
+ read_neon_element64(tmp, a->vd, 0, MO_64);
162
accfn(tmp, tmp, rd0);
163
- neon_store_reg64(tmp, a->vd);
164
- neon_load_reg64(tmp, a->vd + 1);
165
+ write_neon_element64(tmp, a->vd, 0, MO_64);
166
+ read_neon_element64(tmp, a->vd, 1, MO_64);
167
accfn(tmp, tmp, rd1);
168
- neon_store_reg64(tmp, a->vd + 1);
169
+ write_neon_element64(tmp, a->vd, 1, MO_64);
170
tcg_temp_free_i64(tmp);
171
} else {
172
- neon_store_reg64(rd0, a->vd);
173
- neon_store_reg64(rd1, a->vd + 1);
174
+ write_neon_element64(rd0, a->vd, 0, MO_64);
175
+ write_neon_element64(rd1, a->vd, 1, MO_64);
176
}
177
178
tcg_temp_free_i64(rd0);
179
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
180
181
if (accfn) {
182
TCGv_i64 t64 = tcg_temp_new_i64();
183
- neon_load_reg64(t64, a->vd);
184
+ read_neon_element64(t64, a->vd, 0, MO_64);
185
accfn(t64, t64, rn0_64);
186
- neon_store_reg64(t64, a->vd);
187
- neon_load_reg64(t64, a->vd + 1);
188
+ write_neon_element64(t64, a->vd, 0, MO_64);
189
+ read_neon_element64(t64, a->vd, 1, MO_64);
190
accfn(t64, t64, rn1_64);
191
- neon_store_reg64(t64, a->vd + 1);
192
+ write_neon_element64(t64, a->vd, 1, MO_64);
193
tcg_temp_free_i64(t64);
194
} else {
195
- neon_store_reg64(rn0_64, a->vd);
196
- neon_store_reg64(rn1_64, a->vd + 1);
197
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
198
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
199
}
200
tcg_temp_free_i64(rn0_64);
201
tcg_temp_free_i64(rn1_64);
202
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
203
right = tcg_temp_new_i64();
204
dest = tcg_temp_new_i64();
205
206
- neon_load_reg64(right, a->vn);
207
- neon_load_reg64(left, a->vm);
208
+ read_neon_element64(right, a->vn, 0, MO_64);
209
+ read_neon_element64(left, a->vm, 0, MO_64);
210
tcg_gen_extract2_i64(dest, right, left, a->imm * 8);
211
- neon_store_reg64(dest, a->vd);
212
+ write_neon_element64(dest, a->vd, 0, MO_64);
213
214
tcg_temp_free_i64(left);
215
tcg_temp_free_i64(right);
216
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
217
destright = tcg_temp_new_i64();
218
219
if (a->imm < 8) {
220
- neon_load_reg64(right, a->vn);
221
- neon_load_reg64(middle, a->vn + 1);
222
+ read_neon_element64(right, a->vn, 0, MO_64);
223
+ read_neon_element64(middle, a->vn, 1, MO_64);
224
tcg_gen_extract2_i64(destright, right, middle, a->imm * 8);
225
- neon_load_reg64(left, a->vm);
226
+ read_neon_element64(left, a->vm, 0, MO_64);
227
tcg_gen_extract2_i64(destleft, middle, left, a->imm * 8);
228
} else {
229
- neon_load_reg64(right, a->vn + 1);
230
- neon_load_reg64(middle, a->vm);
231
+ read_neon_element64(right, a->vn, 1, MO_64);
232
+ read_neon_element64(middle, a->vm, 0, MO_64);
233
tcg_gen_extract2_i64(destright, right, middle, (a->imm - 8) * 8);
234
- neon_load_reg64(left, a->vm + 1);
235
+ read_neon_element64(left, a->vm, 1, MO_64);
236
tcg_gen_extract2_i64(destleft, middle, left, (a->imm - 8) * 8);
237
}
238
239
- neon_store_reg64(destright, a->vd);
240
- neon_store_reg64(destleft, a->vd + 1);
241
+ write_neon_element64(destright, a->vd, 0, MO_64);
242
+ write_neon_element64(destleft, a->vd, 1, MO_64);
243
244
tcg_temp_free_i64(destright);
245
tcg_temp_free_i64(destleft);
246
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
247
248
if (accfn) {
249
TCGv_i64 tmp64 = tcg_temp_new_i64();
250
- neon_load_reg64(tmp64, a->vd + pass);
251
+ read_neon_element64(tmp64, a->vd, pass, MO_64);
252
accfn(rd_64, tmp64, rd_64);
253
tcg_temp_free_i64(tmp64);
254
}
255
- neon_store_reg64(rd_64, a->vd + pass);
256
+ write_neon_element64(rd_64, a->vd, pass, MO_64);
257
tcg_temp_free_i64(rd_64);
258
}
259
return true;
260
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
261
rd0 = tcg_temp_new_i32();
262
rd1 = tcg_temp_new_i32();
263
264
- neon_load_reg64(rm, a->vm);
265
+ read_neon_element64(rm, a->vm, 0, MO_64);
266
narrowfn(rd0, cpu_env, rm);
267
- neon_load_reg64(rm, a->vm + 1);
268
+ read_neon_element64(rm, a->vm, 1, MO_64);
269
narrowfn(rd1, cpu_env, rm);
270
write_neon_element32(rd0, a->vd, 0, MO_32);
271
write_neon_element32(rd1, a->vd, 1, MO_32);
272
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
273
274
widenfn(rd, rm0);
275
tcg_gen_shli_i64(rd, rd, 8 << a->size);
276
- neon_store_reg64(rd, a->vd);
277
+ write_neon_element64(rd, a->vd, 0, MO_64);
278
widenfn(rd, rm1);
279
tcg_gen_shli_i64(rd, rd, 8 << a->size);
280
- neon_store_reg64(rd, a->vd + 1);
281
+ write_neon_element64(rd, a->vd, 1, MO_64);
282
283
tcg_temp_free_i64(rd);
284
tcg_temp_free_i32(rm0);
285
@@ -XXX,XX +XXX,XX @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a)
286
rm = tcg_temp_new_i64();
287
rd = tcg_temp_new_i64();
288
for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
289
- neon_load_reg64(rm, a->vm + pass);
290
- neon_load_reg64(rd, a->vd + pass);
291
- neon_store_reg64(rm, a->vd + pass);
292
- neon_store_reg64(rd, a->vm + pass);
293
+ read_neon_element64(rm, a->vm, pass, MO_64);
294
+ read_neon_element64(rd, a->vd, pass, MO_64);
295
+ write_neon_element64(rm, a->vd, pass, MO_64);
296
+ write_neon_element64(rd, a->vm, pass, MO_64);
297
}
298
tcg_temp_free_i64(rm);
299
tcg_temp_free_i64(rd);
194
--
300
--
195
2.20.1
301
2.20.1
196
302
197
303
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
The only uses of this function are for loading VFP
4
an array of qemu_irq and passing it around, directly call
4
double-precision values, and nothing to do with NEON.
5
qdev_get_gpio_in() on the gic field.
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20201030022618.785675-10-richard.henderson@linaro.org
8
Message-id: 20191206162303.30338-1-philmd@redhat.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/arm/sbsa-ref.c | 86 +++++++++++++++++++++++------------------------
11
target/arm/translate.c | 8 ++--
13
1 file changed, 42 insertions(+), 44 deletions(-)
12
target/arm/translate-vfp.c.inc | 84 +++++++++++++++++-----------------
14
13
2 files changed, 46 insertions(+), 46 deletions(-)
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
14
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
17
--- a/target/arm/translate.c
18
+++ b/hw/arm/sbsa-ref.c
18
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct {
19
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
20
void *fdt;
20
}
21
int fdt_size;
22
int psci_conduit;
23
+ DeviceState *gic;
24
PFlashCFI01 *flash[2];
25
} SBSAMachineState;
26
27
@@ -XXX,XX +XXX,XX @@ static void create_secure_ram(SBSAMachineState *sms,
28
memory_region_add_subregion(secure_sysmem, base, secram);
29
}
21
}
30
22
31
-static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
23
-static inline void neon_load_reg64(TCGv_i64 var, int reg)
32
+static void create_gic(SBSAMachineState *sms)
24
+static inline void vfp_load_reg64(TCGv_i64 var, int reg)
33
{
25
{
34
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
26
- tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
35
- DeviceState *gicdev;
27
+ tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
36
SysBusDevice *gicbusdev;
37
const char *gictype;
38
uint32_t redist0_capacity, redist0_count;
39
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
40
41
gictype = gicv3_class_name();
42
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
}
28
}
102
29
103
-static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
30
-static inline void neon_store_reg64(TCGv_i64 var, int reg)
104
+static void create_uart(const SBSAMachineState *sms, int uart,
31
+static inline void vfp_store_reg64(TCGv_i64 var, int reg)
105
MemoryRegion *mem, Chardev *chr)
106
{
32
{
107
hwaddr base = sbsa_ref_memmap[uart].base;
33
- tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
108
@@ -XXX,XX +XXX,XX @@ static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
34
+ tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
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
}
35
}
115
36
116
-static void create_rtc(const SBSAMachineState *sms, qemu_irq *pic)
37
static inline void vfp_load_reg32(TCGv_i32 var, int reg)
117
+static void create_rtc(const SBSAMachineState *sms)
38
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
118
{
39
index XXXXXXX..XXXXXXX 100644
119
hwaddr base = sbsa_ref_memmap[SBSA_RTC].base;
40
--- a/target/arm/translate-vfp.c.inc
120
int irq = sbsa_ref_irqmap[SBSA_RTC];
41
+++ b/target/arm/translate-vfp.c.inc
121
42
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
122
- sysbus_create_simple("pl031", base, pic[irq]);
43
tcg_gen_ext_i32_i64(nf, cpu_NF);
123
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(sms->gic, irq));
44
tcg_gen_ext_i32_i64(vf, cpu_VF);
124
}
45
125
46
- neon_load_reg64(frn, rn);
126
static DeviceState *gpio_key_dev;
47
- neon_load_reg64(frm, rm);
127
@@ -XXX,XX +XXX,XX @@ static Notifier sbsa_ref_powerdown_notifier = {
48
+ vfp_load_reg64(frn, rn);
128
.notify = sbsa_ref_powerdown_req
49
+ vfp_load_reg64(frm, rm);
129
};
50
switch (a->cc) {
130
51
case 0: /* eq: Z */
131
-static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
52
tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
132
+static void create_gpio(const SBSAMachineState *sms)
53
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
133
{
54
tcg_temp_free_i64(tmp);
134
DeviceState *pl061_dev;
55
break;
135
hwaddr base = sbsa_ref_memmap[SBSA_GPIO].base;
56
}
136
int irq = sbsa_ref_irqmap[SBSA_GPIO];
57
- neon_store_reg64(dest, rd);
137
58
+ vfp_store_reg64(dest, rd);
138
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
59
tcg_temp_free_i64(frn);
139
+ pl061_dev = sysbus_create_simple("pl061", base,
60
tcg_temp_free_i64(frm);
140
+ qdev_get_gpio_in(sms->gic, irq));
61
tcg_temp_free_i64(dest);
141
62
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
142
gpio_key_dev = sysbus_create_simple("gpio-key", -1,
63
TCGv_i64 tcg_res;
143
qdev_get_gpio_in(pl061_dev, 3));
64
tcg_op = tcg_temp_new_i64();
144
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
65
tcg_res = tcg_temp_new_i64();
145
qemu_register_powerdown_notifier(&sbsa_ref_powerdown_notifier);
66
- neon_load_reg64(tcg_op, rm);
146
}
67
+ vfp_load_reg64(tcg_op, rm);
147
68
gen_helper_rintd(tcg_res, tcg_op, fpst);
148
-static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
69
- neon_store_reg64(tcg_res, rd);
149
+static void create_ahci(const SBSAMachineState *sms)
70
+ vfp_store_reg64(tcg_res, rd);
150
{
71
tcg_temp_free_i64(tcg_op);
151
hwaddr base = sbsa_ref_memmap[SBSA_AHCI].base;
72
tcg_temp_free_i64(tcg_res);
152
int irq = sbsa_ref_irqmap[SBSA_AHCI];
73
} else {
153
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
154
qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS);
75
tcg_double = tcg_temp_new_i64();
155
qdev_init_nofail(dev);
76
tcg_res = tcg_temp_new_i64();
156
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
77
tcg_tmp = tcg_temp_new_i32();
157
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
78
- neon_load_reg64(tcg_double, rm);
158
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
79
+ vfp_load_reg64(tcg_double, rm);
159
80
if (is_signed) {
160
sysahci = SYSBUS_AHCI(dev);
81
gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
161
ahci = &sysahci->ahci;
82
} else {
162
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
163
}
84
tmp = tcg_temp_new_i64();
164
}
85
if (a->l) {
165
86
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
166
-static void create_ehci(const SBSAMachineState *sms, qemu_irq *pic)
87
- neon_store_reg64(tmp, a->vd);
167
+static void create_ehci(const SBSAMachineState *sms)
88
+ vfp_store_reg64(tmp, a->vd);
168
{
89
} else {
169
hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
90
- neon_load_reg64(tmp, a->vd);
170
int irq = sbsa_ref_irqmap[SBSA_EHCI];
91
+ vfp_load_reg64(tmp, a->vd);
171
92
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
172
- sysbus_create_simple("platform-ehci-usb", base, pic[irq]);
93
}
173
+ sysbus_create_simple("platform-ehci-usb", base,
94
tcg_temp_free_i64(tmp);
174
+ qdev_get_gpio_in(sms->gic, irq));
95
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
175
}
96
if (a->l) {
176
97
/* load */
177
-static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
98
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
178
- PCIBus *bus)
99
- neon_store_reg64(tmp, a->vd + i);
179
+static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
100
+ vfp_store_reg64(tmp, a->vd + i);
180
{
101
} else {
181
hwaddr base = sbsa_ref_memmap[SBSA_SMMU].base;
102
/* store */
182
int irq = sbsa_ref_irqmap[SBSA_SMMU];
103
- neon_load_reg64(tmp, a->vd + i);
183
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
104
+ vfp_load_reg64(tmp, a->vd + i);
184
qdev_init_nofail(dev);
105
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
185
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
106
}
186
for (i = 0; i < NUM_SMMU_IRQS; i++) {
107
tcg_gen_addi_i32(addr, addr, offset);
187
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
108
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
188
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
109
fd = tcg_temp_new_i64();
189
+ qdev_get_gpio_in(sms->gic, irq + 1));
110
fpst = fpstatus_ptr(FPST_FPCR);
190
}
111
191
}
112
- neon_load_reg64(f0, vn);
192
113
- neon_load_reg64(f1, vm);
193
-static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
114
+ vfp_load_reg64(f0, vn);
194
+static void create_pcie(SBSAMachineState *sms)
115
+ vfp_load_reg64(f1, vm);
195
{
116
196
hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base;
117
for (;;) {
197
hwaddr size_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].size;
118
if (reads_vd) {
198
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
119
- neon_load_reg64(fd, vd);
199
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
120
+ vfp_load_reg64(fd, vd);
200
121
}
201
for (i = 0; i < GPEX_NUM_IRQS; i++) {
122
fn(fd, f0, f1, fpst);
202
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
123
- neon_store_reg64(fd, vd);
203
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
124
+ vfp_store_reg64(fd, vd);
204
+ qdev_get_gpio_in(sms->gic, irq + 1));
125
205
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
126
if (veclen == 0) {
206
}
127
break;
207
128
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
208
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
129
veclen--;
209
130
vd = vfp_advance_dreg(vd, delta_d);
210
pci_create_simple(pci->bus, -1, "VGA");
131
vn = vfp_advance_dreg(vn, delta_d);
211
132
- neon_load_reg64(f0, vn);
212
- create_smmu(sms, pic, pci->bus);
133
+ vfp_load_reg64(f0, vn);
213
+ create_smmu(sms, pci->bus);
134
if (delta_m) {
214
}
135
vm = vfp_advance_dreg(vm, delta_m);
215
136
- neon_load_reg64(f1, vm);
216
static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
137
+ vfp_load_reg64(f1, vm);
217
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
138
}
218
bool firmware_loaded;
139
}
219
const CPUArchIdList *possible_cpus;
140
220
int n, sbsa_max_cpus;
141
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
221
- qemu_irq pic[NUM_IRQS];
142
f0 = tcg_temp_new_i64();
222
143
fd = tcg_temp_new_i64();
223
if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) {
144
224
error_report("sbsa-ref: CPU type other than the built-in "
145
- neon_load_reg64(f0, vm);
225
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
146
+ vfp_load_reg64(f0, vm);
226
147
227
create_secure_ram(sms, secure_sysmem);
148
for (;;) {
228
149
fn(fd, f0);
229
- create_gic(sms, pic);
150
- neon_store_reg64(fd, vd);
230
+ create_gic(sms);
151
+ vfp_store_reg64(fd, vd);
231
152
232
- create_uart(sms, pic, SBSA_UART, sysmem, serial_hd(0));
153
if (veclen == 0) {
233
- create_uart(sms, pic, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
154
break;
234
+ create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
155
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
235
+ create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
156
/* single source one-many */
236
/* Second secure UART for RAS and MM from EL0 */
157
while (veclen--) {
237
- create_uart(sms, pic, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
158
vd = vfp_advance_dreg(vd, delta_d);
238
+ create_uart(sms, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
159
- neon_store_reg64(fd, vd);
239
160
+ vfp_store_reg64(fd, vd);
240
- create_rtc(sms, pic);
161
}
241
+ create_rtc(sms);
162
break;
242
163
}
243
- create_gpio(sms, pic);
164
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
244
+ create_gpio(sms);
165
veclen--;
245
166
vd = vfp_advance_dreg(vd, delta_d);
246
- create_ahci(sms, pic);
167
vd = vfp_advance_dreg(vm, delta_m);
247
+ create_ahci(sms);
168
- neon_load_reg64(f0, vm);
248
169
+ vfp_load_reg64(f0, vm);
249
- create_ehci(sms, pic);
170
}
250
+ create_ehci(sms);
171
251
172
tcg_temp_free_i64(f0);
252
- create_pcie(sms, pic);
173
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
253
+ create_pcie(sms);
174
vm = tcg_temp_new_i64();
254
175
vd = tcg_temp_new_i64();
255
sms->bootinfo.ram_size = machine->ram_size;
176
256
sms->bootinfo.nb_cpus = smp_cpus;
177
- neon_load_reg64(vn, a->vn);
178
- neon_load_reg64(vm, a->vm);
179
+ vfp_load_reg64(vn, a->vn);
180
+ vfp_load_reg64(vm, a->vm);
181
if (neg_n) {
182
/* VFNMS, VFMS */
183
gen_helper_vfp_negd(vn, vn);
184
}
185
- neon_load_reg64(vd, a->vd);
186
+ vfp_load_reg64(vd, a->vd);
187
if (neg_d) {
188
/* VFNMA, VFNMS */
189
gen_helper_vfp_negd(vd, vd);
190
}
191
fpst = fpstatus_ptr(FPST_FPCR);
192
gen_helper_vfp_muladdd(vd, vn, vm, vd, fpst);
193
- neon_store_reg64(vd, a->vd);
194
+ vfp_store_reg64(vd, a->vd);
195
196
tcg_temp_free_ptr(fpst);
197
tcg_temp_free_i64(vn);
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
199
fd = tcg_const_i64(vfp_expand_imm(MO_64, a->imm));
200
201
for (;;) {
202
- neon_store_reg64(fd, vd);
203
+ vfp_store_reg64(fd, vd);
204
205
if (veclen == 0) {
206
break;
207
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
208
vd = tcg_temp_new_i64();
209
vm = tcg_temp_new_i64();
210
211
- neon_load_reg64(vd, a->vd);
212
+ vfp_load_reg64(vd, a->vd);
213
if (a->z) {
214
tcg_gen_movi_i64(vm, 0);
215
} else {
216
- neon_load_reg64(vm, a->vm);
217
+ vfp_load_reg64(vm, a->vm);
218
}
219
220
if (a->e) {
221
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
222
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
223
vd = tcg_temp_new_i64();
224
gen_helper_vfp_fcvt_f16_to_f64(vd, tmp, fpst, ahp_mode);
225
- neon_store_reg64(vd, a->vd);
226
+ vfp_store_reg64(vd, a->vd);
227
tcg_temp_free_i32(ahp_mode);
228
tcg_temp_free_ptr(fpst);
229
tcg_temp_free_i32(tmp);
230
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
231
tmp = tcg_temp_new_i32();
232
vm = tcg_temp_new_i64();
233
234
- neon_load_reg64(vm, a->vm);
235
+ vfp_load_reg64(vm, a->vm);
236
gen_helper_vfp_fcvt_f64_to_f16(tmp, vm, fpst, ahp_mode);
237
tcg_temp_free_i64(vm);
238
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
239
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
240
}
241
242
tmp = tcg_temp_new_i64();
243
- neon_load_reg64(tmp, a->vm);
244
+ vfp_load_reg64(tmp, a->vm);
245
fpst = fpstatus_ptr(FPST_FPCR);
246
gen_helper_rintd(tmp, tmp, fpst);
247
- neon_store_reg64(tmp, a->vd);
248
+ vfp_store_reg64(tmp, a->vd);
249
tcg_temp_free_ptr(fpst);
250
tcg_temp_free_i64(tmp);
251
return true;
252
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
253
}
254
255
tmp = tcg_temp_new_i64();
256
- neon_load_reg64(tmp, a->vm);
257
+ vfp_load_reg64(tmp, a->vm);
258
fpst = fpstatus_ptr(FPST_FPCR);
259
tcg_rmode = tcg_const_i32(float_round_to_zero);
260
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
261
gen_helper_rintd(tmp, tmp, fpst);
262
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
263
- neon_store_reg64(tmp, a->vd);
264
+ vfp_store_reg64(tmp, a->vd);
265
tcg_temp_free_ptr(fpst);
266
tcg_temp_free_i64(tmp);
267
tcg_temp_free_i32(tcg_rmode);
268
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
269
}
270
271
tmp = tcg_temp_new_i64();
272
- neon_load_reg64(tmp, a->vm);
273
+ vfp_load_reg64(tmp, a->vm);
274
fpst = fpstatus_ptr(FPST_FPCR);
275
gen_helper_rintd_exact(tmp, tmp, fpst);
276
- neon_store_reg64(tmp, a->vd);
277
+ vfp_store_reg64(tmp, a->vd);
278
tcg_temp_free_ptr(fpst);
279
tcg_temp_free_i64(tmp);
280
return true;
281
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
282
vd = tcg_temp_new_i64();
283
vfp_load_reg32(vm, a->vm);
284
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
285
- neon_store_reg64(vd, a->vd);
286
+ vfp_store_reg64(vd, a->vd);
287
tcg_temp_free_i32(vm);
288
tcg_temp_free_i64(vd);
289
return true;
290
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
291
292
vd = tcg_temp_new_i32();
293
vm = tcg_temp_new_i64();
294
- neon_load_reg64(vm, a->vm);
295
+ vfp_load_reg64(vm, a->vm);
296
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
297
vfp_store_reg32(vd, a->vd);
298
tcg_temp_free_i32(vd);
299
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
300
/* u32 -> f64 */
301
gen_helper_vfp_uitod(vd, vm, fpst);
302
}
303
- neon_store_reg64(vd, a->vd);
304
+ vfp_store_reg64(vd, a->vd);
305
tcg_temp_free_i32(vm);
306
tcg_temp_free_i64(vd);
307
tcg_temp_free_ptr(fpst);
308
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
309
310
vm = tcg_temp_new_i64();
311
vd = tcg_temp_new_i32();
312
- neon_load_reg64(vm, a->vm);
313
+ vfp_load_reg64(vm, a->vm);
314
gen_helper_vjcvt(vd, vm, cpu_env);
315
vfp_store_reg32(vd, a->vd);
316
tcg_temp_free_i64(vm);
317
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
318
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
319
320
vd = tcg_temp_new_i64();
321
- neon_load_reg64(vd, a->vd);
322
+ vfp_load_reg64(vd, a->vd);
323
324
fpst = fpstatus_ptr(FPST_FPCR);
325
shift = tcg_const_i32(frac_bits);
326
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
327
g_assert_not_reached();
328
}
329
330
- neon_store_reg64(vd, a->vd);
331
+ vfp_store_reg64(vd, a->vd);
332
tcg_temp_free_i64(vd);
333
tcg_temp_free_i32(shift);
334
tcg_temp_free_ptr(fpst);
335
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
336
fpst = fpstatus_ptr(FPST_FPCR);
337
vm = tcg_temp_new_i64();
338
vd = tcg_temp_new_i32();
339
- neon_load_reg64(vm, a->vm);
340
+ vfp_load_reg64(vm, a->vm);
341
342
if (a->s) {
343
if (a->rz) {
257
--
344
--
258
2.20.1
345
2.20.1
259
346
260
347
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Switch to ram block writeback for pmem migration.
3
In both cases, we can sink the write-back and perform
4
the accumulate into the normal destination temps.
4
5
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-11-richard.henderson@linaro.org
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Peter Maydell <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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
migration/ram.c | 5 +----
11
target/arm/translate-neon.c.inc | 23 +++++++++--------------
13
1 file changed, 1 insertion(+), 4 deletions(-)
12
1 file changed, 9 insertions(+), 14 deletions(-)
14
13
15
diff --git a/migration/ram.c b/migration/ram.c
14
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/migration/ram.c
16
--- a/target/arm/translate-neon.c.inc
18
+++ b/migration/ram.c
17
+++ b/target/arm/translate-neon.c.inc
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
20
#include "qemu/bitops.h"
19
if (accfn) {
21
#include "qemu/bitmap.h"
20
tmp = tcg_temp_new_i64();
22
#include "qemu/main-loop.h"
21
read_neon_element64(tmp, a->vd, 0, MO_64);
23
-#include "qemu/pmem.h"
22
- accfn(tmp, tmp, rd0);
24
#include "xbzrle.h"
23
- write_neon_element64(tmp, a->vd, 0, MO_64);
25
#include "ram.h"
24
+ accfn(rd0, tmp, rd0);
26
#include "migration.h"
25
read_neon_element64(tmp, a->vd, 1, MO_64);
27
@@ -XXX,XX +XXX,XX @@ static int ram_load_cleanup(void *opaque)
26
- accfn(tmp, tmp, rd1);
28
RAMBlock *rb;
27
- write_neon_element64(tmp, a->vd, 1, MO_64);
29
28
+ accfn(rd1, tmp, rd1);
30
RAMBLOCK_FOREACH_NOT_IGNORED(rb) {
29
tcg_temp_free_i64(tmp);
31
- if (ramblock_is_pmem(rb)) {
30
- } else {
32
- pmem_persist(rb->host, rb->used_length);
31
- write_neon_element64(rd0, a->vd, 0, MO_64);
33
- }
32
- write_neon_element64(rd1, a->vd, 1, MO_64);
34
+ qemu_ram_block_writeback(rb);
35
}
33
}
36
34
37
xbzrle_load_cleanup();
35
+ write_neon_element64(rd0, a->vd, 0, MO_64);
36
+ write_neon_element64(rd1, a->vd, 1, MO_64);
37
tcg_temp_free_i64(rd0);
38
tcg_temp_free_i64(rd1);
39
40
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
41
if (accfn) {
42
TCGv_i64 t64 = tcg_temp_new_i64();
43
read_neon_element64(t64, a->vd, 0, MO_64);
44
- accfn(t64, t64, rn0_64);
45
- write_neon_element64(t64, a->vd, 0, MO_64);
46
+ accfn(rn0_64, t64, rn0_64);
47
read_neon_element64(t64, a->vd, 1, MO_64);
48
- accfn(t64, t64, rn1_64);
49
- write_neon_element64(t64, a->vd, 1, MO_64);
50
+ accfn(rn1_64, t64, rn1_64);
51
tcg_temp_free_i64(t64);
52
- } else {
53
- write_neon_element64(rn0_64, a->vd, 0, MO_64);
54
- write_neon_element64(rn1_64, a->vd, 1, MO_64);
55
}
56
+
57
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
58
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
59
tcg_temp_free_i64(rn0_64);
60
tcg_temp_free_i64(rn1_64);
61
return true;
38
--
62
--
39
2.20.1
63
2.20.1
40
64
41
65
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The Aspeed Watchdog and Timer models have a link pointing to the SCU
3
We can use proper widening loads to extend 32-bit inputs,
4
controller model of the machine.
4
and skip the "widenfn" step.
5
5
6
Change the "scu" property definition so that it explicitly sets the
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
pointer. The property isn't optional : not being able to set the link
7
Message-id: 20201030022618.785675-12-richard.henderson@linaro.org
8
is a bug and QEMU should rather abort than exit in this case.
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
hw/arm/aspeed_ast2600.c | 8 ++++----
11
target/arm/translate.c | 6 +++
18
hw/arm/aspeed_soc.c | 8 ++++----
12
target/arm/translate-neon.c.inc | 66 ++++++++++++++++++---------------
19
hw/timer/aspeed_timer.c | 17 +++++++++--------
13
2 files changed, 43 insertions(+), 29 deletions(-)
20
hw/watchdog/wdt_aspeed.c | 17 ++++++++---------
21
4 files changed, 25 insertions(+), 25 deletions(-)
22
14
23
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/aspeed_ast2600.c
17
--- a/target/arm/translate.c
26
+++ b/hw/arm/aspeed_ast2600.c
18
+++ b/target/arm/translate.c
27
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
19
@@ -XXX,XX +XXX,XX @@ static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
28
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
20
long off = neon_element_offset(reg, ele, memop);
29
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
21
30
sizeof(s->timerctrl), typename);
22
switch (memop) {
31
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
23
+ case MO_SL:
32
- OBJECT(&s->scu), &error_abort);
24
+ tcg_gen_ld32s_i64(dest, cpu_env, off);
33
25
+ break;
34
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
26
+ case MO_UL:
35
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
27
+ tcg_gen_ld32u_i64(dest, cpu_env, off);
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
28
+ break;
37
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
29
case MO_Q:
38
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
30
tcg_gen_ld_i64(dest, cpu_env, off);
39
sizeof(s->wdt[i]), typename);
31
break;
40
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
32
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
41
- OBJECT(&s->scu), &error_abort);
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.c.inc
35
+++ b/target/arm/translate-neon.c.inc
36
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1reg_imm *a)
37
static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
38
NeonGenWidenFn *widenfn,
39
NeonGenTwo64OpFn *opfn,
40
- bool src1_wide)
41
+ int src1_mop, int src2_mop)
42
{
43
/* 3-regs different lengths, prewidening case (VADDL/VSUBL/VAADW/VSUBW) */
44
TCGv_i64 rn0_64, rn1_64, rm_64;
45
- TCGv_i32 rm;
46
47
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
48
return false;
49
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
50
return false;
42
}
51
}
43
52
44
for (i = 0; i < sc->macs_num; i++) {
53
- if (!widenfn || !opfn) {
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
54
+ if (!opfn) {
46
aspeed_soc_get_irq(s, ASPEED_RTC));
55
/* size == 3 case, which is an entirely different insn group */
47
56
return false;
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
}
57
}
83
58
84
for (i = 0; i < sc->macs_num; i++) {
59
- if ((a->vd & 1) || (src1_wide && (a->vn & 1))) {
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
60
+ if ((a->vd & 1) || (src1_mop == MO_Q && (a->vn & 1))) {
86
aspeed_soc_get_irq(s, ASPEED_RTC));
61
return false;
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 @@
108
#include "qemu/timer.h"
109
#include "qemu/log.h"
110
#include "qemu/module.h"
111
+#include "hw/qdev-properties.h"
112
#include "trace.h"
113
114
#define TIMER_NR_REGS 4
115
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_realize(DeviceState *dev, Error **errp)
116
int i;
117
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
118
AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
119
- Object *obj;
120
- Error *err = NULL;
121
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
}
62
}
134
};
63
135
64
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
136
+static Property aspeed_timer_properties[] = {
65
rn1_64 = tcg_temp_new_i64();
137
+ DEFINE_PROP_LINK("scu", AspeedTimerCtrlState, scu, TYPE_ASPEED_SCU,
66
rm_64 = tcg_temp_new_i64();
138
+ AspeedSCUState *),
67
139
+ DEFINE_PROP_END_OF_LIST(),
68
- if (src1_wide) {
140
+};
69
- read_neon_element64(rn0_64, a->vn, 0, MO_64);
141
+
70
+ if (src1_mop >= 0) {
142
static void timer_class_init(ObjectClass *klass, void *data)
71
+ read_neon_element64(rn0_64, a->vn, 0, src1_mop);
143
{
72
} else {
144
DeviceClass *dc = DEVICE_CLASS(klass);
73
TCGv_i32 tmp = tcg_temp_new_i32();
145
@@ -XXX,XX +XXX,XX @@ static void timer_class_init(ObjectClass *klass, void *data)
74
read_neon_element32(tmp, a->vn, 0, MO_32);
146
dc->reset = aspeed_timer_reset;
75
widenfn(rn0_64, tmp);
147
dc->desc = "ASPEED Timer";
76
tcg_temp_free_i32(tmp);
148
dc->vmsd = &vmstate_aspeed_timer_state;
77
}
149
+ dc->props = aspeed_timer_properties;
78
- rm = tcg_temp_new_i32();
79
- read_neon_element32(rm, a->vm, 0, MO_32);
80
+ if (src2_mop >= 0) {
81
+ read_neon_element64(rm_64, a->vm, 0, src2_mop);
82
+ } else {
83
+ TCGv_i32 tmp = tcg_temp_new_i32();
84
+ read_neon_element32(tmp, a->vm, 0, MO_32);
85
+ widenfn(rm_64, tmp);
86
+ tcg_temp_free_i32(tmp);
87
+ }
88
89
- widenfn(rm_64, rm);
90
- tcg_temp_free_i32(rm);
91
opfn(rn0_64, rn0_64, rm_64);
92
93
/*
94
* Load second pass inputs before storing the first pass result, to
95
* avoid incorrect results if a narrow input overlaps with the result.
96
*/
97
- if (src1_wide) {
98
- read_neon_element64(rn1_64, a->vn, 1, MO_64);
99
+ if (src1_mop >= 0) {
100
+ read_neon_element64(rn1_64, a->vn, 1, src1_mop);
101
} else {
102
TCGv_i32 tmp = tcg_temp_new_i32();
103
read_neon_element32(tmp, a->vn, 1, MO_32);
104
widenfn(rn1_64, tmp);
105
tcg_temp_free_i32(tmp);
106
}
107
- rm = tcg_temp_new_i32();
108
- read_neon_element32(rm, a->vm, 1, MO_32);
109
+ if (src2_mop >= 0) {
110
+ read_neon_element64(rm_64, a->vm, 1, src2_mop);
111
+ } else {
112
+ TCGv_i32 tmp = tcg_temp_new_i32();
113
+ read_neon_element32(tmp, a->vm, 1, MO_32);
114
+ widenfn(rm_64, tmp);
115
+ tcg_temp_free_i32(tmp);
116
+ }
117
118
write_neon_element64(rn0_64, a->vd, 0, MO_64);
119
120
- widenfn(rm_64, rm);
121
- tcg_temp_free_i32(rm);
122
opfn(rn1_64, rn1_64, rm_64);
123
write_neon_element64(rn1_64, a->vd, 1, MO_64);
124
125
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
126
return true;
150
}
127
}
151
128
152
static const TypeInfo aspeed_timer_info = {
129
-#define DO_PREWIDEN(INSN, S, EXT, OP, SRC1WIDE) \
153
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
130
+#define DO_PREWIDEN(INSN, S, OP, SRC1WIDE, SIGN) \
154
index XXXXXXX..XXXXXXX 100644
131
static bool trans_##INSN##_3d(DisasContext *s, arg_3diff *a) \
155
--- a/hw/watchdog/wdt_aspeed.c
132
{ \
156
+++ b/hw/watchdog/wdt_aspeed.c
133
static NeonGenWidenFn * const widenfn[] = { \
157
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
134
gen_helper_neon_widen_##S##8, \
158
{
135
gen_helper_neon_widen_##S##16, \
159
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
136
- tcg_gen_##EXT##_i32_i64, \
160
AspeedWDTState *s = ASPEED_WDT(dev);
137
- NULL, \
161
- Error *err = NULL;
138
+ NULL, NULL, \
162
- Object *obj;
139
}; \
163
140
static NeonGenTwo64OpFn * const addfn[] = { \
164
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
141
gen_helper_neon_##OP##l_u16, \
165
- if (!obj) {
142
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
166
- error_propagate(errp, err);
143
tcg_gen_##OP##_i64, \
167
- error_prepend(errp, "required link 'scu' not found: ");
144
NULL, \
168
- return;
145
}; \
169
- }
146
- return do_prewiden_3d(s, a, widenfn[a->size], \
170
- s->scu = ASPEED_SCU(obj);
147
- addfn[a->size], SRC1WIDE); \
171
+ assert(s->scu);
148
+ int narrow_mop = a->size == MO_32 ? MO_32 | SIGN : -1; \
172
149
+ return do_prewiden_3d(s, a, widenfn[a->size], addfn[a->size], \
173
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, aspeed_wdt_timer_expired, dev);
150
+ SRC1WIDE ? MO_Q : narrow_mop, \
174
151
+ narrow_mop); \
175
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
152
}
176
sysbus_init_mmio(sbd, &s->iomem);
153
177
}
154
-DO_PREWIDEN(VADDL_S, s, ext, add, false)
178
155
-DO_PREWIDEN(VADDL_U, u, extu, add, false)
179
+static Property aspeed_wdt_properties[] = {
156
-DO_PREWIDEN(VSUBL_S, s, ext, sub, false)
180
+ DEFINE_PROP_LINK("scu", AspeedWDTState, scu, TYPE_ASPEED_SCU,
157
-DO_PREWIDEN(VSUBL_U, u, extu, sub, false)
181
+ AspeedSCUState *),
158
-DO_PREWIDEN(VADDW_S, s, ext, add, true)
182
+ DEFINE_PROP_END_OF_LIST(),
159
-DO_PREWIDEN(VADDW_U, u, extu, add, true)
183
+};
160
-DO_PREWIDEN(VSUBW_S, s, ext, sub, true)
184
+
161
-DO_PREWIDEN(VSUBW_U, u, extu, sub, true)
185
static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
162
+DO_PREWIDEN(VADDL_S, s, add, false, MO_SIGN)
186
{
163
+DO_PREWIDEN(VADDL_U, u, add, false, 0)
187
DeviceClass *dc = DEVICE_CLASS(klass);
164
+DO_PREWIDEN(VSUBL_S, s, sub, false, MO_SIGN)
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
165
+DO_PREWIDEN(VSUBL_U, u, sub, false, 0)
189
dc->reset = aspeed_wdt_reset;
166
+DO_PREWIDEN(VADDW_S, s, add, true, MO_SIGN)
190
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
167
+DO_PREWIDEN(VADDW_U, u, add, true, 0)
191
dc->vmsd = &vmstate_aspeed_wdt;
168
+DO_PREWIDEN(VSUBW_S, s, sub, true, MO_SIGN)
192
+ dc->props = aspeed_wdt_properties;
169
+DO_PREWIDEN(VSUBW_U, u, sub, true, 0)
193
}
170
194
171
static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
195
static const TypeInfo aspeed_wdt_info = {
172
NeonGenTwo64OpFn *opfn, NeonGenNarrowFn *narrowfn)
196
--
173
--
197
2.20.1
174
2.20.1
198
175
199
176
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
In the neon_padd/pmax/pmin helpers for float16, a cut-and-paste error
2
meant we were using the H4() address swizzler macro rather than the
3
H2() which is required for 2-byte data. This had no effect on
4
little-endian hosts but meant we put the result data into the
5
destination Dreg in the wrong order on big-endian hosts.
2
6
3
The Aspeed MII model has a link pointing to its associated FTGMAC100
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
NIC in the machine.
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20201028191712.4910-2-peter.maydell@linaro.org
11
---
12
target/arm/vec_helper.c | 8 ++++----
13
1 file changed, 4 insertions(+), 4 deletions(-)
5
14
6
Change the "nic" property definition so that it explicitly sets the
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
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-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
16
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/aspeed_ast2600.c
17
--- a/target/arm/vec_helper.c
24
+++ b/hw/arm/aspeed_ast2600.c
18
+++ b/target/arm/vec_helper.c
25
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
19
@@ -XXX,XX +XXX,XX @@ DO_ABA(gvec_uaba_d, uint64_t)
26
20
r2 = float16_##OP(m[H2(0)], m[H2(1)], fpst); \
27
sysbus_init_child_obj(obj, "mii[*]", &s->mii[i], sizeof(s->mii[i]),
21
r3 = float16_##OP(m[H2(2)], m[H2(3)], fpst); \
28
TYPE_ASPEED_MII);
22
\
29
- object_property_add_const_link(OBJECT(&s->mii[i]), "nic",
23
- d[H4(0)] = r0; \
30
- OBJECT(&s->ftgmac100[i]),
24
- d[H4(1)] = r1; \
31
- &error_abort);
25
- d[H4(2)] = r2; \
26
- d[H4(3)] = r3; \
27
+ d[H2(0)] = r0; \
28
+ d[H2(1)] = r1; \
29
+ d[H2(2)] = r2; \
30
+ d[H2(3)] = r3; \
32
}
31
}
33
32
34
sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
33
DO_NEON_PAIRWISE(neon_padd, add)
35
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
36
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
37
aspeed_soc_get_irq(s, ASPEED_ETH1 + i));
38
39
+ object_property_set_link(OBJECT(&s->mii[i]), OBJECT(&s->ftgmac100[i]),
40
+ "nic", &error_abort);
41
object_property_set_bool(OBJECT(&s->mii[i]), true, "realized",
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
}
70
};
71
+
72
+static Property aspeed_mii_properties[] = {
73
+ DEFINE_PROP_LINK("nic", AspeedMiiState, nic, TYPE_FTGMAC100,
74
+ FTGMAC100State *),
75
+ DEFINE_PROP_END_OF_LIST(),
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
}
87
88
static const TypeInfo aspeed_mii_info = {
89
--
34
--
90
2.20.1
35
2.20.1
91
36
92
37
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
The helper functions for performing the udot/sdot operations against
2
a scalar were not using an address-swizzling macro when converting
3
the index of the scalar element into a pointer into the vm array.
4
This had no effect on little-endian hosts but meant we generated
5
incorrect results on big-endian hosts.
2
6
3
After the introduction of generic PCIe root port and PCIe-PCI bridge,
7
For these insns, the index is indexing over group of 4 8-bit values,
4
we will also have SHPC controller on ARM, so just enable SHPC native
8
so 32 bits per indexed entity, and H4() is therefore what we want.
5
hot plug.
9
(For Neon the only possible input indexes are 0 and 1.)
6
10
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20201028191712.4910-3-peter.maydell@linaro.org
15
---
16
target/arm/vec_helper.c | 4 ++--
17
1 file changed, 2 insertions(+), 2 deletions(-)
8
18
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
19
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
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
20
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
21
--- a/target/arm/vec_helper.c
28
+++ b/hw/arm/virt-acpi-build.c
22
+++ b/target/arm/vec_helper.c
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
23
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
24
intptr_t index = simd_data(desc);
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
25
uint32_t *d = vd;
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
26
int8_t *n = vn;
33
- aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
27
- int8_t *m_indexed = (int8_t *)vm + index * 4;
34
+
28
+ int8_t *m_indexed = (int8_t *)vm + H4(index) * 4;
35
+ /*
29
36
+ * Allow OS control for all 5 features:
30
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
37
+ * PCIeHotplug SHPCHotplug PME AER PCIeCapability.
31
* Otherwise opr_sz is a multiple of 16.
38
+ */
32
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
39
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F),
33
intptr_t index = simd_data(desc);
40
aml_name("CTRL")));
34
uint32_t *d = vd;
41
35
uint8_t *n = vn;
42
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
36
- uint8_t *m_indexed = (uint8_t *)vm + index * 4;
43
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
37
+ uint8_t *m_indexed = (uint8_t *)vm + H4(index) * 4;
44
index XXXXXXX..XXXXXXX 100644
38
45
GIT binary patch
39
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
46
delta 28
40
* Otherwise opr_sz is a multiple of 16.
47
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
48
49
delta 28
50
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
51
52
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
53
index XXXXXXX..XXXXXXX 100644
54
GIT binary patch
55
delta 28
56
kcmcaUi}Cs_MlP3NmymE@1_mbija=*8809zbbeqQp0Eq|*2mk;8
57
58
delta 28
59
kcmcaUi}Cs_MlP3NmymE@1_ma@ja=*87-cu_beqQp0ErX{2mk;8
60
61
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
62
index XXXXXXX..XXXXXXX 100644
63
GIT binary patch
64
delta 28
65
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
66
67
delta 28
68
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
69
70
--
41
--
71
2.20.1
42
2.20.1
72
43
73
44
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
2
2
3
QEMU lacks the minimum Jazelle implementation that is required
3
HCR should be applied when NS is set, not when it is cleared.
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: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20191201122018.25808-6-maz@kernel.org
11
[PMM: moved ARMCPRegInfo array to file scope, marked it
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>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
8
---
17
target/arm/helper.c | 27 +++++++++++++++++++++++++++
9
target/arm/helper.c | 5 ++---
18
1 file changed, 27 insertions(+)
10
1 file changed, 2 insertions(+), 3 deletions(-)
19
11
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
14
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
15
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
16
@@ -XXX,XX +XXX,XX @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
25
return CP_ACCESS_OK;
17
18
/*
19
* Non-IS variants of TLB operations are upgraded to
20
- * IS versions if we are at NS EL1 and HCR_EL2.FB is set to
21
+ * IS versions if we are at EL1 and HCR_EL2.FB is effectively set to
22
* force broadcast of these operations.
23
*/
24
static bool tlb_force_broadcast(CPUARMState *env)
25
{
26
- return (env->cp15.hcr_el2 & HCR_FB) &&
27
- arm_current_el(env) == 1 && arm_is_secure_below_el3(env);
28
+ return arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_FB);
26
}
29
}
27
30
28
+static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
31
static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
29
+ bool isread)
30
+{
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID0)) {
32
+ return CP_ACCESS_TRAP_EL2;
33
+ }
34
+
35
+ return CP_ACCESS_OK;
36
+}
37
+
38
+static const ARMCPRegInfo jazelle_regs[] = {
39
+ { .name = "JIDR",
40
+ .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
41
+ .access = PL1_R, .accessfn = access_jazelle,
42
+ .type = ARM_CP_CONST, .resetvalue = 0 },
43
+ { .name = "JOSCR",
44
+ .cp = 14, .crn = 1, .crm = 0, .opc1 = 7, .opc2 = 0,
45
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
46
+ { .name = "JMCR",
47
+ .cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
48
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
49
+ REGINFO_SENTINEL
50
+};
51
+
52
void register_cp_regs_for_features(ARMCPU *cpu)
53
{
54
/* Register all the coprocessor registers based on feature bits */
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
--
32
--
66
2.20.1
33
2.20.1
67
34
68
35
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
2
2
3
HCR_EL2.TID2 mandates that access from EL1 to CTR_EL0, CCSIDR_EL1,
3
Secure mode is not exempted from checking SCR_EL3.TLOR, and in the
4
CCSIDR2_EL1, CLIDR_EL1, CSSELR_EL1 are trapped to EL2, and QEMU
4
future HCR_EL2.TLOR when S-EL2 is enabled.
5
completely ignores it, making it impossible for hypervisors to
6
virtualize the cache hierarchy.
7
5
8
Do the right thing by trapping to EL2 if HCR_EL2.TID2 is set.
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
9
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
9
---
16
target/arm/helper.c | 31 +++++++++++++++++++++++++++----
10
target/arm/helper.c | 19 +++++--------------
17
1 file changed, 27 insertions(+), 4 deletions(-)
11
1 file changed, 5 insertions(+), 14 deletions(-)
18
12
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
17
@@ -XXX,XX +XXX,XX @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
24
raw_write(env, ri, value);
18
#endif
19
20
/* Shared logic between LORID and the rest of the LOR* registers.
21
- * Secure state has already been delt with.
22
+ * Secure state exclusion has already been dealt with.
23
*/
24
-static CPAccessResult access_lor_ns(CPUARMState *env)
25
+static CPAccessResult access_lor_ns(CPUARMState *env,
26
+ const ARMCPRegInfo *ri, bool isread)
27
{
28
int el = arm_current_el(env);
29
30
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_ns(CPUARMState *env)
31
return CP_ACCESS_OK;
25
}
32
}
26
33
27
+static CPAccessResult access_aa64_tid2(CPUARMState *env,
34
-static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri,
28
+ const ARMCPRegInfo *ri,
35
- bool isread)
29
+ bool isread)
36
-{
30
+{
37
- if (arm_is_secure_below_el3(env)) {
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID2)) {
38
- /* Access ok in secure mode. */
32
+ return CP_ACCESS_TRAP_EL2;
39
- return CP_ACCESS_OK;
33
+ }
40
- }
34
+
41
- return access_lor_ns(env);
35
+ return CP_ACCESS_OK;
42
-}
36
+}
43
-
37
+
44
static CPAccessResult access_lor_other(CPUARMState *env,
38
static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
45
const ARMCPRegInfo *ri, bool isread)
39
{
46
{
40
ARMCPU *cpu = env_archcpu(env);
47
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_other(CPUARMState *env,
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
48
/* Access denied in secure mode. */
42
.writefn = pmintenclr_write },
43
{ .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
44
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
45
- .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
46
+ .access = PL1_R,
47
+ .accessfn = access_aa64_tid2,
48
+ .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
49
{ .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
50
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
51
- .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
52
+ .access = PL1_RW,
53
+ .accessfn = access_aa64_tid2,
54
+ .writefn = csselr_write, .resetvalue = 0,
55
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
56
offsetof(CPUARMState, cp15.csselr_ns) } },
57
/* Auxiliary ID register: this actually has an IMPDEF value but for now
58
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
59
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCT)) {
60
return CP_ACCESS_TRAP;
49
return CP_ACCESS_TRAP;
61
}
50
}
62
+
51
- return access_lor_ns(env);
63
+ if (arm_current_el(env) < 2 && arm_hcr_el2_eff(env) & HCR_TID2) {
52
+ return access_lor_ns(env, ri, isread);
64
+ return CP_ACCESS_TRAP_EL2;
65
+ }
66
+
67
return CP_ACCESS_OK;
68
}
53
}
69
54
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
55
/*
71
ARMCPRegInfo clidr = {
56
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lor_reginfo[] = {
72
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
57
.type = ARM_CP_CONST, .resetvalue = 0 },
73
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
58
{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
74
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr
59
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
75
+ .access = PL1_R, .type = ARM_CP_CONST,
60
- .access = PL1_R, .accessfn = access_lorid,
76
+ .accessfn = access_aa64_tid2,
61
+ .access = PL1_R, .accessfn = access_lor_ns,
77
+ .resetvalue = cpu->clidr
62
.type = ARM_CP_CONST, .resetvalue = 0 },
78
};
63
REGINFO_SENTINEL
79
define_one_arm_cp_reg(cpu, &clidr);
64
};
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
--
65
--
92
2.20.1
66
2.20.1
93
67
94
68
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
If we're using the capstone disassembler, disassembly of a run of
2
instructions more than 32 bytes long disassembles the wrong data for
3
instructions beyond the 32 byte mark:
2
4
3
The last argument of AML bit and/or statement is the target variable,
5
(qemu) xp /16x 0x100
4
so we don't need to use a NULL target and then an additional store
6
0000000000000100: 0x00000005 0x54410001 0x00000001 0x00001000
5
operation; using just aml_and() or aml_or() statement is enough.
7
0000000000000110: 0x00000000 0x00000004 0x54410002 0x3c000000
8
0000000000000120: 0x00000000 0x00000004 0x54410009 0x74736574
9
0000000000000130: 0x00000000 0x00000000 0x00000000 0x00000000
10
(qemu) xp /16i 0x100
11
0x00000100: 00000005 andeq r0, r0, r5
12
0x00000104: 54410001 strbpl r0, [r1], #-1
13
0x00000108: 00000001 andeq r0, r0, r1
14
0x0000010c: 00001000 andeq r1, r0, r0
15
0x00000110: 00000000 andeq r0, r0, r0
16
0x00000114: 00000004 andeq r0, r0, r4
17
0x00000118: 54410002 strbpl r0, [r1], #-2
18
0x0000011c: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
19
0x00000120: 54410001 strbpl r0, [r1], #-1
20
0x00000124: 00000001 andeq r0, r0, r1
21
0x00000128: 00001000 andeq r1, r0, r0
22
0x0000012c: 00000000 andeq r0, r0, r0
23
0x00000130: 00000004 andeq r0, r0, r4
24
0x00000134: 54410002 strbpl r0, [r1], #-2
25
0x00000138: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
26
0x0000013c: 00000000 andeq r0, r0, r0
6
27
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
28
Here the disassembly of 0x120..0x13f is using the data that is in
29
0x104..0x123.
8
30
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
31
This is caused by passing the wrong value to the read_memory_func().
10
Cc: Peter Maydell <peter.maydell@linaro.org>
32
The intention is that at this point in the loop the 'cap_buf' buffer
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
33
already contains 'csize' bytes of data for the instruction at guest
12
Cc: Igor Mammedov <imammedo@redhat.com>
34
addr 'pc', and we want to read in an extra 'tsize' bytes. Those
13
Suggested-by: Igor Mammedov <imammedo@redhat.com>
35
extra bytes are therefore at 'pc + csize', not 'pc'. On the first
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
36
time through the loop 'csize' happens to be zero, so the initial read
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
37
of 32 bytes into cap_buf is correct and as long as the disassembly
16
Message-id: 20191209063719.23086-2-guoheyi@huawei.com
38
never needs to read more data we return the correct information.
39
40
Use the correct guest address in the call to read_memory_func().
41
42
Cc: qemu-stable@nongnu.org
43
Fixes: https://bugs.launchpad.net/qemu/+bug/1900779
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
45
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
46
Message-id: 20201022132445.25039-1-peter.maydell@linaro.org
18
---
47
---
19
hw/arm/virt-acpi-build.c | 16 ++++++++--------
48
disas/capstone.c | 2 +-
20
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
49
1 file changed, 1 insertion(+), 1 deletion(-)
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
50
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
51
diff --git a/disas/capstone.c b/disas/capstone.c
26
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
53
--- a/disas/capstone.c
28
+++ b/hw/arm/virt-acpi-build.c
54
+++ b/disas/capstone.c
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
55
@@ -XXX,XX +XXX,XX @@ bool cap_disas_monitor(disassemble_info *info, uint64_t pc, int count)
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
56
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
57
/* Make certain that we can make progress. */
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
58
assert(tsize != 0);
33
- aml_append(ifctx, aml_store(aml_and(aml_name("CTRL"), aml_int(0x1D), NULL),
59
- info->read_memory_func(pc, cap_buf + csize, tsize, info);
34
- aml_name("CTRL")));
60
+ info->read_memory_func(pc + csize, cap_buf + csize, tsize, info);
35
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
61
csize += tsize;
36
+ aml_name("CTRL")));
62
37
63
if (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) {
38
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
39
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x08), NULL),
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
--
64
--
104
2.20.1
65
2.20.1
105
66
106
67
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
Use the BIT_ULL() macro to ensure we use 64-bit arithmetic.
4
an array of qemu_irq and passing it around, directly call
4
This fixes the following Coverity issue (OVERFLOW_BEFORE_WIDEN):
5
qdev_get_gpio_in() on the gic field.
5
6
CID 1432363 (#1 of 1): Unintentional integer overflow:
7
8
overflow_before_widen:
9
Potentially overflowing expression 1 << scale with type int
10
(32 bits, signed) is evaluated using 32-bit arithmetic, and
11
then used in a context that expects an expression of type
12
hwaddr (64 bits, unsigned).
6
13
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
15
Acked-by: Eric Auger <eric.auger@redhat.com>
9
Message-id: 20191209090306.20433-1-philmd@redhat.com
16
Message-id: 20201030144617.1535064-1-philmd@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
19
---
13
include/hw/arm/virt.h | 1 +
20
hw/arm/smmuv3.c | 3 ++-
14
hw/arm/virt.c | 109 +++++++++++++++++++++---------------------
21
1 file changed, 2 insertions(+), 1 deletion(-)
15
2 files changed, 55 insertions(+), 55 deletions(-)
16
22
17
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
23
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
18
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/virt.h
25
--- a/hw/arm/smmuv3.c
20
+++ b/include/hw/arm/virt.h
26
+++ b/hw/arm/smmuv3.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
27
@@ -XXX,XX +XXX,XX @@
22
uint32_t iommu_phandle;
28
*/
23
int psci_conduit;
29
24
hwaddr highest_gpa;
30
#include "qemu/osdep.h"
25
+ DeviceState *gic;
31
+#include "qemu/bitops.h"
26
DeviceState *acpi_dev;
32
#include "hw/irq.h"
27
Notifier powerdown_notifier;
33
#include "hw/sysbus.h"
28
} VirtMachineState;
34
#include "migration/vmstate.h"
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
35
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
30
index XXXXXXX..XXXXXXX 100644
36
scale = CMD_SCALE(cmd);
31
--- a/hw/arm/virt.c
37
num = CMD_NUM(cmd);
32
+++ b/hw/arm/virt.c
38
ttl = CMD_TTL(cmd);
33
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
39
- num_pages = (num + 1) * (1 << (scale));
40
+ num_pages = (num + 1) * BIT_ULL(scale);
34
}
41
}
35
}
42
36
43
if (type == SMMU_CMD_TLBI_NH_VA) {
37
-static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
38
+static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
39
{
40
DeviceState *dev;
41
MachineState *ms = MACHINE(vms);
42
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
43
44
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
45
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
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.20.1
395
46
396
47
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
2
2
3
This change ensures that the FPU can be accessed in Non-Secure mode
3
When booting a CPU with EL3 using the -kernel flag, set up CPTR_EL3 so
4
when the CPU core is reset using the arm_set_cpu_on() function call.
4
that SVE will not trap to EL3.
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
5
10
This is necessary because in this power-control codepath QEMU
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
11
is effectively emulating a bit of EL3 firmware, and has to set
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
the CPU up as the EL3 firmware would.
8
Message-id: 20201030151541.11976-1-remi@remlab.net
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>
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
hw/arm/boot.c | 3 +++
22
1 file changed, 3 insertions(+)
12
1 file changed, 3 insertions(+)
23
13
24
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
14
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/arm-powerctl.c
16
--- a/hw/arm/boot.c
27
+++ b/target/arm/arm-powerctl.c
17
+++ b/hw/arm/boot.c
28
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
18
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
29
/* Processor is not in secure mode */
19
if (cpu_isar_feature(aa64_mte, cpu)) {
30
target_cpu->env.cp15.scr_el3 |= SCR_NS;
20
env->cp15.scr_el3 |= SCR_ATA;
31
21
}
32
+ /* Set NSACR.{CP11,CP10} so NS can access the FPU */
22
+ if (cpu_isar_feature(aa64_sve, cpu)) {
33
+ target_cpu->env.cp15.nsacr |= 3 << 10;
23
+ env->cp15.cptr_el[3] |= CPTR_EZ;
34
+
24
+ }
35
/*
25
/* AArch64 kernels never boot in secure mode */
36
* If QEMU is providing the equivalent of EL3 firmware, then we need
26
assert(!info->secure_boot);
37
* to make sure a CPU targeting EL2 comes out of reset with a
27
/* This hook is only supported for AArch32 currently:
38
--
28
--
39
2.20.1
29
2.20.1
40
30
41
31
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: AlexChen <alex.chen@huawei.com>
2
2
3
Signed-off-by: Cédric Le Goater <clg@kaod.org>
3
In omap_lcd_interrupts(), the pointer omap_lcd is dereferinced before
4
Reviewed-by: Joel Stanley <joel@jms.id.au>
4
being check if it is valid, which may lead to NULL pointer dereference.
5
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
5
So move the assignment to surface after checking that the omap_lcd is valid
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
and move surface_bits_per_pixel(surface) to after the surface assignment.
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
8
Message-id: 20191119141211.25716-6-clg@kaod.org
8
Reported-by: Euler Robot <euler.robot@huawei.com>
9
Signed-off-by: AlexChen <alex.chen@huawei.com>
10
Message-id: 5F9CDB8A.9000001@huawei.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
hw/i2c/aspeed_i2c.c | 93 ++++++++++++++++++++++++++++++++++++++-------
14
hw/display/omap_lcdc.c | 10 +++++++---
12
hw/i2c/trace-events | 9 +++++
15
1 file changed, 7 insertions(+), 3 deletions(-)
13
2 files changed, 89 insertions(+), 13 deletions(-)
14
16
15
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
17
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/i2c/aspeed_i2c.c
19
--- a/hw/display/omap_lcdc.c
18
+++ b/hw/i2c/aspeed_i2c.c
20
+++ b/hw/display/omap_lcdc.c
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
20
#include "hw/i2c/aspeed_i2c.h"
22
static void omap_update_display(void *opaque)
21
#include "hw/irq.h"
22
#include "hw/qdev-properties.h"
23
+#include "trace.h"
24
25
/* I2C Global Register */
26
27
@@ -XXX,XX +XXX,XX @@ static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
28
{
23
{
29
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
24
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
30
25
- DisplaySurface *surface = qemu_console_surface(omap_lcd->con);
31
+ trace_aspeed_i2c_bus_raise_interrupt(bus->intr_status,
26
+ DisplaySurface *surface;
32
+ bus->intr_status & I2CD_INTR_TX_NAK ? "nak|" : "",
27
draw_line_func draw_line;
33
+ bus->intr_status & I2CD_INTR_TX_ACK ? "ack|" : "",
28
int size, height, first, last;
34
+ bus->intr_status & I2CD_INTR_RX_DONE ? "done|" : "",
29
int width, linesize, step, bpp, frame_offset;
35
+ bus->intr_status & I2CD_INTR_NORMAL_STOP ? "normal|" : "",
30
hwaddr frame_base;
36
+ bus->intr_status & I2CD_INTR_ABNORMAL ? "abnormal" : "");
31
37
+
32
- if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable ||
38
bus->intr_status &= bus->intr_ctrl;
33
- !surface_bits_per_pixel(surface)) {
39
if (bus->intr_status) {
34
+ if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable) {
40
bus->controller->intr_status |= 1 << bus->id;
35
+ return;
41
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
42
{
43
AspeedI2CBus *bus = opaque;
44
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
45
+ uint64_t value = -1;
46
47
switch (offset) {
48
case I2CD_FUN_CTRL_REG:
49
- return bus->ctrl;
50
+ value = bus->ctrl;
51
+ break;
52
case I2CD_AC_TIMING_REG1:
53
- return bus->timing[0];
54
+ value = bus->timing[0];
55
+ break;
56
case I2CD_AC_TIMING_REG2:
57
- return bus->timing[1];
58
+ value = bus->timing[1];
59
+ break;
60
case I2CD_INTR_CTRL_REG:
61
- return bus->intr_ctrl;
62
+ value = bus->intr_ctrl;
63
+ break;
64
case I2CD_INTR_STS_REG:
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
}
86
- return bus->dma_addr;
87
+ value = bus->dma_addr;
88
+ break;
89
case I2CD_DMA_LEN:
90
if (!aic->has_dma) {
91
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
92
- return -1;
93
+ break;
94
}
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
}
106
+
107
+ trace_aspeed_i2c_bus_read(bus->id, offset, size, value);
108
+ return value;
109
}
110
111
static void aspeed_i2c_set_state(AspeedI2CBus *bus, uint8_t state)
112
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
113
for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
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
}
137
138
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
139
140
for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
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
+ }
36
+ }
180
+
37
+
181
+ cmd_flags = g_strdup_printf("%s%s%s%s%s%s%s%s%s",
38
+ surface = qemu_console_surface(omap_lcd->con);
182
+ bus->cmd & I2CD_M_START_CMD ? "start|" : "",
39
+ if (!surface_bits_per_pixel(surface)) {
183
+ bus->cmd & I2CD_RX_DMA_ENABLE ? "rxdma|" : "",
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;
40
return;
200
}
41
}
201
42
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
--
43
--
236
2.20.1
44
2.20.1
237
45
238
46
diff view generated by jsdifflib
1
From: PanNengyuan <pannengyuan@huawei.com>
1
From: AlexChen <alex.chen@huawei.com>
2
2
3
Address Sanitizer shows memory leak in hw/gpio/aspeed_gpio.c:875
3
In exynos4210_fimd_update(), the pointer s is dereferinced before
4
being check if it is valid, which may lead to NULL pointer dereference.
5
So move the assignment to global_width after checking that the s is valid.
4
6
5
Reported-by: Euler Robot <euler.robot@huawei.com>
7
Reported-by: Euler Robot <euler.robot@huawei.com>
6
Signed-off-by: PanNengyuan <pannengyuan@huawei.com>
8
Signed-off-by: Alex Chen <alex.chen@huawei.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 5F9F8D88.9030102@huawei.com
9
Message-id: 20191119141211.25716-16-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
hw/gpio/aspeed_gpio.c | 1 +
13
hw/display/exynos4210_fimd.c | 4 +++-
13
1 file changed, 1 insertion(+)
14
1 file changed, 3 insertions(+), 1 deletion(-)
14
15
15
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
16
diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/gpio/aspeed_gpio.c
18
--- a/hw/display/exynos4210_fimd.c
18
+++ b/hw/gpio/aspeed_gpio.c
19
+++ b/hw/display/exynos4210_fimd.c
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_init(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ static void exynos4210_fimd_update(void *opaque)
20
pin_idx % GPIOS_PER_GROUP);
21
bool blend = false;
21
object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
22
uint8_t *host_fb_addr;
22
aspeed_gpio_set_pin, NULL, NULL, NULL);
23
bool is_dirty = false;
23
+ g_free(name);
24
- const int global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
25
+ int global_width;
26
27
if (!s || !s->console || !s->enabled ||
28
surface_bits_per_pixel(qemu_console_surface(s->console)) == 0) {
29
return;
24
}
30
}
25
}
31
+
32
+ global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
33
exynos4210_update_resolution(s);
34
surface = qemu_console_surface(s->console);
26
35
27
--
36
--
28
2.20.1
37
2.20.1
29
38
30
39
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
In arm_v7m_mmu_idx_for_secstate() we get the 'priv' level to pass to
2
armv7m_mmu_idx_for_secstate_and_priv() by calling arm_current_el().
3
This is incorrect when the security state being queried is not the
4
current one, because arm_current_el() uses the current security state
5
to determine which of the banked CONTROL.nPRIV bits to look at.
6
The effect was that if (for instance) Secure state was in privileged
7
mode but Non-Secure was not then we would return the wrong MMU index.
2
8
3
Users benefit from knowing which watchdog timer has expired. The address
9
The only places where we are using this function in a way that could
4
of the watchdog's registers unambiguously indicates which has expired,
10
trigger this bug are for the stack loads during a v8M function-return
5
so log that.
11
and for the instruction fetch of a v8M SG insn.
6
12
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
13
Fix the bug by expanding out the M-profile version of the
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
arm_current_el() logic inline so it can use the passed in secstate
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
15
rather than env->v7m.secure.
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
16
11
Message-id: 20191119141211.25716-9-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20201022164408.13214-1-peter.maydell@linaro.org
13
---
20
---
14
hw/watchdog/wdt_aspeed.c | 3 ++-
21
target/arm/m_helper.c | 3 ++-
15
1 file changed, 2 insertions(+), 1 deletion(-)
22
1 file changed, 2 insertions(+), 1 deletion(-)
16
23
17
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
24
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
18
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/watchdog/wdt_aspeed.c
26
--- a/target/arm/m_helper.c
20
+++ b/hw/watchdog/wdt_aspeed.c
27
+++ b/target/arm/m_helper.c
21
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_timer_expired(void *dev)
28
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
22
return;
29
/* Return the MMU index for a v7M CPU in the specified security state */
23
}
30
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
24
31
{
25
- qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
32
- bool priv = arm_current_el(env) != 0;
26
+ qemu_log_mask(CPU_LOG_RESET, "Watchdog timer %" HWADDR_PRIx " expired.\n",
33
+ bool priv = arm_v7m_is_handler_mode(env) ||
27
+ s->iomem.addr);
34
+ !(env->v7m.control[secstate] & 1);
28
watchdog_perform_action();
35
29
timer_del(s->timer);
36
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
30
}
37
}
31
--
38
--
32
2.20.1
39
2.20.1
33
40
34
41
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
On some hosts (eg Ubuntu Bionic) pkg-config returns a set of
2
libraries for gio-2.0 which don't actually work when compiling
3
statically. (Specifically, the returned library string includes
4
-lmount, but not -lblkid which -lmount depends upon, so linking
5
fails due to missing symbols.)
2
6
3
Add probe_read alongside the write probing equivalent.
7
Check that the libraries work, and don't enable gio if they don't,
8
in the same way we do for gnutls.
4
9
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
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
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20200928160402.7961-1-peter.maydell@linaro.org
10
---
14
---
11
include/exec/exec-all.h | 6 ++++++
15
configure | 10 +++++++++-
12
1 file changed, 6 insertions(+)
16
1 file changed, 9 insertions(+), 1 deletion(-)
13
17
14
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
18
diff --git a/configure b/configure
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100755
16
--- a/include/exec/exec-all.h
20
--- a/configure
17
+++ b/include/exec/exec-all.h
21
+++ b/configure
18
@@ -XXX,XX +XXX,XX @@ static inline void *probe_write(CPUArchState *env, target_ulong addr, int size,
22
@@ -XXX,XX +XXX,XX @@ if test "$static" = yes && test "$mingw32" = yes; then
19
return probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
23
fi
20
}
24
21
25
if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then
22
+static inline void *probe_read(CPUArchState *env, target_ulong addr, int size,
26
- gio=yes
23
+ int mmu_idx, uintptr_t retaddr)
27
gio_cflags=$($pkg_config --cflags gio-2.0)
24
+{
28
gio_libs=$($pkg_config --libs gio-2.0)
25
+ return probe_access(env, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
29
gdbus_codegen=$($pkg_config --variable=gdbus_codegen gio-2.0)
26
+}
30
if [ ! -x "$gdbus_codegen" ]; then
27
+
31
gdbus_codegen=
28
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
32
fi
29
33
+ # Check that the libraries actually work -- Ubuntu 18.04 ships
30
/* Estimated block size for TB allocation. */
34
+ # with pkg-config --static --libs data for gio-2.0 that is missing
35
+ # -lblkid and will give a link error.
36
+ write_c_skeleton
37
+ if compile_prog "" "gio_libs" ; then
38
+ gio=yes
39
+ else
40
+ gio=no
41
+ fi
42
else
43
gio=no
44
fi
31
--
45
--
32
2.20.1
46
2.20.1
33
47
34
48
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
In gicv3_init_cpuif() we copy the ARMCPU gicv3_maintenance_interrupt
2
into the GICv3CPUState struct's maintenance_irq field. This will
3
only work if the board happens to have already wired up the CPU
4
maintenance IRQ before the GIC was realized. Unfortunately this is
5
not the case for the 'virt' board, and so the value that gets copied
6
is NULL (since a qemu_irq is really a pointer to an IRQState struct
7
under the hood). The effect is that the CPU interface code never
8
actually raises the maintenance interrupt line.
2
9
3
HCR_EL2.TID1 mandates that access from EL1 to REVIDR_EL1, AIDR_EL1
10
Instead, since the GICv3CPUState has a pointer to the CPUState, make
4
(and their 32bit equivalents) as well as TCMTR, TLBTR are trapped
11
the dereference at the point where we want to raise the interrupt, to
5
to EL2. QEMU ignores it, making it harder for a hypervisor to
12
avoid an implicit requirement on board code to wire things up in a
6
virtualize the HW (though to be fair, no known hypervisor actually
13
particular order.
7
cares).
8
14
9
Do the right thing by trapping to EL2 if HCR_EL2.TID1 is set.
15
Reported-by: Jose Martins <josemartins90@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20201009153904.28529-1-peter.maydell@linaro.org
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
19
---
20
include/hw/intc/arm_gicv3_common.h | 1 -
21
hw/intc/arm_gicv3_cpuif.c | 5 ++---
22
2 files changed, 2 insertions(+), 4 deletions(-)
10
23
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
24
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-3-maz@kernel.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/helper.c | 36 ++++++++++++++++++++++++++++++++----
18
1 file changed, 32 insertions(+), 4 deletions(-)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
26
--- a/include/hw/intc/arm_gicv3_common.h
23
+++ b/target/arm/helper.c
27
+++ b/include/hw/intc/arm_gicv3_common.h
24
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
28
@@ -XXX,XX +XXX,XX @@ struct GICv3CPUState {
25
return ret;
29
qemu_irq parent_fiq;
30
qemu_irq parent_virq;
31
qemu_irq parent_vfiq;
32
- qemu_irq maintenance_irq;
33
34
/* Redistributor */
35
uint32_t level; /* Current IRQ level */
36
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/arm_gicv3_cpuif.c
39
+++ b/hw/intc/arm_gicv3_cpuif.c
40
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
41
int irqlevel = 0;
42
int fiqlevel = 0;
43
int maintlevel = 0;
44
+ ARMCPU *cpu = ARM_CPU(cs->cpu);
45
46
idx = hppvi_index(cs);
47
trace_gicv3_cpuif_virt_update(gicv3_redist_affid(cs), idx);
48
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
49
50
qemu_set_irq(cs->parent_vfiq, fiqlevel);
51
qemu_set_irq(cs->parent_virq, irqlevel);
52
- qemu_set_irq(cs->maintenance_irq, maintlevel);
53
+ qemu_set_irq(cpu->gicv3_maintenance_interrupt, maintlevel);
26
}
54
}
27
55
28
+static CPAccessResult access_aa64_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
56
static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
29
+ bool isread)
57
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
30
+{
58
&& cpu->gic_num_lrs) {
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID1)) {
59
int j;
32
+ return CP_ACCESS_TRAP_EL2;
60
33
+ }
61
- cs->maintenance_irq = cpu->gicv3_maintenance_interrupt;
34
+
62
-
35
+ return CP_ACCESS_OK;
63
cs->num_list_regs = cpu->gic_num_lrs;
36
+}
64
cs->vpribits = cpu->gic_vpribits;
37
+
65
cs->vprebits = cpu->gic_vprebits;
38
+static CPAccessResult access_aa32_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
39
+ bool isread)
40
+{
41
+ if (arm_feature(env, ARM_FEATURE_V8)) {
42
+ return access_aa64_tid1(env, ri, isread);
43
+ }
44
+
45
+ return CP_ACCESS_OK;
46
+}
47
+
48
static const ARMCPRegInfo v7_cp_reginfo[] = {
49
/* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */
50
{ .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
51
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
52
*/
53
{ .name = "AIDR", .state = ARM_CP_STATE_BOTH,
54
.opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7,
55
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
56
+ .access = PL1_R, .type = ARM_CP_CONST,
57
+ .accessfn = access_aa64_tid1,
58
+ .resetvalue = 0 },
59
/* Auxiliary fault status registers: these also are IMPDEF, and we
60
* choose to RAZ/WI for all cores.
61
*/
62
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
63
.access = PL1_R, .resetvalue = cpu->midr },
64
{ .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,
65
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
66
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
67
+ .access = PL1_R,
68
+ .accessfn = access_aa64_tid1,
69
+ .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
70
REGINFO_SENTINEL
71
};
72
ARMCPRegInfo id_cp_reginfo[] = {
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
74
/* TCMTR and TLBTR exist in v8 but have no 64-bit versions */
75
{ .name = "TCMTR",
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
--
66
--
95
2.20.1
67
2.20.1
96
68
97
69
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
The kerneldoc script currently emits Sphinx markup for a macro with
2
arguments that uses the c:function directive. This is correct for
3
Sphinx versions earlier than Sphinx 3, where c:macro doesn't allow
4
documentation of macros with arguments and c:function is not picky
5
about the syntax of what it is passed. However, in Sphinx 3 the
6
c:macro directive was enhanced to support macros with arguments,
7
and c:function was made more picky about what syntax it accepted.
2
8
3
The Aspeed I2C controller can operate in different transfer modes :
9
When kerneldoc is told that it needs to produce output for Sphinx
10
3 or later, make it emit c:function only for functions and c:macro
11
for macros with arguments. We assume that anything with a return
12
type is a function and anything without is a macro.
4
13
5
- Byte Buffer mode, using a dedicated register to transfer a
14
This fixes the Sphinx error:
6
byte. This is what the model supports today.
7
15
8
- Pool Buffer mode, using an internal SRAM to transfer multiple
16
/home/petmay01/linaro/qemu-from-laptop/qemu/docs/../include/qom/object.h:155:Error in declarator
9
bytes in the same command sequence.
17
If declarator-id with parameters (e.g., 'void f(int arg)'):
18
Invalid C declaration: Expected identifier in nested name. [error at 25]
19
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
20
-------------------------^
21
If parenthesis in noptr-declarator (e.g., 'void (*f(int arg))(double)'):
22
Error in declarator or parameters
23
Invalid C declaration: Expecting "(" in parameters. [error at 39]
24
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
25
---------------------------------------^
10
26
11
Each SoC has different SRAM characteristics. On the AST2400, 2048
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
bytes of SRAM are available at offset 0x800 of the controller AHB
28
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
13
window. The pool buffer can be configured from 1 to 256 bytes per bus.
29
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
30
Message-id: 20201030174700.7204-2-peter.maydell@linaro.org
31
---
32
scripts/kernel-doc | 18 +++++++++++++++++-
33
1 file changed, 17 insertions(+), 1 deletion(-)
14
34
15
On the AST2500, the SRAM is at offset 0x200 and the pool buffer is of
35
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
16
16 bytes per bus.
36
index XXXXXXX..XXXXXXX 100755
17
37
--- a/scripts/kernel-doc
18
On the AST2600, the SRAM is at offset 0xC00 and the pool buffer is of
38
+++ b/scripts/kernel-doc
19
32 bytes per bus. It can be splitted in two for TX and RX but the
39
@@ -XXX,XX +XXX,XX @@ sub output_function_rst(%) {
20
current model does not add support for it as it it unused by known
40
    output_highlight_rst($args{'purpose'});
21
drivers.
41
    $start = "\n\n**Syntax**\n\n ``";
22
42
} else {
23
Signed-off-by: Cédric Le Goater <clg@kaod.org>
43
-    print ".. c:function:: ";
24
Reviewed-by: Joel Stanley <joel@jms.id.au>
44
+ if ((split(/\./, $sphinx_version))[0] >= 3) {
25
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
45
+ # Sphinx 3 and later distinguish macros and functions and
26
Signed-off-by: Cédric Le Goater <clg@kaod.org>
46
+ # complain if you use c:function with something that's not
27
Message-id: 20191119141211.25716-2-clg@kaod.org
47
+ # syntactically valid as a function declaration.
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
+ # We assume that anything with a return type is a function
29
---
49
+ # and anything without is a macro.
30
include/hw/i2c/aspeed_i2c.h | 8 ++
50
+ if ($args{'functiontype'} ne "") {
31
hw/i2c/aspeed_i2c.c | 197 ++++++++++++++++++++++++++++++++----
51
+ print ".. c:function:: ";
32
2 files changed, 186 insertions(+), 19 deletions(-)
33
34
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/i2c/aspeed_i2c.h
37
+++ b/include/hw/i2c/aspeed_i2c.h
38
@@ -XXX,XX +XXX,XX @@
39
OBJECT_CHECK(AspeedI2CState, (obj), TYPE_ASPEED_I2C)
40
41
#define ASPEED_I2C_NR_BUSSES 16
42
+#define ASPEED_I2C_MAX_POOL_SIZE 0x800
43
44
struct AspeedI2CState;
45
46
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
47
uint32_t intr_status;
48
uint32_t cmd;
49
uint32_t buf;
50
+ uint32_t pool_ctrl;
51
} AspeedI2CBus;
52
53
typedef struct AspeedI2CState {
54
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
55
qemu_irq irq;
56
57
uint32_t intr_status;
58
+ MemoryRegion pool_iomem;
59
+ uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
60
61
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
62
} AspeedI2CState;
63
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
64
uint8_t reg_size;
65
uint8_t gap;
66
qemu_irq (*bus_get_irq)(AspeedI2CBus *);
67
+
68
+ uint64_t pool_size;
69
+ hwaddr pool_base;
70
+ uint8_t *(*bus_pool_base)(AspeedI2CBus *);
71
} AspeedI2CClass;
72
73
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
74
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/hw/i2c/aspeed_i2c.c
77
+++ b/hw/i2c/aspeed_i2c.c
78
@@ -XXX,XX +XXX,XX @@
79
/* I2C Device (Bus) Register */
80
81
#define I2CD_FUN_CTRL_REG 0x00 /* I2CD Function Control */
82
-#define I2CD_BUFF_SEL_MASK (0x7 << 20)
83
-#define I2CD_BUFF_SEL(x) (x << 20)
84
+#define I2CD_POOL_PAGE_SEL(x) (((x) >> 20) & 0x7) /* AST2400 */
85
#define I2CD_M_SDA_LOCK_EN (0x1 << 16)
86
#define I2CD_MULTI_MASTER_DIS (0x1 << 15)
87
#define I2CD_M_SCL_DRIVE_EN (0x1 << 14)
88
@@ -XXX,XX +XXX,XX @@
89
#define I2CD_SCL_O_OUT_DIR (0x1 << 12)
90
#define I2CD_BUS_RECOVER_CMD_EN (0x1 << 11)
91
#define I2CD_S_ALT_EN (0x1 << 10)
92
-#define I2CD_RX_DMA_ENABLE (0x1 << 9)
93
-#define I2CD_TX_DMA_ENABLE (0x1 << 8)
94
95
/* Command Bit */
96
+#define I2CD_RX_DMA_ENABLE (0x1 << 9)
97
+#define I2CD_TX_DMA_ENABLE (0x1 << 8)
98
+#define I2CD_RX_BUFF_ENABLE (0x1 << 7)
99
+#define I2CD_TX_BUFF_ENABLE (0x1 << 6)
100
#define I2CD_M_STOP_CMD (0x1 << 5)
101
#define I2CD_M_S_RX_CMD_LAST (0x1 << 4)
102
#define I2CD_M_RX_CMD (0x1 << 3)
103
@@ -XXX,XX +XXX,XX @@
104
#define I2CD_M_START_CMD (0x1)
105
106
#define I2CD_DEV_ADDR_REG 0x18 /* Slave Device Address */
107
-#define I2CD_BUF_CTRL_REG 0x1c /* Pool Buffer Control */
108
+#define I2CD_POOL_CTRL_REG 0x1c /* Pool Buffer Control */
109
+#define I2CD_POOL_RX_COUNT(x) (((x) >> 24) & 0xff)
110
+#define I2CD_POOL_RX_SIZE(x) ((((x) >> 16) & 0xff) + 1)
111
+#define I2CD_POOL_TX_COUNT(x) ((((x) >> 8) & 0xff) + 1)
112
+#define I2CD_POOL_OFFSET(x) (((x) & 0x3f) << 2) /* AST2400 */
113
#define I2CD_BYTE_BUF_REG 0x20 /* Transmit/Receive Byte Buffer */
114
#define I2CD_BYTE_BUF_TX_SHIFT 0
115
#define I2CD_BYTE_BUF_TX_MASK 0xff
116
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
117
return bus->intr_ctrl;
118
case I2CD_INTR_STS_REG:
119
return bus->intr_status;
120
+ case I2CD_POOL_CTRL_REG:
121
+ return bus->pool_ctrl;
122
case I2CD_BYTE_BUF_REG:
123
return bus->buf;
124
case I2CD_CMD_REG:
125
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
126
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
127
}
128
129
+static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
130
+{
131
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
132
+ int ret = -1;
133
+ int i;
134
+
135
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
136
+ for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
137
+ uint8_t *pool_base = aic->bus_pool_base(bus);
138
+
139
+ ret = i2c_send(bus->bus, pool_base[i]);
140
+ if (ret) {
141
+ break;
142
+ }
143
+ }
144
+ bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
145
+ } else {
146
+ ret = i2c_send(bus->bus, bus->buf);
147
+ }
148
+
149
+ return ret;
150
+}
151
+
152
+static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
153
+{
154
+ AspeedI2CState *s = bus->controller;
155
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
156
+ uint8_t data;
157
+ int i;
158
+
159
+ if (bus->cmd & I2CD_RX_BUFF_ENABLE) {
160
+ uint8_t *pool_base = aic->bus_pool_base(bus);
161
+
162
+ for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
163
+ pool_base[i] = i2c_recv(bus->bus);
164
+ }
165
+
166
+ /* Update RX count */
167
+ bus->pool_ctrl &= ~(0xff << 24);
168
+ bus->pool_ctrl |= (i & 0xff) << 24;
169
+ bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
170
+ } else {
171
+ data = i2c_recv(bus->bus);
172
+ bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
173
+ }
174
+}
175
+
176
static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
177
{
178
- uint8_t ret;
179
-
180
aspeed_i2c_set_state(bus, I2CD_MRXD);
181
- ret = i2c_recv(bus->bus);
182
+ aspeed_i2c_bus_recv(bus);
183
bus->intr_status |= I2CD_INTR_RX_DONE;
184
- bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
185
if (bus->cmd & I2CD_M_S_RX_CMD_LAST) {
186
i2c_nack(bus->bus);
187
}
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
189
aspeed_i2c_set_state(bus, I2CD_MACTIVE);
190
}
191
192
+static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
193
+{
194
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
195
+
196
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
197
+ uint8_t *pool_base = aic->bus_pool_base(bus);
198
+
199
+ return pool_base[0];
200
+ } else {
201
+ return bus->buf;
202
+ }
203
+}
204
+
205
/*
206
* The state machine needs some refinement. It is only used to track
207
* invalid STOP commands for the moment.
208
*/
209
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
210
{
211
+ uint8_t pool_start = 0;
212
+
213
bus->cmd &= ~0xFFFF;
214
bus->cmd |= value & 0xFFFF;
215
216
if (bus->cmd & I2CD_M_START_CMD) {
217
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
218
I2CD_MSTARTR : I2CD_MSTART;
219
+ uint8_t addr;
220
221
aspeed_i2c_set_state(bus, state);
222
223
- if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7),
224
- extract32(bus->buf, 0, 1))) {
225
+ addr = aspeed_i2c_get_addr(bus);
226
+
227
+ if (i2c_start_transfer(bus->bus, extract32(addr, 1, 7),
228
+ extract32(addr, 0, 1))) {
229
bus->intr_status |= I2CD_INTR_TX_NAK;
230
} else {
231
bus->intr_status |= I2CD_INTR_TX_ACK;
232
}
233
234
- /* START command is also a TX command, as the slave address is
235
- * sent on the bus */
236
- bus->cmd &= ~(I2CD_M_START_CMD | I2CD_M_TX_CMD);
237
+ bus->cmd &= ~I2CD_M_START_CMD;
238
+
239
+ /*
240
+ * The START command is also a TX command, as the slave
241
+ * address is sent on the bus. Drop the TX flag if nothing
242
+ * else needs to be sent in this sequence.
243
+ */
244
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
245
+ if (I2CD_POOL_TX_COUNT(bus->pool_ctrl) == 1) {
246
+ bus->cmd &= ~I2CD_M_TX_CMD;
247
+ } else {
52
+ } else {
248
+ /*
53
+ print ".. c:macro:: ";
249
+ * Increase the start index in the TX pool buffer to
250
+ * skip the address byte.
251
+ */
252
+ pool_start++;
253
+ }
54
+ }
254
+ } else {
55
+ } else {
255
+ bus->cmd &= ~I2CD_M_TX_CMD;
56
+ # Older Sphinx don't support documenting macros that take
57
+ # arguments with c:macro, and don't complain about the use
58
+ # of c:function for this.
59
+ print ".. c:function:: ";
256
+ }
60
+ }
257
258
/* No slave found */
259
if (!i2c_bus_busy(bus->bus)) {
260
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
261
262
if (bus->cmd & I2CD_M_TX_CMD) {
263
aspeed_i2c_set_state(bus, I2CD_MTXD);
264
- if (i2c_send(bus->bus, bus->buf)) {
265
+ if (aspeed_i2c_bus_send(bus, pool_start)) {
266
bus->intr_status |= (I2CD_INTR_TX_NAK);
267
i2c_end_transfer(bus->bus);
268
} else {
269
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
270
qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
271
__func__);
272
break;
273
+ case I2CD_POOL_CTRL_REG:
274
+ bus->pool_ctrl &= ~0xffffff;
275
+ bus->pool_ctrl |= (value & 0xffffff);
276
+ break;
277
+
278
case I2CD_BYTE_BUF_REG:
279
bus->buf = (value & I2CD_BYTE_BUF_TX_MASK) << I2CD_BYTE_BUF_TX_SHIFT;
280
break;
281
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_ctrl_ops = {
282
.endianness = DEVICE_LITTLE_ENDIAN,
283
};
284
285
+static uint64_t aspeed_i2c_pool_read(void *opaque, hwaddr offset,
286
+ unsigned size)
287
+{
288
+ AspeedI2CState *s = opaque;
289
+ uint64_t ret = 0;
290
+ int i;
291
+
292
+ for (i = 0; i < size; i++) {
293
+ ret |= (uint64_t) s->pool[offset + i] << (8 * i);
294
+ }
295
+
296
+ return ret;
297
+}
298
+
299
+static void aspeed_i2c_pool_write(void *opaque, hwaddr offset,
300
+ uint64_t value, unsigned size)
301
+{
302
+ AspeedI2CState *s = opaque;
303
+ int i;
304
+
305
+ for (i = 0; i < size; i++) {
306
+ s->pool[offset + i] = (value >> (8 * i)) & 0xFF;
307
+ }
308
+}
309
+
310
+static const MemoryRegionOps aspeed_i2c_pool_ops = {
311
+ .read = aspeed_i2c_pool_read,
312
+ .write = aspeed_i2c_pool_write,
313
+ .endianness = DEVICE_LITTLE_ENDIAN,
314
+ .valid = {
315
+ .min_access_size = 1,
316
+ .max_access_size = 4,
317
+ },
318
+};
319
+
320
static const VMStateDescription aspeed_i2c_bus_vmstate = {
321
.name = TYPE_ASPEED_I2C,
322
- .version_id = 1,
323
- .minimum_version_id = 1,
324
+ .version_id = 2,
325
+ .minimum_version_id = 2,
326
.fields = (VMStateField[]) {
327
VMSTATE_UINT8(id, AspeedI2CBus),
328
VMSTATE_UINT32(ctrl, AspeedI2CBus),
329
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
330
VMSTATE_UINT32(intr_status, AspeedI2CBus),
331
VMSTATE_UINT32(cmd, AspeedI2CBus),
332
VMSTATE_UINT32(buf, AspeedI2CBus),
333
+ VMSTATE_UINT32(pool_ctrl, AspeedI2CBus),
334
VMSTATE_END_OF_LIST()
335
}
61
}
336
};
62
if ($args{'functiontype'} ne "") {
337
63
    $start .= $args{'functiontype'} . " " . $args{'function'} . " (";
338
static const VMStateDescription aspeed_i2c_vmstate = {
339
.name = TYPE_ASPEED_I2C,
340
- .version_id = 1,
341
- .minimum_version_id = 1,
342
+ .version_id = 2,
343
+ .minimum_version_id = 2,
344
.fields = (VMStateField[]) {
345
VMSTATE_UINT32(intr_status, AspeedI2CState),
346
VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState,
347
ASPEED_I2C_NR_BUSSES, 1, aspeed_i2c_bus_vmstate,
348
AspeedI2CBus),
349
+ VMSTATE_UINT8_ARRAY(pool, AspeedI2CState, ASPEED_I2C_MAX_POOL_SIZE),
350
VMSTATE_END_OF_LIST()
351
}
352
};
353
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
354
memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset),
355
&s->busses[i].mr);
356
}
357
+
358
+ memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
359
+ "aspeed.i2c-pool", aic->pool_size);
360
+ memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
361
}
362
363
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
364
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CBus *bus)
365
return bus->controller->irq;
366
}
367
368
+static uint8_t *aspeed_2400_i2c_bus_pool_base(AspeedI2CBus *bus)
369
+{
370
+ uint8_t *pool_page =
371
+ &bus->controller->pool[I2CD_POOL_PAGE_SEL(bus->ctrl) * 0x100];
372
+
373
+ return &pool_page[I2CD_POOL_OFFSET(bus->pool_ctrl)];
374
+}
375
+
376
static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
377
{
378
DeviceClass *dc = DEVICE_CLASS(klass);
379
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
380
aic->reg_size = 0x40;
381
aic->gap = 7;
382
aic->bus_get_irq = aspeed_2400_i2c_bus_get_irq;
383
+ aic->pool_size = 0x800;
384
+ aic->pool_base = 0x800;
385
+ aic->bus_pool_base = aspeed_2400_i2c_bus_pool_base;
386
}
387
388
static const TypeInfo aspeed_2400_i2c_info = {
389
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2500_i2c_bus_get_irq(AspeedI2CBus *bus)
390
return bus->controller->irq;
391
}
392
393
+static uint8_t *aspeed_2500_i2c_bus_pool_base(AspeedI2CBus *bus)
394
+{
395
+ return &bus->controller->pool[bus->id * 0x10];
396
+}
397
+
398
static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
399
{
400
DeviceClass *dc = DEVICE_CLASS(klass);
401
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
402
aic->reg_size = 0x40;
403
aic->gap = 7;
404
aic->bus_get_irq = aspeed_2500_i2c_bus_get_irq;
405
+ aic->pool_size = 0x100;
406
+ aic->pool_base = 0x200;
407
+ aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
408
}
409
410
static const TypeInfo aspeed_2500_i2c_info = {
411
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus)
412
return bus->irq;
413
}
414
415
+static uint8_t *aspeed_2600_i2c_bus_pool_base(AspeedI2CBus *bus)
416
+{
417
+ return &bus->controller->pool[bus->id * 0x20];
418
+}
419
+
420
static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
421
{
422
DeviceClass *dc = DEVICE_CLASS(klass);
423
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
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
--
64
--
434
2.20.1
65
2.20.1
435
66
436
67
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The SRAM must be enabled before using the Buffer Pool mode or the DMA
4
mode. This is not required on other SoCs.
5
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 20191119141211.25716-3-clg@kaod.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/i2c/aspeed_i2c.h | 3 +++
14
hw/i2c/aspeed_i2c.c | 37 +++++++++++++++++++++++++++++++++++++
15
2 files changed, 40 insertions(+)
16
17
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/i2c/aspeed_i2c.h
20
+++ b/include/hw/i2c/aspeed_i2c.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
22
qemu_irq irq;
23
24
uint32_t intr_status;
25
+ uint32_t ctrl_global;
26
MemoryRegion pool_iomem;
27
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
28
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
30
uint64_t pool_size;
31
hwaddr pool_base;
32
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
33
+ bool check_sram;
34
+
35
} AspeedI2CClass;
36
37
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
38
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/i2c/aspeed_i2c.c
41
+++ b/hw/i2c/aspeed_i2c.c
42
@@ -XXX,XX +XXX,XX @@
43
#define I2C_CTRL_STATUS 0x00 /* Device Interrupt Status */
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
}
54
55
+static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
56
+{
57
+ AspeedI2CState *s = bus->controller;
58
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
59
+
60
+ if (!aic->check_sram) {
61
+ return true;
62
+ }
63
+
64
+ /*
65
+ * AST2500: SRAM must be enabled before using the Buffer Pool or
66
+ * DMA mode.
67
+ */
68
+ if (!(s->ctrl_global & I2C_CTRL_SRAM_EN) &&
69
+ (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE |
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
+ }
74
+
75
+ return true;
76
+}
77
+
78
/*
79
* The state machine needs some refinement. It is only used to track
80
* invalid STOP commands for the moment.
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
82
bus->cmd &= ~0xFFFF;
83
bus->cmd |= value & 0xFFFF;
84
85
+ if (!aspeed_i2c_check_sram(bus)) {
86
+ return;
87
+ }
88
+
89
if (bus->cmd & I2CD_M_START_CMD) {
90
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
91
I2CD_MSTARTR : I2CD_MSTART;
92
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
93
switch (offset) {
94
case I2C_CTRL_STATUS:
95
return s->intr_status;
96
+ case I2C_CTRL_GLOBAL:
97
+ return s->ctrl_global;
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
2.20.1
124
125
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
Currently, we link the DRAM memory region to the FMC model (for DMAs)
4
through a property alias at the SoC level. The I2C model will need a
5
similar region for DMA support, add a DRAM region property at the SoC
6
level for both model to use.
7
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-id: 20191119141211.25716-4-clg@kaod.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/hw/arm/aspeed_soc.h | 1 +
16
hw/arm/aspeed_ast2600.c | 7 +++++--
17
hw/arm/aspeed_soc.c | 9 +++++++--
18
3 files changed, 13 insertions(+), 4 deletions(-)
19
20
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/aspeed_soc.h
23
+++ b/include/hw/arm/aspeed_soc.h
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
25
ARMCPU cpu[ASPEED_CPUS_NUM];
26
uint32_t num_cpus;
27
A15MPPrivState a7mpcore;
28
+ MemoryRegion *dram_mr;
29
MemoryRegion sram;
30
AspeedVICState vic;
31
AspeedRtcState rtc;
32
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/aspeed_ast2600.c
35
+++ b/hw/arm/aspeed_ast2600.c
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
37
typename);
38
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
39
&error_abort);
40
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
41
- &error_abort);
42
43
for (i = 0; i < sc->spis_num; i++) {
44
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
46
}
47
48
/* FMC, The number of CS is set at the board level */
49
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
50
+ if (err) {
51
+ error_propagate(errp, err);
52
+ return;
53
+ }
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
91
--
92
2.20.1
93
94
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The I2C controller of the Aspeed AST2500 and AST2600 SoCs supports DMA
4
transfers to and from DRAM.
5
6
A pair of registers defines the buffer address and the length of the
7
DMA transfer. The address should be aligned on 4 bytes and the maximum
8
length should not exceed 4K. The receive or transmit DMA transfer can
9
then be initiated with specific bits in the Command/Status register of
10
the controller.
11
12
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
Reviewed-by: Joel Stanley <joel@jms.id.au>
14
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
15
Signed-off-by: Cédric Le Goater <clg@kaod.org>
16
Message-id: 20191119141211.25716-5-clg@kaod.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
include/hw/i2c/aspeed_i2c.h | 5 ++
20
hw/arm/aspeed_ast2600.c | 5 ++
21
hw/arm/aspeed_soc.c | 5 ++
22
hw/i2c/aspeed_i2c.c | 126 +++++++++++++++++++++++++++++++++++-
23
4 files changed, 138 insertions(+), 3 deletions(-)
24
25
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/i2c/aspeed_i2c.h
28
+++ b/include/hw/i2c/aspeed_i2c.h
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
30
uint32_t cmd;
31
uint32_t buf;
32
uint32_t pool_ctrl;
33
+ uint32_t dma_addr;
34
+ uint32_t dma_len;
35
} AspeedI2CBus;
36
37
typedef struct AspeedI2CState {
38
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
39
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
40
41
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
42
+ MemoryRegion *dram_mr;
43
+ AddressSpace dram_as;
44
} AspeedI2CState;
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
57
--- a/hw/arm/aspeed_ast2600.c
58
+++ b/hw/arm/aspeed_ast2600.c
59
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
60
}
61
62
/* I2C */
63
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
64
+ if (err) {
65
+ error_propagate(errp, err);
66
+ return;
67
+ }
68
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
69
if (err) {
70
error_propagate(errp, err);
71
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/arm/aspeed_soc.c
74
+++ b/hw/arm/aspeed_soc.c
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
76
}
77
78
/* I2C */
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
+ }
84
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
85
if (err) {
86
error_propagate(errp, err);
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
+ }
156
+
157
+ bus->dma_addr++;
158
+ bus->dma_len--;
159
+ return 0;
160
+}
161
+
162
static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
163
{
164
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
165
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
166
}
167
}
168
bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
169
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
170
+ while (bus->dma_len) {
171
+ uint8_t data;
172
+ aspeed_i2c_dma_read(bus, &data);
173
+ ret = i2c_send(bus->bus, data);
174
+ if (ret) {
175
+ break;
176
+ }
177
+ }
178
+ bus->cmd &= ~I2CD_TX_DMA_ENABLE;
179
} else {
180
ret = i2c_send(bus->bus, bus->buf);
181
}
182
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
183
bus->pool_ctrl &= ~(0xff << 24);
184
bus->pool_ctrl |= (i & 0xff) << 24;
185
bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
186
+ } else if (bus->cmd & I2CD_RX_DMA_ENABLE) {
187
+ uint8_t data;
188
+
189
+ while (bus->dma_len) {
190
+ MemTxResult result;
191
+
192
+ data = i2c_recv(bus->bus);
193
+ result = address_space_write(&s->dram_as, bus->dma_addr,
194
+ MEMTXATTRS_UNSPECIFIED, &data, 1);
195
+ if (result != MEMTX_OK) {
196
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
197
+ __func__, bus->dma_addr);
198
+ return;
199
+ }
200
+ bus->dma_addr++;
201
+ bus->dma_len--;
202
+ }
203
+ bus->cmd &= ~I2CD_RX_DMA_ENABLE;
204
} else {
205
data = i2c_recv(bus->bus);
206
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
207
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
208
uint8_t *pool_base = aic->bus_pool_base(bus);
209
210
return pool_base[0];
211
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
212
+ uint8_t data;
213
+
214
+ aspeed_i2c_dma_read(bus, &data);
215
+ return data;
216
} else {
217
return bus->buf;
218
}
219
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
220
*/
221
pool_start++;
222
}
223
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
224
+ if (bus->dma_len == 0) {
225
+ bus->cmd &= ~I2CD_M_TX_CMD;
226
+ }
227
} else {
228
bus->cmd &= ~I2CD_M_TX_CMD;
229
}
230
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
231
break;
232
}
233
234
+ if (!aic->has_dma &&
235
+ value & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE)) {
236
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
237
+ break;
238
+ }
239
+
240
aspeed_i2c_bus_handle_cmd(bus, value);
241
aspeed_i2c_bus_raise_interrupt(bus);
242
break;
243
+ case I2CD_DMA_ADDR:
244
+ if (!aic->has_dma) {
245
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
246
+ break;
247
+ }
248
+
249
+ bus->dma_addr = value & 0xfffffffc;
250
+ break;
251
+
252
+ case I2CD_DMA_LEN:
253
+ if (!aic->has_dma) {
254
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
255
+ break;
256
+ }
257
+
258
+ bus->dma_len = value & 0xfff;
259
+ if (!bus->dma_len) {
260
+ qemu_log_mask(LOG_UNIMP, "%s: invalid DMA length\n", __func__);
261
+ }
262
+ break;
263
264
default:
265
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
266
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_pool_ops = {
267
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
}
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
--
343
2.20.1
344
345
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
Sphinx 3.2 is pickier than earlier versions about the option:: markup,
2
and complains about our usage in qemu-option-trace.rst:
2
3
3
Most boards have this much.
4
../../docs/qemu-option-trace.rst.inc:4:Malformed option description
5
'[enable=]PATTERN', should look like "opt", "-opt args", "--opt args",
6
"/opt args" or "+opt args"
4
7
5
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
In this file, we're really trying to document the different parts of
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
the top-level --trace option, which qemu-nbd.rst and qemu-img.rst
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
10
have already introduced with an option:: markup. So it's not right
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
to use option:: here anyway. Switch to a different markup
9
Message-id: 20191119141211.25716-7-clg@kaod.org
12
(definition lists) which gives about the same formatted output.
13
14
(Unlike option::, this markup doesn't produce index entries; but
15
at the moment we don't do anything much with indexes anyway, and
16
in any case I think it doesn't make much sense to have individual
17
index entries for the sub-parts of the --trace option.)
18
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
21
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Message-id: 20201030174700.7204-3-peter.maydell@linaro.org
11
---
23
---
12
hw/misc/aspeed_sdmc.c | 6 +++---
24
docs/qemu-option-trace.rst.inc | 6 +++---
13
1 file changed, 3 insertions(+), 3 deletions(-)
25
1 file changed, 3 insertions(+), 3 deletions(-)
14
26
15
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
27
diff --git a/docs/qemu-option-trace.rst.inc b/docs/qemu-option-trace.rst.inc
16
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/aspeed_sdmc.c
29
--- a/docs/qemu-option-trace.rst.inc
18
+++ b/hw/misc/aspeed_sdmc.c
30
+++ b/docs/qemu-option-trace.rst.inc
19
@@ -XXX,XX +XXX,XX @@ static int ast2600_rambits(AspeedSDMCState *s)
31
@@ -XXX,XX +XXX,XX @@
20
}
32
21
33
Specify tracing options.
22
/* use a common default */
34
23
- warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M",
35
-.. option:: [enable=]PATTERN
24
+ warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 1024M",
36
+``[enable=]PATTERN``
25
s->ram_size);
37
26
- s->ram_size = 512 << 20;
38
Immediately enable events matching *PATTERN*
27
- return ASPEED_SDMC_AST2600_512MB;
39
(either event name or a globbing pattern). This option is only
28
+ s->ram_size = 1024 << 20;
40
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
29
+ return ASPEED_SDMC_AST2600_1024MB;
41
30
}
42
Use :option:`-trace help` to print a list of names of trace points.
31
43
32
static void aspeed_sdmc_reset(DeviceState *dev)
44
-.. option:: events=FILE
45
+``events=FILE``
46
47
Immediately enable events listed in *FILE*.
48
The file must contain one event name (as listed in the ``trace-events-all``
49
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
50
available if QEMU has been compiled with the ``simple``, ``log`` or
51
``ftrace`` tracing backend.
52
53
-.. option:: file=FILE
54
+``file=FILE``
55
56
Log output traces to *FILE*.
57
This option is only available if QEMU has been compiled with
33
--
58
--
34
2.20.1
59
2.20.1
35
60
36
61
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
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The segments can be disabled on the AST2600 (zero register value).
4
CS0 is open by default but not the other CS. This is closing the
5
access to the flash device in user mode and forbids scanning.
6
7
In the model, check the segment size and disable the associated region
8
when the value is zero.
9
10
Fixes: bcaa8ddd081c ("aspeed/smc: Add AST2600 support")
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
--- a/hw/ssi/aspeed_smc.c
23
+++ b/hw/ssi/aspeed_smc.c
24
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
25
uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
26
uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
27
28
- seg->addr = s->ctrl->flash_window_base + start_offset;
29
- seg->size = end_offset + MiB - start_offset;
30
+ if (reg) {
31
+ seg->addr = s->ctrl->flash_window_base + start_offset;
32
+ seg->size = end_offset + MiB - start_offset;
33
+ } else {
34
+ seg->addr = s->ctrl->flash_window_base;
35
+ seg->size = 0;
36
+ }
37
}
38
39
static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
40
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
41
memory_region_transaction_begin();
42
memory_region_set_size(&fl->mmio, seg.size);
43
memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
44
- memory_region_set_enabled(&fl->mmio, true);
45
+ memory_region_set_enabled(&fl->mmio, !!seg.size);
46
memory_region_transaction_commit();
47
48
s->regs[R_SEG_ADDR0 + cs] = regval;
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
50
}
51
52
/* Keep the segment in the overall flash window */
53
- if (seg.addr + seg.size <= s->ctrl->flash_window_base ||
54
- seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size) {
55
+ if (seg.size &&
56
+ (seg.addr + seg.size <= s->ctrl->flash_window_base ||
57
+ seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size)) {
58
qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : "
59
"[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
60
s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
61
--
62
2.20.1
63
64
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
Each CS has its own Read Timing Compensation Register on newer SoCs.
4
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
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>
10
---
11
include/hw/ssi/aspeed_smc.h | 1 +
12
hw/ssi/aspeed_smc.c | 17 ++++++++++++++---
13
2 files changed, 15 insertions(+), 3 deletions(-)
14
15
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/aspeed_smc.h
18
+++ b/include/hw/ssi/aspeed_smc.h
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 @@
32
/* Checksum Calculation Result */
33
#define R_DMA_CHECKSUM (0x90 / 4)
34
35
-/* Misc Control Register #2 */
36
+/* Read Timing Compensation Register */
37
#define R_TIMINGS (0x94 / 4)
38
39
/* SPI controller registers and bits (AST2400) */
40
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
41
.r_ce_ctrl = R_CE_CTRL,
42
.r_ctrl0 = R_CTRL0,
43
.r_timings = R_TIMINGS,
44
+ .nregs_timings = 1,
45
.conf_enable_w0 = CONF_ENABLE_W0,
46
.max_slaves = 5,
47
.segments = aspeed_segments_legacy,
48
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
49
.r_ce_ctrl = R_CE_CTRL,
50
.r_ctrl0 = R_CTRL0,
51
.r_timings = R_TIMINGS,
52
+ .nregs_timings = 1,
53
.conf_enable_w0 = CONF_ENABLE_W0,
54
.max_slaves = 5,
55
.segments = aspeed_segments_fmc,
56
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
57
.r_ce_ctrl = 0xff,
58
.r_ctrl0 = R_SPI_CTRL0,
59
.r_timings = R_SPI_TIMINGS,
60
+ .nregs_timings = 1,
61
.conf_enable_w0 = SPI_CONF_ENABLE_W0,
62
.max_slaves = 1,
63
.segments = aspeed_segments_spi,
64
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
65
.r_ce_ctrl = R_CE_CTRL,
66
.r_ctrl0 = R_CTRL0,
67
.r_timings = R_TIMINGS,
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
--
133
2.20.1
134
135
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
The randomness tests in the NPCM7xx RNG test fail intermittently
2
but fairly frequently. On my machine running the test in a loop:
3
while QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/npcm7xx_rng-test; do true; done
2
4
3
The Tacoma BMC board is replacement board for the BMC of the OpenPOWER
5
will fail in less than a minute with an error like:
4
Witherspoon system. It uses a AST2600 SoC instead of a AST2500 and the
6
ERROR:../../tests/qtest/npcm7xx_rng-test.c:256:test_first_byte_runs:
5
I2C layout is the same as it controls the same main board. Used for HW
7
assertion failed (calc_runs_p(buf.l, sizeof(buf) * BITS_PER_BYTE) > 0.01): (0.00286205989 > 0.01)
6
bringup.
7
8
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
(Failures have been observed on all 4 of the randomness tests,
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
not just first_byte_runs.)
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
11
Message-id: 20191119141211.25716-15-clg@kaod.org
12
It's not clear why these tests are failing like this, but intermittent
13
failures make CI and merge testing awkward, so disable running them
14
unless a developer specifically sets QEMU_TEST_FLAKY_RNG_TESTS when
15
running the test suite, until we work out the cause.
16
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Message-id: 20201102152454.8287-1-peter.maydell@linaro.org
20
Reviewed-by: Havard Skinnemoen <hskinnemoen@google.com>
13
---
21
---
14
hw/arm/aspeed.c | 28 ++++++++++++++++++++++++++++
22
tests/qtest/npcm7xx_rng-test.c | 14 ++++++++++----
15
1 file changed, 28 insertions(+)
23
1 file changed, 10 insertions(+), 4 deletions(-)
16
24
17
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
25
diff --git a/tests/qtest/npcm7xx_rng-test.c b/tests/qtest/npcm7xx_rng-test.c
18
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/aspeed.c
27
--- a/tests/qtest/npcm7xx_rng-test.c
20
+++ b/hw/arm/aspeed.c
28
+++ b/tests/qtest/npcm7xx_rng-test.c
21
@@ -XXX,XX +XXX,XX @@ struct AspeedBoardState {
29
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
22
#define AST2600_EVB_HW_STRAP1 0x000000C0
30
23
#define AST2600_EVB_HW_STRAP2 0x00000003
31
qtest_add_func("npcm7xx_rng/enable_disable", test_enable_disable);
24
32
qtest_add_func("npcm7xx_rng/rosel", test_rosel);
25
+/* Tacoma hardware value */
33
- qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
26
+#define TACOMA_BMC_HW_STRAP1 0x00000000
34
- qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
27
+#define TACOMA_BMC_HW_STRAP2 0x00000000
35
- qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
28
+
36
- qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
29
/*
37
+ /*
30
* The max ram region is for firmwares that scan the address space
38
+ * These tests fail intermittently; only run them on explicit
31
* with load/store to guess how much RAM the SoC has.
39
+ * request until we figure out why.
32
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
40
+ */
33
AspeedSoCState *soc = &bmc->soc;
41
+ if (getenv("QEMU_TEST_FLAKY_RNG_TESTS")) {
34
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
42
+ qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
35
43
+ qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
36
+ /* Bus 3: TODO bmp280@77 */
44
+ qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
37
+ /* Bus 3: TODO max31785@52 */
45
+ qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
38
+ /* Bus 3: TODO dps310@76 */
46
+ }
39
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
47
40
0x60);
48
qtest_start("-machine npcm750-evb");
41
49
ret = g_test_run();
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
--
50
--
85
2.20.1
51
2.20.1
86
52
87
53
diff view generated by jsdifflib