1
First arm pullreq of 5.0!
1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
2
2
3
The following changes since commit 084a398bf8aa7634738e6c6c0103236ee1b3b72f:
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
4
5
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2019-12-13 18:14:07 +0000)
6
4
7
are available in the Git repository at:
5
are available in the Git repository at:
8
6
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191216-1
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
10
8
11
for you to fetch changes up to f80741d107673f162e3b097fc76a1590036cc9d1:
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
12
10
13
target/arm: ensure we use current exception state after SCR update (2019-12-16 10:52:58 +0000)
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
target-arm queue:
14
target-arm queue:
17
* Add support for Cortex-M7 CPU
15
* more MVE instructions
18
* exynos4210_gic: Suppress gcc9 format-truncation warnings
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
19
* aspeed: Various minor bug fixes and improvements
17
* target/arm: Check NaN mode before silencing NaN
20
* aspeed: Add support for the tacoma-bmc board
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
21
* Honour HCR_EL32.TID1 and .TID2 trapping requirements
19
* hw/arm: Add basic power management to raspi.
22
* Handle trapping to EL2 of AArch32 VMRS instructions
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
23
* Handle AArch32 CP15 trapping via HSTR_EL2
24
* Add support for missing Jazelle system registers
25
* arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on
26
* Add support for DC CVAP & DC CVADP instructions
27
* Fix assertion when SCR.NS is changed in Secure-SVC &c
28
* enable SHPC native hot plug in arm ACPI
29
21
30
----------------------------------------------------------------
22
----------------------------------------------------------------
31
Alex Bennée (1):
23
Joe Komlodi (1):
32
target/arm: ensure we use current exception state after SCR update
24
target/arm: Check NaN mode before silencing NaN
33
25
34
Beata Michalska (4):
26
Maxim Uvarov (1):
35
tcg: cputlb: Add probe_read
27
hw/gpio/gpio_pwr: use shutdown function for reboot
36
Memory: Enable writeback for given memory region
37
migration: ram: Switch to ram block writeback
38
target/arm: Add support for DC CVAP & DC CVADP ins
39
28
40
Christophe Lyon (1):
29
Nolan Leake (1):
41
target/arm: Add support for cortex-m7 CPU
30
hw/arm: Add basic power management to raspi.
42
31
43
Cédric Le Goater (12):
32
Patrick Venture (2):
44
aspeed/i2c: Add support for pool buffer transfers
33
docs/system/arm: Add quanta-q7l1-bmc reference
45
aspeed/i2c: Check SRAM enablement on AST2500
34
docs/system/arm: Add quanta-gbs-bmc reference
46
aspeed: Add a DRAM memory region at the SoC level
47
aspeed/i2c: Add support for DMA transfers
48
aspeed/i2c: Add trace events
49
aspeed/smc: Restore default AHB window mapping at reset
50
aspeed/smc: Do not map disabled segment on the AST2600
51
aspeed/smc: Add AST2600 timings registers
52
aspeed: Remove AspeedBoardConfig array and use AspeedMachineClass
53
aspeed: Add support for the tacoma-bmc board
54
aspeed: Change the "scu" property definition
55
aspeed: Change the "nic" property definition
56
35
57
David Gibson (1):
36
Peter Maydell (18):
58
exynos4210_gic: Suppress gcc9 format-truncation warnings
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
39
target/arm: Make asimd_imm_const() public
40
target/arm: Use asimd_imm_const for A64 decode
41
target/arm: Use dup_const() instead of bitfield_replicate()
42
target/arm: Implement MVE logical immediate insns
43
target/arm: Implement MVE vector shift left by immediate insns
44
target/arm: Implement MVE vector shift right by immediate insns
45
target/arm: Implement MVE VSHLL
46
target/arm: Implement MVE VSRI, VSLI
47
target/arm: Implement MVE VSHRN, VRSHRN
48
target/arm: Implement MVE saturating narrowing shifts
49
target/arm: Implement MVE VSHLC
50
target/arm: Implement MVE VADDLV
51
target/arm: Implement MVE long shifts by immediate
52
target/arm: Implement MVE long shifts by register
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
59
55
60
Heyi Guo (2):
56
Philippe Mathieu-Daudé (1):
61
hw/arm/acpi: simplify AML bit and/or statement
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
62
hw/arm/acpi: enable SHPC native hot plug
63
58
64
Joel Stanley (4):
59
docs/system/arm/aspeed.rst | 1 +
65
aspeed/sdmc: Make ast2600 default 1G
60
docs/system/arm/nuvoton.rst | 5 +-
66
aspeed/scu: Fix W1C behavior
61
include/hw/arm/bcm2835_peripherals.h | 3 +-
67
watchdog/aspeed: Improve watchdog timeout message
62
include/hw/misc/bcm2835_powermgt.h | 29 ++
68
watchdog/aspeed: Fix AST2600 frequency behaviour
63
target/arm/helper-mve.h | 108 +++++++
64
target/arm/translate.h | 41 +++
65
target/arm/mve.decode | 177 ++++++++++-
66
target/arm/t32.decode | 71 ++++-
67
hw/arm/bcm2835_peripherals.c | 13 +-
68
hw/gpio/gpio_pwr.c | 2 +-
69
hw/misc/bcm2835_powermgt.c | 160 ++++++++++
70
target/arm/helper-a64.c | 12 +-
71
target/arm/mve_helper.c | 524 +++++++++++++++++++++++++++++++--
72
target/arm/translate-a64.c | 86 +-----
73
target/arm/translate-mve.c | 261 +++++++++++++++-
74
target/arm/translate-neon.c | 81 -----
75
target/arm/translate.c | 327 +++++++++++++++++++-
76
target/arm/vfp_helper.c | 24 +-
77
hw/misc/meson.build | 1 +
78
tests/acceptance/boot_linux_console.py | 43 +++
79
20 files changed, 1760 insertions(+), 209 deletions(-)
80
create mode 100644 include/hw/misc/bcm2835_powermgt.h
81
create mode 100644 hw/misc/bcm2835_powermgt.c
69
82
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: PanNengyuan <pannengyuan@huawei.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
Address Sanitizer shows memory leak in hw/gpio/aspeed_gpio.c:875
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
4
entry.
4
5
5
Reported-by: Euler Robot <euler.robot@huawei.com>
6
Signed-off-by: Patrick Venture <venture@google.com>
6
Signed-off-by: PanNengyuan <pannengyuan@huawei.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20210615192848.1065297-2-venture@google.com
9
Message-id: 20191119141211.25716-16-clg@kaod.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/gpio/aspeed_gpio.c | 1 +
11
docs/system/arm/aspeed.rst | 1 +
13
1 file changed, 1 insertion(+)
12
1 file changed, 1 insertion(+)
14
13
15
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/gpio/aspeed_gpio.c
16
--- a/docs/system/arm/aspeed.rst
18
+++ b/hw/gpio/aspeed_gpio.c
17
+++ b/docs/system/arm/aspeed.rst
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_init(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ etc.
20
pin_idx % GPIOS_PER_GROUP);
19
AST2400 SoC based machines :
21
object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
20
22
aspeed_gpio_set_pin, NULL, NULL, NULL);
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
23
+ g_free(name);
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
24
}
23
25
}
24
AST2500 SoC based machines :
26
25
27
--
26
--
28
2.20.1
27
2.20.1
29
28
30
29
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
Add line item reference to quanta-gbs-bmc machine.
4
an array of qemu_irq and passing it around, directly call
5
qdev_get_gpio_in() on the gic field.
6
4
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Signed-off-by: Patrick Venture <venture@google.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191209090306.20433-1-philmd@redhat.com
7
Message-id: 20210615192848.1065297-3-venture@google.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
[PMM: fixed underline Sphinx warning]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
include/hw/arm/virt.h | 1 +
11
docs/system/arm/nuvoton.rst | 5 +++--
14
hw/arm/virt.c | 109 +++++++++++++++++++++---------------------
12
1 file changed, 3 insertions(+), 2 deletions(-)
15
2 files changed, 55 insertions(+), 55 deletions(-)
16
13
17
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/virt.h
16
--- a/docs/system/arm/nuvoton.rst
20
+++ b/include/hw/arm/virt.h
17
+++ b/docs/system/arm/nuvoton.rst
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
18
@@ -XXX,XX +XXX,XX @@
22
uint32_t iommu_phandle;
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
23
int psci_conduit;
20
-=====================================================
24
hwaddr highest_gpa;
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
25
+ DeviceState *gic;
22
+================================================================
26
DeviceState *acpi_dev;
23
27
Notifier powerdown_notifier;
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
28
} VirtMachineState;
25
designed to be used as Baseboard Management Controllers (BMCs) in various
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
30
index XXXXXXX..XXXXXXX 100644
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
31
--- a/hw/arm/virt.c
28
Hyperscale applications. The following machines are based on this chip :
32
+++ b/hw/arm/virt.c
29
33
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
34
}
31
- ``quanta-gsj`` Quanta GSJ server BMC
35
}
32
36
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
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
--
34
--
394
2.20.1
35
2.20.1
395
36
396
37
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Nolan Leake <nolan@sigbus.net>
2
2
3
The I2C controller of the Aspeed AST2500 and AST2600 SoCs supports DMA
3
This is just enough to make reboot and poweroff work. Works for
4
transfers to and from DRAM.
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
5
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
6
A pair of registers defines the buffer address and the length of the
6
do what linux does for reset.
7
DMA transfer. The address should be aligned on 4 bytes and the maximum
7
8
length should not exceed 4K. The receive or transmit DMA transfer can
8
The watchdog timer functionality is not yet implemented.
9
then be initiated with specific bits in the Command/Status register of
9
10
the controller.
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
11
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
12
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
14
Message-id: 20210625210209.1870217-1-nolan@sigbus.net
15
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
[PMM: tweaked commit title; fixed region size to 0x200;
16
Message-id: 20191119141211.25716-5-clg@kaod.org
16
moved header file to include/]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
18
---
19
include/hw/i2c/aspeed_i2c.h | 5 ++
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
20
hw/arm/aspeed_ast2600.c | 5 ++
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
21
hw/arm/aspeed_soc.c | 5 ++
21
hw/arm/bcm2835_peripherals.c | 13 ++-
22
hw/i2c/aspeed_i2c.c | 126 +++++++++++++++++++++++++++++++++++-
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
23
4 files changed, 138 insertions(+), 3 deletions(-)
23
hw/misc/meson.build | 1 +
24
24
5 files changed, 204 insertions(+), 2 deletions(-)
25
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
26
create mode 100644 hw/misc/bcm2835_powermgt.c
27
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
26
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/i2c/aspeed_i2c.h
30
--- a/include/hw/arm/bcm2835_peripherals.h
28
+++ b/include/hw/i2c/aspeed_i2c.h
31
+++ b/include/hw/arm/bcm2835_peripherals.h
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
32
@@ -XXX,XX +XXX,XX @@
30
uint32_t cmd;
33
#include "hw/misc/bcm2835_mphi.h"
31
uint32_t buf;
34
#include "hw/misc/bcm2835_thermal.h"
32
uint32_t pool_ctrl;
35
#include "hw/misc/bcm2835_cprman.h"
33
+ uint32_t dma_addr;
36
+#include "hw/misc/bcm2835_powermgt.h"
34
+ uint32_t dma_len;
37
#include "hw/sd/sdhci.h"
35
} AspeedI2CBus;
38
#include "hw/sd/bcm2835_sdhost.h"
36
39
#include "hw/gpio/bcm2835_gpio.h"
37
typedef struct AspeedI2CState {
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
38
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
41
BCM2835MphiState mphi;
39
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
42
UnimplementedDeviceState txp;
40
43
UnimplementedDeviceState armtmr;
41
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
44
- UnimplementedDeviceState powermgt;
42
+ MemoryRegion *dram_mr;
45
+ BCM2835PowerMgtState powermgt;
43
+ AddressSpace dram_as;
46
BCM2835CprmanState cprman;
44
} AspeedI2CState;
47
PL011State uart0;
45
48
BCM2835AuxState aux;
46
#define ASPEED_I2C_CLASS(klass) \
49
diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h
47
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
50
new file mode 100644
48
hwaddr pool_base;
51
index XXXXXXX..XXXXXXX
49
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
52
--- /dev/null
50
bool check_sram;
53
+++ b/include/hw/misc/bcm2835_powermgt.h
51
+ bool has_dma;
54
@@ -XXX,XX +XXX,XX @@
52
55
+/*
53
} AspeedI2CClass;
56
+ * BCM2835 Power Management emulation
54
57
+ *
55
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
60
+ *
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
62
+ * See the COPYING file in the top-level directory.
63
+ */
64
+
65
+#ifndef BCM2835_POWERMGT_H
66
+#define BCM2835_POWERMGT_H
67
+
68
+#include "hw/sysbus.h"
69
+#include "qom/object.h"
70
+
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
73
+
74
+struct BCM2835PowerMgtState {
75
+ SysBusDevice busdev;
76
+ MemoryRegion iomem;
77
+
78
+ uint32_t rstc;
79
+ uint32_t rsts;
80
+ uint32_t wdog;
81
+};
82
+
83
+#endif
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
56
index XXXXXXX..XXXXXXX 100644
85
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/aspeed_ast2600.c
86
--- a/hw/arm/bcm2835_peripherals.c
58
+++ b/hw/arm/aspeed_ast2600.c
87
+++ b/hw/arm/bcm2835_peripherals.c
59
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
60
}
89
61
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
62
/* I2C */
91
OBJECT(&s->gpu_bus_mr));
63
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
92
+
64
+ if (err) {
93
+ /* Power Management */
65
+ error_propagate(errp, err);
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
95
+ TYPE_BCM2835_POWERMGT);
96
}
97
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
101
INTERRUPT_USB));
102
103
+ /* Power Management */
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
66
+ return;
105
+ return;
67
+ }
106
+ }
68
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
107
+
69
if (err) {
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
70
error_propagate(errp, err);
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
71
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
110
+
72
index XXXXXXX..XXXXXXX 100644
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
73
--- a/hw/arm/aspeed_soc.c
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
74
+++ b/hw/arm/aspeed_soc.c
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
76
}
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
77
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
78
/* I2C */
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
79
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
118
new file mode 100644
80
+ if (err) {
119
index XXXXXXX..XXXXXXX
81
+ error_propagate(errp, err);
120
--- /dev/null
121
+++ b/hw/misc/bcm2835_powermgt.c
122
@@ -XXX,XX +XXX,XX @@
123
+/*
124
+ * BCM2835 Power Management emulation
125
+ *
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
128
+ *
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
130
+ * See the COPYING file in the top-level directory.
131
+ */
132
+
133
+#include "qemu/osdep.h"
134
+#include "qemu/log.h"
135
+#include "qemu/module.h"
136
+#include "hw/misc/bcm2835_powermgt.h"
137
+#include "migration/vmstate.h"
138
+#include "sysemu/runstate.h"
139
+
140
+#define PASSWORD 0x5a000000
141
+#define PASSWORD_MASK 0xff000000
142
+
143
+#define R_RSTC 0x1c
144
+#define V_RSTC_RESET 0x20
145
+#define R_RSTS 0x20
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
147
+#define R_WDOG 0x24
148
+
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
150
+ unsigned size)
151
+{
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
153
+ uint32_t res = 0;
154
+
155
+ switch (offset) {
156
+ case R_RSTC:
157
+ res = s->rstc;
158
+ break;
159
+ case R_RSTS:
160
+ res = s->rsts;
161
+ break;
162
+ case R_WDOG:
163
+ res = s->wdog;
164
+ break;
165
+
166
+ default:
167
+ qemu_log_mask(LOG_UNIMP,
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
169
+ "\n", offset);
170
+ res = 0;
171
+ break;
172
+ }
173
+
174
+ return res;
175
+}
176
+
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
178
+ uint64_t value, unsigned size)
179
+{
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
181
+
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
183
+ qemu_log_mask(LOG_GUEST_ERROR,
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
186
+ value, offset);
82
+ return;
187
+ return;
83
+ }
188
+ }
84
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
189
+
85
if (err) {
190
+ value = value & ~PASSWORD_MASK;
86
error_propagate(errp, err);
191
+
87
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
192
+ switch (offset) {
88
index XXXXXXX..XXXXXXX 100644
193
+ case R_RSTC:
89
--- a/hw/i2c/aspeed_i2c.c
194
+ s->rstc = value;
90
+++ b/hw/i2c/aspeed_i2c.c
195
+ if (value & V_RSTC_RESET) {
91
@@ -XXX,XX +XXX,XX @@
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
92
#include "migration/vmstate.h"
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
93
#include "qemu/log.h"
198
+ } else {
94
#include "qemu/module.h"
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
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
+ }
200
+ }
177
+ }
201
+ }
178
+ bus->cmd &= ~I2CD_TX_DMA_ENABLE;
202
+ break;
179
} else {
203
+ case R_RSTS:
180
ret = i2c_send(bus->bus, bus->buf);
204
+ qemu_log_mask(LOG_UNIMP,
181
}
205
+ "bcm2835_powermgt_write: RSTS\n");
182
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
206
+ s->rsts = value;
183
bus->pool_ctrl &= ~(0xff << 24);
207
+ break;
184
bus->pool_ctrl |= (i & 0xff) << 24;
208
+ case R_WDOG:
185
bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
209
+ qemu_log_mask(LOG_UNIMP,
186
+ } else if (bus->cmd & I2CD_RX_DMA_ENABLE) {
210
+ "bcm2835_powermgt_write: WDOG\n");
187
+ uint8_t data;
211
+ s->wdog = value;
188
+
212
+ break;
189
+ while (bus->dma_len) {
213
+
190
+ MemTxResult result;
214
+ default:
191
+
215
+ qemu_log_mask(LOG_UNIMP,
192
+ data = i2c_recv(bus->bus);
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
193
+ result = address_space_write(&s->dram_as, bus->dma_addr,
217
+ "\n", offset);
194
+ MEMTXATTRS_UNSPECIFIED, &data, 1);
218
+ break;
195
+ if (result != MEMTX_OK) {
219
+ }
196
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
220
+}
197
+ __func__, bus->dma_addr);
221
+
198
+ return;
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
199
+ }
223
+ .read = bcm2835_powermgt_read,
200
+ bus->dma_addr++;
224
+ .write = bcm2835_powermgt_write,
201
+ bus->dma_len--;
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
202
+ }
226
+ .impl.min_access_size = 4,
203
+ bus->cmd &= ~I2CD_RX_DMA_ENABLE;
227
+ .impl.max_access_size = 4,
204
} else {
228
+};
205
data = i2c_recv(bus->bus);
229
+
206
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
207
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
231
+ .name = TYPE_BCM2835_POWERMGT,
208
uint8_t *pool_base = aic->bus_pool_base(bus);
232
+ .version_id = 1,
209
233
+ .minimum_version_id = 1,
210
return pool_base[0];
234
+ .fields = (VMStateField[]) {
211
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
212
+ uint8_t data;
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
213
+
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
214
+ aspeed_i2c_dma_read(bus, &data);
238
+ VMSTATE_END_OF_LIST()
215
+ return data;
239
+ }
216
} else {
240
+};
217
return bus->buf;
241
+
218
}
242
+static void bcm2835_powermgt_init(Object *obj)
219
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
243
+{
220
*/
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
221
pool_start++;
245
+
222
}
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
223
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
247
+ TYPE_BCM2835_POWERMGT, 0x200);
224
+ if (bus->dma_len == 0) {
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
225
+ bus->cmd &= ~I2CD_M_TX_CMD;
249
+}
226
+ }
250
+
227
} else {
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
228
bus->cmd &= ~I2CD_M_TX_CMD;
252
+{
229
}
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
230
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
254
+
231
break;
255
+ /* https://elinux.org/BCM2835_registers#PM */
232
}
256
+ s->rstc = 0x00000102;
233
257
+ s->rsts = 0x00001000;
234
+ if (!aic->has_dma &&
258
+ s->wdog = 0x00000000;
235
+ value & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE)) {
259
+}
236
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
260
+
237
+ break;
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
238
+ }
262
+{
239
+
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
240
aspeed_i2c_bus_handle_cmd(bus, value);
264
+
241
aspeed_i2c_bus_raise_interrupt(bus);
265
+ dc->reset = bcm2835_powermgt_reset;
242
break;
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
243
+ case I2CD_DMA_ADDR:
267
+}
244
+ if (!aic->has_dma) {
268
+
245
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
269
+static TypeInfo bcm2835_powermgt_info = {
246
+ break;
270
+ .name = TYPE_BCM2835_POWERMGT,
247
+ }
271
+ .parent = TYPE_SYS_BUS_DEVICE,
248
+
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
249
+ bus->dma_addr = value & 0xfffffffc;
273
+ .class_init = bcm2835_powermgt_class_init,
250
+ break;
274
+ .instance_init = bcm2835_powermgt_init,
251
+
275
+};
252
+ case I2CD_DMA_LEN:
276
+
253
+ if (!aic->has_dma) {
277
+static void bcm2835_powermgt_register_types(void)
254
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
278
+{
255
+ break;
279
+ type_register_static(&bcm2835_powermgt_info);
256
+ }
280
+}
257
+
281
+
258
+ bus->dma_len = value & 0xfff;
282
+type_init(bcm2835_powermgt_register_types)
259
+ if (!bus->dma_len) {
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
260
+ qemu_log_mask(LOG_UNIMP, "%s: invalid DMA length\n", __func__);
284
index XXXXXXX..XXXXXXX 100644
261
+ }
285
--- a/hw/misc/meson.build
262
+ break;
286
+++ b/hw/misc/meson.build
263
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
264
default:
288
'bcm2835_rng.c',
265
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
289
'bcm2835_thermal.c',
266
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_pool_ops = {
290
'bcm2835_cprman.c',
267
291
+ 'bcm2835_powermgt.c',
268
static const VMStateDescription aspeed_i2c_bus_vmstate = {
292
))
269
.name = TYPE_ASPEED_I2C,
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
270
- .version_id = 2,
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
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
--
295
--
343
2.20.1
296
2.20.1
344
297
345
298
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
After the introduction of generic PCIe root port and PCIe-PCI bridge,
3
Add a test booting and quickly shutdown a raspi2 machine,
4
we will also have SHPC controller on ARM, so just enable SHPC native
4
to test the power management model:
5
hot plug.
6
5
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
8
console: [ 0.000000] Linux version 4.14.98-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1200 SMP Tue Feb 12 20:27:48 GMT 2019
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
10
console: [ 0.000000] CPU: div instructions available: patching division code
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
12
console: [ 0.000000] OF: fdt: Machine model: Raspberry Pi 2 Model B
13
...
14
console: Boot successful.
15
console: cat /proc/cpuinfo
16
console: / # cat /proc/cpuinfo
17
...
18
console: processor : 3
19
console: model name : ARMv7 Processor rev 5 (v7l)
20
console: BogoMIPS : 125.00
21
console: Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
22
console: CPU implementer : 0x41
23
console: CPU architecture: 7
24
console: CPU variant : 0x0
25
console: CPU part : 0xc07
26
console: CPU revision : 5
27
console: Hardware : BCM2835
28
console: Revision : 0000
29
console: Serial : 0000000000000000
30
console: cat /proc/iomem
31
console: / # cat /proc/iomem
32
console: 00000000-3bffffff : System RAM
33
console: 00008000-00afffff : Kernel code
34
console: 00c00000-00d468ef : Kernel data
35
console: 3f006000-3f006fff : dwc_otg
36
console: 3f007000-3f007eff : /soc/dma@7e007000
37
console: 3f00b880-3f00b8bf : /soc/mailbox@7e00b880
38
console: 3f100000-3f100027 : /soc/watchdog@7e100000
39
console: 3f101000-3f102fff : /soc/cprman@7e101000
40
console: 3f200000-3f2000b3 : /soc/gpio@7e200000
41
PASS (24.59 s)
42
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
43
JOB TIME : 25.02 s
8
44
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Cc: Peter Maydell <peter.maydell@linaro.org>
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
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>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
49
---
19
hw/arm/virt-acpi-build.c | 7 ++++++-
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
20
tests/data/acpi/virt/DSDT | Bin 18462 -> 18462 bytes
51
1 file changed, 43 insertions(+)
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
52
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
26
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
55
--- a/tests/acceptance/boot_linux_console.py
28
+++ b/hw/arm/virt-acpi-build.c
56
+++ b/tests/acceptance/boot_linux_console.py
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
57
@@ -XXX,XX +XXX,XX @@
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
58
from avocado import skip
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
59
from avocado import skipUnless
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
60
from avocado_qemu import Test
33
- aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
61
+from avocado_qemu import exec_command
62
from avocado_qemu import exec_command_and_wait_for_pattern
63
from avocado_qemu import interrupt_interactive_console_until_pattern
64
from avocado_qemu import wait_for_console_pattern
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
66
"""
67
self.do_test_arm_raspi2(0)
68
69
+ def test_arm_raspi2_initrd(self):
70
+ """
71
+ :avocado: tags=arch:arm
72
+ :avocado: tags=machine:raspi2
73
+ """
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
75
+ 'pool/main/r/raspberrypi-firmware/'
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
34
+
81
+
35
+ /*
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
36
+ * Allow OS control for all 5 features:
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
37
+ * PCIeHotplug SHPCHotplug PME AER PCIeCapability.
84
+ 'arm/rootfs-armv7a.cpio.gz')
38
+ */
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
39
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F),
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
40
aml_name("CTRL")));
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
41
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
42
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
89
+
43
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
90
+ self.vm.set_console()
44
index XXXXXXX..XXXXXXX 100644
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
45
GIT binary patch
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
46
delta 28
93
+ 'panic=-1 noreboot ' +
47
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
94
+ 'dwc_otg.fiq_fsm_enable=0')
48
95
+ self.vm.add_args('-kernel', kernel_path,
49
delta 28
96
+ '-dtb', dtb_path,
50
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
97
+ '-initrd', initrd_path,
51
98
+ '-append', kernel_command_line,
52
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
99
+ '-no-reboot')
53
index XXXXXXX..XXXXXXX 100644
100
+ self.vm.launch()
54
GIT binary patch
101
+ self.wait_for_console_pattern('Boot successful.')
55
delta 28
102
+
56
kcmcaUi}Cs_MlP3NmymE@1_mbija=*8809zbbeqQp0Eq|*2mk;8
103
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
57
104
+ 'BCM2835')
58
delta 28
105
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
59
kcmcaUi}Cs_MlP3NmymE@1_ma@ja=*87-cu_beqQp0ErX{2mk;8
106
+ '/soc/cprman@7e101000')
60
107
+ exec_command(self, 'halt')
61
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
108
+ # Wait for VM to shut down gracefully
62
index XXXXXXX..XXXXXXX 100644
109
+ self.vm.wait()
63
GIT binary patch
110
+
64
delta 28
111
def test_arm_exynos4210_initrd(self):
65
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
112
"""
66
113
:avocado: tags=arch:arm
67
delta 28
68
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
69
70
--
114
--
71
2.20.1
115
2.20.1
72
116
73
117
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
HCR_EL2.TID3 requires that AArch32 reads of MVFR[012] are trapped to
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
4
EL2, and HCR_EL2.TID0 does the same for reads of FPSID.
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
5
In order to handle this, introduce a new TCG helper function that
5
assert due to fpst->default_nan_mode being set.
6
checks for these control bits before executing the VMRC instruction.
7
6
8
Tested with a hacked-up version of KVM/arm64 that sets the control
7
To avoid this, we check to see what NaN mode we're running in before we call
9
bits for 32bit guests.
8
floatxx_silence_nan().
10
9
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-4-maz@kernel.org
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
15
[PMM: move helper declaration to helper.h; make it
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
TCG_CALL_NO_WG]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
15
---
19
target/arm/helper.h | 2 ++
16
target/arm/helper-a64.c | 12 +++++++++---
20
target/arm/translate-vfp.inc.c | 20 ++++++++++++++++----
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
21
target/arm/vfp_helper.c | 29 +++++++++++++++++++++++++++++
18
2 files changed, 27 insertions(+), 9 deletions(-)
22
3 files changed, 47 insertions(+), 4 deletions(-)
23
19
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
22
--- a/target/arm/helper-a64.c
27
+++ b/target/arm/helper.h
23
+++ b/target/arm/helper-a64.c
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG, f64, f64, ptr)
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
29
DEF_HELPER_FLAGS_2(vjcvt, TCG_CALL_NO_RWG, i32, f64, env)
25
float16 nan = a;
30
DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
26
if (float16_is_signaling_nan(a, fpst)) {
31
27
float_raise(float_flag_invalid, fpst);
32
+DEF_HELPER_FLAGS_3(check_hcr_el2_trap, TCG_CALL_NO_WG, void, env, i32, i32)
28
- nan = float16_silence_nan(a, fpst);
33
+
29
+ if (!fpst->default_nan_mode) {
34
/* neon_helper.c */
30
+ nan = float16_silence_nan(a, fpst);
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
+ }
31
+ }
64
+ /* fall through */
32
}
65
+ case ARM_VFP_FPEXC:
33
if (fpst->default_nan_mode) {
66
+ case ARM_VFP_FPINST:
34
nan = float16_default_nan(fpst);
67
+ case ARM_VFP_FPINST2:
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
68
tmp = load_cpu_field(vfp.xregs[a->reg]);
36
float32 nan = a;
69
break;
37
if (float32_is_signaling_nan(a, fpst)) {
70
case ARM_VFP_FPSCR:
38
float_raise(float_flag_invalid, fpst);
39
- nan = float32_silence_nan(a, fpst);
40
+ if (!fpst->default_nan_mode) {
41
+ nan = float32_silence_nan(a, fpst);
42
+ }
43
}
44
if (fpst->default_nan_mode) {
45
nan = float32_default_nan(fpst);
46
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
47
float64 nan = a;
48
if (float64_is_signaling_nan(a, fpst)) {
49
float_raise(float_flag_invalid, fpst);
50
- nan = float64_silence_nan(a, fpst);
51
+ if (!fpst->default_nan_mode) {
52
+ nan = float64_silence_nan(a, fpst);
53
+ }
54
}
55
if (fpst->default_nan_mode) {
56
nan = float64_default_nan(fpst);
71
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
57
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
72
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/vfp_helper.c
59
--- a/target/arm/vfp_helper.c
74
+++ b/target/arm/vfp_helper.c
60
+++ b/target/arm/vfp_helper.c
75
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frint64_d)(float64 f, void *fpst)
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
76
return frint_d(f, fpst, 64);
62
float16 nan = f16;
77
}
63
if (float16_is_signaling_nan(f16, fpst)) {
78
64
float_raise(float_flag_invalid, fpst);
79
+void HELPER(check_hcr_el2_trap)(CPUARMState *env, uint32_t rt, uint32_t reg)
65
- nan = float16_silence_nan(f16, fpst);
80
+{
66
+ if (!fpst->default_nan_mode) {
81
+ uint32_t syndrome;
67
+ nan = float16_silence_nan(f16, fpst);
82
+
68
+ }
83
+ switch (reg) {
69
}
84
+ case ARM_VFP_MVFR0:
70
if (fpst->default_nan_mode) {
85
+ case ARM_VFP_MVFR1:
71
nan = float16_default_nan(fpst);
86
+ case ARM_VFP_MVFR2:
72
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
87
+ if (!(arm_hcr_el2_eff(env) & HCR_TID3)) {
73
float32 nan = f32;
88
+ return;
74
if (float32_is_signaling_nan(f32, fpst)) {
89
+ }
75
float_raise(float_flag_invalid, fpst);
90
+ break;
76
- nan = float32_silence_nan(f32, fpst);
91
+ case ARM_VFP_FPSID:
77
+ if (!fpst->default_nan_mode) {
92
+ if (!(arm_hcr_el2_eff(env) & HCR_TID0)) {
78
+ nan = float32_silence_nan(f32, fpst);
93
+ return;
79
+ }
94
+ }
80
}
95
+ break;
81
if (fpst->default_nan_mode) {
96
+ default:
82
nan = float32_default_nan(fpst);
97
+ g_assert_not_reached();
83
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
98
+ }
84
float64 nan = f64;
99
+
85
if (float64_is_signaling_nan(f64, fpst)) {
100
+ syndrome = ((EC_FPIDTRAP << ARM_EL_EC_SHIFT)
86
float_raise(float_flag_invalid, fpst);
101
+ | ARM_EL_IL
87
- nan = float64_silence_nan(f64, fpst);
102
+ | (1 << 24) | (0xe << 20) | (7 << 14)
88
+ if (!fpst->default_nan_mode) {
103
+ | (reg << 10) | (rt << 5) | 1);
89
+ nan = float64_silence_nan(f64, fpst);
104
+
90
+ }
105
+ raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
91
}
106
+}
92
if (fpst->default_nan_mode) {
107
+
93
nan = float64_default_nan(fpst);
108
#endif
94
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
95
float16 nan = f16;
96
if (float16_is_signaling_nan(f16, s)) {
97
float_raise(float_flag_invalid, s);
98
- nan = float16_silence_nan(f16, s);
99
+ if (!s->default_nan_mode) {
100
+ nan = float16_silence_nan(f16, fpstp);
101
+ }
102
}
103
if (s->default_nan_mode) {
104
nan = float16_default_nan(s);
105
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
106
float32 nan = f32;
107
if (float32_is_signaling_nan(f32, s)) {
108
float_raise(float_flag_invalid, s);
109
- nan = float32_silence_nan(f32, s);
110
+ if (!s->default_nan_mode) {
111
+ nan = float32_silence_nan(f32, fpstp);
112
+ }
113
}
114
if (s->default_nan_mode) {
115
nan = float32_default_nan(s);
116
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
117
float64 nan = f64;
118
if (float64_is_signaling_nan(f64, s)) {
119
float_raise(float_flag_invalid, s);
120
- nan = float64_silence_nan(f64, s);
121
+ if (!s->default_nan_mode) {
122
+ nan = float64_silence_nan(f64, fpstp);
123
+ }
124
}
125
if (s->default_nan_mode) {
126
nan = float64_default_nan(s);
109
--
127
--
110
2.20.1
128
2.20.1
111
129
112
130
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
4
an array of qemu_irq and passing it around, directly call
4
function has to be used for machine shutdown. Otherwise we cause
5
qdev_get_gpio_in() on the gic field.
5
a reset with a bogus "cause" value, when we intended a shutdown.
6
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@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>
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
10
[PMM: tweaked commit message]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
hw/arm/sbsa-ref.c | 86 +++++++++++++++++++++++------------------------
13
hw/gpio/gpio_pwr.c | 2 +-
13
1 file changed, 42 insertions(+), 44 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
18
--- a/hw/gpio/gpio_pwr.c
18
+++ b/hw/arm/sbsa-ref.c
19
+++ b/hw/gpio/gpio_pwr.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct {
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
20
void *fdt;
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
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
}
30
31
-static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
32
+static void create_gic(SBSAMachineState *sms)
33
{
22
{
34
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
23
if (level) {
35
- DeviceState *gicdev;
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
36
SysBusDevice *gicbusdev;
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
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
}
102
103
-static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
104
+static void create_uart(const SBSAMachineState *sms, int uart,
105
MemoryRegion *mem, Chardev *chr)
106
{
107
hwaddr base = sbsa_ref_memmap[uart].base;
108
@@ -XXX,XX +XXX,XX @@ static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
109
qdev_init_nofail(dev);
110
memory_region_add_subregion(mem, base,
111
sysbus_mmio_get_region(s, 0));
112
- sysbus_connect_irq(s, 0, pic[irq]);
113
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(sms->gic, irq));
114
}
115
116
-static void create_rtc(const SBSAMachineState *sms, qemu_irq *pic)
117
+static void create_rtc(const SBSAMachineState *sms)
118
{
119
hwaddr base = sbsa_ref_memmap[SBSA_RTC].base;
120
int irq = sbsa_ref_irqmap[SBSA_RTC];
121
122
- sysbus_create_simple("pl031", base, pic[irq]);
123
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(sms->gic, irq));
124
}
125
126
static DeviceState *gpio_key_dev;
127
@@ -XXX,XX +XXX,XX @@ static Notifier sbsa_ref_powerdown_notifier = {
128
.notify = sbsa_ref_powerdown_req
129
};
130
131
-static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
132
+static void create_gpio(const SBSAMachineState *sms)
133
{
134
DeviceState *pl061_dev;
135
hwaddr base = sbsa_ref_memmap[SBSA_GPIO].base;
136
int irq = sbsa_ref_irqmap[SBSA_GPIO];
137
138
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
139
+ pl061_dev = sysbus_create_simple("pl061", base,
140
+ qdev_get_gpio_in(sms->gic, irq));
141
142
gpio_key_dev = sysbus_create_simple("gpio-key", -1,
143
qdev_get_gpio_in(pl061_dev, 3));
144
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
145
qemu_register_powerdown_notifier(&sbsa_ref_powerdown_notifier);
146
}
147
148
-static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
149
+static void create_ahci(const SBSAMachineState *sms)
150
{
151
hwaddr base = sbsa_ref_memmap[SBSA_AHCI].base;
152
int irq = sbsa_ref_irqmap[SBSA_AHCI];
153
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
154
qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS);
155
qdev_init_nofail(dev);
156
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
157
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
158
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
159
160
sysahci = SYSBUS_AHCI(dev);
161
ahci = &sysahci->ahci;
162
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
163
}
26
}
164
}
27
}
165
28
166
-static void create_ehci(const SBSAMachineState *sms, qemu_irq *pic)
167
+static void create_ehci(const SBSAMachineState *sms)
168
{
169
hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
170
int irq = sbsa_ref_irqmap[SBSA_EHCI];
171
172
- sysbus_create_simple("platform-ehci-usb", base, pic[irq]);
173
+ sysbus_create_simple("platform-ehci-usb", base,
174
+ qdev_get_gpio_in(sms->gic, irq));
175
}
176
177
-static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
178
- PCIBus *bus)
179
+static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
180
{
181
hwaddr base = sbsa_ref_memmap[SBSA_SMMU].base;
182
int irq = sbsa_ref_irqmap[SBSA_SMMU];
183
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
184
qdev_init_nofail(dev);
185
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
186
for (i = 0; i < NUM_SMMU_IRQS; i++) {
187
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
188
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
189
+ qdev_get_gpio_in(sms->gic, irq + 1));
190
}
191
}
192
193
-static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
194
+static void create_pcie(SBSAMachineState *sms)
195
{
196
hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base;
197
hwaddr size_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].size;
198
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
199
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
200
201
for (i = 0; i < GPEX_NUM_IRQS; i++) {
202
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
203
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
204
+ qdev_get_gpio_in(sms->gic, irq + 1));
205
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
206
}
207
208
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
209
210
pci_create_simple(pci->bus, -1, "VGA");
211
212
- create_smmu(sms, pic, pci->bus);
213
+ create_smmu(sms, pci->bus);
214
}
215
216
static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
217
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
218
bool firmware_loaded;
219
const CPUArchIdList *possible_cpus;
220
int n, sbsa_max_cpus;
221
- qemu_irq pic[NUM_IRQS];
222
223
if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) {
224
error_report("sbsa-ref: CPU type other than the built-in "
225
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
226
227
create_secure_ram(sms, secure_sysmem);
228
229
- create_gic(sms, pic);
230
+ create_gic(sms);
231
232
- create_uart(sms, pic, SBSA_UART, sysmem, serial_hd(0));
233
- create_uart(sms, pic, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
234
+ create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
235
+ create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
236
/* Second secure UART for RAS and MM from EL0 */
237
- create_uart(sms, pic, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
238
+ create_uart(sms, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
239
240
- create_rtc(sms, pic);
241
+ create_rtc(sms);
242
243
- create_gpio(sms, pic);
244
+ create_gpio(sms);
245
246
- create_ahci(sms, pic);
247
+ create_ahci(sms);
248
249
- create_ehci(sms, pic);
250
+ create_ehci(sms);
251
252
- create_pcie(sms, pic);
253
+ create_pcie(sms);
254
255
sms->bootinfo.ram_size = machine->ram_size;
256
sms->bootinfo.nb_cpus = smp_cpus;
257
--
29
--
258
2.20.1
30
2.20.1
259
31
260
32
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
In do_ldst(), the calculation of the offset needs to be based on the
2
size of the memory access, not the size of the elements in the
3
vector. This meant we were getting it wrong for the widening and
4
narrowing variants of the various VLDR and VSTR insns.
2
5
3
AspeedBoardConfig is a redundant way to define class attributes and it
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
complexifies the machine definition and initialization.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
9
---
10
target/arm/translate-mve.c | 17 +++++++++--------
11
1 file changed, 9 insertions(+), 8 deletions(-)
5
12
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-14-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/aspeed.h | 24 ++--
13
hw/arm/aspeed.c | 243 ++++++++++++++++++++++------------------
14
2 files changed, 143 insertions(+), 124 deletions(-)
15
16
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/aspeed.h
15
--- a/target/arm/translate-mve.c
19
+++ b/include/hw/arm/aspeed.h
16
+++ b/target/arm/translate-mve.c
20
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
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
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
67
- const AspeedBoardConfig *cfg)
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
68
+static void aspeed_machine_init(MachineState *machine)
23
+ unsigned msize)
69
{
24
{
70
AspeedBoardState *bmc;
25
TCGv_i32 addr;
71
+ AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
26
uint32_t offset;
72
AspeedSoCClass *sc;
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
73
DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
28
return true;
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
}
29
}
118
30
119
for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
31
- offset = a->imm << a->size;
120
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
32
+ offset = a->imm << msize;
121
0x60);
33
if (!a->a) {
34
offset = -offset;
35
}
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
37
{ gen_helper_mve_vstrw, gen_helper_mve_vldrw },
38
{ NULL, NULL }
39
};
40
- return do_ldst(s, a, ldstfns[a->size][a->l]);
41
+ return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
122
}
42
}
123
43
124
-static void aspeed_machine_init(MachineState *machine)
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
125
-{
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
126
- AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
127
-
47
{ \
128
- aspeed_board_init(machine, amc->board);
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
129
-}
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
130
-
50
{ NULL, gen_helper_mve_##ULD }, \
131
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
51
}; \
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
54
}
55
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
62
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
132
{
64
{
133
MachineClass *mc = MACHINE_CLASS(oc);
134
- AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
135
- const AspeedBoardConfig *board = data;
136
137
- mc->desc = board->desc;
138
mc->init = aspeed_machine_init;
139
mc->max_cpus = ASPEED_CPUS_NUM;
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->no_parallel = 1;
143
- if (board->ram) {
144
- mc->default_ram_size = board->ram;
145
- }
146
- amc->board = board;
147
}
148
149
-static const TypeInfo aspeed_machine_type = {
150
- .name = TYPE_ASPEED_MACHINE,
151
- .parent = TYPE_MACHINE,
152
- .instance_size = sizeof(AspeedMachine),
153
- .class_size = sizeof(AspeedMachineClass),
154
- .abstract = true,
155
-};
156
-
157
-static const AspeedBoardConfig aspeed_boards[] = {
158
- {
159
- .name = MACHINE_TYPE_NAME("palmetto-bmc"),
160
- .desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)",
161
- .soc_name = "ast2400-a1",
162
- .hw_strap1 = PALMETTO_BMC_HW_STRAP1,
163
- .fmc_model = "n25q256a",
164
- .spi_model = "mx25l25635e",
165
- .num_cs = 1,
166
- .i2c_init = palmetto_bmc_i2c_init,
167
- .ram = 256 * MiB,
168
- }, {
169
- .name = MACHINE_TYPE_NAME("ast2500-evb"),
170
- .desc = "Aspeed AST2500 EVB (ARM1176)",
171
- .soc_name = "ast2500-a1",
172
- .hw_strap1 = AST2500_EVB_HW_STRAP1,
173
- .fmc_model = "w25q256",
174
- .spi_model = "mx25l25635e",
175
- .num_cs = 1,
176
- .i2c_init = ast2500_evb_i2c_init,
177
- .ram = 512 * MiB,
178
- }, {
179
- .name = MACHINE_TYPE_NAME("romulus-bmc"),
180
- .desc = "OpenPOWER Romulus BMC (ARM1176)",
181
- .soc_name = "ast2500-a1",
182
- .hw_strap1 = ROMULUS_BMC_HW_STRAP1,
183
- .fmc_model = "n25q256a",
184
- .spi_model = "mx66l1g45g",
185
- .num_cs = 2,
186
- .i2c_init = romulus_bmc_i2c_init,
187
- .ram = 512 * MiB,
188
- }, {
189
- .name = MACHINE_TYPE_NAME("swift-bmc"),
190
- .desc = "OpenPOWER Swift BMC (ARM1176)",
191
- .soc_name = "ast2500-a1",
192
- .hw_strap1 = SWIFT_BMC_HW_STRAP1,
193
- .fmc_model = "mx66l1g45g",
194
- .spi_model = "mx66l1g45g",
195
- .num_cs = 2,
196
- .i2c_init = swift_bmc_i2c_init,
197
- .ram = 512 * MiB,
198
- }, {
199
- .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
200
- .desc = "OpenPOWER Witherspoon BMC (ARM1176)",
201
- .soc_name = "ast2500-a1",
202
- .hw_strap1 = WITHERSPOON_BMC_HW_STRAP1,
203
- .fmc_model = "mx25l25635e",
204
- .spi_model = "mx66l1g45g",
205
- .num_cs = 2,
206
- .i2c_init = witherspoon_bmc_i2c_init,
207
- .ram = 512 * MiB,
208
- }, {
209
- .name = MACHINE_TYPE_NAME("ast2600-evb"),
210
- .desc = "Aspeed AST2600 EVB (Cortex A7)",
211
- .soc_name = "ast2600-a0",
212
- .hw_strap1 = AST2600_EVB_HW_STRAP1,
213
- .hw_strap2 = AST2600_EVB_HW_STRAP2,
214
- .fmc_model = "w25q512jv",
215
- .spi_model = "mx66u51235f",
216
- .num_cs = 1,
217
- .i2c_init = ast2600_evb_i2c_init,
218
- .ram = 1 * GiB,
219
- },
220
-};
221
-
222
-static void aspeed_machine_types(void)
223
+static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data)
224
{
225
- int i;
226
+ MachineClass *mc = MACHINE_CLASS(oc);
227
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
228
229
- type_register_static(&aspeed_machine_type);
230
- for (i = 0; i < ARRAY_SIZE(aspeed_boards); ++i) {
231
- TypeInfo ti = {
232
- .name = aspeed_boards[i].name,
233
- .parent = TYPE_ASPEED_MACHINE,
234
- .class_init = aspeed_machine_class_init,
235
- .class_data = (void *)&aspeed_boards[i],
236
- };
237
- type_register(&ti);
238
+ mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)";
239
+ amc->soc_name = "ast2400-a1";
240
+ amc->hw_strap1 = PALMETTO_BMC_HW_STRAP1;
241
+ amc->fmc_model = "n25q256a";
242
+ amc->spi_model = "mx25l25635e";
243
+ amc->num_cs = 1;
244
+ amc->i2c_init = palmetto_bmc_i2c_init;
245
+ mc->default_ram_size = 256 * MiB;
246
+};
247
+
248
+static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data)
249
+{
250
+ MachineClass *mc = MACHINE_CLASS(oc);
251
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
252
+
253
+ mc->desc = "Aspeed AST2500 EVB (ARM1176)";
254
+ amc->soc_name = "ast2500-a1";
255
+ amc->hw_strap1 = AST2500_EVB_HW_STRAP1;
256
+ amc->fmc_model = "w25q256";
257
+ amc->spi_model = "mx25l25635e";
258
+ amc->num_cs = 1;
259
+ amc->i2c_init = ast2500_evb_i2c_init;
260
+ mc->default_ram_size = 512 * MiB;
261
+};
262
+
263
+static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data)
264
+{
265
+ MachineClass *mc = MACHINE_CLASS(oc);
266
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
267
+
268
+ mc->desc = "OpenPOWER Romulus BMC (ARM1176)";
269
+ amc->soc_name = "ast2500-a1";
270
+ amc->hw_strap1 = ROMULUS_BMC_HW_STRAP1;
271
+ amc->fmc_model = "n25q256a";
272
+ amc->spi_model = "mx66l1g45g";
273
+ amc->num_cs = 2;
274
+ amc->i2c_init = romulus_bmc_i2c_init;
275
+ mc->default_ram_size = 512 * MiB;
276
+};
277
+
278
+static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data)
279
+{
280
+ MachineClass *mc = MACHINE_CLASS(oc);
281
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
282
+
283
+ mc->desc = "OpenPOWER Swift BMC (ARM1176)";
284
+ amc->soc_name = "ast2500-a1";
285
+ amc->hw_strap1 = SWIFT_BMC_HW_STRAP1;
286
+ amc->fmc_model = "mx66l1g45g";
287
+ amc->spi_model = "mx66l1g45g";
288
+ amc->num_cs = 2;
289
+ amc->i2c_init = swift_bmc_i2c_init;
290
+ mc->default_ram_size = 512 * MiB;
291
+};
292
+
293
+static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data)
294
+{
295
+ MachineClass *mc = MACHINE_CLASS(oc);
296
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
297
+
298
+ mc->desc = "OpenPOWER Witherspoon BMC (ARM1176)";
299
+ amc->soc_name = "ast2500-a1";
300
+ amc->hw_strap1 = WITHERSPOON_BMC_HW_STRAP1;
301
+ amc->fmc_model = "mx25l25635e";
302
+ amc->spi_model = "mx66l1g45g";
303
+ amc->num_cs = 2;
304
+ amc->i2c_init = witherspoon_bmc_i2c_init;
305
+ mc->default_ram_size = 512 * MiB;
306
+};
307
+
308
+static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
309
+{
310
+ MachineClass *mc = MACHINE_CLASS(oc);
311
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
312
+
313
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
314
+ amc->soc_name = "ast2600-a0";
315
+ amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
316
+ amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
317
+ amc->fmc_model = "w25q512jv";
318
+ amc->spi_model = "mx66u51235f";
319
+ amc->num_cs = 1;
320
+ amc->i2c_init = ast2600_evb_i2c_init;
321
+ mc->default_ram_size = 1 * GiB;
322
+};
323
+
324
+static const TypeInfo aspeed_machine_types[] = {
325
+ {
326
+ .name = MACHINE_TYPE_NAME("palmetto-bmc"),
327
+ .parent = TYPE_ASPEED_MACHINE,
328
+ .class_init = aspeed_machine_palmetto_class_init,
329
+ }, {
330
+ .name = MACHINE_TYPE_NAME("ast2500-evb"),
331
+ .parent = TYPE_ASPEED_MACHINE,
332
+ .class_init = aspeed_machine_ast2500_evb_class_init,
333
+ }, {
334
+ .name = MACHINE_TYPE_NAME("romulus-bmc"),
335
+ .parent = TYPE_ASPEED_MACHINE,
336
+ .class_init = aspeed_machine_romulus_class_init,
337
+ }, {
338
+ .name = MACHINE_TYPE_NAME("swift-bmc"),
339
+ .parent = TYPE_ASPEED_MACHINE,
340
+ .class_init = aspeed_machine_swift_class_init,
341
+ }, {
342
+ .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
343
+ .parent = TYPE_ASPEED_MACHINE,
344
+ .class_init = aspeed_machine_witherspoon_class_init,
345
+ }, {
346
+ .name = MACHINE_TYPE_NAME("ast2600-evb"),
347
+ .parent = TYPE_ASPEED_MACHINE,
348
+ .class_init = aspeed_machine_ast2600_evb_class_init,
349
+ }, {
350
+ .name = TYPE_ASPEED_MACHINE,
351
+ .parent = TYPE_MACHINE,
352
+ .instance_size = sizeof(AspeedMachine),
353
+ .class_size = sizeof(AspeedMachineClass),
354
+ .class_init = aspeed_machine_class_init,
355
+ .abstract = true,
356
}
357
-}
358
+};
359
360
-type_init(aspeed_machine_types)
361
+DEFINE_TYPES(aspeed_machine_types)
362
--
65
--
363
2.20.1
66
2.20.1
364
67
365
68
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
The initial implementation of the MVE VRMLALDAVH and VRMLSLDAVH
2
insns had some bugs:
3
* the 32x32 multiply of elements was being done as 32x32->32,
4
not 32x32->64
5
* we were incorrectly maintaining the accumulator in its full
6
72-bit form across all 4 beats of the insn; in the pseudocode
7
it is squashed back into the 64 bits of the RdaHi:RdaLo
8
registers after each beat
2
9
3
Switch to ram block writeback for pmem migration.
10
In particular, fixing the second of these allows us to recast
11
the implementation to avoid 128-bit arithmetic entirely.
4
12
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
13
Since the element size here is always 4, we can also drop the
14
parameterization of ESIZE to make the code a little more readable.
15
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
8
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
9
Message-id: 20191121000843.24844-4-beata.michalska@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
20
---
12
migration/ram.c | 5 +----
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
13
1 file changed, 1 insertion(+), 4 deletions(-)
22
1 file changed, 21 insertions(+), 17 deletions(-)
14
23
15
diff --git a/migration/ram.c b/migration/ram.c
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
16
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
17
--- a/migration/ram.c
26
--- a/target/arm/mve_helper.c
18
+++ b/migration/ram.c
27
+++ b/target/arm/mve_helper.c
19
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
20
#include "qemu/bitops.h"
29
*/
21
#include "qemu/bitmap.h"
30
22
#include "qemu/main-loop.h"
31
#include "qemu/osdep.h"
23
-#include "qemu/pmem.h"
32
-#include "qemu/int128.h"
24
#include "xbzrle.h"
33
#include "cpu.h"
25
#include "ram.h"
34
#include "internals.h"
26
#include "migration.h"
35
#include "vec_internal.h"
27
@@ -XXX,XX +XXX,XX @@ static int ram_load_cleanup(void *opaque)
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
28
RAMBlock *rb;
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
29
38
30
RAMBLOCK_FOREACH_NOT_IGNORED(rb) {
39
/*
31
- if (ramblock_is_pmem(rb)) {
40
- * Rounding multiply add long dual accumulate high: we must keep
32
- pmem_persist(rb->host, rb->used_length);
41
- * a 72-bit internal accumulator value and return the top 64 bits.
33
- }
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
34
+ qemu_ram_block_writeback(rb);
43
+ * this is implemented with a 72-bit internal accumulator value of which
44
+ * the top 64 bits are returned. We optimize this to avoid having to
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
46
+ * is squashed back into 64-bits after each beat.
47
*/
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
51
void *vm, uint64_t a) \
52
{ \
53
uint16_t mask = mve_element_mask(env); \
54
unsigned e; \
55
TYPE *n = vn, *m = vm; \
56
- Int128 acc = int128_lshift(TO128(a), 8); \
57
- for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
58
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
59
if (mask & 1) { \
60
+ LTYPE mul; \
61
if (e & 1) { \
62
- acc = ODDACC(acc, TO128(n[H##ESIZE(e - 1 * XCHG)] * \
63
- m[H##ESIZE(e)])); \
64
+ mul = (LTYPE)n[H4(e - 1 * XCHG)] * m[H4(e)]; \
65
+ if (SUB) { \
66
+ mul = -mul; \
67
+ } \
68
} else { \
69
- acc = EVENACC(acc, TO128(n[H##ESIZE(e + 1 * XCHG)] * \
70
- m[H##ESIZE(e)])); \
71
+ mul = (LTYPE)n[H4(e + 1 * XCHG)] * m[H4(e)]; \
72
} \
73
- acc = int128_add(acc, int128_make64(1 << 7)); \
74
+ mul = (mul >> 8) + ((mul >> 7) & 1); \
75
+ a += mul; \
76
} \
77
} \
78
mve_advance_vpt(env); \
79
- return int128_getlo(int128_rshift(acc, 8)); \
80
+ return a; \
35
}
81
}
36
82
37
xbzrle_load_cleanup();
83
-DO_LDAVH(vrmlaldavhsw, 4, int32_t, false, int128_add, int128_add, int128_makes64)
84
-DO_LDAVH(vrmlaldavhxsw, 4, int32_t, true, int128_add, int128_add, int128_makes64)
85
+DO_LDAVH(vrmlaldavhsw, int32_t, int64_t, false, false)
86
+DO_LDAVH(vrmlaldavhxsw, int32_t, int64_t, true, false)
87
88
-DO_LDAVH(vrmlaldavhuw, 4, uint32_t, false, int128_add, int128_add, int128_make64)
89
+DO_LDAVH(vrmlaldavhuw, uint32_t, uint64_t, false, false)
90
91
-DO_LDAVH(vrmlsldavhsw, 4, int32_t, false, int128_add, int128_sub, int128_makes64)
92
-DO_LDAVH(vrmlsldavhxsw, 4, int32_t, true, int128_add, int128_sub, int128_makes64)
93
+DO_LDAVH(vrmlsldavhsw, int32_t, int64_t, false, true)
94
+DO_LDAVH(vrmlsldavhxsw, int32_t, int64_t, true, true)
95
96
/* Vector add across vector */
97
#define DO_VADDV(OP, ESIZE, TYPE) \
38
--
98
--
39
2.20.1
99
2.20.1
40
100
41
101
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
The function asimd_imm_const() in translate-neon.c is an
2
implementation of the pseudocode AdvSIMDExpandImm(), which we will
3
also want for MVE. Move the implementation to translate.c, with a
4
prototype in translate.h.
2
5
3
Add probe_read alongside the write probing equivalent.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
9
---
10
target/arm/translate.h | 16 ++++++++++
11
target/arm/translate-neon.c | 63 -------------------------------------
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
13
3 files changed, 73 insertions(+), 63 deletions(-)
4
14
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20191121000843.24844-2-beata.michalska@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/exec/exec-all.h | 6 ++++++
12
1 file changed, 6 insertions(+)
13
14
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/exec-all.h
17
--- a/target/arm/translate.h
17
+++ b/include/exec/exec-all.h
18
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ static inline void *probe_write(CPUArchState *env, target_ulong addr, int size,
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
19
return probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
20
return opc | s->be_data;
20
}
21
}
21
22
22
+static inline void *probe_read(CPUArchState *env, target_ulong addr, int size,
23
+/**
23
+ int mmu_idx, uintptr_t retaddr)
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
25
+ *
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
29
+ *
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
31
+ * callers must catch this.
32
+ *
33
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
34
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
35
+ * we produce an immediate constant value of 0 in these cases.
36
+ */
37
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.c
43
+++ b/target/arm/translate-neon.c
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
47
48
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
49
-{
50
- /*
51
- * Expand the encoded constant.
52
- * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
53
- * We choose to not special-case this and will behave as if a
54
- * valid constant encoding of 0 had been given.
55
- * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
56
- */
57
- switch (cmode) {
58
- case 0: case 1:
59
- /* no-op */
60
- break;
61
- case 2: case 3:
62
- imm <<= 8;
63
- break;
64
- case 4: case 5:
65
- imm <<= 16;
66
- break;
67
- case 6: case 7:
68
- imm <<= 24;
69
- break;
70
- case 8: case 9:
71
- imm |= imm << 16;
72
- break;
73
- case 10: case 11:
74
- imm = (imm << 8) | (imm << 24);
75
- break;
76
- case 12:
77
- imm = (imm << 8) | 0xff;
78
- break;
79
- case 13:
80
- imm = (imm << 16) | 0xffff;
81
- break;
82
- case 14:
83
- if (op) {
84
- /*
85
- * This is the only case where the top and bottom 32 bits
86
- * of the encoded constant differ.
87
- */
88
- uint64_t imm64 = 0;
89
- int n;
90
-
91
- for (n = 0; n < 8; n++) {
92
- if (imm & (1 << n)) {
93
- imm64 |= (0xffULL << (n * 8));
94
- }
95
- }
96
- return imm64;
97
- }
98
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
99
- break;
100
- case 15:
101
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
102
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
103
- break;
104
- }
105
- if (op) {
106
- imm = ~imm;
107
- }
108
- return dup_const(MO_32, imm);
109
-}
110
-
111
static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
112
GVecGen2iFn *fn)
113
{
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
117
+++ b/target/arm/translate.c
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
119
a64_translate_init();
120
}
121
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
24
+{
123
+{
25
+ return probe_access(env, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
125
+ switch (cmode) {
126
+ case 0: case 1:
127
+ /* no-op */
128
+ break;
129
+ case 2: case 3:
130
+ imm <<= 8;
131
+ break;
132
+ case 4: case 5:
133
+ imm <<= 16;
134
+ break;
135
+ case 6: case 7:
136
+ imm <<= 24;
137
+ break;
138
+ case 8: case 9:
139
+ imm |= imm << 16;
140
+ break;
141
+ case 10: case 11:
142
+ imm = (imm << 8) | (imm << 24);
143
+ break;
144
+ case 12:
145
+ imm = (imm << 8) | 0xff;
146
+ break;
147
+ case 13:
148
+ imm = (imm << 16) | 0xffff;
149
+ break;
150
+ case 14:
151
+ if (op) {
152
+ /*
153
+ * This is the only case where the top and bottom 32 bits
154
+ * of the encoded constant differ.
155
+ */
156
+ uint64_t imm64 = 0;
157
+ int n;
158
+
159
+ for (n = 0; n < 8; n++) {
160
+ if (imm & (1 << n)) {
161
+ imm64 |= (0xffULL << (n * 8));
162
+ }
163
+ }
164
+ return imm64;
165
+ }
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
167
+ break;
168
+ case 15:
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
171
+ break;
172
+ }
173
+ if (op) {
174
+ imm = ~imm;
175
+ }
176
+ return dup_const(MO_32, imm);
26
+}
177
+}
27
+
178
+
28
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
179
/* Generate a label used for skipping this instruction */
29
180
void arm_gen_condlabel(DisasContext *s)
30
/* Estimated block size for TB allocation. */
181
{
31
--
182
--
32
2.20.1
183
2.20.1
33
184
34
185
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
The A64 AdvSIMD modified-immediate grouping uses almost the same
2
constant encoding that A32 Neon does; reuse asimd_imm_const() (to
3
which we add the AArch64-specific case for cmode 15 op 1) instead of
4
reimplementing it all.
2
5
3
HSTR_EL2 offers a way to trap ranges of CP15 system register
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
accesses to EL2, and it looks like this register is completely
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
ignored by QEMU.
8
Message-id: 20210628135835.6690-5-peter.maydell@linaro.org
9
---
10
target/arm/translate.h | 3 +-
11
target/arm/translate-a64.c | 86 ++++----------------------------------
12
target/arm/translate.c | 17 +++++++-
13
3 files changed, 24 insertions(+), 82 deletions(-)
6
14
7
To avoid adding extra .accessfn filters all over the place (which
8
would have a direct performance impact), let's add a new TB flag
9
that gets set whenever HSTR_EL2 is non-zero and that QEMU translates
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>
20
---
21
target/arm/cpu.h | 2 ++
22
target/arm/translate.h | 2 ++
23
target/arm/helper.c | 6 ++++++
24
target/arm/op_helper.c | 22 ++++++++++++++++++++++
25
target/arm/translate.c | 3 ++-
26
5 files changed, 34 insertions(+), 1 deletion(-)
27
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
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
42
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/translate.h
17
--- a/target/arm/translate.h
44
+++ b/target/arm/translate.h
18
+++ b/target/arm/translate.h
45
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
46
bool pauth_active;
20
* VMVN and VBIC (when cmode < 14 && op == 1).
47
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
21
*
48
bool bt;
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
49
+ /* True if any CP15 access is trapped by HSTR_EL2 */
23
- * callers must catch this.
50
+ bool hstr_active;
24
+ * callers must catch this; we return the 64-bit constant value defined
51
/*
25
+ * for AArch64.
52
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
26
*
53
* < 0, set by the current instruction.
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
54
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
55
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/helper.c
31
--- a/target/arm/translate-a64.c
57
+++ b/target/arm/helper.c
32
+++ b/target/arm/translate-a64.c
58
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
59
if (arm_el_is_aa64(env, 1)) {
34
{
60
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
35
int rd = extract32(insn, 0, 5);
61
}
36
int cmode = extract32(insn, 12, 4);
62
+
37
- int cmode_3_1 = extract32(cmode, 1, 3);
63
+ if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
38
- int cmode_0 = extract32(cmode, 0, 1);
64
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
39
int o2 = extract32(insn, 11, 1);
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
66
+ }
41
bool is_neg = extract32(insn, 29, 1);
67
+
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
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;
43
return;
102
}
44
}
103
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
45
104
g_assert_not_reached();
46
- /* See AdvSIMDExpandImm() in ARM ARM */
47
- switch (cmode_3_1) {
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
51
- case 3: /* Replicate(imm8:Zeros(24), 2) */
52
- {
53
- int shift = cmode_3_1 * 8;
54
- imm = bitfield_replicate(abcdefgh << shift, 32);
55
- break;
56
- }
57
- case 4: /* Replicate(Zeros(8):imm8, 4) */
58
- case 5: /* Replicate(imm8:Zeros(8), 4) */
59
- {
60
- int shift = (cmode_3_1 & 0x1) * 8;
61
- imm = bitfield_replicate(abcdefgh << shift, 16);
62
- break;
63
- }
64
- case 6:
65
- if (cmode_0) {
66
- /* Replicate(Zeros(8):imm8:Ones(16), 2) */
67
- imm = (abcdefgh << 16) | 0xffff;
68
- } else {
69
- /* Replicate(Zeros(16):imm8:Ones(8), 2) */
70
- imm = (abcdefgh << 8) | 0xff;
71
- }
72
- imm = bitfield_replicate(imm, 32);
73
- break;
74
- case 7:
75
- if (!cmode_0 && !is_neg) {
76
- imm = bitfield_replicate(abcdefgh, 8);
77
- } else if (!cmode_0 && is_neg) {
78
- int i;
79
- imm = 0;
80
- for (i = 0; i < 8; i++) {
81
- if ((abcdefgh) & (1 << i)) {
82
- imm |= 0xffULL << (i * 8);
83
- }
84
- }
85
- } else if (cmode_0) {
86
- if (is_neg) {
87
- imm = (abcdefgh & 0x3f) << 48;
88
- if (abcdefgh & 0x80) {
89
- imm |= 0x8000000000000000ULL;
90
- }
91
- if (abcdefgh & 0x40) {
92
- imm |= 0x3fc0000000000000ULL;
93
- } else {
94
- imm |= 0x4000000000000000ULL;
95
- }
96
- } else {
97
- if (o2) {
98
- /* FMOV (vector, immediate) - half-precision */
99
- imm = vfp_expand_imm(MO_16, abcdefgh);
100
- /* now duplicate across the lanes */
101
- imm = bitfield_replicate(imm, 16);
102
- } else {
103
- imm = (abcdefgh & 0x3f) << 19;
104
- if (abcdefgh & 0x80) {
105
- imm |= 0x80000000;
106
- }
107
- if (abcdefgh & 0x40) {
108
- imm |= 0x3e000000;
109
- } else {
110
- imm |= 0x40000000;
111
- }
112
- imm |= (imm << 32);
113
- }
114
- }
115
- }
116
- break;
117
- default:
118
- g_assert_not_reached();
119
- }
120
-
121
- if (cmode_3_1 != 7 && is_neg) {
122
- imm = ~imm;
123
+ if (cmode == 15 && o2 && !is_neg) {
124
+ /* FMOV (vector, immediate) - half-precision */
125
+ imm = vfp_expand_imm(MO_16, abcdefgh);
126
+ /* now duplicate across the lanes */
127
+ imm = bitfield_replicate(imm, 16);
128
+ } else {
129
+ imm = asimd_imm_const(abcdefgh, cmode, is_neg);
105
}
130
}
106
131
107
+exept:
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
108
raise_exception(env, EXCP_UDEF, syndrome, target_el);
109
}
110
111
diff --git a/target/arm/translate.c b/target/arm/translate.c
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
112
index XXXXXXX..XXXXXXX 100644
134
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/translate.c
135
--- a/target/arm/translate.c
114
+++ b/target/arm/translate.c
136
+++ b/target/arm/translate.c
115
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
116
return 1;
138
case 14:
117
}
139
if (op) {
118
140
/*
119
- if (ri->accessfn ||
141
- * This is the only case where the top and bottom 32 bits
120
+ if (s->hstr_active || ri->accessfn ||
142
- * of the encoded constant differ.
121
(arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
143
+ * This and cmode == 15 op == 1 are the only cases where
122
/* Emit code to perform further access permissions checks at
144
+ * the top and bottom 32 bits of the encoded constant differ.
123
* runtime; this may result in an exception.
145
*/
124
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
146
uint64_t imm64 = 0;
125
!arm_el_is_aa64(env, 3);
147
int n;
126
dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
148
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
127
dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
149
imm |= (imm << 8) | (imm << 16) | (imm << 24);
128
+ dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
150
break;
129
dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
151
case 15:
130
condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
152
+ if (op) {
131
dc->condexec_mask = (condexec & 0xf) << 1;
153
+ /* Reserved encoding for AArch32; valid for AArch64 */
154
+ uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
155
+ if (imm & 0x80) {
156
+ imm64 |= 0x8000000000000000ULL;
157
+ }
158
+ if (imm & 0x40) {
159
+ imm64 |= 0x3fc0000000000000ULL;
160
+ } else {
161
+ imm64 |= 0x4000000000000000ULL;
162
+ }
163
+ return imm64;
164
+ }
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
167
break;
132
--
168
--
133
2.20.1
169
2.20.1
134
170
135
171
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
Use dup_const() instead of bitfield_replicate() in
2
disas_simd_mod_imm().
2
3
3
The last argument of AML bit and/or statement is the target variable,
4
(We can't replace the other use of bitfield_replicate() in this file,
4
so we don't need to use a NULL target and then an additional store
5
in logic_imm_decode_wmask(), because that location needs to handle 2
5
operation; using just aml_and() or aml_or() statement is enough.
6
and 4 bit elements, which dup_const() cannot.)
6
7
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210628135835.6690-6-peter.maydell@linaro.org
11
---
12
target/arm/translate-a64.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
8
14
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.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
Suggested-by: Igor Mammedov <imammedo@redhat.com>
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
16
Message-id: 20191209063719.23086-2-guoheyi@huawei.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
hw/arm/virt-acpi-build.c | 16 ++++++++--------
20
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
21
tests/data/acpi/virt/DSDT.memhp | Bin 19807 -> 19799 bytes
22
tests/data/acpi/virt/DSDT.numamem | Bin 18470 -> 18462 bytes
23
4 files changed, 8 insertions(+), 8 deletions(-)
24
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
26
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
17
--- a/target/arm/translate-a64.c
28
+++ b/hw/arm/virt-acpi-build.c
18
+++ b/target/arm/translate-a64.c
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
20
/* FMOV (vector, immediate) - half-precision */
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
21
imm = vfp_expand_imm(MO_16, abcdefgh);
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
22
/* now duplicate across the lanes */
33
- aml_append(ifctx, aml_store(aml_and(aml_name("CTRL"), aml_int(0x1D), NULL),
23
- imm = bitfield_replicate(imm, 16);
34
- aml_name("CTRL")));
24
+ imm = dup_const(MO_16, imm);
35
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
25
} else {
36
+ aml_name("CTRL")));
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
37
27
}
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
--
28
--
104
2.20.1
29
2.20.1
105
30
106
31
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
2
VORR and VBIC). These have essentially the same encoding
3
as their Neon equivalents, and we implement the decode
4
in the same way.
2
5
3
QEMU lacks the minimum Jazelle implementation that is required
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
by the architecture (everything is RAZ or RAZ/WI). Add it
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
together with the HCR_EL2.TID0 trapping that goes with it.
8
Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
9
---
10
target/arm/helper-mve.h | 4 +++
11
target/arm/mve.decode | 17 +++++++++++++
12
target/arm/mve_helper.c | 24 ++++++++++++++++++
13
target/arm/translate-mve.c | 50 ++++++++++++++++++++++++++++++++++++++
14
4 files changed, 95 insertions(+)
6
15
7
Signed-off-by: Marc Zyngier <maz@kernel.org>
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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>
16
---
17
target/arm/helper.c | 27 +++++++++++++++++++++++++++
18
1 file changed, 27 insertions(+)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
18
--- a/target/arm/helper-mve.h
23
+++ b/target/arm/helper.c
19
+++ b/target/arm/helper-mve.h
24
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
25
return CP_ACCESS_OK;
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
26
}
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
27
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
28
+static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
24
+
29
+ bool isread)
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
30
+{
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID0)) {
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
32
+ return CP_ACCESS_TRAP_EL2;
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/mve.decode
31
+++ b/target/arm/mve.decode
32
@@ -XXX,XX +XXX,XX @@
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
34
%size_28 28:1 !function=plus_1
35
36
+# 1imm format immediate
37
+%imm_28_16_0 28:1 16:3 0:4
38
+
39
&vldr_vstr rn qd imm p a w size l u
40
&1op qd qm size
41
&2op qd qm qn size
42
&2scalar qd qn rm size
43
+&1imm qd imm cmode op
44
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
46
# Note that both Rn and Qd are 3 bits only (no D bit)
47
@@ -XXX,XX +XXX,XX @@
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
50
size=%size_28
51
+@1imm .... .... .... .... .... cmode:4 .. op:1 . .... &1imm qd=%qd imm=%imm_28_16_0
52
53
# The _rev suffix indicates that Vn and Vm are reversed. This is
54
# the case for shifts. In the Arm ARM these insns are documented
55
@@ -XXX,XX +XXX,XX @@ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rd
56
# Predicate operations
57
%mask_22_13 22:1 13:3
58
VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
59
+
60
+# Logical immediate operations (1 reg and modified-immediate)
61
+
62
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMVN, but
63
+# not in a way we can conveniently represent in decodetree without
64
+# a lot of repetition:
65
+# VORR: op=0, (cmode & 1) && cmode < 12
66
+# VBIC: op=1, (cmode & 1) && cmode < 12
67
+# VMOV: everything else
68
+# So we have a single decode line and check the cmode/op in the
69
+# trans function.
70
+Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
71
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/mve_helper.c
74
+++ b/target/arm/mve_helper.c
75
@@ -XXX,XX +XXX,XX @@ DO_1OP(vnegw, 4, int32_t, DO_NEG)
76
DO_1OP(vfnegh, 8, uint64_t, DO_FNEGH)
77
DO_1OP(vfnegs, 8, uint64_t, DO_FNEGS)
78
79
+/*
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
81
+ * All these insns work at 64-bit widths.
82
+ */
83
+#define DO_1OP_IMM(OP, FN) \
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
85
+ { \
86
+ uint64_t *da = vda; \
87
+ uint16_t mask = mve_element_mask(env); \
88
+ unsigned e; \
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
91
+ } \
92
+ mve_advance_vpt(env); \
33
+ }
93
+ }
34
+
94
+
35
+ return CP_ACCESS_OK;
95
+#define DO_MOVI(N, I) (I)
96
+#define DO_ANDI(N, I) ((N) & (I))
97
+#define DO_ORRI(N, I) ((N) | (I))
98
+
99
+DO_1OP_IMM(vmovi, DO_MOVI)
100
+DO_1OP_IMM(vandi, DO_ANDI)
101
+DO_1OP_IMM(vorri, DO_ORRI)
102
+
103
#define DO_2OP(OP, ESIZE, TYPE, FN) \
104
void HELPER(glue(mve_, OP))(CPUARMState *env, \
105
void *vd, void *vn, void *vm) \
106
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-mve.c
109
+++ b/target/arm/translate-mve.c
110
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
111
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
112
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
113
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
114
+typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
115
116
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
117
static inline long mve_qreg_offset(unsigned reg)
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
119
mve_update_eci(s);
120
return true;
121
}
122
+
123
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
124
+{
125
+ TCGv_ptr qd;
126
+ uint64_t imm;
127
+
128
+ if (!dc_isar_feature(aa32_mve, s) ||
129
+ !mve_check_qreg_bank(s, a->qd) ||
130
+ !fn) {
131
+ return false;
132
+ }
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
134
+ return true;
135
+ }
136
+
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
138
+
139
+ qd = mve_qreg_ptr(a->qd);
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
141
+ tcg_temp_free_ptr(qd);
142
+ mve_update_eci(s);
143
+ return true;
36
+}
144
+}
37
+
145
+
38
+static const ARMCPRegInfo jazelle_regs[] = {
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
39
+ { .name = "JIDR",
147
+{
40
+ .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
41
+ .access = PL1_R, .accessfn = access_jazelle,
149
+ MVEGenOneOpImmFn *fn;
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
+
150
+
52
void register_cp_regs_for_features(ARMCPU *cpu)
151
+ if ((a->cmode & 1) && a->cmode < 12) {
53
{
152
+ if (a->op) {
54
/* Register all the coprocessor registers based on feature bits */
153
+ /*
55
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
56
if (arm_feature(env, ARM_FEATURE_LPAE)) {
155
+ * so the VBIC becomes a logical AND operation.
57
define_arm_cp_regs(cpu, lpae_cp_reginfo);
156
+ */
58
}
157
+ fn = gen_helper_mve_vandi;
59
+ if (cpu_isar_feature(jazelle, cpu)) {
158
+ } else {
60
+ define_arm_cp_regs(cpu, jazelle_regs);
159
+ fn = gen_helper_mve_vorri;
160
+ }
161
+ } else {
162
+ /* There is one unallocated cmode/op combination in this space */
163
+ if (a->cmode == 15 && a->op == 1) {
164
+ return false;
165
+ }
166
+ /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
167
+ fn = gen_helper_mve_vmovi;
61
+ }
168
+ }
62
/* Slightly awkwardly, the OMAP and StrongARM cores need all of
169
+ return do_1imm(s, a, fn);
63
* cp15 crn=0 to be writes-ignored, whereas for other cores they should
170
+}
64
* be read-only (ie write causes UNDEF exception).
65
--
171
--
66
2.20.1
172
2.20.1
67
173
68
174
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
2
2
and VQSHLU.
3
The current model only restores the Segment Register values but leaves
3
4
the previous CS mapping behind. Introduce a helper setting the
4
The size-and-immediate encoding here is the same as Neon, and we
5
register value and mapping the region at the requested address. Use
5
handle it the same way neon-dp.decode does.
6
this helper when a Segment register is set and at reset.
6
7
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-11-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
13
---
10
---
14
hw/ssi/aspeed_smc.c | 32 +++++++++++++++++++++-----------
11
target/arm/helper-mve.h | 16 +++++++++++
15
1 file changed, 21 insertions(+), 11 deletions(-)
12
target/arm/mve.decode | 23 +++++++++++++++
16
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
17
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
18
index XXXXXXX..XXXXXXX 100644
15
4 files changed, 147 insertions(+)
19
--- a/hw/ssi/aspeed_smc.c
16
20
+++ b/hw/ssi/aspeed_smc.c
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
18
index XXXXXXX..XXXXXXX 100644
22
return false;
19
--- a/target/arm/helper-mve.h
20
+++ b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
25
+
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+
34
+DEF_HELPER_FLAGS_4(mve_vqshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_4(mve_vqshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/mve.decode
44
+++ b/target/arm/mve.decode
45
@@ -XXX,XX +XXX,XX @@
46
&2op qd qm qn size
47
&2scalar qd qn rm size
48
&1imm qd imm cmode op
49
+&2shift qd qm shift size
50
51
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
52
# Note that both Rn and Qd are 3 bits only (no D bit)
53
@@ -XXX,XX +XXX,XX @@
54
@2scalar .... .... .. size:2 .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
55
@2scalar_nosz .... .... .... .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
56
57
+@2_shl_b .... .... .. 001 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
58
+@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
59
+@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
60
+
61
# Vector loads and stores
62
63
# Widening loads and narrowing stores:
64
@@ -XXX,XX +XXX,XX @@ VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
65
# So we have a single decode line and check the cmode/op in the
66
# trans function.
67
Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
68
+
69
+# Shifts by immediate
70
+
71
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
72
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
73
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
74
+
75
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
76
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
77
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
78
+
79
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
80
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
81
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
82
+
83
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
84
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
85
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
86
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/mve_helper.c
89
+++ b/target/arm/mve_helper.c
90
@@ -XXX,XX +XXX,XX @@ DO_2OP_SAT(vqsubsw, 4, int32_t, DO_SQSUB_W)
91
WRAP_QRSHL_HELPER(do_sqrshl_bhs, N, M, true, satp)
92
#define DO_UQRSHL_OP(N, M, satp) \
93
WRAP_QRSHL_HELPER(do_uqrshl_bhs, N, M, true, satp)
94
+#define DO_SUQSHL_OP(N, M, satp) \
95
+ WRAP_QRSHL_HELPER(do_suqrshl_bhs, N, M, false, satp)
96
97
DO_2OP_SAT_S(vqshls, DO_SQSHL_OP)
98
DO_2OP_SAT_U(vqshlu, DO_UQSHL_OP)
99
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvsw, 4, uint32_t)
100
DO_VADDV(vaddvub, 1, uint8_t)
101
DO_VADDV(vaddvuh, 2, uint16_t)
102
DO_VADDV(vaddvuw, 4, uint32_t)
103
+
104
+/* Shifts by immediate */
105
+#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
106
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
107
+ void *vm, uint32_t shift) \
108
+ { \
109
+ TYPE *d = vd, *m = vm; \
110
+ uint16_t mask = mve_element_mask(env); \
111
+ unsigned e; \
112
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
113
+ mergemask(&d[H##ESIZE(e)], \
114
+ FN(m[H##ESIZE(e)], shift), mask); \
115
+ } \
116
+ mve_advance_vpt(env); \
117
+ }
118
+
119
+#define DO_2SHIFT_SAT(OP, ESIZE, TYPE, FN) \
120
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
121
+ void *vm, uint32_t shift) \
122
+ { \
123
+ TYPE *d = vd, *m = vm; \
124
+ uint16_t mask = mve_element_mask(env); \
125
+ unsigned e; \
126
+ bool qc = false; \
127
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
128
+ bool sat = false; \
129
+ mergemask(&d[H##ESIZE(e)], \
130
+ FN(m[H##ESIZE(e)], shift, &sat), mask); \
131
+ qc |= sat & mask & 1; \
132
+ } \
133
+ if (qc) { \
134
+ env->vfp.qc[0] = qc; \
135
+ } \
136
+ mve_advance_vpt(env); \
137
+ }
138
+
139
+/* provide unsigned 2-op shift helpers for all sizes */
140
+#define DO_2SHIFT_U(OP, FN) \
141
+ DO_2SHIFT(OP##b, 1, uint8_t, FN) \
142
+ DO_2SHIFT(OP##h, 2, uint16_t, FN) \
143
+ DO_2SHIFT(OP##w, 4, uint32_t, FN)
144
+
145
+#define DO_2SHIFT_SAT_U(OP, FN) \
146
+ DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
147
+ DO_2SHIFT_SAT(OP##h, 2, uint16_t, FN) \
148
+ DO_2SHIFT_SAT(OP##w, 4, uint32_t, FN)
149
+#define DO_2SHIFT_SAT_S(OP, FN) \
150
+ DO_2SHIFT_SAT(OP##b, 1, int8_t, FN) \
151
+ DO_2SHIFT_SAT(OP##h, 2, int16_t, FN) \
152
+ DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
153
+
154
+DO_2SHIFT_U(vshli_u, DO_VSHLU)
155
+DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
156
+DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
157
+DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
158
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/translate-mve.c
161
+++ b/target/arm/translate-mve.c
162
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
163
typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
164
typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
165
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
166
+typedef void MVEGenTwoOpShiftFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
167
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
168
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
169
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
170
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
171
}
172
return do_1imm(s, a, fn);
23
}
173
}
24
174
+
25
+static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
26
+ uint64_t regval)
176
+ bool negateshift)
27
+{
177
+{
28
+ AspeedSMCFlash *fl = &s->flashes[cs];
178
+ TCGv_ptr qd, qm;
29
+ AspeedSegments seg;
179
+ int shift = a->shift;
30
+
180
+
31
+ s->ctrl->reg_to_segment(s, regval, &seg);
181
+ if (!dc_isar_feature(aa32_mve, s) ||
32
+
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
33
+ memory_region_transaction_begin();
183
+ !fn) {
34
+ memory_region_set_size(&fl->mmio, seg.size);
184
+ return false;
35
+ memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
185
+ }
36
+ memory_region_set_enabled(&fl->mmio, true);
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
37
+ memory_region_transaction_commit();
187
+ return true;
38
+
188
+ }
39
+ s->regs[R_SEG_ADDR0 + cs] = regval;
189
+
190
+ /*
191
+ * When we handle a right shift insn using a left-shift helper
192
+ * which permits a negative shift count to indicate a right-shift,
193
+ * we must negate the shift count.
194
+ */
195
+ if (negateshift) {
196
+ shift = -shift;
197
+ }
198
+
199
+ qd = mve_qreg_ptr(a->qd);
200
+ qm = mve_qreg_ptr(a->qm);
201
+ fn(cpu_env, qd, qm, tcg_constant_i32(shift));
202
+ tcg_temp_free_ptr(qd);
203
+ tcg_temp_free_ptr(qm);
204
+ mve_update_eci(s);
205
+ return true;
40
+}
206
+}
41
+
207
+
42
static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
43
uint64_t new)
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
44
{
210
+ { \
45
- AspeedSMCFlash *fl = &s->flashes[cs];
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
46
AspeedSegments seg;
212
+ gen_helper_mve_##FN##b, \
47
213
+ gen_helper_mve_##FN##h, \
48
s->ctrl->reg_to_segment(s, new, &seg);
214
+ gen_helper_mve_##FN##w, \
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
215
+ NULL, \
50
aspeed_smc_flash_overlap(s, &seg, cs);
216
+ }; \
51
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
52
/* All should be fine now to move the region */
218
+ }
53
- memory_region_transaction_begin();
219
+
54
- memory_region_set_size(&fl->mmio, seg.size);
220
+DO_2SHIFT(VSHLI, vshli_u, false)
55
- memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
56
- memory_region_set_enabled(&fl->mmio, true);
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
57
- memory_region_transaction_commit();
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
58
-
59
- s->regs[R_SEG_ADDR0 + cs] = new;
60
+ aspeed_smc_flash_set_segment_region(s, cs, new);
61
}
62
63
static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
64
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
65
qemu_set_irq(s->cs_lines[i], true);
66
}
67
68
- /* setup default segment register values for all */
69
+ /* setup the default segment register values and regions for all */
70
for (i = 0; i < s->ctrl->max_slaves; ++i) {
71
- s->regs[R_SEG_ADDR0 + i] =
72
- s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]);
73
+ aspeed_smc_flash_set_segment_region(s, i,
74
+ s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]));
75
}
76
77
/* HW strapping flash type for the AST2600 controllers */
78
--
224
--
79
2.20.1
225
2.20.1
80
226
81
227
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Implement the MVE vector shift right by immediate insns VSHRI and
2
VRSHRI. As with Neon, we implement these by using helper functions
3
which perform left shifts but allow negative shift counts to indicate
4
right shifts.
2
5
3
The Aspeed I2C controller can operate in different transfer modes :
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
9
---
10
target/arm/helper-mve.h | 12 ++++++++++++
11
target/arm/translate.h | 20 ++++++++++++++++++++
12
target/arm/mve.decode | 28 ++++++++++++++++++++++++++++
13
target/arm/mve_helper.c | 7 +++++++
14
target/arm/translate-mve.c | 5 +++++
15
target/arm/translate-neon.c | 18 ------------------
16
6 files changed, 72 insertions(+), 18 deletions(-)
4
17
5
- Byte Buffer mode, using a dedicated register to transfer a
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
6
byte. This is what the model supports today.
7
8
- Pool Buffer mode, using an internal SRAM to transfer multiple
9
bytes in the same command sequence.
10
11
Each SoC has different SRAM characteristics. On the AST2400, 2048
12
bytes of SRAM are available at offset 0x800 of the controller AHB
13
window. The pool buffer can be configured from 1 to 256 bytes per bus.
14
15
On the AST2500, the SRAM is at offset 0x200 and the pool buffer is of
16
16 bytes per bus.
17
18
On the AST2600, the SRAM is at offset 0xC00 and the pool buffer is of
19
32 bytes per bus. It can be splitted in two for TX and RX but the
20
current model does not add support for it as it it unused by known
21
drivers.
22
23
Signed-off-by: Cédric Le Goater <clg@kaod.org>
24
Reviewed-by: Joel Stanley <joel@jms.id.au>
25
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
26
Signed-off-by: Cédric Le Goater <clg@kaod.org>
27
Message-id: 20191119141211.25716-2-clg@kaod.org
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
30
include/hw/i2c/aspeed_i2c.h | 8 ++
31
hw/i2c/aspeed_i2c.c | 197 ++++++++++++++++++++++++++++++++----
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
19
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/i2c/aspeed_i2c.h
20
--- a/target/arm/helper-mve.h
37
+++ b/include/hw/i2c/aspeed_i2c.h
21
+++ b/target/arm/helper-mve.h
38
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
39
OBJECT_CHECK(AspeedI2CState, (obj), TYPE_ASPEED_I2C)
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
40
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
41
#define ASPEED_I2C_NR_BUSSES 16
25
42
+#define ASPEED_I2C_MAX_POOL_SIZE 0x800
26
+DEF_HELPER_FLAGS_4(mve_vshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
27
+DEF_HELPER_FLAGS_4(mve_vshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
struct AspeedI2CState;
28
+DEF_HELPER_FLAGS_4(mve_vshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
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
+
29
+
68
+ uint64_t pool_size;
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
69
+ hwaddr pool_base;
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
70
+ uint8_t *(*bus_pool_base)(AspeedI2CBus *);
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
71
} AspeedI2CClass;
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
72
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
73
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
35
DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
74
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
36
DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(mve_vrshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vrshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+
42
+DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
75
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
76
--- a/hw/i2c/aspeed_i2c.c
47
--- a/target/arm/translate.h
77
+++ b/hw/i2c/aspeed_i2c.c
48
+++ b/target/arm/translate.h
78
@@ -XXX,XX +XXX,XX @@
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
79
/* I2C Device (Bus) Register */
50
return x * 2 + 1;
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
}
51
}
128
52
129
+static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
53
+static inline int rsub_64(DisasContext *s, int x)
130
+{
54
+{
131
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
55
+ return 64 - x;
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
+}
56
+}
151
+
57
+
152
+static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
58
+static inline int rsub_32(DisasContext *s, int x)
153
+{
59
+{
154
+ AspeedI2CState *s = bus->controller;
60
+ return 32 - x;
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
+}
61
+}
175
+
62
+
176
static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
63
+static inline int rsub_16(DisasContext *s, int x)
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
+{
64
+{
194
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
65
+ return 16 - x;
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
+}
66
+}
204
+
67
+
205
/*
68
+static inline int rsub_8(DisasContext *s, int x)
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 {
248
+ /*
249
+ * Increase the start index in the TX pool buffer to
250
+ * skip the address byte.
251
+ */
252
+ pool_start++;
253
+ }
254
+ } else {
255
+ bus->cmd &= ~I2CD_M_TX_CMD;
256
+ }
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
+{
69
+{
288
+ AspeedI2CState *s = opaque;
70
+ return 8 - x;
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
+}
71
+}
298
+
72
+
299
+static void aspeed_i2c_pool_write(void *opaque, hwaddr offset,
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
300
+ uint64_t value, unsigned size)
74
{
301
+{
75
return (dc->features & (1ULL << feature)) != 0;
302
+ AspeedI2CState *s = opaque;
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
303
+ int i;
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/mve.decode
79
+++ b/target/arm/mve.decode
80
@@ -XXX,XX +XXX,XX @@
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
83
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
85
+%rshift_i5 16:5 !function=rsub_32
86
+%rshift_i4 16:4 !function=rsub_16
87
+%rshift_i3 16:3 !function=rsub_8
304
+
88
+
305
+ for (i = 0; i < size; i++) {
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
306
+ s->pool[offset + i] = (value >> (8 * i)) & 0xFF;
90
+ size=0 shift=%rshift_i3
307
+ }
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
308
+}
92
+ size=1 shift=%rshift_i4
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
94
+ size=2 shift=%rshift_i5
309
+
95
+
310
+static const MemoryRegionOps aspeed_i2c_pool_ops = {
96
# Vector loads and stores
311
+ .read = aspeed_i2c_pool_read,
97
312
+ .write = aspeed_i2c_pool_write,
98
# Widening loads and narrowing stores:
313
+ .endianness = DEVICE_LITTLE_ENDIAN,
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
314
+ .valid = {
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
315
+ .min_access_size = 1,
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
316
+ .max_access_size = 4,
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
317
+ },
318
+};
319
+
103
+
320
static const VMStateDescription aspeed_i2c_bus_vmstate = {
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
321
.name = TYPE_ASPEED_I2C,
105
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
322
- .version_id = 1,
106
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
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
}
336
};
337
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
+
107
+
358
+ memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
108
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
359
+ "aspeed.i2c-pool", aic->pool_size);
109
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
360
+ memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
110
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
111
+
112
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
113
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
114
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
115
+
116
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
117
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
118
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
119
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/mve_helper.c
122
+++ b/target/arm/mve_helper.c
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
127
+#define DO_2SHIFT_S(OP, FN) \
128
+ DO_2SHIFT(OP##b, 1, int8_t, FN) \
129
+ DO_2SHIFT(OP##h, 2, int16_t, FN) \
130
+ DO_2SHIFT(OP##w, 4, int32_t, FN)
131
132
#define DO_2SHIFT_SAT_U(OP, FN) \
133
DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
134
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
135
DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
136
137
DO_2SHIFT_U(vshli_u, DO_VSHLU)
138
+DO_2SHIFT_S(vshli_s, DO_VSHLS)
139
DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
140
DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
141
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
142
+DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
143
+DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
144
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-mve.c
147
+++ b/target/arm/translate-mve.c
148
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHLI, vshli_u, false)
149
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
150
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
151
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
152
+/* These right shifts use a left-shift helper with negated shift count */
153
+DO_2SHIFT(VSHRI_S, vshli_s, true)
154
+DO_2SHIFT(VSHRI_U, vshli_u, true)
155
+DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
+DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/translate-neon.c
160
+++ b/target/arm/translate-neon.c
161
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
162
return x + 1;
361
}
163
}
362
164
363
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
165
-static inline int rsub_64(DisasContext *s, int x)
364
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CBus *bus)
166
-{
365
return bus->controller->irq;
167
- return 64 - x;
366
}
168
-}
367
169
-
368
+static uint8_t *aspeed_2400_i2c_bus_pool_base(AspeedI2CBus *bus)
170
-static inline int rsub_32(DisasContext *s, int x)
369
+{
171
-{
370
+ uint8_t *pool_page =
172
- return 32 - x;
371
+ &bus->controller->pool[I2CD_POOL_PAGE_SEL(bus->ctrl) * 0x100];
173
-}
372
+
174
-static inline int rsub_16(DisasContext *s, int x)
373
+ return &pool_page[I2CD_POOL_OFFSET(bus->pool_ctrl)];
175
-{
374
+}
176
- return 16 - x;
375
+
177
-}
376
static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
178
-static inline int rsub_8(DisasContext *s, int x)
179
-{
180
- return 8 - x;
181
-}
182
-
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
377
{
184
{
378
DeviceClass *dc = DEVICE_CLASS(klass);
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
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
--
186
--
434
2.20.1
187
2.20.1
435
188
436
189
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
Implement the MVE VHLL (vector shift left long) insn. This has two
2
encodings: the T1 encoding is the usual shift-by-immediate format,
3
and the T2 encoding is a special case where the shift count is always
4
equal to the element size.
2
5
3
ARMv8.2 introduced support for Data Cache Clean instructions
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
to PoP (point-of-persistence) - DC CVAP and PoDP (point-of-deep-persistence)
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
- DV CVADP. Both specify conceptual points in a memory system where all writes
8
Message-id: 20210628135835.6690-10-peter.maydell@linaro.org
6
that are to reach them are considered persistent.
9
---
7
The support provided considers both to be actually the same so there is no
10
target/arm/helper-mve.h | 9 +++++++
8
distinction between the two. If none is available (there is no backing store
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
9
for given memory) both will result in Data Cache Clean up to the point of
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
10
coherency. Otherwise sync for the specified range shall be performed.
13
target/arm/translate-mve.c | 15 +++++++++++
14
4 files changed, 105 insertions(+), 4 deletions(-)
11
15
12
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191121000843.24844-5-beata.michalska@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/cpu.h | 10 ++++++++
18
linux-user/elfload.c | 2 ++
19
target/arm/cpu64.c | 1 +
20
target/arm/helper.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
21
4 files changed, 69 insertions(+)
22
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
18
--- a/target/arm/helper-mve.h
26
+++ b/target/arm/cpu.h
19
+++ b/target/arm/helper-mve.h
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
}
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
24
+
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
40
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
43
+# VSHLL encoding T2 where shift == esize
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
45
+ qd=%qd qm=%qm size=0 shift=8
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
47
+ qd=%qd qm=%qm size=1 shift=16
48
+
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
50
%rshift_i5 16:5 !function=rsub_32
51
%rshift_i4 16:4 !function=rsub_16
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
53
VSUB 1111 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
54
VMUL 1110 1111 0 . .. ... 0 ... 0 1001 . 1 . 1 ... 0 @2op
55
56
-VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
57
-VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
58
+# The VSHLL T2 encoding is not a @2op pattern, but is here because it
59
+# overlaps what would be size=0b11 VMULH/VRMULH
32
+{
60
+{
33
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0;
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
62
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
63
64
-VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
65
-VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
66
+ VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
34
+}
67
+}
35
+
68
+
36
+static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
37
+{
69
+{
38
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
72
+
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
39
+}
74
+}
40
+
75
+
41
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
76
+{
42
{
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
43
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
44
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/linux-user/elfload.c
47
+++ b/linux-user/elfload.c
48
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
49
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
50
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
51
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
52
+ GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
53
54
return hwcaps;
55
}
56
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
57
ARMCPU *cpu = ARM_CPU(thread_cpu);
58
uint32_t hwcaps = 0;
59
60
+ GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
61
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
62
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
63
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
cpu->isar.id_aa64isar0 = t;
70
71
t = cpu->isar.id_aa64isar1;
72
+ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
73
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
74
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
75
t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
76
diff --git a/target/arm/helper.c b/target/arm/helper.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/helper.c
79
+++ b/target/arm/helper.c
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo rndr_reginfo[] = {
81
.access = PL0_R, .readfn = rndr_readfn },
82
REGINFO_SENTINEL
83
};
84
+
79
+
85
+#ifndef CONFIG_USER_ONLY
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
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
+}
81
+}
112
+
82
+
113
+static const ARMCPRegInfo dcpop_reg[] = {
83
+{
114
+ { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
115
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
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
+
86
+
121
+static const ARMCPRegInfo dcpodp_reg[] = {
87
+ VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
122
+ { .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
88
+}
123
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
89
124
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
90
VMAX_S 111 0 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
125
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
91
VMAX_U 111 1 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
126
+ REGINFO_SENTINEL
92
@@ -XXX,XX +XXX,XX @@ VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
127
+};
93
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
128
+#endif /*CONFIG_USER_ONLY*/
94
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
95
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
129
+
96
+
130
#endif
97
+# VSHLL T1 encoding; the T2 VSHLL encoding is elsewhere in this file
131
98
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
132
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
99
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
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
+
100
+
142
+ if (cpu_isar_feature(aa64_dcpodp, cpu)) {
101
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
143
+ define_one_arm_cp_reg(cpu, dcpodp_reg);
102
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
144
+ }
103
+
104
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
105
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
106
+
107
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
108
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
109
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/mve_helper.c
112
+++ b/target/arm/mve_helper.c
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
117
+
118
+/*
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
121
+ * the input, and LESIZE, LTYPE for the output.
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
123
+ * because the long shift is strictly left-only.
124
+ */
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
127
+ void *vm, uint32_t shift) \
128
+ { \
129
+ LTYPE *d = vd; \
130
+ TYPE *m = vm; \
131
+ uint16_t mask = mve_element_mask(env); \
132
+ unsigned le; \
133
+ assert(shift <= 16); \
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
135
+ LTYPE r = (LTYPE)m[H##ESIZE(le * 2 + TOP)] << shift; \
136
+ mergemask(&d[H##LESIZE(le)], r, mask); \
137
+ } \
138
+ mve_advance_vpt(env); \
145
+ }
139
+ }
146
+#endif /*CONFIG_USER_ONLY*/
140
+
147
#endif
141
+#define DO_VSHLL_ALL(OP, TOP) \
148
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
149
/*
143
+ DO_VSHLL(OP##ub, TOP, 1, uint8_t, 2, uint16_t) \
144
+ DO_VSHLL(OP##sh, TOP, 2, int16_t, 4, int32_t) \
145
+ DO_VSHLL(OP##uh, TOP, 2, uint16_t, 4, uint32_t) \
146
+
147
+DO_VSHLL_ALL(vshllb, false)
148
+DO_VSHLL_ALL(vshllt, true)
149
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-mve.c
152
+++ b/target/arm/translate-mve.c
153
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_S, vshli_s, true)
154
DO_2SHIFT(VSHRI_U, vshli_u, true)
155
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
+
158
+#define DO_VSHLL(INSN, FN) \
159
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
160
+ { \
161
+ static MVEGenTwoOpShiftFn * const fns[] = { \
162
+ gen_helper_mve_##FN##b, \
163
+ gen_helper_mve_##FN##h, \
164
+ }; \
165
+ return do_2shift(s, a, fns[a->size], false); \
166
+ }
167
+
168
+DO_VSHLL(VSHLL_BS, vshllbs)
169
+DO_VSHLL(VSHLL_BU, vshllbu)
170
+DO_VSHLL(VSHLL_TS, vshllts)
171
+DO_VSHLL(VSHLL_TU, vshlltu)
150
--
172
--
151
2.20.1
173
2.20.1
152
174
153
175
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Implement the MVE VSRI and VSLI insns, which perform a
2
shift-and-insert operation.
2
3
3
The Tacoma BMC board is replacement board for the BMC of the OpenPOWER
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Witherspoon system. It uses a AST2600 SoC instead of a AST2500 and the
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
I2C layout is the same as it controls the same main board. Used for HW
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
6
bringup.
7
---
8
target/arm/helper-mve.h | 8 ++++++++
9
target/arm/mve.decode | 9 ++++++++
10
target/arm/mve_helper.c | 42 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-mve.c | 3 +++
12
4 files changed, 62 insertions(+)
7
13
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-15-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/aspeed.c | 28 ++++++++++++++++++++++++++++
15
1 file changed, 28 insertions(+)
16
17
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/aspeed.c
16
--- a/target/arm/helper-mve.h
20
+++ b/hw/arm/aspeed.c
17
+++ b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@ struct AspeedBoardState {
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
#define AST2600_EVB_HW_STRAP1 0x000000C0
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
#define AST2600_EVB_HW_STRAP2 0x00000003
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+/* Tacoma hardware value */
22
+
26
+#define TACOMA_BMC_HW_STRAP1 0x00000000
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+#define TACOMA_BMC_HW_STRAP2 0x00000000
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/mve.decode
33
+++ b/target/arm/mve.decode
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
35
36
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
37
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
38
+
39
+# Shift-and-insert
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
43
+
44
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
45
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
46
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
47
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/mve_helper.c
50
+++ b/target/arm/mve_helper.c
51
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
52
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
53
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
54
55
+/* Shift-and-insert; we always work with 64 bits at a time */
56
+#define DO_2SHIFT_INSERT(OP, ESIZE, SHIFTFN, MASKFN) \
57
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
58
+ void *vm, uint32_t shift) \
59
+ { \
60
+ uint64_t *d = vd, *m = vm; \
61
+ uint16_t mask; \
62
+ uint64_t shiftmask; \
63
+ unsigned e; \
64
+ if (shift == 0 || shift == ESIZE * 8) { \
65
+ /* \
66
+ * Only VSLI can shift by 0; only VSRI can shift by <dt>. \
67
+ * The generic logic would give the right answer for 0 but \
68
+ * fails for <dt>. \
69
+ */ \
70
+ goto done; \
71
+ } \
72
+ assert(shift < ESIZE * 8); \
73
+ mask = mve_element_mask(env); \
74
+ /* ESIZE / 2 gives the MO_* value if ESIZE is in [1,2,4] */ \
75
+ shiftmask = dup_const(ESIZE / 2, MASKFN(ESIZE * 8, shift)); \
76
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
77
+ uint64_t r = (SHIFTFN(m[H8(e)], shift) & shiftmask) | \
78
+ (d[H8(e)] & ~shiftmask); \
79
+ mergemask(&d[H8(e)], r, mask); \
80
+ } \
81
+done: \
82
+ mve_advance_vpt(env); \
83
+ }
84
+
85
+#define DO_SHL(N, SHIFT) ((N) << (SHIFT))
86
+#define DO_SHR(N, SHIFT) ((N) >> (SHIFT))
87
+#define SHL_MASK(EBITS, SHIFT) MAKE_64BIT_MASK((SHIFT), (EBITS) - (SHIFT))
88
+#define SHR_MASK(EBITS, SHIFT) MAKE_64BIT_MASK(0, (EBITS) - (SHIFT))
89
+
90
+DO_2SHIFT_INSERT(vsrib, 1, DO_SHR, SHR_MASK)
91
+DO_2SHIFT_INSERT(vsrih, 2, DO_SHR, SHR_MASK)
92
+DO_2SHIFT_INSERT(vsriw, 4, DO_SHR, SHR_MASK)
93
+DO_2SHIFT_INSERT(vslib, 1, DO_SHL, SHL_MASK)
94
+DO_2SHIFT_INSERT(vslih, 2, DO_SHL, SHL_MASK)
95
+DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
28
+
96
+
29
/*
97
/*
30
* The max ram region is for firmwares that scan the address space
98
* Long shifts taking half-sized inputs from top or bottom of the input
31
* with load/store to guess how much RAM the SoC has.
99
* vector and producing a double-width result. ESIZE, TYPE are for
32
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
33
AspeedSoCState *soc = &bmc->soc;
101
index XXXXXXX..XXXXXXX 100644
34
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
102
--- a/target/arm/translate-mve.c
35
103
+++ b/target/arm/translate-mve.c
36
+ /* Bus 3: TODO bmp280@77 */
104
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_U, vshli_u, true)
37
+ /* Bus 3: TODO max31785@52 */
105
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
38
+ /* Bus 3: TODO dps310@76 */
106
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
39
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
107
40
0x60);
108
+DO_2SHIFT(VSRI, vsri, false)
41
109
+DO_2SHIFT(VSLI, vsli, false)
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
+
110
+
59
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
111
#define DO_VSHLL(INSN, FN) \
60
+ amc->soc_name = "ast2600-a0";
112
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
61
+ amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
113
{ \
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
--
114
--
85
2.20.1
115
2.20.1
86
116
87
117
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
2
2
3
HCR_EL2.TID1 mandates that access from EL1 to REVIDR_EL1, AIDR_EL1
3
do_urshr() is borrowed from sve_helper.c.
4
(and their 32bit equivalents) as well as TCMTR, TLBTR are trapped
5
to EL2. QEMU ignores it, making it harder for a hypervisor to
6
virtualize the HW (though to be fair, no known hypervisor actually
7
cares).
8
4
9
Do the right thing by trapping to EL2 if HCR_EL2.TID1 is set.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
8
---
9
target/arm/helper-mve.h | 10 ++++++++++
10
target/arm/mve.decode | 11 +++++++++++
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-mve.c | 15 ++++++++++++++
13
4 files changed, 76 insertions(+)
10
14
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.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
16
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
17
--- a/target/arm/helper-mve.h
23
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper-mve.h
24
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
return ret;
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
}
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+static CPAccessResult access_aa64_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
23
+
29
+ bool isread)
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+{
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID1)) {
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+ return CP_ACCESS_TRAP_EL2;
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
41
+
42
+# Narrowing shifts (which only support b and h sizes)
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
46
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
47
+
48
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
49
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
50
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
51
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
52
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/mve_helper.c
55
+++ b/target/arm/mve_helper.c
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
57
58
DO_VSHLL_ALL(vshllb, false)
59
DO_VSHLL_ALL(vshllt, true)
60
+
61
+/*
62
+ * Narrowing right shifts, taking a double sized input, shifting it
63
+ * and putting the result in either the top or bottom half of the output.
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
65
+ */
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
68
+ void *vm, uint32_t shift) \
69
+ { \
70
+ LTYPE *m = vm; \
71
+ TYPE *d = vd; \
72
+ uint16_t mask = mve_element_mask(env); \
73
+ unsigned le; \
74
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
75
+ TYPE r = FN(m[H##LESIZE(le)], shift); \
76
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
77
+ } \
78
+ mve_advance_vpt(env); \
33
+ }
79
+ }
34
+
80
+
35
+ return CP_ACCESS_OK;
81
+#define DO_VSHRN_ALL(OP, FN) \
82
+ DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
83
+ DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
84
+ DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
85
+ DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
86
+
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
88
+{
89
+ if (likely(sh < 64)) {
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
91
+ } else if (sh == 64) {
92
+ return x >> 63;
93
+ } else {
94
+ return 0;
95
+ }
36
+}
96
+}
37
+
97
+
38
+static CPAccessResult access_aa32_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
39
+ bool isread)
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
40
+{
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
41
+ if (arm_feature(env, ARM_FEATURE_V8)) {
101
index XXXXXXX..XXXXXXX 100644
42
+ return access_aa64_tid1(env, ri, isread);
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_VSHLL(VSHLL_BS, vshllbs)
105
DO_VSHLL(VSHLL_BU, vshllbu)
106
DO_VSHLL(VSHLL_TS, vshllts)
107
DO_VSHLL(VSHLL_TU, vshlltu)
108
+
109
+#define DO_2SHIFT_N(INSN, FN) \
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
111
+ { \
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
113
+ gen_helper_mve_##FN##b, \
114
+ gen_helper_mve_##FN##h, \
115
+ }; \
116
+ return do_2shift(s, a, fns[a->size], false); \
43
+ }
117
+ }
44
+
118
+
45
+ return CP_ACCESS_OK;
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
46
+}
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
47
+
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
48
static const ARMCPRegInfo v7_cp_reginfo[] = {
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
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
--
123
--
95
2.20.1
124
2.20.1
96
125
97
126
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
Implement the MVE saturating shift-right-and-narrow insns
2
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
The AST2600 control register sneakily changed the meaning of bit 4
3
4
without anyone noticing. It no longer controls the 1MHz vs APB clock
4
do_srshr() is borrowed from sve_helper.c.
5
select, and instead always runs at 1MHz.
5
6
7
The AST2500 was always 1MHz too, but it retained bit 4, making it read
8
only. We can model both using the same fixed 1MHz calculation.
9
10
Fixes: 6b2b2a703cad ("hw: wdt_aspeed: Add AST2600 support")
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Joel Stanley <joel@jms.id.au>
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Message-id: 20191119141211.25716-10-clg@kaod.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-13-peter.maydell@linaro.org
17
---
9
---
18
include/hw/watchdog/wdt_aspeed.h | 1 +
10
target/arm/helper-mve.h | 30 +++++++++++
19
hw/watchdog/wdt_aspeed.c | 21 +++++++++++++++++----
11
target/arm/mve.decode | 28 ++++++++++
20
2 files changed, 18 insertions(+), 4 deletions(-)
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
21
13
target/arm/translate-mve.c | 12 +++++
22
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
14
4 files changed, 174 insertions(+)
23
index XXXXXXX..XXXXXXX 100644
15
24
--- a/include/hw/watchdog/wdt_aspeed.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
25
+++ b/include/hw/watchdog/wdt_aspeed.h
17
index XXXXXXX..XXXXXXX 100644
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedWDTClass {
18
--- a/target/arm/helper-mve.h
27
uint32_t ext_pulse_width_mask;
19
+++ b/target/arm/helper-mve.h
28
uint32_t reset_ctrl_reg;
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+ void (*wdt_reload)(AspeedWDTState *s);
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
} AspeedWDTClass;
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
24
+
33
#endif /* WDT_ASPEED_H */
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
index XXXXXXX..XXXXXXX 100644
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
--- a/hw/watchdog/wdt_aspeed.c
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+++ b/hw/watchdog/wdt_aspeed.c
29
+
38
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
}
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
-static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
34
+
43
+static void aspeed_wdt_reload(AspeedWDTState *s)
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
{
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
uint64_t reload;
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
- if (pclk) {
39
+
48
+ if (!(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK)) {
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
reload = muldiv64(s->regs[WDT_RELOAD_VALUE], NANOSECONDS_PER_SECOND,
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
s->pclk_freq);
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
} else {
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
44
+
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/mve.decode
57
+++ b/target/arm/mve.decode
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
62
+
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
68
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
69
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
70
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
71
+
72
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
73
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
74
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
75
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
76
+
77
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
78
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
79
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
80
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
81
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
82
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
83
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
84
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
85
+
86
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
87
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
88
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
89
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
90
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/mve_helper.c
93
+++ b/target/arm/mve_helper.c
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
53
}
95
}
54
}
96
}
55
97
56
+static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
57
+{
99
+{
58
+ uint64_t reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL;
100
+ if (likely(sh < 64)) {
59
+
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
60
+ if (aspeed_wdt_is_enabled(s)) {
102
+ } else {
61
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
103
+ /* Rounding the sign bit always produces 0. */
104
+ return 0;
62
+ }
105
+ }
63
+}
106
+}
64
+
107
+
65
+
108
DO_VSHRN_ALL(vshrn, DO_SHR)
66
static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
109
DO_VSHRN_ALL(vrshrn, do_urshr)
67
unsigned size)
110
+
68
{
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
69
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
112
+ bool *satp)
70
case WDT_RESTART:
113
+{
71
if ((data & 0xFFFF) == WDT_RESTART_MAGIC) {
114
+ if (val > max) {
72
s->regs[WDT_STATUS] = s->regs[WDT_RELOAD_VALUE];
115
+ *satp = true;
73
- aspeed_wdt_reload(s, !(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK));
116
+ return max;
74
+ awc->wdt_reload(s);
117
+ } else if (val < min) {
75
}
118
+ *satp = true;
76
break;
119
+ return min;
77
case WDT_CTRL:
120
+ } else {
78
if (enable && !aspeed_wdt_is_enabled(s)) {
121
+ return val;
79
s->regs[WDT_CTRL] = data;
122
+ }
80
- aspeed_wdt_reload(s, !(data & WDT_CTRL_1MHZ_CLK));
123
+}
81
+ awc->wdt_reload(s);
124
+
82
} else if (!enable && aspeed_wdt_is_enabled(s)) {
125
+/* Saturating narrowing right shifts */
83
s->regs[WDT_CTRL] = data;
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
84
timer_del(s->timer);
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data)
128
+ void *vm, uint32_t shift) \
86
awc->offset = 0x20;
129
+ { \
87
awc->ext_pulse_width_mask = 0xff;
130
+ LTYPE *m = vm; \
88
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
131
+ TYPE *d = vd; \
89
+ awc->wdt_reload = aspeed_wdt_reload;
132
+ uint16_t mask = mve_element_mask(env); \
90
}
133
+ bool qc = false; \
91
134
+ unsigned le; \
92
static const TypeInfo aspeed_2400_wdt_info = {
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
93
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
136
+ bool sat = false; \
94
awc->ext_pulse_width_mask = 0xfffff;
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
95
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
96
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
97
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
140
+ } \
98
}
141
+ if (qc) { \
99
142
+ env->vfp.qc[0] = qc; \
100
static const TypeInfo aspeed_2500_wdt_info = {
143
+ } \
101
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
144
+ mve_advance_vpt(env); \
102
awc->ext_pulse_width_mask = 0xfffff; /* TODO */
145
+ }
103
awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
146
+
104
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
105
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
106
}
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
107
150
+
108
static const TypeInfo aspeed_2600_wdt_info = {
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
154
+
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
158
+
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
162
+
163
+#define DO_SHRN_SB(N, M, SATP) \
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
165
+#define DO_SHRN_UB(N, M, SATP) \
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
167
+#define DO_SHRUN_B(N, M, SATP) \
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
169
+
170
+#define DO_SHRN_SH(N, M, SATP) \
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
172
+#define DO_SHRN_UH(N, M, SATP) \
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
174
+#define DO_SHRUN_H(N, M, SATP) \
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
176
+
177
+#define DO_RSHRN_SB(N, M, SATP) \
178
+ do_sat_bhs(do_srshr(N, M), INT8_MIN, INT8_MAX, SATP)
179
+#define DO_RSHRN_UB(N, M, SATP) \
180
+ do_sat_bhs(do_urshr(N, M), 0, UINT8_MAX, SATP)
181
+#define DO_RSHRUN_B(N, M, SATP) \
182
+ do_sat_bhs(do_srshr(N, M), 0, UINT8_MAX, SATP)
183
+
184
+#define DO_RSHRN_SH(N, M, SATP) \
185
+ do_sat_bhs(do_srshr(N, M), INT16_MIN, INT16_MAX, SATP)
186
+#define DO_RSHRN_UH(N, M, SATP) \
187
+ do_sat_bhs(do_urshr(N, M), 0, UINT16_MAX, SATP)
188
+#define DO_RSHRUN_H(N, M, SATP) \
189
+ do_sat_bhs(do_srshr(N, M), 0, UINT16_MAX, SATP)
190
+
191
+DO_VSHRN_SAT_SB(vqshrnb_sb, vqshrnt_sb, DO_SHRN_SB)
192
+DO_VSHRN_SAT_SH(vqshrnb_sh, vqshrnt_sh, DO_SHRN_SH)
193
+DO_VSHRN_SAT_UB(vqshrnb_ub, vqshrnt_ub, DO_SHRN_UB)
194
+DO_VSHRN_SAT_UH(vqshrnb_uh, vqshrnt_uh, DO_SHRN_UH)
195
+DO_VSHRN_SAT_SB(vqshrunbb, vqshruntb, DO_SHRUN_B)
196
+DO_VSHRN_SAT_SH(vqshrunbh, vqshrunth, DO_SHRUN_H)
197
+
198
+DO_VSHRN_SAT_SB(vqrshrnb_sb, vqrshrnt_sb, DO_RSHRN_SB)
199
+DO_VSHRN_SAT_SH(vqrshrnb_sh, vqrshrnt_sh, DO_RSHRN_SH)
200
+DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
201
+DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
202
+DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
203
+DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
204
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/arm/translate-mve.c
207
+++ b/target/arm/translate-mve.c
208
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VSHRNB, vshrnb)
209
DO_2SHIFT_N(VSHRNT, vshrnt)
210
DO_2SHIFT_N(VRSHRNB, vrshrnb)
211
DO_2SHIFT_N(VRSHRNT, vrshrnt)
212
+DO_2SHIFT_N(VQSHRNB_S, vqshrnb_s)
213
+DO_2SHIFT_N(VQSHRNT_S, vqshrnt_s)
214
+DO_2SHIFT_N(VQSHRNB_U, vqshrnb_u)
215
+DO_2SHIFT_N(VQSHRNT_U, vqshrnt_u)
216
+DO_2SHIFT_N(VQSHRUNB, vqshrunb)
217
+DO_2SHIFT_N(VQSHRUNT, vqshrunt)
218
+DO_2SHIFT_N(VQRSHRNB_S, vqrshrnb_s)
219
+DO_2SHIFT_N(VQRSHRNT_S, vqrshrnt_s)
220
+DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
221
+DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
222
+DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
223
+DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
109
--
224
--
110
2.20.1
225
2.20.1
111
226
112
227
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
Implement the MVE VSHLC insn, which performs a shift left of the
2
entire vector with carry in bits provided from a general purpose
3
register and carry out bits written back to that register.
2
4
3
HCR_EL2.TID2 mandates that access from EL1 to CTR_EL0, CCSIDR_EL1,
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
CCSIDR2_EL1, CLIDR_EL1, CSSELR_EL1 are trapped to EL2, and QEMU
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
completely ignores it, making it impossible for hypervisors to
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
6
virtualize the cache hierarchy.
8
---
9
target/arm/helper-mve.h | 2 ++
10
target/arm/mve.decode | 2 ++
11
target/arm/mve_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-mve.c | 30 ++++++++++++++++++++++++++++++
13
4 files changed, 72 insertions(+)
7
14
8
Do the right thing by trapping to EL2 if HCR_EL2.TID2 is set.
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
9
10
Signed-off-by: Marc Zyngier <maz@kernel.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20191201122018.25808-2-maz@kernel.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/helper.c | 31 +++++++++++++++++++++++++++----
17
1 file changed, 27 insertions(+), 4 deletions(-)
18
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
17
--- a/target/arm/helper-mve.h
22
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper-mve.h
23
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
raw_write(env, ri, value);
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
}
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+static CPAccessResult access_aa64_tid2(CPUARMState *env,
23
+
28
+ const ARMCPRegInfo *ri,
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
29
+ bool isread)
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/mve.decode
28
+++ b/target/arm/mve.decode
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
33
+
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/mve_helper.c
38
+++ b/target/arm/mve_helper.c
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
43
+
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
45
+ uint32_t shift)
30
+{
46
+{
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID2)) {
47
+ uint32_t *d = vd;
32
+ return CP_ACCESS_TRAP_EL2;
48
+ uint16_t mask = mve_element_mask(env);
49
+ unsigned e;
50
+ uint32_t r;
51
+
52
+ /*
53
+ * For each 32-bit element, we shift it left, bringing in the
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
55
+ * the top become the new rdm, if the predicate mask permits.
56
+ * The final rdm value is returned to update the register.
57
+ * shift == 0 here means "shift by 32 bits".
58
+ */
59
+ if (shift == 0) {
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
61
+ r = rdm;
62
+ if (mask & 1) {
63
+ rdm = d[H4(e)];
64
+ }
65
+ mergemask(&d[H4(e)], r, mask);
66
+ }
67
+ } else {
68
+ uint32_t shiftmask = MAKE_64BIT_MASK(0, shift);
69
+
70
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
71
+ r = (d[H4(e)] << shift) | (rdm & shiftmask);
72
+ if (mask & 1) {
73
+ rdm = d[H4(e)] >> (32 - shift);
74
+ }
75
+ mergemask(&d[H4(e)], r, mask);
76
+ }
77
+ }
78
+ mve_advance_vpt(env);
79
+ return rdm;
80
+}
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/translate-mve.c
84
+++ b/target/arm/translate-mve.c
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
86
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
87
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
88
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
89
+
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
91
+{
92
+ /*
93
+ * Whole Vector Left Shift with Carry. The carry is taken
94
+ * from a general purpose register and written back there.
95
+ * An imm of 0 means "shift by 32".
96
+ */
97
+ TCGv_ptr qd;
98
+ TCGv_i32 rdm;
99
+
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
101
+ return false;
102
+ }
103
+ if (a->rdm == 13 || a->rdm == 15) {
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
105
+ return false;
106
+ }
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
108
+ return true;
33
+ }
109
+ }
34
+
110
+
35
+ return CP_ACCESS_OK;
111
+ qd = mve_qreg_ptr(a->qd);
112
+ rdm = load_reg(s, a->rdm);
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
114
+ store_reg(s, a->rdm, rdm);
115
+ tcg_temp_free_ptr(qd);
116
+ mve_update_eci(s);
117
+ return true;
36
+}
118
+}
37
+
38
static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
39
{
40
ARMCPU *cpu = env_archcpu(env);
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
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;
61
}
62
+
63
+ if (arm_current_el(env) < 2 && arm_hcr_el2_eff(env) & HCR_TID2) {
64
+ return CP_ACCESS_TRAP_EL2;
65
+ }
66
+
67
return CP_ACCESS_OK;
68
}
69
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
71
ARMCPRegInfo clidr = {
72
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
73
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
74
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr
75
+ .access = PL1_R, .type = ARM_CP_CONST,
76
+ .accessfn = access_aa64_tid2,
77
+ .resetvalue = cpu->clidr
78
};
79
define_one_arm_cp_reg(cpu, &clidr);
80
define_arm_cp_regs(cpu, v7_cp_reginfo);
81
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
82
/* These are common to v8 and pre-v8 */
83
{ .name = "CTR",
84
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
85
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
86
+ .access = PL1_R, .accessfn = ctr_el0_access,
87
+ .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
88
{ .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
89
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
90
.access = PL0_R, .accessfn = ctr_el0_access,
91
--
119
--
92
2.20.1
120
2.20.1
93
121
94
122
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
2
that it accumulates 32-bit elements into a 64-bit accumulator
3
stored in a pair of general-purpose registers.
2
4
3
The SRAM must be enabled before using the Buffer Pool mode or the DMA
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
mode. This is not required on other SoCs.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
8
---
9
target/arm/helper-mve.h | 3 ++
10
target/arm/mve.decode | 6 +++-
11
target/arm/mve_helper.c | 19 ++++++++++++
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
13
4 files changed, 90 insertions(+), 1 deletion(-)
5
14
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
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
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/i2c/aspeed_i2c.h
17
--- a/target/arm/helper-mve.h
20
+++ b/include/hw/i2c/aspeed_i2c.h
18
+++ b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
qemu_irq irq;
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
23
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
24
uint32_t intr_status;
22
25
+ uint32_t ctrl_global;
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
26
MemoryRegion pool_iomem;
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
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
+
25
+
35
} AspeedI2CClass;
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
36
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
37
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
38
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
39
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/i2c/aspeed_i2c.c
31
--- a/target/arm/mve.decode
41
+++ b/hw/i2c/aspeed_i2c.c
32
+++ b/target/arm/mve.decode
42
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
43
#define I2C_CTRL_STATUS 0x00 /* Device Interrupt Status */
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
44
#define I2C_CTRL_ASSIGN 0x08 /* Device Interrupt Target
35
45
Assignment */
36
# Vector add across vector
46
+#define I2C_CTRL_GLOBAL 0x0C /* Global Control Register */
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
47
+#define I2C_CTRL_SRAM_EN BIT(0)
38
+{
48
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
49
/* I2C Device (Bus) Register */
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
50
41
+ rdahi=%rdahi rdalo=%rdalo
51
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
42
+}
52
}
43
44
# Predicate operations
45
%mask_22_13 22:1 13:3
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/mve_helper.c
49
+++ b/target/arm/mve_helper.c
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
51
DO_VADDV(vaddvuh, 2, uint16_t)
52
DO_VADDV(vaddvuw, 4, uint32_t)
53
54
+#define DO_VADDLV(OP, TYPE, LTYPE) \
55
+ uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vm, \
56
+ uint64_t ra) \
57
+ { \
58
+ uint16_t mask = mve_element_mask(env); \
59
+ unsigned e; \
60
+ TYPE *m = vm; \
61
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
62
+ if (mask & 1) { \
63
+ ra += (LTYPE)m[H4(e)]; \
64
+ } \
65
+ } \
66
+ mve_advance_vpt(env); \
67
+ return ra; \
68
+ } \
69
+
70
+DO_VADDLV(vaddlv_s, int32_t, int64_t)
71
+DO_VADDLV(vaddlv_u, uint32_t, uint64_t)
72
+
73
/* Shifts by immediate */
74
#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
75
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
76
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate-mve.c
79
+++ b/target/arm/translate-mve.c
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
81
return true;
53
}
82
}
54
83
55
+static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
56
+{
85
+{
57
+ AspeedI2CState *s = bus->controller;
86
+ /*
58
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
88
+ * elements of the vector into a 64-bit result stored in
89
+ * a pair of general-purpose registers.
90
+ * No need to check Qm's bank: it is only 3 bits in decode.
91
+ */
92
+ TCGv_ptr qm;
93
+ TCGv_i64 rda;
94
+ TCGv_i32 rdalo, rdahi;
59
+
95
+
60
+ if (!aic->check_sram) {
96
+ if (!dc_isar_feature(aa32_mve, s)) {
97
+ return false;
98
+ }
99
+ /*
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
102
+ */
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
104
+ return false;
105
+ }
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
61
+ return true;
107
+ return true;
62
+ }
108
+ }
63
+
109
+
64
+ /*
110
+ /*
65
+ * AST2500: SRAM must be enabled before using the Buffer Pool or
111
+ * This insn is subject to beat-wise execution. Partial execution
66
+ * DMA mode.
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
67
+ */
114
+ */
68
+ if (!(s->ctrl_global & I2C_CTRL_SRAM_EN) &&
115
+ if (a->a || mve_skip_first_beat(s)) {
69
+ (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE |
116
+ /* Accumulate input from RdaHi:RdaLo */
70
+ I2CD_RX_BUFF_ENABLE | I2CD_TX_BUFF_ENABLE))) {
117
+ rda = tcg_temp_new_i64();
71
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: SRAM is not enabled\n", __func__);
118
+ rdalo = load_reg(s, a->rdalo);
72
+ return false;
119
+ rdahi = load_reg(s, a->rdahi);
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
121
+ tcg_temp_free_i32(rdalo);
122
+ tcg_temp_free_i32(rdahi);
123
+ } else {
124
+ /* Accumulate starting at zero */
125
+ rda = tcg_const_i64(0);
73
+ }
126
+ }
74
+
127
+
128
+ qm = mve_qreg_ptr(a->qm);
129
+ if (a->u) {
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
131
+ } else {
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
133
+ }
134
+ tcg_temp_free_ptr(qm);
135
+
136
+ rdalo = tcg_temp_new_i32();
137
+ rdahi = tcg_temp_new_i32();
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
140
+ store_reg(s, a->rdalo, rdalo);
141
+ store_reg(s, a->rdahi, rdahi);
142
+ tcg_temp_free_i64(rda);
143
+ mve_update_eci(s);
75
+ return true;
144
+ return true;
76
+}
145
+}
77
+
146
+
78
/*
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
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
{
148
{
105
+ AspeedI2CState *s = opaque;
149
TCGv_ptr qd;
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
--
150
--
123
2.20.1
151
2.20.1
124
152
125
153
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
The MVE extension to v8.1M includes some new shift instructions which
2
2
sit entirely within the non-coprocessor part of the encoding space
3
Signed-off-by: Cédric Le Goater <clg@kaod.org>
3
and which operate only on general-purpose registers. They take up
4
Reviewed-by: Joel Stanley <joel@jms.id.au>
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
5
with Rm == 13 or 15.
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Implement the long shifts by immediate, which perform shifts on a
8
Message-id: 20191119141211.25716-6-clg@kaod.org
8
pair of general-purpose registers treated as a 64-bit quantity, with
9
an immediate shift count between 1 and 32.
10
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
14
is too difficult, because the functions that generate the code are
15
shared between a dozen different kinds of arithmetic or logical
16
instruction for all A32, T16 and T32 encodings, and for some insns
17
and some encodings Rm==13,15 are valid.)
18
19
We make the helper functions we need for UQSHLL and SQSHLL take
20
a 32-bit value which the helper casts to int8_t because we'll need
21
these helpers also for the shift-by-register insns, where the shift
22
count might be < 0 or > 32.
23
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
10
---
27
---
11
hw/i2c/aspeed_i2c.c | 93 ++++++++++++++++++++++++++++++++++++++-------
28
target/arm/helper-mve.h | 3 ++
12
hw/i2c/trace-events | 9 +++++
29
target/arm/translate.h | 1 +
13
2 files changed, 89 insertions(+), 13 deletions(-)
30
target/arm/t32.decode | 28 +++++++++++++
14
31
target/arm/mve_helper.c | 10 +++++
15
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
16
index XXXXXXX..XXXXXXX 100644
33
5 files changed, 132 insertions(+)
17
--- a/hw/i2c/aspeed_i2c.c
34
18
+++ b/hw/i2c/aspeed_i2c.c
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper-mve.h
38
+++ b/target/arm/helper-mve.h
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
43
+
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.h
49
+++ b/target/arm/translate.h
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
55
56
/**
57
* arm_tbflags_from_tb:
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/t32.decode
61
+++ b/target/arm/t32.decode
19
@@ -XXX,XX +XXX,XX @@
62
@@ -XXX,XX +XXX,XX @@
20
#include "hw/i2c/aspeed_i2c.h"
63
&mcr !extern cp opc1 crn crm opc2 rt
21
#include "hw/irq.h"
64
&mcrr !extern cp opc1 crm rt rt2
22
#include "hw/qdev-properties.h"
65
23
+#include "trace.h"
66
+&mve_shl_ri rdalo rdahi shim
24
67
+
25
/* I2C Global Register */
68
+# rdahi: bits [3:1] from insn, bit 0 is 1
26
69
+# rdalo: bits [3:1] from insn, bit 0 is 0
27
@@ -XXX,XX +XXX,XX @@ static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
70
+%rdahi_9 9:3 !function=times_2_plus_1
71
+%rdalo_17 17:3 !function=times_2
72
+
73
# Data-processing (register)
74
75
%imm5_12_6 12:3 6:2
76
@@ -XXX,XX +XXX,XX @@
77
@S_xrr_shi ....... .... . rn:4 .... .... .. shty:2 rm:4 \
78
&s_rrr_shi shim=%imm5_12_6 s=1 rd=0
79
80
+@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
81
+ &mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
82
+
28
{
83
{
29
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
84
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
30
85
AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi
31
+ trace_aspeed_i2c_bus_raise_interrupt(bus->intr_status,
86
}
32
+ bus->intr_status & I2CD_INTR_TX_NAK ? "nak|" : "",
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
33
+ bus->intr_status & I2CD_INTR_TX_ACK ? "ack|" : "",
34
+ bus->intr_status & I2CD_INTR_RX_DONE ? "done|" : "",
35
+ bus->intr_status & I2CD_INTR_NORMAL_STOP ? "normal|" : "",
36
+ bus->intr_status & I2CD_INTR_ABNORMAL ? "abnormal" : "");
37
+
38
bus->intr_status &= bus->intr_ctrl;
39
if (bus->intr_status) {
40
bus->controller->intr_status |= 1 << bus->id;
41
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
42
{
88
{
43
AspeedI2CBus *bus = opaque;
89
+ # The v8.1M MVE shift insns overlap in encoding with MOVS/ORRS
44
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
90
+ # and are distinguished by having Rm==13 or 15. Those are UNPREDICTABLE
45
+ uint64_t value = -1;
91
+ # cases for MOVS/ORRS. We decode the MVE cases first, ensuring that
46
92
+ # they explicitly call unallocated_encoding() for cases that must UNDEF
47
switch (offset) {
93
+ # (eg "using a new shift insn on a v8.1M CPU without MVE"), and letting
48
case I2CD_FUN_CTRL_REG:
94
+ # the rest fall through (where ORR_rrri and MOV_rxri will end up
49
- return bus->ctrl;
95
+ # handling them as r13 and r15 accesses with the same semantics as A32).
50
+ value = bus->ctrl;
96
+ [
51
+ break;
97
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
52
case I2CD_AC_TIMING_REG1:
98
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
53
- return bus->timing[0];
99
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
54
+ value = bus->timing[0];
100
+
55
+ break;
101
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
56
case I2CD_AC_TIMING_REG2:
102
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
57
- return bus->timing[1];
103
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
58
+ value = bus->timing[1];
104
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
59
+ break;
105
+ ]
60
case I2CD_INTR_CTRL_REG:
106
+
61
- return bus->intr_ctrl;
107
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
62
+ value = bus->intr_ctrl;
108
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
63
+ break;
109
}
64
case I2CD_INTR_STS_REG:
110
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
65
- return bus->intr_status;
111
index XXXXXXX..XXXXXXX 100644
66
+ value = bus->intr_status;
112
--- a/target/arm/mve_helper.c
67
+ break;
113
+++ b/target/arm/mve_helper.c
68
case I2CD_POOL_CTRL_REG:
114
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
69
- return bus->pool_ctrl;
115
mve_advance_vpt(env);
70
+ value = bus->pool_ctrl;
116
return rdm;
71
+ break;
117
}
72
case I2CD_BYTE_BUF_REG:
118
+
73
- return bus->buf;
119
+uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
74
+ value = bus->buf;
120
+{
75
+ break;
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
76
case I2CD_CMD_REG:
122
+}
77
- return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
123
+
78
+ value = bus->cmd | (i2c_bus_busy(bus->bus) << 16);
124
+uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
79
+ break;
125
+{
80
case I2CD_DMA_ADDR:
126
+ return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
81
if (!aic->has_dma) {
127
+}
82
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
83
- return -1;
129
index XXXXXXX..XXXXXXX 100644
84
+ break;
130
--- a/target/arm/translate.c
85
}
131
+++ b/target/arm/translate.c
86
- return bus->dma_addr;
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
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;
133
return true;
166
}
134
}
167
135
168
+static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
136
+/*
169
+{
137
+ * v8.1M MVE wide-shifts
170
+ g_autofree char *cmd_flags;
138
+ */
171
+ uint32_t count;
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
172
+
140
+ WideShiftImmFn *fn)
173
+ if (bus->cmd & (I2CD_RX_BUFF_ENABLE | I2CD_RX_BUFF_ENABLE)) {
141
+{
174
+ count = I2CD_POOL_TX_COUNT(bus->pool_ctrl);
142
+ TCGv_i64 rda;
175
+ } else if (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_RX_DMA_ENABLE)) {
143
+ TCGv_i32 rdalo, rdahi;
176
+ count = bus->dma_len;
144
+
177
+ } else { /* BYTE mode */
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
178
+ count = 1;
146
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
179
+ }
147
+ return false;
180
+
148
+ }
181
+ cmd_flags = g_strdup_printf("%s%s%s%s%s%s%s%s%s",
149
+ if (a->rdahi == 15) {
182
+ bus->cmd & I2CD_M_START_CMD ? "start|" : "",
150
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
183
+ bus->cmd & I2CD_RX_DMA_ENABLE ? "rxdma|" : "",
151
+ return false;
184
+ bus->cmd & I2CD_TX_DMA_ENABLE ? "txdma|" : "",
152
+ }
185
+ bus->cmd & I2CD_RX_BUFF_ENABLE ? "rxbuf|" : "",
153
+ if (!dc_isar_feature(aa32_mve, s) ||
186
+ bus->cmd & I2CD_TX_BUFF_ENABLE ? "txbuf|" : "",
154
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
187
+ bus->cmd & I2CD_M_TX_CMD ? "tx|" : "",
155
+ a->rdahi == 13) {
188
+ bus->cmd & I2CD_M_RX_CMD ? "rx|" : "",
156
+ /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
189
+ bus->cmd & I2CD_M_S_RX_CMD_LAST ? "last|" : "",
157
+ unallocated_encoding(s);
190
+ bus->cmd & I2CD_M_STOP_CMD ? "stop" : "");
158
+ return true;
191
+
159
+ }
192
+ trace_aspeed_i2c_bus_cmd(bus->cmd, cmd_flags, count, bus->intr_status);
160
+
161
+ if (a->shim == 0) {
162
+ a->shim = 32;
163
+ }
164
+
165
+ rda = tcg_temp_new_i64();
166
+ rdalo = load_reg(s, a->rdalo);
167
+ rdahi = load_reg(s, a->rdahi);
168
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
169
+
170
+ fn(rda, rda, a->shim);
171
+
172
+ tcg_gen_extrl_i64_i32(rdalo, rda);
173
+ tcg_gen_extrh_i64_i32(rdahi, rda);
174
+ store_reg(s, a->rdalo, rdalo);
175
+ store_reg(s, a->rdahi, rdahi);
176
+ tcg_temp_free_i64(rda);
177
+
178
+ return true;
179
+}
180
+
181
+static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
182
+{
183
+ return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
184
+}
185
+
186
+static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
187
+{
188
+ return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
189
+}
190
+
191
+static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
192
+{
193
+ return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
194
+}
195
+
196
+static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
197
+{
198
+ gen_helper_mve_sqshll(r, cpu_env, n, tcg_constant_i32(shift));
199
+}
200
+
201
+static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
202
+{
203
+ return do_mve_shl_ri(s, a, gen_mve_sqshll);
204
+}
205
+
206
+static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
207
+{
208
+ gen_helper_mve_uqshll(r, cpu_env, n, tcg_constant_i32(shift));
209
+}
210
+
211
+static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
212
+{
213
+ return do_mve_shl_ri(s, a, gen_mve_uqshll);
214
+}
215
+
216
+static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
217
+{
218
+ return do_mve_shl_ri(s, a, gen_srshr64_i64);
219
+}
220
+
221
+static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
222
+{
223
+ return do_mve_shl_ri(s, a, gen_urshr64_i64);
193
+}
224
+}
194
+
225
+
195
/*
226
/*
196
* The state machine needs some refinement. It is only used to track
227
* Multiply and multiply accumulate
197
* invalid STOP commands for the moment.
228
*/
198
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
199
return;
200
}
201
202
+ if (trace_event_get_state_backends(TRACE_ASPEED_I2C_BUS_CMD)) {
203
+ aspeed_i2c_bus_cmd_dump(bus);
204
+ }
205
+
206
if (bus->cmd & I2CD_M_START_CMD) {
207
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
208
I2CD_MSTARTR : I2CD_MSTART;
209
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
210
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
211
bool handle_rx;
212
213
+ trace_aspeed_i2c_bus_write(bus->id, offset, size, value);
214
+
215
switch (offset) {
216
case I2CD_FUN_CTRL_REG:
217
if (value & I2CD_SLAVE_EN) {
218
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/i2c/trace-events
221
+++ b/hw/i2c/trace-events
222
@@ -XXX,XX +XXX,XX @@
223
i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)"
224
i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x"
225
i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
226
+
227
+# aspeed_i2c.c
228
+
229
+aspeed_i2c_bus_cmd(uint32_t cmd, const char *cmd_flags, uint32_t count, uint32_t intr_status) "handling cmd=0x%x %s count=%d intr=0x%x"
230
+aspeed_i2c_bus_raise_interrupt(uint32_t intr_status, const char *str1, const char *str2, const char *str3, const char *str4, const char *str5) "handled intr=0x%x %s%s%s%s%s"
231
+aspeed_i2c_bus_read(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
232
+aspeed_i2c_bus_write(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
233
+aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s send %d/%d 0x%02x"
234
+aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s recv %d/%d 0x%02x"
235
--
229
--
236
2.20.1
230
2.20.1
237
231
238
232
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Implement the MVE long shifts by register, which perform shifts on a
2
2
pair of general-purpose registers treated as a 64-bit quantity, with
3
A write to the SCR can change the effective EL by droppping the system
3
the shift count in another general-purpose register, which might be
4
from secure to non-secure mode. However if we use a cached current_el
4
either positive or negative.
5
from before the change we'll rebuild the flags incorrectly. To fix
5
6
this we introduce the ARM_CP_NEWEL CP flag to indicate the new EL
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
should be used when recomputing the flags.
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
we have to move the CSEL pattern into the same decodetree group.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20191212114734.6962-1-alex.bennee@linaro.org
14
Message-id: 20210628135835.6690-17-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>
17
---
15
---
18
target/arm/cpu.h | 8 ++++++--
16
target/arm/helper-mve.h | 6 +++
19
target/arm/helper.h | 1 +
17
target/arm/translate.h | 1 +
20
target/arm/helper.c | 14 +++++++++++++-
18
target/arm/t32.decode | 16 +++++--
21
target/arm/translate.c | 6 +++++-
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
22
4 files changed, 25 insertions(+), 4 deletions(-)
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
23
21
5 files changed, 182 insertions(+), 3 deletions(-)
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
25
index XXXXXXX..XXXXXXX 100644
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
26
--- a/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
27
+++ b/target/arm/cpu.h
25
--- a/target/arm/helper-mve.h
28
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
26
+++ b/target/arm/helper-mve.h
29
* RAISES_EXC is for when the read or write hook might raise an exception;
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
* the generated code will synchronize the CPU state before calling the hook
28
31
* so that it is safe for the hook to call raise_exception().
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
32
+ * NEWEL is for writes to registers that might change the exception
30
33
+ * level - typically on older ARM chips. For those cases we need to
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
34
+ * re-read the new el when recomputing the translation flags.
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
35
*/
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
36
#define ARM_CP_SPECIAL 0x0001
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
37
#define ARM_CP_CONST 0x0002
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
38
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
39
#define ARM_CP_SVE 0x2000
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
40
#define ARM_CP_NO_GDB 0x4000
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
41
#define ARM_CP_RAISES_EXC 0x8000
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
42
+#define ARM_CP_NEWEL 0x10000
40
index XXXXXXX..XXXXXXX 100644
43
/* Used only as a terminator for ARMCPRegInfo lists */
41
--- a/target/arm/translate.h
44
-#define ARM_CP_SENTINEL 0xffff
42
+++ b/target/arm/translate.h
45
+#define ARM_CP_SENTINEL 0xfffff
43
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
46
/* Mask of only the flag bits in a type field */
44
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
47
-#define ARM_CP_FLAG_MASK 0xf0ff
45
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
48
+#define ARM_CP_FLAG_MASK 0x1f0ff
46
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
49
47
+typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
50
/* Valid values for ARMCPRegInfo state field, indicating which of
48
51
* the AArch32 and AArch64 execution states this register is visible in.
49
/**
52
diff --git a/target/arm/helper.h b/target/arm/helper.h
50
* arm_tbflags_from_tb:
53
index XXXXXXX..XXXXXXX 100644
51
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
54
--- a/target/arm/helper.h
52
index XXXXXXX..XXXXXXX 100644
55
+++ b/target/arm/helper.h
53
--- a/target/arm/t32.decode
56
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_user_reg, i32, env, i32)
54
+++ b/target/arm/t32.decode
57
DEF_HELPER_3(set_user_reg, void, env, i32, i32)
55
@@ -XXX,XX +XXX,XX @@
58
56
&mcrr !extern cp opc1 crm rt rt2
59
DEF_HELPER_FLAGS_2(rebuild_hflags_m32, TCG_CALL_NO_RWG, void, env, int)
57
60
+DEF_HELPER_FLAGS_1(rebuild_hflags_a32_newel, TCG_CALL_NO_RWG, void, env)
58
&mve_shl_ri rdalo rdahi shim
61
DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, int)
59
+&mve_shl_rr rdalo rdahi rm
62
DEF_HELPER_FLAGS_2(rebuild_hflags_a64, TCG_CALL_NO_RWG, void, env, int)
60
63
61
# rdahi: bits [3:1] from insn, bit 0 is 1
64
diff --git a/target/arm/helper.c b/target/arm/helper.c
62
# rdalo: bits [3:1] from insn, bit 0 is 0
65
index XXXXXXX..XXXXXXX 100644
63
@@ -XXX,XX +XXX,XX @@
66
--- a/target/arm/helper.c
64
67
+++ b/target/arm/helper.c
65
@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
68
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
66
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
69
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
67
+@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
70
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
68
+ &mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
71
.resetvalue = 0, .writefn = scr_write },
69
72
- { .name = "SCR", .type = ARM_CP_ALIAS,
70
{
73
+ { .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
71
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
74
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
72
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
75
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
73
URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
76
.fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
74
SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
77
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
75
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
78
env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
76
+
79
}
77
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
80
78
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
81
+/*
79
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
82
+ * If we have triggered a EL state change we can't rely on the
80
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
83
+ * translator having passed it too us, we need to recompute.
81
+ UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
84
+ */
82
+ SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
85
+void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
83
]
86
+{
84
87
+ int el = arm_current_el(env);
85
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
88
+ int fp_el = fp_exception_el(env, el);
86
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
89
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
87
+
90
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
88
+ # v8.1M CSEL and friends
91
+}
89
+ CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
92
+
90
}
93
void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
91
{
94
{
92
MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi
95
int fp_el = fp_exception_el(env, el);
93
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
94
}
95
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
96
97
-# v8.1M CSEL and friends
98
-CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
99
-
100
# Data-processing (register-shifted register)
101
102
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
103
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/mve_helper.c
106
+++ b/target/arm/mve_helper.c
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
108
return rdm;
109
}
110
111
+uint64_t HELPER(mve_sshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
112
+{
113
+ return do_sqrshl_d(n, -(int8_t)shift, false, NULL);
114
+}
115
+
116
+uint64_t HELPER(mve_ushll)(CPUARMState *env, uint64_t n, uint32_t shift)
117
+{
118
+ return do_uqrshl_d(n, (int8_t)shift, false, NULL);
119
+}
120
+
121
uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
122
{
123
return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
124
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
{
126
return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
}
128
+
129
+uint64_t HELPER(mve_sqrshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
130
+{
131
+ return do_sqrshl_d(n, -(int8_t)shift, true, &env->QF);
132
+}
133
+
134
+uint64_t HELPER(mve_uqrshll)(CPUARMState *env, uint64_t n, uint32_t shift)
135
+{
136
+ return do_uqrshl_d(n, (int8_t)shift, true, &env->QF);
137
+}
138
+
139
+/* Operate on 64-bit values, but saturate at 48 bits */
140
+static inline int64_t do_sqrshl48_d(int64_t src, int64_t shift,
141
+ bool round, uint32_t *sat)
142
+{
143
+ if (shift <= -48) {
144
+ /* Rounding the sign bit always produces 0. */
145
+ if (round) {
146
+ return 0;
147
+ }
148
+ return src >> 63;
149
+ } else if (shift < 0) {
150
+ if (round) {
151
+ src >>= -shift - 1;
152
+ return (src >> 1) + (src & 1);
153
+ }
154
+ return src >> -shift;
155
+ } else if (shift < 48) {
156
+ int64_t val = src << shift;
157
+ int64_t extval = sextract64(val, 0, 48);
158
+ if (!sat || val == extval) {
159
+ return extval;
160
+ }
161
+ } else if (!sat || src == 0) {
162
+ return 0;
163
+ }
164
+
165
+ *sat = 1;
166
+ return (1ULL << 47) - (src >= 0);
167
+}
168
+
169
+/* Operate on 64-bit values, but saturate at 48 bits */
170
+static inline uint64_t do_uqrshl48_d(uint64_t src, int64_t shift,
171
+ bool round, uint32_t *sat)
172
+{
173
+ uint64_t val, extval;
174
+
175
+ if (shift <= -(48 + round)) {
176
+ return 0;
177
+ } else if (shift < 0) {
178
+ if (round) {
179
+ val = src >> (-shift - 1);
180
+ val = (val >> 1) + (val & 1);
181
+ } else {
182
+ val = src >> -shift;
183
+ }
184
+ extval = extract64(val, 0, 48);
185
+ if (!sat || val == extval) {
186
+ return extval;
187
+ }
188
+ } else if (shift < 48) {
189
+ uint64_t val = src << shift;
190
+ uint64_t extval = extract64(val, 0, 48);
191
+ if (!sat || val == extval) {
192
+ return extval;
193
+ }
194
+ } else if (!sat || src == 0) {
195
+ return 0;
196
+ }
197
+
198
+ *sat = 1;
199
+ return MAKE_64BIT_MASK(0, 48);
200
+}
201
+
202
+uint64_t HELPER(mve_sqrshrl48)(CPUARMState *env, uint64_t n, uint32_t shift)
203
+{
204
+ return do_sqrshl48_d(n, -(int8_t)shift, true, &env->QF);
205
+}
206
+
207
+uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
208
+{
209
+ return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
210
+}
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
211
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
213
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
214
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
215
@@ -XXX,XX +XXX,XX @@ static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
101
if (arm_dc_feature(s, ARM_FEATURE_M)) {
216
return do_mve_shl_ri(s, a, gen_urshr64_i64);
102
gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
217
}
103
} else {
218
104
- gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
219
+static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
105
+ if (ri->type & ARM_CP_NEWEL) {
220
+{
106
+ gen_helper_rebuild_hflags_a32_newel(cpu_env);
221
+ TCGv_i64 rda;
107
+ } else {
222
+ TCGv_i32 rdalo, rdahi;
108
+ gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
223
+
109
+ }
224
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
110
}
225
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
111
tcg_temp_free_i32(tcg_el);
226
+ return false;
112
/*
227
+ }
228
+ if (a->rdahi == 15) {
229
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
230
+ return false;
231
+ }
232
+ if (!dc_isar_feature(aa32_mve, s) ||
233
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
234
+ a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
235
+ a->rm == a->rdahi || a->rm == a->rdalo) {
236
+ /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
237
+ unallocated_encoding(s);
238
+ return true;
239
+ }
240
+
241
+ rda = tcg_temp_new_i64();
242
+ rdalo = load_reg(s, a->rdalo);
243
+ rdahi = load_reg(s, a->rdahi);
244
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
245
+
246
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
247
+ fn(rda, cpu_env, rda, cpu_R[a->rm]);
248
+
249
+ tcg_gen_extrl_i64_i32(rdalo, rda);
250
+ tcg_gen_extrh_i64_i32(rdahi, rda);
251
+ store_reg(s, a->rdalo, rdalo);
252
+ store_reg(s, a->rdahi, rdahi);
253
+ tcg_temp_free_i64(rda);
254
+
255
+ return true;
256
+}
257
+
258
+static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
259
+{
260
+ return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
261
+}
262
+
263
+static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
264
+{
265
+ return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
266
+}
267
+
268
+static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
269
+{
270
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
271
+}
272
+
273
+static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
274
+{
275
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
276
+}
277
+
278
+static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
279
+{
280
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
281
+}
282
+
283
+static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
284
+{
285
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
286
+}
287
+
288
/*
289
* Multiply and multiply accumulate
290
*/
113
--
291
--
114
2.20.1
292
2.20.1
115
293
116
294
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Implement the MVE shifts by immediate, which perform shifts
2
2
on a single general-purpose register.
3
Currently, we link the DRAM memory region to the FMC model (for DMAs)
3
4
through a property alias at the SoC level. The I2C model will need a
4
These patterns overlap with the long-shift-by-immediates,
5
similar region for DMA support, add a DRAM region property at the SoC
5
so we have to rearrange the grouping a little here.
6
level for both model to use.
6
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>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
14
---
10
---
15
include/hw/arm/aspeed_soc.h | 1 +
11
target/arm/helper-mve.h | 3 ++
16
hw/arm/aspeed_ast2600.c | 7 +++++--
12
target/arm/translate.h | 1 +
17
hw/arm/aspeed_soc.c | 9 +++++++--
13
target/arm/t32.decode | 31 ++++++++++++++-----
18
3 files changed, 13 insertions(+), 4 deletions(-)
14
target/arm/mve_helper.c | 10 ++++++
19
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
20
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
16
5 files changed, 104 insertions(+), 9 deletions(-)
21
index XXXXXXX..XXXXXXX 100644
17
22
--- a/include/hw/arm/aspeed_soc.h
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
23
+++ b/include/hw/arm/aspeed_soc.h
19
index XXXXXXX..XXXXXXX 100644
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
20
--- a/target/arm/helper-mve.h
25
ARMCPU cpu[ASPEED_CPUS_NUM];
21
+++ b/target/arm/helper-mve.h
26
uint32_t num_cpus;
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
27
A15MPPrivState a7mpcore;
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
28
+ MemoryRegion *dram_mr;
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
29
MemoryRegion sram;
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
30
AspeedVICState vic;
26
+
31
AspeedRtcState rtc;
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
32
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
33
index XXXXXXX..XXXXXXX 100644
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
34
--- a/hw/arm/aspeed_ast2600.c
30
index XXXXXXX..XXXXXXX 100644
35
+++ b/hw/arm/aspeed_ast2600.c
31
--- a/target/arm/translate.h
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
32
+++ b/target/arm/translate.h
37
typename);
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
38
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
39
&error_abort);
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
40
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
41
- &error_abort);
37
+typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
42
38
43
for (i = 0; i < sc->spis_num; i++) {
39
/**
44
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
40
* arm_tbflags_from_tb:
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
41
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
46
}
42
index XXXXXXX..XXXXXXX 100644
47
43
--- a/target/arm/t32.decode
48
/* FMC, The number of CS is set at the board level */
44
+++ b/target/arm/t32.decode
49
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
45
@@ -XXX,XX +XXX,XX @@
50
+ if (err) {
46
51
+ error_propagate(errp, err);
47
&mve_shl_ri rdalo rdahi shim
48
&mve_shl_rr rdalo rdahi rm
49
+&mve_sh_ri rda shim
50
51
# rdahi: bits [3:1] from insn, bit 0 is 1
52
# rdalo: bits [3:1] from insn, bit 0 is 0
53
@@ -XXX,XX +XXX,XX @@
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
58
+ &mve_sh_ri shim=%imm5_12_6
59
60
{
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
62
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
63
# the rest fall through (where ORR_rrri and MOV_rxri will end up
64
# handling them as r13 and r15 accesses with the same semantics as A32).
65
[
66
- LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
67
- LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
68
- ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
69
+ {
70
+ UQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 00 1111 @mve_sh_ri
71
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
72
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
73
+ }
74
75
- UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
76
- URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
77
- SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
78
- SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
79
+ {
80
+ URSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 01 1111 @mve_sh_ri
81
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
82
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
83
+ }
84
+
85
+ {
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
89
+ }
90
+
91
+ {
92
+ SQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 11 1111 @mve_sh_ri
93
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
94
+ }
95
96
LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
97
ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
98
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/mve_helper.c
101
+++ b/target/arm/mve_helper.c
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
103
{
104
return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
105
}
106
+
107
+uint32_t HELPER(mve_uqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
108
+{
109
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
110
+}
111
+
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
113
+{
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
115
+}
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/translate.c
119
+++ b/target/arm/translate.c
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
121
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
123
{
124
- TCGv_i32 t = tcg_temp_new_i32();
125
+ TCGv_i32 t;
126
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
128
+ if (sh == 32) {
129
+ tcg_gen_movi_i32(d, 0);
52
+ return;
130
+ return;
53
+ }
131
+ }
54
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
132
+ t = tcg_temp_new_i32();
55
"sdram-base", &err);
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
56
if (err) {
134
tcg_gen_sari_i32(d, a, sh);
57
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
135
tcg_gen_add_i32(d, d, t);
58
index XXXXXXX..XXXXXXX 100644
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
59
--- a/hw/arm/aspeed_soc.c
137
60
+++ b/hw/arm/aspeed_soc.c
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
61
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
139
{
62
typename);
140
- TCGv_i32 t = tcg_temp_new_i32();
63
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
141
+ TCGv_i32 t;
64
&error_abort);
142
65
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
66
- &error_abort);
144
+ if (sh == 32) {
67
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
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;
146
+ return;
78
+ }
147
+ }
79
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
148
+ t = tcg_temp_new_i32();
80
"sdram-base", &err);
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
81
if (err) {
150
tcg_gen_shri_i32(d, a, sh);
82
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
151
tcg_gen_add_i32(d, d, t);
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
83
}
154
}
84
static Property aspeed_soc_properties[] = {
155
85
DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
156
+static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
86
+ DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
157
+{
87
+ MemoryRegion *),
158
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
88
DEFINE_PROP_END_OF_LIST(),
159
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
89
};
160
+ return false;
90
161
+ }
162
+ if (!dc_isar_feature(aa32_mve, s) ||
163
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
164
+ a->rda == 13 || a->rda == 15) {
165
+ /* These rda cases are UNPREDICTABLE; we choose to UNDEF */
166
+ unallocated_encoding(s);
167
+ return true;
168
+ }
169
+
170
+ if (a->shim == 0) {
171
+ a->shim = 32;
172
+ }
173
+ fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);
174
+
175
+ return true;
176
+}
177
+
178
+static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
179
+{
180
+ return do_mve_sh_ri(s, a, gen_urshr32_i32);
181
+}
182
+
183
+static bool trans_SRSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
184
+{
185
+ return do_mve_sh_ri(s, a, gen_srshr32_i32);
186
+}
187
+
188
+static void gen_mve_sqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
189
+{
190
+ gen_helper_mve_sqshl(r, cpu_env, n, tcg_constant_i32(shift));
191
+}
192
+
193
+static bool trans_SQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
194
+{
195
+ return do_mve_sh_ri(s, a, gen_mve_sqshl);
196
+}
197
+
198
+static void gen_mve_uqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
199
+{
200
+ gen_helper_mve_uqshl(r, cpu_env, n, tcg_constant_i32(shift));
201
+}
202
+
203
+static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
204
+{
205
+ return do_mve_sh_ri(s, a, gen_mve_uqshl);
206
+}
207
+
208
/*
209
* Multiply and multiply accumulate
210
*/
91
--
211
--
92
2.20.1
212
2.20.1
93
213
94
214
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
Most boards have this much.
4
5
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-7-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/misc/aspeed_sdmc.c | 6 +++---
13
1 file changed, 3 insertions(+), 3 deletions(-)
14
15
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/aspeed_sdmc.c
18
+++ b/hw/misc/aspeed_sdmc.c
19
@@ -XXX,XX +XXX,XX @@ static int ast2600_rambits(AspeedSDMCState *s)
20
}
21
22
/* use a common default */
23
- warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M",
24
+ warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 1024M",
25
s->ram_size);
26
- s->ram_size = 512 << 20;
27
- return ASPEED_SDMC_AST2600_512MB;
28
+ s->ram_size = 1024 << 20;
29
+ return ASPEED_SDMC_AST2600_1024MB;
30
}
31
32
static void aspeed_sdmc_reset(DeviceState *dev)
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
This models the clock write one to clear registers, and fixes up some
4
incorrect behavior in all of the write to clear registers.
5
6
There was also a typo in one of the register definitions.
7
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Joel Stanley <joel@jms.id.au>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-id: 20191119141211.25716-8-clg@kaod.org
13
[clg: checkpatch.pl fixes ]
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/misc/aspeed_scu.c | 19 ++++++++++++++-----
18
1 file changed, 14 insertions(+), 5 deletions(-)
19
20
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/aspeed_scu.c
23
+++ b/hw/misc/aspeed_scu.c
24
@@ -XXX,XX +XXX,XX @@
25
#define AST2600_CLK_STOP_CTRL TO_REG(0x80)
26
#define AST2600_CLK_STOP_CTRL_CLR TO_REG(0x84)
27
#define AST2600_CLK_STOP_CTRL2 TO_REG(0x90)
28
-#define AST2600_CLK_STOP_CTR2L_CLR TO_REG(0x94)
29
+#define AST2600_CLK_STOP_CTRL2_CLR TO_REG(0x94)
30
#define AST2600_SDRAM_HANDSHAKE TO_REG(0x100)
31
#define AST2600_HPLL_PARAM TO_REG(0x200)
32
#define AST2600_HPLL_EXT TO_REG(0x204)
33
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_ast2600_scu_read(void *opaque, hwaddr offset,
34
return s->regs[reg];
35
}
36
37
-static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
38
- unsigned size)
39
+static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
40
+ uint64_t data64, unsigned size)
41
{
42
AspeedSCUState *s = ASPEED_SCU(opaque);
43
int reg = TO_REG(offset);
44
+ /* Truncate here so bitwise operations below behave as expected */
45
+ uint32_t data = data64;
46
47
if (reg >= ASPEED_AST2600_SCU_NR_REGS) {
48
qemu_log_mask(LOG_GUEST_ERROR,
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
50
/* fall through */
51
case AST2600_SYS_RST_CTRL:
52
case AST2600_SYS_RST_CTRL2:
53
+ case AST2600_CLK_STOP_CTRL:
54
+ case AST2600_CLK_STOP_CTRL2:
55
/* W1S (Write 1 to set) registers */
56
s->regs[reg] |= data;
57
return;
58
case AST2600_SYS_RST_CTRL_CLR:
59
case AST2600_SYS_RST_CTRL2_CLR:
60
+ case AST2600_CLK_STOP_CTRL_CLR:
61
+ case AST2600_CLK_STOP_CTRL2_CLR:
62
case AST2600_HW_STRAP1_CLR:
63
case AST2600_HW_STRAP2_CLR:
64
- /* W1C (Write 1 to clear) registers */
65
- s->regs[reg] &= ~data;
66
+ /*
67
+ * W1C (Write 1 to clear) registers are offset by one address from
68
+ * the data register
69
+ */
70
+ s->regs[reg - 1] &= ~data;
71
return;
72
73
case AST2600_RNG_DATA:
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
Users benefit from knowing which watchdog timer has expired. The address
4
of the watchdog's registers unambiguously indicates which has expired,
5
so log that.
6
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-9-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/watchdog/wdt_aspeed.c | 3 ++-
15
1 file changed, 2 insertions(+), 1 deletion(-)
16
17
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/watchdog/wdt_aspeed.c
20
+++ b/hw/watchdog/wdt_aspeed.c
21
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_timer_expired(void *dev)
22
return;
23
}
24
25
- qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
26
+ qemu_log_mask(CPU_LOG_RESET, "Watchdog timer %" HWADDR_PRIx " expired.\n",
27
+ s->iomem.addr);
28
watchdog_perform_action();
29
timer_del(s->timer);
30
}
31
--
32
2.20.1
33
34
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
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The Aspeed Watchdog and Timer models have a link pointing to the SCU
4
controller model of the machine.
5
6
Change the "scu" property definition so that it explicitly sets the
7
pointer. The property isn't optional : not being able to set the link
8
is a bug and QEMU should rather abort than exit in this case.
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Greg Kurz <groug@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-17-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/aspeed_ast2600.c | 8 ++++----
18
hw/arm/aspeed_soc.c | 8 ++++----
19
hw/timer/aspeed_timer.c | 17 +++++++++--------
20
hw/watchdog/wdt_aspeed.c | 17 ++++++++---------
21
4 files changed, 25 insertions(+), 25 deletions(-)
22
23
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/aspeed_ast2600.c
26
+++ b/hw/arm/aspeed_ast2600.c
27
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
28
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
29
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
30
sizeof(s->timerctrl), typename);
31
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
32
- OBJECT(&s->scu), &error_abort);
33
34
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
35
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
37
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
38
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
39
sizeof(s->wdt[i]), typename);
40
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
41
- OBJECT(&s->scu), &error_abort);
42
}
43
44
for (i = 0; i < sc->macs_num; i++) {
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
46
aspeed_soc_get_irq(s, ASPEED_RTC));
47
48
/* Timer */
49
+ object_property_set_link(OBJECT(&s->timerctrl),
50
+ OBJECT(&s->scu), "scu", &error_abort);
51
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
52
if (err) {
53
error_propagate(errp, err);
54
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
55
for (i = 0; i < sc->wdts_num; i++) {
56
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
57
58
+ object_property_set_link(OBJECT(&s->wdt[i]),
59
+ OBJECT(&s->scu), "scu", &error_abort);
60
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
61
if (err) {
62
error_propagate(errp, err);
63
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/aspeed_soc.c
66
+++ b/hw/arm/aspeed_soc.c
67
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
68
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
69
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
70
sizeof(s->timerctrl), typename);
71
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
72
- OBJECT(&s->scu), &error_abort);
73
74
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
75
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
76
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
77
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
78
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
79
sizeof(s->wdt[i]), typename);
80
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
81
- OBJECT(&s->scu), &error_abort);
82
}
83
84
for (i = 0; i < sc->macs_num; i++) {
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
86
aspeed_soc_get_irq(s, ASPEED_RTC));
87
88
/* Timer */
89
+ object_property_set_link(OBJECT(&s->timerctrl),
90
+ OBJECT(&s->scu), "scu", &error_abort);
91
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
92
if (err) {
93
error_propagate(errp, err);
94
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
95
for (i = 0; i < sc->wdts_num; i++) {
96
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
97
98
+ object_property_set_link(OBJECT(&s->wdt[i]),
99
+ OBJECT(&s->scu), "scu", &error_abort);
100
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
101
if (err) {
102
error_propagate(errp, err);
103
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/hw/timer/aspeed_timer.c
106
+++ b/hw/timer/aspeed_timer.c
107
@@ -XXX,XX +XXX,XX @@
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
}
134
};
135
136
+static Property aspeed_timer_properties[] = {
137
+ DEFINE_PROP_LINK("scu", AspeedTimerCtrlState, scu, TYPE_ASPEED_SCU,
138
+ AspeedSCUState *),
139
+ DEFINE_PROP_END_OF_LIST(),
140
+};
141
+
142
static void timer_class_init(ObjectClass *klass, void *data)
143
{
144
DeviceClass *dc = DEVICE_CLASS(klass);
145
@@ -XXX,XX +XXX,XX @@ static void timer_class_init(ObjectClass *klass, void *data)
146
dc->reset = aspeed_timer_reset;
147
dc->desc = "ASPEED Timer";
148
dc->vmsd = &vmstate_aspeed_timer_state;
149
+ dc->props = aspeed_timer_properties;
150
}
151
152
static const TypeInfo aspeed_timer_info = {
153
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/watchdog/wdt_aspeed.c
156
+++ b/hw/watchdog/wdt_aspeed.c
157
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
158
{
159
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
160
AspeedWDTState *s = ASPEED_WDT(dev);
161
- Error *err = NULL;
162
- Object *obj;
163
164
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
165
- if (!obj) {
166
- error_propagate(errp, err);
167
- error_prepend(errp, "required link 'scu' not found: ");
168
- return;
169
- }
170
- s->scu = ASPEED_SCU(obj);
171
+ assert(s->scu);
172
173
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, aspeed_wdt_timer_expired, dev);
174
175
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
176
sysbus_init_mmio(sbd, &s->iomem);
177
}
178
179
+static Property aspeed_wdt_properties[] = {
180
+ DEFINE_PROP_LINK("scu", AspeedWDTState, scu, TYPE_ASPEED_SCU,
181
+ AspeedSCUState *),
182
+ DEFINE_PROP_END_OF_LIST(),
183
+};
184
+
185
static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
186
{
187
DeviceClass *dc = DEVICE_CLASS(klass);
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
189
dc->reset = aspeed_wdt_reset;
190
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
191
dc->vmsd = &vmstate_aspeed_wdt;
192
+ dc->props = aspeed_wdt_properties;
193
}
194
195
static const TypeInfo aspeed_wdt_info = {
196
--
197
2.20.1
198
199
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
The Aspeed MII model has a link pointing to its associated FTGMAC100
4
NIC in the machine.
5
6
Change the "nic" property definition so that it explicitly sets the
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
23
--- a/hw/arm/aspeed_ast2600.c
24
+++ b/hw/arm/aspeed_ast2600.c
25
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
26
27
sysbus_init_child_obj(obj, "mii[*]", &s->mii[i], sizeof(s->mii[i]),
28
TYPE_ASPEED_MII);
29
- object_property_add_const_link(OBJECT(&s->mii[i]), "nic",
30
- OBJECT(&s->ftgmac100[i]),
31
- &error_abort);
32
}
33
34
sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
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
--
90
2.20.1
91
92
diff view generated by jsdifflib
Deleted patch
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
2
1
3
This change ensures that the FPU can be accessed in Non-Secure mode
4
when the CPU core is reset using the arm_set_cpu_on() function call.
5
The NSACR.{CP11,CP10} bits define the exception level required to
6
access the FPU in Non-Secure mode. Without these bits set, the CPU
7
will give an undefined exception trap on the first FPU access for the
8
secondary cores under Linux.
9
10
This is necessary because in this power-control codepath QEMU
11
is effectively emulating a bit of EL3 firmware, and has to set
12
the CPU up as the EL3 firmware would.
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>
20
---
21
target/arm/arm-powerctl.c | 3 +++
22
1 file changed, 3 insertions(+)
23
24
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/arm-powerctl.c
27
+++ b/target/arm/arm-powerctl.c
28
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
29
/* Processor is not in secure mode */
30
target_cpu->env.cp15.scr_el3 |= SCR_NS;
31
32
+ /* Set NSACR.{CP11,CP10} so NS can access the FPU */
33
+ target_cpu->env.cp15.nsacr |= 3 << 10;
34
+
35
/*
36
* If QEMU is providing the equivalent of EL3 firmware, then we need
37
* to make sure a CPU targeting EL2 comes out of reset with a
38
--
39
2.20.1
40
41
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
Implement the MVE shifts by register, which perform
2
shifts on a single general-purpose register.
2
3
3
Add an option to trigger memory writeback to sync given memory region
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
with the corresponding backing store, case one is available.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
This extends the support for persistent memory, allowing syncing on-demand.
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
7
---
8
target/arm/helper-mve.h | 2 ++
9
target/arm/translate.h | 1 +
10
target/arm/t32.decode | 18 ++++++++++++++----
11
target/arm/mve_helper.c | 10 ++++++++++
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
5 files changed, 57 insertions(+), 4 deletions(-)
6
14
7
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20191121000843.24844-3-beata.michalska@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/exec/memory.h | 6 ++++++
13
include/exec/ram_addr.h | 8 ++++++++
14
include/qemu/cutils.h | 1 +
15
exec.c | 36 ++++++++++++++++++++++++++++++++++++
16
memory.c | 12 ++++++++++++
17
util/cutils.c | 38 ++++++++++++++++++++++++++++++++++++++
18
6 files changed, 101 insertions(+)
19
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/memory.h
17
--- a/target/arm/helper-mve.h
23
+++ b/include/exec/memory.h
18
+++ b/target/arm/helper-mve.h
24
@@ -XXX,XX +XXX,XX @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
25
*/
20
26
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
21
DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
27
Error **errp);
22
DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
28
+/**
23
+DEF_HELPER_FLAGS_3(mve_uqrshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
29
+ * memory_region_do_writeback: Trigger writeback for selected address range
24
+DEF_HELPER_FLAGS_3(mve_sqrshr, TCG_CALL_NO_RWG, i32, env, i32, i32)
30
+ * [addr, addr + size]
25
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
+ *
26
index XXXXXXX..XXXXXXX 100644
32
+ */
27
--- a/target/arm/translate.h
33
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size);
28
+++ b/target/arm/translate.h
29
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
30
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
31
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
32
typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
33
+typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
34
34
35
/**
35
/**
36
* memory_region_set_log: Turn dirty logging on or off for a region.
36
* arm_tbflags_from_tb:
37
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
37
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
38
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/exec/ram_addr.h
39
--- a/target/arm/t32.decode
40
+++ b/include/exec/ram_addr.h
40
+++ b/target/arm/t32.decode
41
@@ -XXX,XX +XXX,XX @@ void qemu_ram_free(RAMBlock *block);
41
@@ -XXX,XX +XXX,XX @@
42
42
&mve_shl_ri rdalo rdahi shim
43
int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
43
&mve_shl_rr rdalo rdahi rm
44
44
&mve_sh_ri rda shim
45
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length);
45
+&mve_sh_rr rda rm
46
47
# rdahi: bits [3:1] from insn, bit 0 is 1
48
# rdalo: bits [3:1] from insn, bit 0 is 0
49
@@ -XXX,XX +XXX,XX @@
50
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
51
@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
52
&mve_sh_ri shim=%imm5_12_6
53
+@mve_sh_rr ....... .... . rda:4 rm:4 .... .... .... &mve_sh_rr
54
55
{
56
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
57
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
58
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
59
}
60
61
- LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
62
- ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
63
- UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
64
- SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
65
+ {
66
+ UQRSHL_rr 1110101 0010 1 .... .... 1111 0000 1101 @mve_sh_rr
67
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
68
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
69
+ }
46
+
70
+
47
+/* Clear whole block of mem */
71
+ {
48
+static inline void qemu_ram_block_writeback(RAMBlock *block)
72
+ SQRSHR_rr 1110101 0010 1 .... .... 1111 0010 1101 @mve_sh_rr
73
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
74
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
75
+ }
76
+
77
UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
78
SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
79
]
80
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/mve_helper.c
83
+++ b/target/arm/mve_helper.c
84
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
85
{
86
return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
87
}
88
+
89
+uint32_t HELPER(mve_uqrshl)(CPUARMState *env, uint32_t n, uint32_t shift)
49
+{
90
+{
50
+ qemu_ram_writeback(block, 0, block->used_length);
91
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, true, &env->QF);
51
+}
92
+}
52
+
93
+
53
#define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1)
94
+uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
54
#define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE))
95
+{
55
96
+ return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
56
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
97
+}
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
57
index XXXXXXX..XXXXXXX 100644
99
index XXXXXXX..XXXXXXX 100644
58
--- a/include/qemu/cutils.h
100
--- a/target/arm/translate.c
59
+++ b/include/qemu/cutils.h
101
+++ b/target/arm/translate.c
60
@@ -XXX,XX +XXX,XX @@ const char *qemu_strchrnul(const char *s, int c);
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
61
#endif
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
62
time_t mktimegm(struct tm *tm);
104
}
63
int qemu_fdatasync(int fd);
105
64
+int qemu_msync(void *addr, size_t length, int fd);
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
65
int fcntl_setfl(int fd, int flag);
107
+{
66
int qemu_parse_fd(const char *param);
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
67
int qemu_strtoi(const char *nptr, const char **endptr, int base,
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
68
diff --git a/exec.c b/exec.c
110
+ return false;
69
index XXXXXXX..XXXXXXX 100644
111
+ }
70
--- a/exec.c
112
+ if (!dc_isar_feature(aa32_mve, s) ||
71
+++ b/exec.c
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
72
@@ -XXX,XX +XXX,XX @@
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
73
#include "exec/ram_addr.h"
115
+ a->rm == a->rda) {
74
#include "exec/log.h"
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
75
117
+ unallocated_encoding(s);
76
+#include "qemu/pmem.h"
118
+ return true;
119
+ }
77
+
120
+
78
#include "migration/vmstate.h"
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
79
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
80
#include "qemu/range.h"
123
+ return true;
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
+ }
117
+}
124
+}
118
+
125
+
119
/* Called with ram_list.mutex held */
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
120
static void dirty_memory_extend(ram_addr_t old_ram_size,
127
+{
121
ram_addr_t new_ram_size)
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
122
diff --git a/memory.c b/memory.c
129
+}
123
index XXXXXXX..XXXXXXX 100644
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
}
129
130
+
130
+
131
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
132
+{
132
+{
133
+ /*
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
134
+ * Might be extended case needed to cover
135
+ * different types of memory regions
136
+ */
137
+ if (mr->ram_block && mr->dirty_log_mask) {
138
+ qemu_ram_writeback(mr->ram_block, addr, size);
139
+ }
140
+}
134
+}
141
+
135
+
142
/*
136
/*
143
* Call proper memory listeners about the change on the newly
137
* Multiply and multiply accumulate
144
* added/removed CoalescedMemoryRange.
138
*/
145
diff --git a/util/cutils.c b/util/cutils.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/util/cutils.c
148
+++ b/util/cutils.c
149
@@ -XXX,XX +XXX,XX @@ int qemu_fdatasync(int fd)
150
#endif
151
}
152
153
+/**
154
+ * Sync changes made to the memory mapped file back to the backing
155
+ * storage. For POSIX compliant systems this will fallback
156
+ * to regular msync call. Otherwise it will trigger whole file sync
157
+ * (including the metadata case there is no support to skip that otherwise)
158
+ *
159
+ * @addr - start of the memory area to be synced
160
+ * @length - length of the are to be synced
161
+ * @fd - file descriptor for the file to be synced
162
+ * (mandatory only for POSIX non-compliant systems)
163
+ */
164
+int qemu_msync(void *addr, size_t length, int fd)
165
+{
166
+#ifdef CONFIG_POSIX
167
+ size_t align_mask = ~(qemu_real_host_page_size - 1);
168
+
169
+ /**
170
+ * There are no strict reqs as per the length of mapping
171
+ * to be synced. Still the length needs to follow the address
172
+ * alignment changes. Additionally - round the size to the multiple
173
+ * of PAGE_SIZE
174
+ */
175
+ length += ((uintptr_t)addr & (qemu_real_host_page_size - 1));
176
+ length = (length + ~align_mask) & align_mask;
177
+
178
+ addr = (void *)((uintptr_t)addr & align_mask);
179
+
180
+ return msync(addr, length, MS_SYNC);
181
+#else /* CONFIG_POSIX */
182
+ /**
183
+ * Perform the sync based on the file descriptor
184
+ * The sync range will most probably be wider than the one
185
+ * requested - but it will still get the job done
186
+ */
187
+ return qemu_fdatasync(fd);
188
+#endif /* CONFIG_POSIX */
189
+}
190
+
191
#ifndef _WIN32
192
/* Sets a specific flag */
193
int fcntl_setfl(int fd, int flag)
194
--
139
--
195
2.20.1
140
2.20.1
196
141
197
142
diff view generated by jsdifflib