1
target-arm queue: nothing big, just a collection of minor things.
1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
2
2
3
-- PMM
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
4
5
The following changes since commit ae3aa5da96f4ccf0c2a28851449d92db9fcfad71:
6
7
Merge remote-tracking branch 'remotes/berrange/tags/socket-next-pull-request' into staging (2020-05-21 16:47:28 +0100)
8
4
9
are available in the Git repository at:
5
are available in the Git repository at:
10
6
11
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200521
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
12
8
13
for you to fetch changes up to 17b5df7b65d0192c5d775b5e1581518580774c77:
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
14
10
15
linux-user/arm/signal.c: Drop TARGET_CONFIG_CPU_32 (2020-05-21 20:00:19 +0100)
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
16
12
17
----------------------------------------------------------------
13
----------------------------------------------------------------
18
target-arm queue:
14
target-arm queue:
19
* tests/acceptance: Add a test for the canon-a1100 machine
15
* more MVE instructions
20
* docs/system: Document some of the Arm development boards
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
21
* linux-user: make BKPT insn cause SIGTRAP, not be a syscall
17
* target/arm: Check NaN mode before silencing NaN
22
* target/arm: Remove unused GEN_NEON_INTEGER_OP macro
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
23
* fsl-imx25, fsl-imx31, fsl-imx6, fsl-imx6ul, fsl-imx7: implement watchdog
19
* hw/arm: Add basic power management to raspi.
24
* hw/arm: Use qemu_log_mask() instead of hw_error() in various places
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
25
* ARM: PL061: Introduce N_GPIOS
26
* target/arm: Improve clear_vec_high() usage
27
* target/arm: Allow user-mode code to write CPSR.E via MSR
28
* linux-user/arm: Reset CPSR_E when entering a signal handler
29
* linux-user/arm/signal.c: Drop TARGET_CONFIG_CPU_32
30
21
31
----------------------------------------------------------------
22
----------------------------------------------------------------
32
Amanieu d'Antras (1):
23
Joe Komlodi (1):
33
linux-user/arm: Reset CPSR_E when entering a signal handler
24
target/arm: Check NaN mode before silencing NaN
34
25
35
Geert Uytterhoeven (1):
26
Maxim Uvarov (1):
36
ARM: PL061: Introduce N_GPIOS
27
hw/gpio/gpio_pwr: use shutdown function for reboot
37
28
38
Guenter Roeck (8):
29
Nolan Leake (1):
39
hw: Move i.MX watchdog driver to hw/watchdog
30
hw/arm: Add basic power management to raspi.
40
hw/watchdog: Implement full i.MX watchdog support
41
hw/arm/fsl-imx25: Wire up watchdog
42
hw/arm/fsl-imx31: Wire up watchdog
43
hw/arm/fsl-imx6: Connect watchdog interrupts
44
hw/arm/fsl-imx6ul: Connect watchdog interrupts
45
hw/arm/fsl-imx7: Instantiate various unimplemented devices
46
hw/arm/fsl-imx7: Connect watchdog interrupts
47
31
48
Peter Maydell (12):
32
Patrick Venture (2):
49
docs/system: Add 'Arm' to the Integrator/CP document title
33
docs/system/arm: Add quanta-q7l1-bmc reference
50
docs/system: Sort Arm board index into alphabetical order
34
docs/system/arm: Add quanta-gbs-bmc reference
51
docs/system: Document Arm Versatile Express boards
52
docs/system: Document the various MPS2 models
53
docs/system: Document Musca boards
54
linux-user/arm: BKPT should cause SIGTRAP, not be a syscall
55
linux-user/arm: Remove bogus SVC 0xf0002 handling
56
linux-user/arm: Handle invalid arm-specific syscalls correctly
57
linux-user/arm: Fix identification of syscall numbers
58
target/arm: Remove unused GEN_NEON_INTEGER_OP macro
59
target/arm: Allow user-mode code to write CPSR.E via MSR
60
linux-user/arm/signal.c: Drop TARGET_CONFIG_CPU_32
61
35
62
Philippe Mathieu-Daudé (4):
36
Peter Maydell (18):
63
hw/arm/integratorcp: Replace hw_error() by qemu_log_mask()
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
64
hw/arm/pxa2xx: Replace hw_error() by qemu_log_mask()
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
65
hw/char/xilinx_uartlite: Replace hw_error() by qemu_log_mask()
39
target/arm: Make asimd_imm_const() public
66
hw/timer/exynos4210_mct: Replace hw_error() by qemu_log_mask()
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
67
55
68
Richard Henderson (2):
56
Philippe Mathieu-Daudé (1):
69
target/arm: Use tcg_gen_gvec_mov for clear_vec_high
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
70
target/arm: Use clear_vec_high more effectively
71
58
72
Thomas Huth (1):
59
docs/system/arm/aspeed.rst | 1 +
73
tests/acceptance: Add a test for the canon-a1100 machine
60
docs/system/arm/nuvoton.rst | 5 +-
61
include/hw/arm/bcm2835_peripherals.h | 3 +-
62
include/hw/misc/bcm2835_powermgt.h | 29 ++
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
74
82
75
docs/system/arm/integratorcp.rst | 4 +-
76
docs/system/arm/mps2.rst | 29 +++
77
docs/system/arm/musca.rst | 31 +++
78
docs/system/arm/vexpress.rst | 60 ++++++
79
docs/system/target-arm.rst | 20 +-
80
include/hw/arm/fsl-imx25.h | 5 +
81
include/hw/arm/fsl-imx31.h | 4 +
82
include/hw/arm/fsl-imx6.h | 2 +-
83
include/hw/arm/fsl-imx6ul.h | 2 +-
84
include/hw/arm/fsl-imx7.h | 23 ++-
85
include/hw/misc/imx2_wdt.h | 33 ----
86
include/hw/watchdog/wdt_imx2.h | 90 +++++++++
87
target/arm/cpu.h | 2 +-
88
hw/arm/fsl-imx25.c | 10 +
89
hw/arm/fsl-imx31.c | 6 +
90
hw/arm/fsl-imx6.c | 9 +
91
hw/arm/fsl-imx6ul.c | 10 +
92
hw/arm/fsl-imx7.c | 35 ++++
93
hw/arm/integratorcp.c | 23 ++-
94
hw/arm/pxa2xx_gpio.c | 7 +-
95
hw/char/xilinx_uartlite.c | 5 +-
96
hw/display/pxa2xx_lcd.c | 8 +-
97
hw/dma/pxa2xx_dma.c | 14 +-
98
hw/gpio/pl061.c | 12 +-
99
hw/misc/imx2_wdt.c | 90 ---------
100
hw/timer/exynos4210_mct.c | 12 +-
101
hw/watchdog/wdt_imx2.c | 303 +++++++++++++++++++++++++++++
102
linux-user/arm/cpu_loop.c | 145 ++++++++------
103
linux-user/arm/signal.c | 15 +-
104
target/arm/translate-a64.c | 63 +++---
105
target/arm/translate.c | 23 ---
106
MAINTAINERS | 6 +
107
hw/arm/Kconfig | 5 +
108
hw/misc/Makefile.objs | 1 -
109
hw/watchdog/Kconfig | 3 +
110
hw/watchdog/Makefile.objs | 1 +
111
tests/acceptance/machine_arm_canona1100.py | 35 ++++
112
37 files changed, 854 insertions(+), 292 deletions(-)
113
create mode 100644 docs/system/arm/mps2.rst
114
create mode 100644 docs/system/arm/musca.rst
115
create mode 100644 docs/system/arm/vexpress.rst
116
delete mode 100644 include/hw/misc/imx2_wdt.h
117
create mode 100644 include/hw/watchdog/wdt_imx2.h
118
delete mode 100644 hw/misc/imx2_wdt.c
119
create mode 100644 hw/watchdog/wdt_imx2.c
120
create mode 100644 tests/acceptance/machine_arm_canona1100.py
121
diff view generated by jsdifflib
1
From: Amanieu d'Antras <amanieu@gmail.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
This fixes signal handlers running with the wrong endianness if the
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
4
interrupted code used SETEND to dynamically switch endianness.
4
entry.
5
5
6
Signed-off-by: Amanieu d'Antras <amanieu@gmail.com>
6
Signed-off-by: Patrick Venture <venture@google.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20200511131117.2486486-1-amanieu@gmail.com
8
Message-id: 20210615192848.1065297-2-venture@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
linux-user/arm/signal.c | 8 +++++++-
11
docs/system/arm/aspeed.rst | 1 +
12
1 file changed, 7 insertions(+), 1 deletion(-)
12
1 file changed, 1 insertion(+)
13
13
14
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/arm/signal.c
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/linux-user/arm/signal.c
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ setup_return(CPUARMState *env, struct target_sigaction *ka,
18
@@ -XXX,XX +XXX,XX @@ etc.
19
} else {
19
AST2400 SoC based machines :
20
cpsr &= ~CPSR_T;
20
21
}
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
22
+ if (env->cp15.sctlr_el[1] & SCTLR_E0E) {
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
23
+ cpsr |= CPSR_E;
23
24
+ } else {
24
AST2500 SoC based machines :
25
+ cpsr &= ~CPSR_E;
25
26
+ }
27
28
if (ka->sa_flags & TARGET_SA_RESTORER) {
29
if (is_fdpic) {
30
@@ -XXX,XX +XXX,XX @@ setup_return(CPUARMState *env, struct target_sigaction *ka,
31
env->regs[13] = frame_addr;
32
env->regs[14] = retcode;
33
env->regs[15] = handler & (thumb ? ~1 : ~3);
34
- cpsr_write(env, cpsr, CPSR_IT | CPSR_T, CPSRWriteByInstr);
35
+ cpsr_write(env, cpsr, CPSR_IT | CPSR_T | CPSR_E, CPSRWriteByInstr);
36
+ arm_rebuild_hflags(env);
37
38
return 0;
39
}
40
--
26
--
41
2.20.1
27
2.20.1
42
28
43
29
diff view generated by jsdifflib
1
From: Geert Uytterhoeven <geert+renesas@glider.be>
1
From: Patrick Venture <venture@google.com>
2
2
3
Add a definition for the number of GPIO lines controlled by a PL061
3
Add line item reference to quanta-gbs-bmc machine.
4
instance, and use it instead of the hardcoded magic value 8.
5
4
6
Suggested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Patrick Venture <venture@google.com>
7
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210615192848.1065297-3-venture@google.com
9
Message-id: 20200519085143.1376-1-geert+renesas@glider.be
8
[PMM: fixed underline Sphinx warning]
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/pl061.c | 12 +++++++-----
11
docs/system/arm/nuvoton.rst | 5 +++--
13
1 file changed, 7 insertions(+), 5 deletions(-)
12
1 file changed, 3 insertions(+), 2 deletions(-)
14
13
15
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/gpio/pl061.c
16
--- a/docs/system/arm/nuvoton.rst
18
+++ b/hw/gpio/pl061.c
17
+++ b/docs/system/arm/nuvoton.rst
19
@@ -XXX,XX +XXX,XX @@ static const uint8_t pl061_id_luminary[12] =
18
@@ -XXX,XX +XXX,XX @@
20
#define TYPE_PL061 "pl061"
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
21
#define PL061(obj) OBJECT_CHECK(PL061State, (obj), TYPE_PL061)
20
-=====================================================
22
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
23
+#define N_GPIOS 8
22
+================================================================
24
+
23
25
typedef struct PL061State {
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
26
SysBusDevice parent_obj;
25
designed to be used as Baseboard Management Controllers (BMCs) in various
27
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
28
@@ -XXX,XX +XXX,XX @@ typedef struct PL061State {
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
29
uint32_t cr;
28
Hyperscale applications. The following machines are based on this chip :
30
uint32_t amsel;
29
31
qemu_irq irq;
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
32
- qemu_irq out[8];
31
- ``quanta-gsj`` Quanta GSJ server BMC
33
+ qemu_irq out[N_GPIOS];
32
34
const unsigned char *id;
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
35
uint32_t rsvd_start; /* reserved area: [rsvd_start, 0xfcc] */
36
} PL061State;
37
@@ -XXX,XX +XXX,XX @@ static void pl061_update(PL061State *s)
38
changed = s->old_out_data ^ out;
39
if (changed) {
40
s->old_out_data = out;
41
- for (i = 0; i < 8; i++) {
42
+ for (i = 0; i < N_GPIOS; i++) {
43
mask = 1 << i;
44
if (changed & mask) {
45
DPRINTF("Set output %d = %d\n", i, (out & mask) != 0);
46
@@ -XXX,XX +XXX,XX @@ static void pl061_update(PL061State *s)
47
changed = (s->old_in_data ^ s->data) & ~s->dir;
48
if (changed) {
49
s->old_in_data = s->data;
50
- for (i = 0; i < 8; i++) {
51
+ for (i = 0; i < N_GPIOS; i++) {
52
mask = 1 << i;
53
if (changed & mask) {
54
DPRINTF("Changed input %d = %d\n", i, (s->data & mask) != 0);
55
@@ -XXX,XX +XXX,XX @@ static void pl061_init(Object *obj)
56
memory_region_init_io(&s->iomem, obj, &pl061_ops, s, "pl061", 0x1000);
57
sysbus_init_mmio(sbd, &s->iomem);
58
sysbus_init_irq(sbd, &s->irq);
59
- qdev_init_gpio_in(dev, pl061_set_irq, 8);
60
- qdev_init_gpio_out(dev, s->out, 8);
61
+ qdev_init_gpio_in(dev, pl061_set_irq, N_GPIOS);
62
+ qdev_init_gpio_out(dev, s->out, N_GPIOS);
63
}
64
65
static void pl061_class_init(ObjectClass *klass, void *data)
66
--
34
--
67
2.20.1
35
2.20.1
68
36
69
37
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Nolan Leake <nolan@sigbus.net>
2
2
3
The canon-a1100 machine can be used with the Barebox firmware. The
3
This is just enough to make reboot and poweroff work. Works for
4
QEMU Advent Calendar 2018 features a pre-compiled image which we
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
5
can use for testing.
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
6
6
do what linux does for reset.
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
8
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
The watchdog timer functionality is not yet implemented.
9
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
9
10
Tested-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
11
Signed-off-by: Thomas Huth <thuth@redhat.com>
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20200514190422.23645-1-f4bug@amsat.org
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-Id: <20200129090420.13954-1-thuth@redhat.com>
14
Message-id: 20210625210209.1870217-1-nolan@sigbus.net
15
[PMD: Rebased MAINTAINERS]
15
[PMM: tweaked commit title; fixed region size to 0x200;
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.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
MAINTAINERS | 1 +
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
20
tests/acceptance/machine_arm_canona1100.py | 35 ++++++++++++++++++++++
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
21
2 files changed, 36 insertions(+)
21
hw/arm/bcm2835_peripherals.c | 13 ++-
22
create mode 100644 tests/acceptance/machine_arm_canona1100.py
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
23
23
hw/misc/meson.build | 1 +
24
diff --git a/MAINTAINERS b/MAINTAINERS
24
5 files changed, 204 insertions(+), 2 deletions(-)
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
25
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
26
--- a/MAINTAINERS
30
--- a/include/hw/arm/bcm2835_peripherals.h
27
+++ b/MAINTAINERS
31
+++ b/include/hw/arm/bcm2835_peripherals.h
28
@@ -XXX,XX +XXX,XX @@ S: Odd Fixes
32
@@ -XXX,XX +XXX,XX @@
29
F: include/hw/arm/digic.h
33
#include "hw/misc/bcm2835_mphi.h"
30
F: hw/*/digic*
34
#include "hw/misc/bcm2835_thermal.h"
31
F: include/hw/*/digic*
35
#include "hw/misc/bcm2835_cprman.h"
32
+F: tests/acceptance/machine_arm_canona1100.py
36
+#include "hw/misc/bcm2835_powermgt.h"
33
37
#include "hw/sd/sdhci.h"
34
Goldfish RTC
38
#include "hw/sd/bcm2835_sdhost.h"
35
M: Anup Patel <anup.patel@wdc.com>
39
#include "hw/gpio/bcm2835_gpio.h"
36
diff --git a/tests/acceptance/machine_arm_canona1100.py b/tests/acceptance/machine_arm_canona1100.py
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
41
BCM2835MphiState mphi;
42
UnimplementedDeviceState txp;
43
UnimplementedDeviceState armtmr;
44
- UnimplementedDeviceState powermgt;
45
+ BCM2835PowerMgtState powermgt;
46
BCM2835CprmanState cprman;
47
PL011State uart0;
48
BCM2835AuxState aux;
49
diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h
37
new file mode 100644
50
new file mode 100644
38
index XXXXXXX..XXXXXXX
51
index XXXXXXX..XXXXXXX
39
--- /dev/null
52
--- /dev/null
40
+++ b/tests/acceptance/machine_arm_canona1100.py
53
+++ b/include/hw/misc/bcm2835_powermgt.h
41
@@ -XXX,XX +XXX,XX @@
54
@@ -XXX,XX +XXX,XX @@
42
+# Functional test that boots the canon-a1100 machine with firmware
55
+/*
43
+#
56
+ * BCM2835 Power Management emulation
44
+# Copyright (c) 2020 Red Hat, Inc.
57
+ *
45
+#
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
46
+# Author:
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
47
+# Thomas Huth <thuth@redhat.com>
60
+ *
48
+#
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
49
+# This work is licensed under the terms of the GNU GPL, version 2 or
62
+ * See the COPYING file in the top-level directory.
50
+# later. See the COPYING file in the top-level directory.
63
+ */
51
+
64
+
52
+from avocado_qemu import Test
65
+#ifndef BCM2835_POWERMGT_H
53
+from avocado_qemu import wait_for_console_pattern
66
+#define BCM2835_POWERMGT_H
54
+from avocado.utils import archive
67
+
55
+
68
+#include "hw/sysbus.h"
56
+class CanonA1100Machine(Test):
69
+#include "qom/object.h"
57
+ """Boots the barebox firmware and checks that the console is operational"""
70
+
58
+
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
59
+ timeout = 90
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
60
+
73
+
61
+ def test_arm_canona1100(self):
74
+struct BCM2835PowerMgtState {
62
+ """
75
+ SysBusDevice busdev;
63
+ :avocado: tags=arch:arm
76
+ MemoryRegion iomem;
64
+ :avocado: tags=machine:canon-a1100
77
+
65
+ :avocado: tags=device:pflash_cfi02
78
+ uint32_t rstc;
66
+ """
79
+ uint32_t rsts;
67
+ tar_url = ('https://www.qemu-advent-calendar.org'
80
+ uint32_t wdog;
68
+ '/2018/download/day18.tar.xz')
81
+};
69
+ tar_hash = '068b5fc4242b29381acee94713509f8a876e9db6'
82
+
70
+ file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
83
+#endif
71
+ archive.extract(file_path, self.workdir)
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
72
+ self.vm.set_console()
85
index XXXXXXX..XXXXXXX 100644
73
+ self.vm.add_args('-bios',
86
--- a/hw/arm/bcm2835_peripherals.c
74
+ self.workdir + '/day18/barebox.canon-a1100.bin')
87
+++ b/hw/arm/bcm2835_peripherals.c
75
+ self.vm.launch()
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
76
+ wait_for_console_pattern(self, 'running /env/bin/init')
89
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
91
OBJECT(&s->gpu_bus_mr));
92
+
93
+ /* Power Management */
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)) {
105
+ return;
106
+ }
107
+
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
110
+
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
118
new file mode 100644
119
index XXXXXXX..XXXXXXX
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);
187
+ return;
188
+ }
189
+
190
+ value = value & ~PASSWORD_MASK;
191
+
192
+ switch (offset) {
193
+ case R_RSTC:
194
+ s->rstc = value;
195
+ if (value & V_RSTC_RESET) {
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
198
+ } else {
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
200
+ }
201
+ }
202
+ break;
203
+ case R_RSTS:
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "bcm2835_powermgt_write: RSTS\n");
206
+ s->rsts = value;
207
+ break;
208
+ case R_WDOG:
209
+ qemu_log_mask(LOG_UNIMP,
210
+ "bcm2835_powermgt_write: WDOG\n");
211
+ s->wdog = value;
212
+ break;
213
+
214
+ default:
215
+ qemu_log_mask(LOG_UNIMP,
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
217
+ "\n", offset);
218
+ break;
219
+ }
220
+}
221
+
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
223
+ .read = bcm2835_powermgt_read,
224
+ .write = bcm2835_powermgt_write,
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
226
+ .impl.min_access_size = 4,
227
+ .impl.max_access_size = 4,
228
+};
229
+
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
231
+ .name = TYPE_BCM2835_POWERMGT,
232
+ .version_id = 1,
233
+ .minimum_version_id = 1,
234
+ .fields = (VMStateField[]) {
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
238
+ VMSTATE_END_OF_LIST()
239
+ }
240
+};
241
+
242
+static void bcm2835_powermgt_init(Object *obj)
243
+{
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
245
+
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
247
+ TYPE_BCM2835_POWERMGT, 0x200);
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
249
+}
250
+
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
252
+{
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
254
+
255
+ /* https://elinux.org/BCM2835_registers#PM */
256
+ s->rstc = 0x00000102;
257
+ s->rsts = 0x00001000;
258
+ s->wdog = 0x00000000;
259
+}
260
+
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
262
+{
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
264
+
265
+ dc->reset = bcm2835_powermgt_reset;
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
267
+}
268
+
269
+static TypeInfo bcm2835_powermgt_info = {
270
+ .name = TYPE_BCM2835_POWERMGT,
271
+ .parent = TYPE_SYS_BUS_DEVICE,
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
273
+ .class_init = bcm2835_powermgt_class_init,
274
+ .instance_init = bcm2835_powermgt_init,
275
+};
276
+
277
+static void bcm2835_powermgt_register_types(void)
278
+{
279
+ type_register_static(&bcm2835_powermgt_info);
280
+}
281
+
282
+type_init(bcm2835_powermgt_register_types)
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
284
index XXXXXXX..XXXXXXX 100644
285
--- a/hw/misc/meson.build
286
+++ b/hw/misc/meson.build
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
288
'bcm2835_rng.c',
289
'bcm2835_thermal.c',
290
'bcm2835_cprman.c',
291
+ 'bcm2835_powermgt.c',
292
))
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
77
--
295
--
78
2.20.1
296
2.20.1
79
297
80
298
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
hw_error() calls exit(). This a bit overkill when we can log
3
Add a test booting and quickly shutdown a raspi2 machine,
4
the accesses as unimplemented or guest error.
4
to test the power management model:
5
5
6
When fuzzing the devices, we don't want the whole process to
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
7
exit. Replace some hw_error() calls by qemu_log_mask().
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
8
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
Per the datasheet "Exynos 4412 RISC Microprocessor Rev 1.00"
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
10
Chapter 25 "Multi Core Timer (MCT)" figure 1 and table 4,
10
console: [ 0.000000] CPU: div instructions available: patching division code
11
the default value on the APB bus is 0.
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
12
44
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
15
Message-id: 20200518140309.5220-5-f4bug@amsat.org
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
49
---
18
hw/timer/exynos4210_mct.c | 12 +++++-------
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
19
1 file changed, 5 insertions(+), 7 deletions(-)
51
1 file changed, 43 insertions(+)
20
52
21
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
22
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/timer/exynos4210_mct.c
55
--- a/tests/acceptance/boot_linux_console.py
24
+++ b/hw/timer/exynos4210_mct.c
56
+++ b/tests/acceptance/boot_linux_console.py
25
@@ -XXX,XX +XXX,XX @@
57
@@ -XXX,XX +XXX,XX @@
26
58
from avocado import skip
27
#include "qemu/osdep.h"
59
from avocado import skipUnless
28
#include "qemu/log.h"
60
from avocado_qemu import Test
29
-#include "hw/hw.h"
61
+from avocado_qemu import exec_command
30
#include "hw/sysbus.h"
62
from avocado_qemu import exec_command_and_wait_for_pattern
31
#include "migration/vmstate.h"
63
from avocado_qemu import interrupt_interactive_console_until_pattern
32
#include "qemu/timer.h"
64
from avocado_qemu import wait_for_console_pattern
33
@@ -XXX,XX +XXX,XX @@
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
34
#include "hw/ptimer.h"
66
"""
35
67
self.do_test_arm_raspi2(0)
36
#include "hw/arm/exynos4210.h"
68
37
-#include "hw/hw.h"
69
+ def test_arm_raspi2_initrd(self):
38
#include "hw/irq.h"
70
+ """
39
71
+ :avocado: tags=arch:arm
40
//#define DEBUG_MCT
72
+ :avocado: tags=machine:raspi2
41
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_mct_read(void *opaque, hwaddr offset,
73
+ """
42
int index;
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
43
int shift;
75
+ 'pool/main/r/raspberrypi-firmware/'
44
uint64_t count;
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
45
- uint32_t value;
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
46
+ uint32_t value = 0;
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
47
int lt_i;
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
48
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
49
switch (offset) {
81
+
50
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_mct_read(void *opaque, hwaddr offset,
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
51
break;
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
52
84
+ 'arm/rootfs-armv7a.cpio.gz')
53
default:
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
54
- hw_error("exynos4210.mct: bad read offset "
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
55
- TARGET_FMT_plx "\n", offset);
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
56
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
57
+ __func__, offset);
89
+
58
break;
90
+ self.vm.set_console()
59
}
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
60
return value;
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_write(void *opaque, hwaddr offset,
93
+ 'panic=-1 noreboot ' +
62
break;
94
+ 'dwc_otg.fiq_fsm_enable=0')
63
95
+ self.vm.add_args('-kernel', kernel_path,
64
default:
96
+ '-dtb', dtb_path,
65
- hw_error("exynos4210.mct: bad write offset "
97
+ '-initrd', initrd_path,
66
- TARGET_FMT_plx "\n", offset);
98
+ '-append', kernel_command_line,
67
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
99
+ '-no-reboot')
68
+ __func__, offset);
100
+ self.vm.launch()
69
break;
101
+ self.wait_for_console_pattern('Boot successful.')
70
}
102
+
71
}
103
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
104
+ 'BCM2835')
105
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
106
+ '/soc/cprman@7e101000')
107
+ exec_command(self, 'halt')
108
+ # Wait for VM to shut down gracefully
109
+ self.vm.wait()
110
+
111
def test_arm_exynos4210_initrd(self):
112
"""
113
:avocado: tags=arch:arm
72
--
114
--
73
2.20.1
115
2.20.1
74
116
75
117
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
i.MX7 supports watchdog pretimeout interupts. With this commit,
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
4
the watchdog in mcimx7d-sabre is fully operational, including
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
5
pretimeout support.
5
assert due to fpst->default_nan_mode being set.
6
6
7
To avoid this, we check to see what NaN mode we're running in before we call
8
floatxx_silence_nan().
9
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Message-id: 20200517162135.110364-9-linux@roeck-us.net
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
include/hw/arm/fsl-imx7.h | 5 +++++
16
target/arm/helper-a64.c | 12 +++++++++---
13
hw/arm/fsl-imx7.c | 11 +++++++++++
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
14
2 files changed, 16 insertions(+)
18
2 files changed, 27 insertions(+), 9 deletions(-)
15
19
16
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/fsl-imx7.h
22
--- a/target/arm/helper-a64.c
19
+++ b/include/hw/arm/fsl-imx7.h
23
+++ b/target/arm/helper-a64.c
20
@@ -XXX,XX +XXX,XX @@ enum FslIMX7IRQs {
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
21
FSL_IMX7_USB2_IRQ = 42,
25
float16 nan = a;
22
FSL_IMX7_USB3_IRQ = 40,
26
if (float16_is_signaling_nan(a, fpst)) {
23
27
float_raise(float_flag_invalid, fpst);
24
+ FSL_IMX7_WDOG1_IRQ = 78,
28
- nan = float16_silence_nan(a, fpst);
25
+ FSL_IMX7_WDOG2_IRQ = 79,
29
+ if (!fpst->default_nan_mode) {
26
+ FSL_IMX7_WDOG3_IRQ = 10,
30
+ nan = float16_silence_nan(a, fpst);
27
+ FSL_IMX7_WDOG4_IRQ = 109,
31
+ }
28
+
32
}
29
FSL_IMX7_PCI_INTA_IRQ = 125,
33
if (fpst->default_nan_mode) {
30
FSL_IMX7_PCI_INTB_IRQ = 124,
34
nan = float16_default_nan(fpst);
31
FSL_IMX7_PCI_INTC_IRQ = 123,
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
32
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
36
float32 nan = a;
37
if (float32_is_signaling_nan(a, fpst)) {
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);
57
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
33
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/fsl-imx7.c
59
--- a/target/arm/vfp_helper.c
35
+++ b/hw/arm/fsl-imx7.c
60
+++ b/target/arm/vfp_helper.c
36
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
37
FSL_IMX7_WDOG3_ADDR,
62
float16 nan = f16;
38
FSL_IMX7_WDOG4_ADDR,
63
if (float16_is_signaling_nan(f16, fpst)) {
39
};
64
float_raise(float_flag_invalid, fpst);
40
+ static const int FSL_IMX7_WDOGn_IRQ[FSL_IMX7_NUM_WDTS] = {
65
- nan = float16_silence_nan(f16, fpst);
41
+ FSL_IMX7_WDOG1_IRQ,
66
+ if (!fpst->default_nan_mode) {
42
+ FSL_IMX7_WDOG2_IRQ,
67
+ nan = float16_silence_nan(f16, fpst);
43
+ FSL_IMX7_WDOG3_IRQ,
68
+ }
44
+ FSL_IMX7_WDOG4_IRQ,
69
}
45
+ };
70
if (fpst->default_nan_mode) {
46
71
nan = float16_default_nan(fpst);
47
+ object_property_set_bool(OBJECT(&s->wdt[i]), true, "pretimeout-support",
72
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
48
+ &error_abort);
73
float32 nan = f32;
49
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized",
74
if (float32_is_signaling_nan(f32, fpst)) {
50
&error_abort);
75
float_raise(float_flag_invalid, fpst);
51
76
- nan = float32_silence_nan(f32, fpst);
52
sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX7_WDOGn_ADDR[i]);
77
+ if (!fpst->default_nan_mode) {
53
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0,
78
+ nan = float32_silence_nan(f32, fpst);
54
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
79
+ }
55
+ FSL_IMX7_WDOGn_IRQ[i]));
80
}
56
}
81
if (fpst->default_nan_mode) {
57
82
nan = float32_default_nan(fpst);
58
/*
83
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
84
float64 nan = f64;
85
if (float64_is_signaling_nan(f64, fpst)) {
86
float_raise(float_flag_invalid, fpst);
87
- nan = float64_silence_nan(f64, fpst);
88
+ if (!fpst->default_nan_mode) {
89
+ nan = float64_silence_nan(f64, fpst);
90
+ }
91
}
92
if (fpst->default_nan_mode) {
93
nan = float64_default_nan(fpst);
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);
59
--
127
--
60
2.20.1
128
2.20.1
61
129
62
130
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
hw_error() calls exit(). This a bit overkill when we can log
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
4
the accesses as unimplemented or guest error.
4
function has to be used for machine shutdown. Otherwise we cause
5
a reset with a bogus "cause" value, when we intended a shutdown.
5
6
6
When fuzzing the devices, we don't want the whole process to
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
7
exit. Replace some hw_error() calls by qemu_log_mask().
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
[PMM: tweaked commit message]
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 20200518140309.5220-2-f4bug@amsat.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
12
---
14
hw/arm/integratorcp.c | 23 +++++++++++++++--------
13
hw/gpio/gpio_pwr.c | 2 +-
15
1 file changed, 15 insertions(+), 8 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
16
15
17
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/integratorcp.c
18
--- a/hw/gpio/gpio_pwr.c
20
+++ b/hw/arm/integratorcp.c
19
+++ b/hw/gpio/gpio_pwr.c
21
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
22
#include "exec/address-spaces.h"
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
23
#include "sysemu/runstate.h"
22
{
24
#include "sysemu/sysemu.h"
23
if (level) {
25
+#include "qemu/log.h"
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
26
#include "qemu/error-report.h"
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
27
#include "hw/char/pl011.h"
28
#include "hw/hw.h"
29
@@ -XXX,XX +XXX,XX @@ static uint64_t integratorcm_read(void *opaque, hwaddr offset,
30
/* ??? Voltage control unimplemented. */
31
return 0;
32
default:
33
- hw_error("integratorcm_read: Unimplemented offset 0x%x\n",
34
- (int)offset);
35
+ qemu_log_mask(LOG_UNIMP,
36
+ "%s: Unimplemented offset 0x%" HWADDR_PRIX "\n",
37
+ __func__, offset);
38
return 0;
39
}
26
}
40
}
27
}
41
@@ -XXX,XX +XXX,XX @@ static void integratorcm_write(void *opaque, hwaddr offset,
42
/* ??? Voltage control unimplemented. */
43
break;
44
default:
45
- hw_error("integratorcm_write: Unimplemented offset 0x%x\n",
46
- (int)offset);
47
+ qemu_log_mask(LOG_UNIMP,
48
+ "%s: Unimplemented offset 0x%" HWADDR_PRIX "\n",
49
+ __func__, offset);
50
break;
51
}
52
}
53
@@ -XXX,XX +XXX,XX @@ static uint64_t icp_pic_read(void *opaque, hwaddr offset,
54
case 5: /* INT_SOFTCLR */
55
case 11: /* FRQ_ENABLECLR */
56
default:
57
- printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
58
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
59
+ __func__, offset);
60
return 0;
61
}
62
}
63
@@ -XXX,XX +XXX,XX @@ static void icp_pic_write(void *opaque, hwaddr offset,
64
case 8: /* FRQ_STATUS */
65
case 9: /* FRQ_RAWSTAT */
66
default:
67
- printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
68
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
69
+ __func__, offset);
70
return;
71
}
72
icp_pic_update(s);
73
@@ -XXX,XX +XXX,XX @@ static uint64_t icp_control_read(void *opaque, hwaddr offset,
74
case 3: /* CP_DECODE */
75
return 0x11;
76
default:
77
- hw_error("icp_control_read: Bad offset %x\n", (int)offset);
78
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
79
+ __func__, offset);
80
return 0;
81
}
82
}
83
@@ -XXX,XX +XXX,XX @@ static void icp_control_write(void *opaque, hwaddr offset,
84
/* Nothing interesting implemented yet. */
85
break;
86
default:
87
- hw_error("icp_control_write: Bad offset %x\n", (int)offset);
88
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
89
+ __func__, offset);
90
}
91
}
92
28
93
--
29
--
94
2.20.1
30
2.20.1
95
31
96
32
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.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
hw_error() calls exit(). This a bit overkill when we can log
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
the accesses as unimplemented or guest error.
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
When fuzzing the devices, we don't want the whole process to
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
7
exit. Replace some hw_error() calls by qemu_log_mask().
8
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 20200518140309.5220-3-f4bug@amsat.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/pxa2xx_gpio.c | 7 ++++---
15
hw/display/pxa2xx_lcd.c | 8 +++++---
16
hw/dma/pxa2xx_dma.c | 14 +++++++++-----
17
3 files changed, 18 insertions(+), 11 deletions(-)
18
19
diff --git a/hw/arm/pxa2xx_gpio.c b/hw/arm/pxa2xx_gpio.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/pxa2xx_gpio.c
15
--- a/target/arm/translate-mve.c
22
+++ b/hw/arm/pxa2xx_gpio.c
16
+++ b/target/arm/translate-mve.c
23
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
24
25
#include "qemu/osdep.h"
26
#include "cpu.h"
27
-#include "hw/hw.h"
28
#include "hw/irq.h"
29
#include "hw/qdev-properties.h"
30
#include "hw/sysbus.h"
31
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_gpio_read(void *opaque, hwaddr offset,
32
return s->status[bank];
33
34
default:
35
- hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
36
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
37
+ __func__, offset);
38
}
39
40
return 0;
41
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_gpio_write(void *opaque, hwaddr offset,
42
break;
43
44
default:
45
- hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
46
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
47
+ __func__, offset);
48
}
18
}
49
}
19
}
50
20
51
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
52
index XXXXXXX..XXXXXXX 100644
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
53
--- a/hw/display/pxa2xx_lcd.c
23
+ unsigned msize)
54
+++ b/hw/display/pxa2xx_lcd.c
24
{
55
@@ -XXX,XX +XXX,XX @@
25
TCGv_i32 addr;
56
*/
26
uint32_t offset;
57
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
58
#include "qemu/osdep.h"
28
return true;
59
-#include "hw/hw.h"
60
+#include "qemu/log.h"
61
#include "hw/irq.h"
62
#include "migration/vmstate.h"
63
#include "ui/console.h"
64
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_lcdc_read(void *opaque, hwaddr offset,
65
66
default:
67
fail:
68
- hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
69
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
70
+ __func__, offset);
71
}
29
}
72
30
73
return 0;
31
- offset = a->imm << a->size;
74
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_write(void *opaque, hwaddr offset,
32
+ offset = a->imm << msize;
75
33
if (!a->a) {
76
default:
34
offset = -offset;
77
fail:
78
- hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
79
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
80
+ __func__, offset);
81
}
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);
82
}
42
}
83
43
84
diff --git a/hw/dma/pxa2xx_dma.c b/hw/dma/pxa2xx_dma.c
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
85
index XXXXXXX..XXXXXXX 100644
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
86
--- a/hw/dma/pxa2xx_dma.c
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
87
+++ b/hw/dma/pxa2xx_dma.c
47
{ \
88
@@ -XXX,XX +XXX,XX @@
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
89
*/
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
90
50
{ NULL, gen_helper_mve_##ULD }, \
91
#include "qemu/osdep.h"
51
}; \
92
+#include "qemu/log.h"
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
93
#include "hw/hw.h"
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
94
#include "hw/irq.h"
95
#include "hw/qdev-properties.h"
96
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_dma_read(void *opaque, hwaddr offset,
97
unsigned int channel;
98
99
if (size != 4) {
100
- hw_error("%s: Bad access width\n", __func__);
101
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad access width %u\n",
102
+ __func__, size);
103
return 5;
104
}
54
}
105
55
106
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_dma_read(void *opaque, hwaddr offset,
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
107
return s->chan[channel].cmd;
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
108
}
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
109
}
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
110
-
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
111
- hw_error("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
112
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
62
113
+ __func__, offset);
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
114
return 7;
64
{
115
}
116
117
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_dma_write(void *opaque, hwaddr offset,
118
unsigned int channel;
119
120
if (size != 4) {
121
- hw_error("%s: Bad access width\n", __func__);
122
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad access width %u\n",
123
+ __func__, size);
124
return;
125
}
126
127
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_dma_write(void *opaque, hwaddr offset,
128
break;
129
}
130
fail:
131
- hw_error("%s: Bad offset " TARGET_FMT_plx "\n", __func__, offset);
132
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
133
+ __func__, offset);
134
}
135
}
136
137
--
65
--
138
2.20.1
66
2.20.1
139
67
140
68
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.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
hw_error() calls exit(). This a bit overkill when we can log
10
In particular, fixing the second of these allows us to recast
4
the accesses as unimplemented or guest error.
11
the implementation to avoid 128-bit arithmetic entirely.
5
12
6
When fuzzing the devices, we don't want the whole process to
13
Since the element size here is always 4, we can also drop the
7
exit. Replace some hw_error() calls by qemu_log_mask().
14
parameterization of ESIZE to make the code a little more readable.
8
15
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-id: 20200518140309.5220-4-f4bug@amsat.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
14
---
20
---
15
hw/char/xilinx_uartlite.c | 5 +++--
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
16
1 file changed, 3 insertions(+), 2 deletions(-)
22
1 file changed, 21 insertions(+), 17 deletions(-)
17
23
18
diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
19
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/char/xilinx_uartlite.c
26
--- a/target/arm/mve_helper.c
21
+++ b/hw/char/xilinx_uartlite.c
27
+++ b/target/arm/mve_helper.c
22
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
23
*/
29
*/
24
30
25
#include "qemu/osdep.h"
31
#include "qemu/osdep.h"
26
-#include "hw/hw.h"
32
-#include "qemu/int128.h"
27
+#include "qemu/log.h"
33
#include "cpu.h"
28
#include "hw/irq.h"
34
#include "internals.h"
29
#include "hw/qdev-properties.h"
35
#include "vec_internal.h"
30
#include "hw/sysbus.h"
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
31
@@ -XXX,XX +XXX,XX @@ uart_write(void *opaque, hwaddr addr,
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
32
switch (addr)
38
33
{
39
/*
34
case R_STATUS:
40
- * Rounding multiply add long dual accumulate high: we must keep
35
- hw_error("write to UART STATUS?\n");
41
- * a 72-bit internal accumulator value and return the top 64 bits.
36
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: write to UART STATUS\n",
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
37
+ __func__);
43
+ * this is implemented with a 72-bit internal accumulator value of which
38
break;
44
+ * the top 64 bits are returned. We optimize this to avoid having to
39
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
40
case R_CTRL:
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; \
81
}
82
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) \
41
--
98
--
42
2.20.1
99
2.20.1
43
100
44
101
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
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
With this commit, the watchdog on imx25-pdk is fully operational,
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
including pretimeout support.
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(-)
5
14
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20200517162135.110364-4-linux@roeck-us.net
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/fsl-imx25.h | 5 +++++
12
hw/arm/fsl-imx25.c | 10 ++++++++++
13
hw/arm/Kconfig | 1 +
14
3 files changed, 16 insertions(+)
15
16
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/fsl-imx25.h
17
--- a/target/arm/translate.h
19
+++ b/include/hw/arm/fsl-imx25.h
18
+++ b/target/arm/translate.h
20
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
21
#include "hw/gpio/imx_gpio.h"
20
return opc | s->be_data;
22
#include "hw/sd/sdhci.h"
21
}
23
#include "hw/usb/chipidea.h"
22
24
+#include "hw/watchdog/wdt_imx2.h"
23
+/**
25
#include "exec/memory.h"
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
26
#include "target/arm/cpu.h"
25
+ *
27
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
28
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
29
IMXGPIOState gpio[FSL_IMX25_NUM_GPIOS];
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
30
SDHCIState esdhc[FSL_IMX25_NUM_ESDHCS];
29
+ *
31
ChipideaState usb[FSL_IMX25_NUM_USBS];
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
32
+ IMX2WdtState wdt;
31
+ * callers must catch this.
33
MemoryRegion rom[2];
32
+ *
34
MemoryRegion iram;
33
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
35
MemoryRegion iram_alias;
34
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
36
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
35
+ * we produce an immediate constant value of 0 in these cases.
37
#define FSL_IMX25_GPIO1_SIZE 0x4000
36
+ */
38
#define FSL_IMX25_GPIO2_ADDR 0x53FD0000
37
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
39
#define FSL_IMX25_GPIO2_SIZE 0x4000
38
+
40
+#define FSL_IMX25_WDT_ADDR 0x53FDC000
39
#endif /* TARGET_ARM_TRANSLATE_H */
41
+#define FSL_IMX25_WDT_SIZE 0x4000
40
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
42
#define FSL_IMX25_USB1_ADDR 0x53FF4000
43
#define FSL_IMX25_USB1_SIZE 0x0200
44
#define FSL_IMX25_USB2_ADDR 0x53FF4400
45
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
46
#define FSL_IMX25_ESDHC2_IRQ 8
47
#define FSL_IMX25_USB1_IRQ 37
48
#define FSL_IMX25_USB2_IRQ 35
49
+#define FSL_IMX25_WDT_IRQ 55
50
51
#endif /* FSL_IMX25_H */
52
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
53
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/arm/fsl-imx25.c
42
--- a/target/arm/translate-neon.c
55
+++ b/hw/arm/fsl-imx25.c
43
+++ b/target/arm/translate-neon.c
56
@@ -XXX,XX +XXX,XX @@ static void fsl_imx25_init(Object *obj)
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
57
TYPE_CHIPIDEA);
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
58
}
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
59
47
60
+ sysbus_init_child_obj(obj, "wdt", &s->wdt, sizeof(s->wdt), TYPE_IMX2_WDT);
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();
61
}
120
}
62
121
63
static void fsl_imx25_realize(DeviceState *dev, Error **errp)
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
64
@@ -XXX,XX +XXX,XX @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
123
+{
65
usb_table[i].irq));
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
66
}
125
+ switch (cmode) {
67
126
+ case 0: case 1:
68
+ /* Watchdog */
127
+ /* no-op */
69
+ object_property_set_bool(OBJECT(&s->wdt), true, "pretimeout-support",
128
+ break;
70
+ &error_abort);
129
+ case 2: case 3:
71
+ object_property_set_bool(OBJECT(&s->wdt), true, "realized", &error_abort);
130
+ imm <<= 8;
72
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt), 0, FSL_IMX25_WDT_ADDR);
131
+ break;
73
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt), 0,
132
+ case 4: case 5:
74
+ qdev_get_gpio_in(DEVICE(&s->avic),
133
+ imm <<= 16;
75
+ FSL_IMX25_WDT_IRQ));
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;
76
+
158
+
77
/* initialize 2 x 16 KB ROM */
159
+ for (n = 0; n < 8; n++) {
78
memory_region_init_rom(&s->rom[0], OBJECT(dev), "imx25.rom0",
160
+ if (imm & (1 << n)) {
79
FSL_IMX25_ROM0_SIZE, &err);
161
+ imm64 |= (0xffULL << (n * 8));
80
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
162
+ }
81
index XXXXXXX..XXXXXXX 100644
163
+ }
82
--- a/hw/arm/Kconfig
164
+ return imm64;
83
+++ b/hw/arm/Kconfig
165
+ }
84
@@ -XXX,XX +XXX,XX @@ config FSL_IMX25
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
85
select IMX
167
+ break;
86
select IMX_FEC
168
+ case 15:
87
select IMX_I2C
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
88
+ select WDT_IMX2
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
89
select DS1338
171
+ break;
90
172
+ }
91
config FSL_IMX31
173
+ if (op) {
174
+ imm = ~imm;
175
+ }
176
+ return dup_const(MO_32, imm);
177
+}
178
+
179
/* Generate a label used for skipping this instruction */
180
void arm_gen_condlabel(DisasContext *s)
181
{
92
--
182
--
93
2.20.1
183
2.20.1
94
184
95
185
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.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
Do not explicitly store zero to the NEON high part
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
when we can pass !is_q to clear_vec_high.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
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(-)
5
14
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
index XXXXXXX..XXXXXXX 100644
8
Message-id: 20200519212453.28494-3-richard.henderson@linaro.org
17
--- a/target/arm/translate.h
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
+++ b/target/arm/translate.h
10
---
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
11
target/arm/translate-a64.c | 53 +++++++++++++++++++++++---------------
20
* VMVN and VBIC (when cmode < 14 && op == 1).
12
1 file changed, 32 insertions(+), 21 deletions(-)
21
*
13
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
23
- * callers must catch this.
24
+ * callers must catch this; we return the 64-bit constant value defined
25
+ * for AArch64.
26
*
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
31
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
19
{
34
{
20
/* This always zero-extends and writes to a full 128 bit wide vector */
35
int rd = extract32(insn, 0, 5);
21
TCGv_i64 tmplo = tcg_temp_new_i64();
36
int cmode = extract32(insn, 12, 4);
22
- TCGv_i64 tmphi;
37
- int cmode_3_1 = extract32(cmode, 1, 3);
23
+ TCGv_i64 tmphi = NULL;
38
- int cmode_0 = extract32(cmode, 0, 1);
24
39
int o2 = extract32(insn, 11, 1);
25
if (size < 4) {
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
26
MemOp memop = s->be_data + size;
41
bool is_neg = extract32(insn, 29, 1);
27
- tmphi = tcg_const_i64(0);
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
28
tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
43
return;
29
} else {
30
bool be = s->be_data == MO_BE;
31
@@ -XXX,XX +XXX,XX @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
32
}
44
}
33
45
34
tcg_gen_st_i64(tmplo, cpu_env, fp_reg_offset(s, destidx, MO_64));
46
- /* See AdvSIMDExpandImm() in ARM ARM */
35
- tcg_gen_st_i64(tmphi, cpu_env, fp_reg_hi_offset(s, destidx));
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
- }
36
-
120
-
37
tcg_temp_free_i64(tmplo);
121
- if (cmode_3_1 != 7 && is_neg) {
38
- tcg_temp_free_i64(tmphi);
122
- imm = ~imm;
39
123
+ if (cmode == 15 && o2 && !is_neg) {
40
- clear_vec_high(s, true, destidx);
124
+ /* FMOV (vector, immediate) - half-precision */
41
+ if (tmphi) {
125
+ imm = vfp_expand_imm(MO_16, abcdefgh);
42
+ tcg_gen_st_i64(tmphi, cpu_env, fp_reg_hi_offset(s, destidx));
126
+ /* now duplicate across the lanes */
43
+ tcg_temp_free_i64(tmphi);
127
+ imm = bitfield_replicate(imm, 16);
44
+ }
128
+ } else {
45
+ clear_vec_high(s, tmphi != NULL, destidx);
129
+ imm = asimd_imm_const(abcdefgh, cmode, is_neg);
46
}
47
48
/*
49
@@ -XXX,XX +XXX,XX @@ static void disas_simd_ext(DisasContext *s, uint32_t insn)
50
read_vec_element(s, tcg_resh, rm, 0, MO_64);
51
do_ext64(s, tcg_resh, tcg_resl, pos);
52
}
53
- tcg_gen_movi_i64(tcg_resh, 0);
54
} else {
55
TCGv_i64 tcg_hh;
56
typedef struct {
57
@@ -XXX,XX +XXX,XX @@ static void disas_simd_ext(DisasContext *s, uint32_t insn)
58
59
write_vec_element(s, tcg_resl, rd, 0, MO_64);
60
tcg_temp_free_i64(tcg_resl);
61
- write_vec_element(s, tcg_resh, rd, 1, MO_64);
62
+ if (is_q) {
63
+ write_vec_element(s, tcg_resh, rd, 1, MO_64);
64
+ }
65
tcg_temp_free_i64(tcg_resh);
66
- clear_vec_high(s, true, rd);
67
+ clear_vec_high(s, is_q, rd);
68
}
69
70
/* TBL/TBX
71
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
72
* the input.
73
*/
74
tcg_resl = tcg_temp_new_i64();
75
- tcg_resh = tcg_temp_new_i64();
76
+ tcg_resh = NULL;
77
78
if (is_tblx) {
79
read_vec_element(s, tcg_resl, rd, 0, MO_64);
80
} else {
81
tcg_gen_movi_i64(tcg_resl, 0);
82
}
130
}
83
- if (is_tblx && is_q) {
131
84
- read_vec_element(s, tcg_resh, rd, 1, MO_64);
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
85
- } else {
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
86
- tcg_gen_movi_i64(tcg_resh, 0);
134
index XXXXXXX..XXXXXXX 100644
87
+
135
--- a/target/arm/translate.c
88
+ if (is_q) {
136
+++ b/target/arm/translate.c
89
+ tcg_resh = tcg_temp_new_i64();
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
90
+ if (is_tblx) {
138
case 14:
91
+ read_vec_element(s, tcg_resh, rd, 1, MO_64);
139
if (op) {
92
+ } else {
140
/*
93
+ tcg_gen_movi_i64(tcg_resh, 0);
141
- * This is the only case where the top and bottom 32 bits
142
- * of the encoded constant differ.
143
+ * This and cmode == 15 op == 1 are the only cases where
144
+ * the top and bottom 32 bits of the encoded constant differ.
145
*/
146
uint64_t imm64 = 0;
147
int n;
148
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
149
imm |= (imm << 8) | (imm << 16) | (imm << 24);
150
break;
151
case 15:
152
+ if (op) {
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;
94
+ }
164
+ }
95
}
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
96
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
97
tcg_idx = tcg_temp_new_i64();
167
break;
98
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
99
100
write_vec_element(s, tcg_resl, rd, 0, MO_64);
101
tcg_temp_free_i64(tcg_resl);
102
- write_vec_element(s, tcg_resh, rd, 1, MO_64);
103
- tcg_temp_free_i64(tcg_resh);
104
- clear_vec_high(s, true, rd);
105
+
106
+ if (is_q) {
107
+ write_vec_element(s, tcg_resh, rd, 1, MO_64);
108
+ tcg_temp_free_i64(tcg_resh);
109
+ }
110
+ clear_vec_high(s, is_q, rd);
111
}
112
113
/* ZIP/UZP/TRN
114
@@ -XXX,XX +XXX,XX @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn)
115
}
116
117
tcg_resl = tcg_const_i64(0);
118
- tcg_resh = tcg_const_i64(0);
119
+ tcg_resh = is_q ? tcg_const_i64(0) : NULL;
120
tcg_res = tcg_temp_new_i64();
121
122
for (i = 0; i < elements; i++) {
123
@@ -XXX,XX +XXX,XX @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn)
124
125
write_vec_element(s, tcg_resl, rd, 0, MO_64);
126
tcg_temp_free_i64(tcg_resl);
127
- write_vec_element(s, tcg_resh, rd, 1, MO_64);
128
- tcg_temp_free_i64(tcg_resh);
129
- clear_vec_high(s, true, rd);
130
+
131
+ if (is_q) {
132
+ write_vec_element(s, tcg_resh, rd, 1, MO_64);
133
+ tcg_temp_free_i64(tcg_resh);
134
+ }
135
+ clear_vec_high(s, is_q, rd);
136
}
137
138
/*
139
--
168
--
140
2.20.1
169
2.20.1
141
170
142
171
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Use dup_const() instead of bitfield_replicate() in
2
disas_simd_mod_imm().
2
3
3
The 8-byte store for the end a !is_q operation can be
4
(We can't replace the other use of bitfield_replicate() in this file,
4
merged with the other stores. Use a no-op vector move
5
in logic_imm_decode_wmask(), because that location needs to handle 2
5
to trigger the expand_clr portion of tcg_gen_gvec_mov.
6
and 4 bit elements, which dup_const() cannot.)
6
7
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200519212453.28494-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
---
11
---
12
target/arm/translate-a64.c | 10 ++--------
12
target/arm/translate-a64.c | 2 +-
13
1 file changed, 2 insertions(+), 8 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void clear_vec_high(DisasContext *s, bool is_q, int rd)
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
20
unsigned ofs = fp_reg_offset(s, rd, MO_64);
20
/* FMOV (vector, immediate) - half-precision */
21
unsigned vsz = vec_full_reg_size(s);
21
imm = vfp_expand_imm(MO_16, abcdefgh);
22
22
/* now duplicate across the lanes */
23
- if (!is_q) {
23
- imm = bitfield_replicate(imm, 16);
24
- TCGv_i64 tcg_zero = tcg_const_i64(0);
24
+ imm = dup_const(MO_16, imm);
25
- tcg_gen_st_i64(tcg_zero, cpu_env, ofs + 8);
25
} else {
26
- tcg_temp_free_i64(tcg_zero);
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
27
- }
27
}
28
- if (vsz > 16) {
29
- tcg_gen_gvec_dup_imm(MO_64, ofs + 16, vsz - 16, vsz - 16, 0);
30
- }
31
+ /* Nop move, with side effect of clearing the tail. */
32
+ tcg_gen_gvec_mov(MO_64, ofs, ofs, is_q ? 16 : 8, vsz);
33
}
34
35
void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v)
36
--
28
--
37
2.20.1
29
2.20.1
38
30
39
31
diff view generated by jsdifflib
1
Our code to identify syscall numbers has some issues:
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
2
* for Thumb mode, we never need the immediate value from the insn,
2
VORR and VBIC). These have essentially the same encoding
3
but we always read it anyway
3
as their Neon equivalents, and we implement the decode
4
* bad immediate values in the svc insn should cause a SIGILL, but we
4
in the same way.
5
were abort()ing instead (via "goto error")
6
7
We can fix both these things by refactoring the code that identifies
8
the syscall number to more closely follow the kernel COMPAT_OABI code:
9
* for Thumb it is always r7
10
* for Arm, if the immediate value is 0, then this is an EABI call
11
with the syscall number in r7
12
* otherwise, we XOR the immediate value with 0x900000
13
(ARM_SYSCALL_BASE for QEMU; __NR_OABI_SYSCALL_BASE in the kernel),
14
which converts valid syscall immediates into the desired value,
15
and puts all invalid immediates in the range 0x100000 or above
16
* then we can just let the existing "value too large, deliver
17
SIGILL" case handle invalid numbers, and drop the 'goto error'
18
5
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20200420212206.12776-5-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
22
---
9
---
23
linux-user/arm/cpu_loop.c | 143 ++++++++++++++++++++------------------
10
target/arm/helper-mve.h | 4 +++
24
1 file changed, 77 insertions(+), 66 deletions(-)
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(+)
25
15
26
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
27
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
28
--- a/linux-user/arm/cpu_loop.c
18
--- a/target/arm/helper-mve.h
29
+++ b/linux-user/arm/cpu_loop.c
19
+++ b/target/arm/helper-mve.h
30
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
31
env->eabi = 1;
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
32
/* system call */
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
33
if (env->thumb) {
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
34
- /* FIXME - what to do if get_user() fails? */
35
- get_user_code_u16(insn, env->regs[15] - 2, env);
36
- n = insn & 0xff;
37
+ /* Thumb is always EABI style with syscall number in r7 */
38
+ n = env->regs[7];
39
} else {
40
+ /*
41
+ * Equivalent of kernel CONFIG_OABI_COMPAT: read the
42
+ * Arm SVC insn to extract the immediate, which is the
43
+ * syscall number in OABI.
44
+ */
45
/* FIXME - what to do if get_user() fails? */
46
get_user_code_u32(insn, env->regs[15] - 4, env);
47
n = insn & 0xffffff;
48
- }
49
-
50
- if (n == 0 || n >= ARM_SYSCALL_BASE || env->thumb) {
51
- /* linux syscall */
52
- if (env->thumb || n == 0) {
53
+ if (n == 0) {
54
+ /* zero immediate: EABI, syscall number in r7 */
55
n = env->regs[7];
56
} else {
57
- n -= ARM_SYSCALL_BASE;
58
+ /*
59
+ * This XOR matches the kernel code: an immediate
60
+ * in the valid range (0x900000 .. 0x9fffff) is
61
+ * converted into the correct EABI-style syscall
62
+ * number; invalid immediates end up as values
63
+ * > 0xfffff and are handled below as out-of-range.
64
+ */
65
+ n ^= ARM_SYSCALL_BASE;
66
env->eabi = 0;
67
}
68
- if ( n > ARM_NR_BASE) {
69
- switch (n) {
70
- case ARM_NR_cacheflush:
71
- /* nop */
72
- break;
73
- case ARM_NR_set_tls:
74
- cpu_set_tls(env, env->regs[0]);
75
- env->regs[0] = 0;
76
- break;
77
- case ARM_NR_breakpoint:
78
- env->regs[15] -= env->thumb ? 2 : 4;
79
- goto excp_debug;
80
- case ARM_NR_get_tls:
81
- env->regs[0] = cpu_get_tls(env);
82
- break;
83
- default:
84
- if (n < 0xf0800) {
85
- /*
86
- * Syscalls 0xf0000..0xf07ff (or 0x9f0000..
87
- * 0x9f07ff in OABI numbering) are defined
88
- * to return -ENOSYS rather than raising
89
- * SIGILL. Note that we have already
90
- * removed the 0x900000 prefix.
91
- */
92
- qemu_log_mask(LOG_UNIMP,
93
- "qemu: Unsupported ARM syscall: 0x%x\n",
94
- n);
95
- env->regs[0] = -TARGET_ENOSYS;
96
+ }
97
+
24
+
98
+ if (n > ARM_NR_BASE) {
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
99
+ switch (n) {
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
100
+ case ARM_NR_cacheflush:
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
101
+ /* nop */
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
102
+ break;
29
index XXXXXXX..XXXXXXX 100644
103
+ case ARM_NR_set_tls:
30
--- a/target/arm/mve.decode
104
+ cpu_set_tls(env, env->regs[0]);
31
+++ b/target/arm/mve.decode
105
+ env->regs[0] = 0;
32
@@ -XXX,XX +XXX,XX @@
106
+ break;
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
107
+ case ARM_NR_breakpoint:
34
%size_28 28:1 !function=plus_1
108
+ env->regs[15] -= env->thumb ? 2 : 4;
35
109
+ goto excp_debug;
36
+# 1imm format immediate
110
+ case ARM_NR_get_tls:
37
+%imm_28_16_0 28:1 16:3 0:4
111
+ env->regs[0] = cpu_get_tls(env);
38
+
112
+ break;
39
&vldr_vstr rn qd imm p a w size l u
113
+ default:
40
&1op qd qm size
114
+ if (n < 0xf0800) {
41
&2op qd qm qn size
115
+ /*
42
&2scalar qd qn rm size
116
+ * Syscalls 0xf0000..0xf07ff (or 0x9f0000..
43
+&1imm qd imm cmode op
117
+ * 0x9f07ff in OABI numbering) are defined
44
118
+ * to return -ENOSYS rather than raising
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
119
+ * SIGILL. Note that we have already
46
# Note that both Rn and Qd are 3 bits only (no D bit)
120
+ * removed the 0x900000 prefix.
47
@@ -XXX,XX +XXX,XX @@
121
+ */
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
122
+ qemu_log_mask(LOG_UNIMP,
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
123
+ "qemu: Unsupported ARM syscall: 0x%x\n",
50
size=%size_28
124
+ n);
51
+@1imm .... .... .... .... .... cmode:4 .. op:1 . .... &1imm qd=%qd imm=%imm_28_16_0
125
+ env->regs[0] = -TARGET_ENOSYS;
52
126
+ } else {
53
# The _rev suffix indicates that Vn and Vm are reversed. This is
127
+ /*
54
# the case for shifts. In the Arm ARM these insns are documented
128
+ * Otherwise SIGILL. This includes any SWI with
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
129
+ * immediate not originally 0x9fxxxx, because
56
# Predicate operations
130
+ * of the earlier XOR.
57
%mask_22_13 22:1 13:3
131
+ */
58
VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
132
+ info.si_signo = TARGET_SIGILL;
59
+
133
+ info.si_errno = 0;
60
+# Logical immediate operations (1 reg and modified-immediate)
134
+ info.si_code = TARGET_ILL_ILLTRP;
61
+
135
+ info._sifields._sigfault._addr = env->regs[15];
62
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMVN, but
136
+ if (env->thumb) {
63
+# not in a way we can conveniently represent in decodetree without
137
+ info._sifields._sigfault._addr -= 2;
64
+# a lot of repetition:
138
} else {
65
+# VORR: op=0, (cmode & 1) && cmode < 12
139
- /* Otherwise SIGILL */
66
+# VBIC: op=1, (cmode & 1) && cmode < 12
140
- info.si_signo = TARGET_SIGILL;
67
+# VMOV: everything else
141
- info.si_errno = 0;
68
+# So we have a single decode line and check the cmode/op in the
142
- info.si_code = TARGET_ILL_ILLTRP;
69
+# trans function.
143
- info._sifields._sigfault._addr = env->regs[15];
70
+Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
144
- if (env->thumb) {
71
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
145
- info._sifields._sigfault._addr -= 2;
72
index XXXXXXX..XXXXXXX 100644
146
- } else {
73
--- a/target/arm/mve_helper.c
147
- info._sifields._sigfault._addr -= 4;
74
+++ b/target/arm/mve_helper.c
148
- }
75
@@ -XXX,XX +XXX,XX @@ DO_1OP(vnegw, 4, int32_t, DO_NEG)
149
- queue_signal(env, info.si_signo,
76
DO_1OP(vfnegh, 8, uint64_t, DO_FNEGH)
150
- QEMU_SI_FAULT, &info);
77
DO_1OP(vfnegs, 8, uint64_t, DO_FNEGS)
151
+ info._sifields._sigfault._addr -= 4;
78
152
}
79
+/*
153
- break;
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
154
- }
81
+ * All these insns work at 64-bit widths.
155
- } else {
82
+ */
156
- ret = do_syscall(env,
83
+#define DO_1OP_IMM(OP, FN) \
157
- n,
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
158
- env->regs[0],
85
+ { \
159
- env->regs[1],
86
+ uint64_t *da = vda; \
160
- env->regs[2],
87
+ uint16_t mask = mve_element_mask(env); \
161
- env->regs[3],
88
+ unsigned e; \
162
- env->regs[4],
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
163
- env->regs[5],
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
164
- 0, 0);
91
+ } \
165
- if (ret == -TARGET_ERESTARTSYS) {
92
+ mve_advance_vpt(env); \
166
- env->regs[15] -= env->thumb ? 2 : 4;
93
+ }
167
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
94
+
168
- env->regs[0] = ret;
95
+#define DO_MOVI(N, I) (I)
169
+ queue_signal(env, info.si_signo,
96
+#define DO_ANDI(N, I) ((N) & (I))
170
+ QEMU_SI_FAULT, &info);
97
+#define DO_ORRI(N, I) ((N) | (I))
171
}
98
+
172
+ break;
99
+DO_1OP_IMM(vmovi, DO_MOVI)
173
}
100
+DO_1OP_IMM(vandi, DO_ANDI)
174
} else {
101
+DO_1OP_IMM(vorri, DO_ORRI)
175
- goto error;
102
+
176
+ ret = do_syscall(env,
103
#define DO_2OP(OP, ESIZE, TYPE, FN) \
177
+ n,
104
void HELPER(glue(mve_, OP))(CPUARMState *env, \
178
+ env->regs[0],
105
void *vd, void *vn, void *vm) \
179
+ env->regs[1],
106
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
180
+ env->regs[2],
107
index XXXXXXX..XXXXXXX 100644
181
+ env->regs[3],
108
--- a/target/arm/translate-mve.c
182
+ env->regs[4],
109
+++ b/target/arm/translate-mve.c
183
+ env->regs[5],
110
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
184
+ 0, 0);
111
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
185
+ if (ret == -TARGET_ERESTARTSYS) {
112
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
186
+ env->regs[15] -= env->thumb ? 2 : 4;
113
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
187
+ } else if (ret != -TARGET_QEMU_ESIGRETURN) {
114
+typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
188
+ env->regs[0] = ret;
115
189
+ }
116
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
190
}
117
static inline long mve_qreg_offset(unsigned reg)
191
}
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
192
break;
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;
144
+}
145
+
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
147
+{
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
149
+ MVEGenOneOpImmFn *fn;
150
+
151
+ if ((a->cmode & 1) && a->cmode < 12) {
152
+ if (a->op) {
153
+ /*
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
155
+ * so the VBIC becomes a logical AND operation.
156
+ */
157
+ fn = gen_helper_mve_vandi;
158
+ } else {
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;
168
+ }
169
+ return do_1imm(s, a, fn);
170
+}
193
--
171
--
194
2.20.1
172
2.20.1
195
173
196
174
diff view generated by jsdifflib
1
We incorrectly treat SVC 0xf0002 as a cacheflush request (which is a
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
2
NOP for QEMU). This is the wrong syscall number, because in the
2
and VQSHLU.
3
svc-immediate OABI syscall numbers are all offset by the
3
4
ARM_SYSCALL_BASE value and so the correct insn is SVC 0x9f0002.
4
The size-and-immediate encoding here is the same as Neon, and we
5
(This is handled further down in the code with the other Arm-specific
5
handle it the same way neon-dp.decode does.
6
syscalls like NR_breakpoint.)
7
8
When this code was initially added in commit 6f1f31c069b20611 in
9
2004, ARM_NR_cacheflush was defined as (ARM_SYSCALL_BASE + 0xf0000 + 2)
10
so the value in the comparison took account of the extra 0x900000
11
offset. In commit fbb4a2e371f2fa7 in 2008, the ARM_SYSCALL_BASE
12
was removed from the definition of ARM_NR_cacheflush and handling
13
for this group of syscalls was added below the point where we subtract
14
ARM_SYSCALL_BASE from the SVC immediate value. However that commit
15
forgot to remove the now-obsolete earlier handling code.
16
17
Remove the spurious ARM_NR_cacheflush condition.
18
6
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
22
Message-id: 20200420212206.12776-3-peter.maydell@linaro.org
23
---
10
---
24
linux-user/arm/cpu_loop.c | 4 +---
11
target/arm/helper-mve.h | 16 +++++++++++
25
1 file changed, 1 insertion(+), 3 deletions(-)
12
target/arm/mve.decode | 23 +++++++++++++++
26
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
27
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
28
index XXXXXXX..XXXXXXX 100644
15
4 files changed, 147 insertions(+)
29
--- a/linux-user/arm/cpu_loop.c
16
30
+++ b/linux-user/arm/cpu_loop.c
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
31
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
18
index XXXXXXX..XXXXXXX 100644
32
n = insn & 0xffffff;
19
--- a/target/arm/helper-mve.h
33
}
20
+++ b/target/arm/helper-mve.h
34
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
35
- if (n == ARM_NR_cacheflush) {
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
36
- /* nop */
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
37
- } else if (n == 0 || n >= ARM_SYSCALL_BASE || env->thumb) {
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
38
+ if (n == 0 || n >= ARM_SYSCALL_BASE || env->thumb) {
25
+
39
/* linux syscall */
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
if (env->thumb || n == 0) {
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
n = env->regs[7];
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);
173
}
174
+
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
176
+ bool negateshift)
177
+{
178
+ TCGv_ptr qd, qm;
179
+ int shift = a->shift;
180
+
181
+ if (!dc_isar_feature(aa32_mve, s) ||
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
183
+ !fn) {
184
+ return false;
185
+ }
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
187
+ return true;
188
+ }
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;
206
+}
207
+
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
210
+ { \
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
212
+ gen_helper_mve_##FN##b, \
213
+ gen_helper_mve_##FN##h, \
214
+ gen_helper_mve_##FN##w, \
215
+ NULL, \
216
+ }; \
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
218
+ }
219
+
220
+DO_2SHIFT(VSHLI, vshli_u, false)
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
42
--
224
--
43
2.20.1
225
2.20.1
44
226
45
227
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
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
With this patch, the watchdog on i.MX31 emulations is fully operational.
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
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
7
Message-id: 20200517162135.110364-5-linux@roeck-us.net
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
include/hw/arm/fsl-imx31.h | 4 ++++
11
hw/arm/fsl-imx31.c | 6 ++++++
12
hw/arm/Kconfig | 1 +
13
3 files changed, 11 insertions(+)
14
15
diff --git a/include/hw/arm/fsl-imx31.h b/include/hw/arm/fsl-imx31.h
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/fsl-imx31.h
20
--- a/target/arm/helper-mve.h
18
+++ b/include/hw/arm/fsl-imx31.h
21
+++ b/target/arm/helper-mve.h
22
@@ -XXX,XX +XXX,XX @@ 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_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
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
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate.h
48
+++ b/target/arm/translate.h
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
50
return x * 2 + 1;
51
}
52
53
+static inline int rsub_64(DisasContext *s, int x)
54
+{
55
+ return 64 - x;
56
+}
57
+
58
+static inline int rsub_32(DisasContext *s, int x)
59
+{
60
+ return 32 - x;
61
+}
62
+
63
+static inline int rsub_16(DisasContext *s, int x)
64
+{
65
+ return 16 - x;
66
+}
67
+
68
+static inline int rsub_8(DisasContext *s, int x)
69
+{
70
+ return 8 - x;
71
+}
72
+
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
74
{
75
return (dc->features & (1ULL << feature)) != 0;
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/mve.decode
79
+++ b/target/arm/mve.decode
19
@@ -XXX,XX +XXX,XX @@
80
@@ -XXX,XX +XXX,XX @@
20
#include "hw/timer/imx_epit.h"
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
21
#include "hw/i2c/imx_i2c.h"
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
22
#include "hw/gpio/imx_gpio.h"
83
23
+#include "hw/watchdog/wdt_imx2.h"
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
24
#include "exec/memory.h"
85
+%rshift_i5 16:5 !function=rsub_32
25
#include "target/arm/cpu.h"
86
+%rshift_i4 16:4 !function=rsub_16
26
87
+%rshift_i3 16:3 !function=rsub_8
27
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX31State {
88
+
28
IMXEPITState epit[FSL_IMX31_NUM_EPITS];
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
29
IMXI2CState i2c[FSL_IMX31_NUM_I2CS];
90
+ size=0 shift=%rshift_i3
30
IMXGPIOState gpio[FSL_IMX31_NUM_GPIOS];
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
31
+ IMX2WdtState wdt;
92
+ size=1 shift=%rshift_i4
32
MemoryRegion secure_rom;
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
33
MemoryRegion rom;
94
+ size=2 shift=%rshift_i5
34
MemoryRegion iram;
95
+
35
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX31State {
96
# Vector loads and stores
36
#define FSL_IMX31_GPIO1_SIZE 0x4000
97
37
#define FSL_IMX31_GPIO2_ADDR 0x53FD0000
98
# Widening loads and narrowing stores:
38
#define FSL_IMX31_GPIO2_SIZE 0x4000
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
39
+#define FSL_IMX31_WDT_ADDR 0x53FDC000
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
40
+#define FSL_IMX31_WDT_SIZE 0x4000
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
41
#define FSL_IMX31_AVIC_ADDR 0x68000000
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
42
#define FSL_IMX31_AVIC_SIZE 0x100
103
+
43
#define FSL_IMX31_SDRAM0_ADDR 0x80000000
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
44
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
105
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
106
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
107
+
108
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
109
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
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
45
index XXXXXXX..XXXXXXX 100644
120
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/fsl-imx31.c
121
--- a/target/arm/mve_helper.c
47
+++ b/hw/arm/fsl-imx31.c
122
+++ b/target/arm/mve_helper.c
48
@@ -XXX,XX +XXX,XX @@ static void fsl_imx31_init(Object *obj)
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
49
sysbus_init_child_obj(obj, "gpio[*]", &s->gpio[i], sizeof(s->gpio[i]),
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
50
TYPE_IMX_GPIO);
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
51
}
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
52
+
127
+#define DO_2SHIFT_S(OP, FN) \
53
+ sysbus_init_child_obj(obj, "wdt", &s->wdt, sizeof(s->wdt), TYPE_IMX2_WDT);
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;
54
}
163
}
55
164
56
static void fsl_imx31_realize(DeviceState *dev, Error **errp)
165
-static inline int rsub_64(DisasContext *s, int x)
57
@@ -XXX,XX +XXX,XX @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
166
-{
58
gpio_table[i].irq));
167
- return 64 - x;
59
}
168
-}
60
169
-
61
+ /* Watchdog */
170
-static inline int rsub_32(DisasContext *s, int x)
62
+ object_property_set_bool(OBJECT(&s->wdt), true, "realized", &error_abort);
171
-{
63
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt), 0, FSL_IMX31_WDT_ADDR);
172
- return 32 - x;
64
+
173
-}
65
/* On a real system, the first 16k is a `secure boot rom' */
174
-static inline int rsub_16(DisasContext *s, int x)
66
memory_region_init_rom(&s->secure_rom, OBJECT(dev), "imx31.secure_rom",
175
-{
67
FSL_IMX31_SECURE_ROM_SIZE, &err);
176
- return 16 - x;
68
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
177
-}
69
index XXXXXXX..XXXXXXX 100644
178
-static inline int rsub_8(DisasContext *s, int x)
70
--- a/hw/arm/Kconfig
179
-{
71
+++ b/hw/arm/Kconfig
180
- return 8 - x;
72
@@ -XXX,XX +XXX,XX @@ config FSL_IMX31
181
-}
73
select SERIAL
182
-
74
select IMX
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
75
select IMX_I2C
184
{
76
+ select WDT_IMX2
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
77
select LAN9118
78
79
config FSL_IMX6
80
--
186
--
81
2.20.1
187
2.20.1
82
188
83
189
diff view generated by jsdifflib
1
Provide a minimal documentation of the Musca boards.
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
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Message-id: 20210628135835.6690-10-peter.maydell@linaro.org
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20200507151819.28444-6-peter.maydell@linaro.org
8
---
9
---
9
docs/system/arm/musca.rst | 31 +++++++++++++++++++++++++++++++
10
target/arm/helper-mve.h | 9 +++++++
10
docs/system/target-arm.rst | 1 +
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
11
MAINTAINERS | 1 +
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
12
3 files changed, 33 insertions(+)
13
target/arm/translate-mve.c | 15 +++++++++++
13
create mode 100644 docs/system/arm/musca.rst
14
4 files changed, 105 insertions(+), 4 deletions(-)
14
15
15
diff --git a/docs/system/arm/musca.rst b/docs/system/arm/musca.rst
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
new file mode 100644
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX
18
--- a/target/arm/helper-mve.h
18
--- /dev/null
19
+++ b/target/arm/helper-mve.h
19
+++ b/docs/system/arm/musca.rst
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
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
20
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
21
+Arm Musca boards (``musca-a``, ``musca-b1``)
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
22
+============================================
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
23
+
48
+
24
+The Arm Musca development boards are a reference implementation
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
25
+of a system using the SSE-200 Subsystem for Embedded. They are
50
%rshift_i5 16:5 !function=rsub_32
26
+dual Cortex-M33 systems.
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
60
+{
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
67
+}
27
+
68
+
28
+QEMU provides models of the A and B1 variants of this board.
69
+{
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
29
+
72
+
30
+Unimplemented devices:
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
74
+}
31
+
75
+
32
+- SPI
76
+{
33
+- |I2C|
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
34
+- |I2S|
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
35
+- PWM
36
+- QSPI
37
+- Timer
38
+- SCC
39
+- GPIO
40
+- eFlash
41
+- MHU
42
+- PVT
43
+- SDIO
44
+- CryptoCell
45
+
79
+
46
+Note that (like the real hardware) the Musca-A machine is
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
47
+asymmetric: CPU 0 does not have the FPU or DSP extensions,
81
+}
48
+but CPU 1 does. Also like the real hardware, the memory maps
49
+for the A and B1 variants differ significantly, so guest
50
+software must be built for the right variant.
51
+
82
+
52
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
83
+{
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
86
+
87
+ VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
88
+}
89
90
VMAX_S 111 0 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
91
VMAX_U 111 1 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
92
@@ -XXX,XX +XXX,XX @@ VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
93
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
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
96
+
97
+# VSHLL T1 encoding; the T2 VSHLL encoding is elsewhere in this file
98
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
99
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
100
+
101
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
102
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
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
53
index XXXXXXX..XXXXXXX 100644
110
index XXXXXXX..XXXXXXX 100644
54
--- a/docs/system/target-arm.rst
111
--- a/target/arm/mve_helper.c
55
+++ b/docs/system/target-arm.rst
112
+++ b/target/arm/mve_helper.c
56
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
57
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
58
arm/integratorcp
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
59
arm/mps2
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
60
+ arm/musca
117
+
61
arm/realview
118
+/*
62
arm/versatile
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
63
arm/vexpress
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
64
diff --git a/MAINTAINERS b/MAINTAINERS
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); \
139
+ }
140
+
141
+#define DO_VSHLL_ALL(OP, TOP) \
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
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
65
index XXXXXXX..XXXXXXX 100644
150
index XXXXXXX..XXXXXXX 100644
66
--- a/MAINTAINERS
151
--- a/target/arm/translate-mve.c
67
+++ b/MAINTAINERS
152
+++ b/target/arm/translate-mve.c
68
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
153
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_S, vshli_s, true)
69
L: qemu-arm@nongnu.org
154
DO_2SHIFT(VSHRI_U, vshli_u, true)
70
S: Maintained
155
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
71
F: hw/arm/musca.c
156
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
72
+F: docs/system/arm/musca.rst
157
+
73
158
+#define DO_VSHLL(INSN, FN) \
74
Musicpal
159
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
75
M: Jan Kiszka <jan.kiszka@web.de>
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)
76
--
172
--
77
2.20.1
173
2.20.1
78
174
79
175
diff view generated by jsdifflib
1
The kernel has different handling for syscalls with invalid
1
Implement the MVE VSRI and VSLI insns, which perform a
2
numbers that are in the "arm-specific" range 0x9f0000 and up:
2
shift-and-insert operation.
3
* 0x9f0000..0x9f07ff return -ENOSYS if not implemented
4
* other out of range syscalls cause a SIGILL
5
(see the kernel's arch/arm/kernel/traps.c:arm_syscall())
6
7
Implement this distinction. (Note that our code doesn't look
8
quite like the kernel's, because we have removed the
9
0x900000 prefix by this point, whereas the kernel retains
10
it in arm_syscall().)
11
3
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200420212206.12776-4-peter.maydell@linaro.org
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
15
---
7
---
16
linux-user/arm/cpu_loop.c | 30 ++++++++++++++++++++++++++----
8
target/arm/helper-mve.h | 8 ++++++++
17
1 file changed, 26 insertions(+), 4 deletions(-)
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(+)
18
13
19
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/linux-user/arm/cpu_loop.c
16
--- a/target/arm/helper-mve.h
22
+++ b/linux-user/arm/cpu_loop.c
17
+++ b/target/arm/helper-mve.h
23
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
env->regs[0] = cpu_get_tls(env);
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
break;
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
default:
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
- qemu_log_mask(LOG_UNIMP,
22
+
28
- "qemu: Unsupported ARM syscall: 0x%x\n",
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
- n);
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
- env->regs[0] = -TARGET_ENOSYS;
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+ if (n < 0xf0800) {
26
+
32
+ /*
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+ * Syscalls 0xf0000..0xf07ff (or 0x9f0000..
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+ * 0x9f07ff in OABI numbering) are defined
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+ * to return -ENOSYS rather than raising
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
36
+ * SIGILL. Note that we have already
31
index XXXXXXX..XXXXXXX 100644
37
+ * removed the 0x900000 prefix.
32
--- a/target/arm/mve.decode
38
+ */
33
+++ b/target/arm/mve.decode
39
+ qemu_log_mask(LOG_UNIMP,
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
40
+ "qemu: Unsupported ARM syscall: 0x%x\n",
35
41
+ n);
36
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
42
+ env->regs[0] = -TARGET_ENOSYS;
37
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
43
+ } else {
38
+
44
+ /* Otherwise SIGILL */
39
+# Shift-and-insert
45
+ info.si_signo = TARGET_SIGILL;
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
46
+ info.si_errno = 0;
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
47
+ info.si_code = TARGET_ILL_ILLTRP;
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
48
+ info._sifields._sigfault._addr = env->regs[15];
43
+
49
+ if (env->thumb) {
44
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
50
+ info._sifields._sigfault._addr -= 2;
45
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
51
+ } else {
46
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
52
+ info._sifields._sigfault._addr -= 4;
47
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
53
+ }
48
index XXXXXXX..XXXXXXX 100644
54
+ queue_signal(env, info.si_signo,
49
--- a/target/arm/mve_helper.c
55
+ QEMU_SI_FAULT, &info);
50
+++ b/target/arm/mve_helper.c
56
+ }
51
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
57
break;
52
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
58
}
53
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
59
} else {
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)
96
+
97
/*
98
* Long shifts taking half-sized inputs from top or bottom of the input
99
* vector and producing a double-width result. ESIZE, TYPE are for
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_U, vshli_u, true)
105
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
106
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
107
108
+DO_2SHIFT(VSRI, vsri, false)
109
+DO_2SHIFT(VSLI, vsli, false)
110
+
111
#define DO_VSHLL(INSN, FN) \
112
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
113
{ \
60
--
114
--
61
2.20.1
115
2.20.1
62
116
63
117
diff view generated by jsdifflib
1
Provide a minimal documentation of the Versatile Express boards
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
2
(vexpress-a9, vexpress-a15).
2
3
do_urshr() is borrowed from sve_helper.c.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20200507151819.28444-4-peter.maydell@linaro.org
9
---
8
---
10
docs/system/arm/vexpress.rst | 60 ++++++++++++++++++++++++++++++++++++
9
target/arm/helper-mve.h | 10 ++++++++++
11
docs/system/target-arm.rst | 1 +
10
target/arm/mve.decode | 11 +++++++++++
12
MAINTAINERS | 1 +
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
13
3 files changed, 62 insertions(+)
12
target/arm/translate-mve.c | 15 ++++++++++++++
14
create mode 100644 docs/system/arm/vexpress.rst
13
4 files changed, 76 insertions(+)
15
14
16
diff --git a/docs/system/arm/vexpress.rst b/docs/system/arm/vexpress.rst
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
17
new file mode 100644
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX
17
--- a/target/arm/helper-mve.h
19
--- /dev/null
18
+++ b/target/arm/helper-mve.h
20
+++ b/docs/system/arm/vexpress.rst
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
@@ -XXX,XX +XXX,XX @@
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
+Arm Versatile Express boards (``vexpress-a9``, ``vexpress-a15``)
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
+================================================================
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+
23
+
25
+QEMU models two variants of the Arm Versatile Express development
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+board family:
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+
28
+
28
+- ``vexpress-a9`` models the combination of the Versatile Express
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+ motherboard and the CoreTile Express A9x4 daughterboard
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+- ``vexpress-a15`` models the combination of the Versatile Express
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+ motherboard and the CoreTile Express A15x2 daughterboard
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
32
+
41
+
33
+Note that as this hardware does not have PCI, IDE or SCSI,
42
+# Narrowing shifts (which only support b and h sizes)
34
+the only available storage option is emulated SD card.
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
35
+
47
+
36
+Implemented devices:
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)
37
+
60
+
38
+- PL041 audio
61
+/*
39
+- PL181 SD controller
62
+ * Narrowing right shifts, taking a double sized input, shifting it
40
+- PL050 keyboard and mouse
63
+ * and putting the result in either the top or bottom half of the output.
41
+- PL011 UARTs
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
42
+- SP804 timers
65
+ */
43
+- I2C controller
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
44
+- PL031 RTC
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
45
+- PL111 LCD display controller
68
+ void *vm, uint32_t shift) \
46
+- Flash memory
69
+ { \
47
+- LAN9118 ethernet
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); \
79
+ }
48
+
80
+
49
+Unimplemented devices:
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)
50
+
86
+
51
+- SP810 system control block
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
52
+- PCI-express
88
+{
53
+- USB controller (Philips ISP1761)
89
+ if (likely(sh < 64)) {
54
+- Local DAP ROM
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
55
+- CoreSight interfaces
91
+ } else if (sh == 64) {
56
+- PL301 AXI interconnect
92
+ return x >> 63;
57
+- SCC
93
+ } else {
58
+- System counter
94
+ return 0;
59
+- HDLCD controller (``vexpress-a15``)
95
+ }
60
+- SP805 watchdog
96
+}
61
+- PL341 dynamic memory controller
62
+- DMA330 DMA controller
63
+- PL354 static memory controller
64
+- BP147 TrustZone Protection Controller
65
+- TrustZone Address Space Controller
66
+
97
+
67
+Other differences between the hardware and the QEMU model:
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
101
index XXXXXXX..XXXXXXX 100644
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)
68
+
108
+
69
+- QEMU will default to creating one CPU unless you pass a different
109
+#define DO_2SHIFT_N(INSN, FN) \
70
+ ``-smp`` argument
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
71
+- QEMU allows the amount of RAM provided to be specified with the
111
+ { \
72
+ ``-m`` argument
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
73
+- QEMU defaults to providing a CPU which does not provide either
113
+ gen_helper_mve_##FN##b, \
74
+ TrustZone or the Virtualization Extensions: if you want these you
114
+ gen_helper_mve_##FN##h, \
75
+ must enable them with ``-machine secure=on`` and ``-machine
115
+ }; \
76
+ virtualization=on``
116
+ return do_2shift(s, a, fns[a->size], false); \
77
+- QEMU provides 4 virtio-mmio virtio transports; these start at
117
+ }
78
+ address ``0x10013000`` for ``vexpress-a9`` and at ``0x1c130000`` for
118
+
79
+ ``vexpress-a15``, and have IRQs from 40 upwards. If a dtb is
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
80
+ provided on the command line then QEMU will edit it to include
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
81
+ suitable entries describing these transports for the guest.
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
82
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
83
index XXXXXXX..XXXXXXX 100644
84
--- a/docs/system/target-arm.rst
85
+++ b/docs/system/target-arm.rst
86
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
87
arm/integratorcp
88
arm/realview
89
arm/versatile
90
+ arm/vexpress
91
arm/musicpal
92
arm/nseries
93
arm/orangepi
94
diff --git a/MAINTAINERS b/MAINTAINERS
95
index XXXXXXX..XXXXXXX 100644
96
--- a/MAINTAINERS
97
+++ b/MAINTAINERS
98
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
99
L: qemu-arm@nongnu.org
100
S: Maintained
101
F: hw/arm/vexpress.c
102
+F: docs/system/arm/vexpress.rst
103
104
Versatile PB
105
M: Peter Maydell <peter.maydell@linaro.org>
106
--
123
--
107
2.20.1
124
2.20.1
108
125
109
126
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
Implement the MVE saturating shift-right-and-narrow insns
2
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
Implement full support for the watchdog in i.MX systems.
3
4
Pretimeout support is optional because the watchdog hardware
4
do_srshr() is borrowed from sve_helper.c.
5
on i.MX31 does not support pretimeouts.
5
6
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20200517162135.110364-3-linux@roeck-us.net
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-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
11
---
9
---
12
include/hw/watchdog/wdt_imx2.h | 61 ++++++++-
10
target/arm/helper-mve.h | 30 +++++++++++
13
hw/watchdog/wdt_imx2.c | 239 +++++++++++++++++++++++++++++++--
11
target/arm/mve.decode | 28 ++++++++++
14
2 files changed, 285 insertions(+), 15 deletions(-)
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
15
13
target/arm/translate-mve.c | 12 +++++
16
diff --git a/include/hw/watchdog/wdt_imx2.h b/include/hw/watchdog/wdt_imx2.h
14
4 files changed, 174 insertions(+)
17
index XXXXXXX..XXXXXXX 100644
15
18
--- a/include/hw/watchdog/wdt_imx2.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
19
+++ b/include/hw/watchdog/wdt_imx2.h
17
index XXXXXXX..XXXXXXX 100644
20
@@ -XXX,XX +XXX,XX @@
18
--- a/target/arm/helper-mve.h
21
#ifndef IMX2_WDT_H
19
+++ b/target/arm/helper-mve.h
22
#define IMX2_WDT_H
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+#include "qemu/bitops.h"
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
#include "hw/sysbus.h"
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+#include "hw/irq.h"
24
+
27
+#include "hw/ptimer.h"
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
#define TYPE_IMX2_WDT "imx2.wdt"
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
#define IMX2_WDT(obj) OBJECT_CHECK(IMX2WdtState, (obj), TYPE_IMX2_WDT)
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
29
+
32
enum IMX2WdtRegisters {
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
- IMX2_WDT_WCR = 0x0000,
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
- IMX2_WDT_REG_NUM = 0x0008 / sizeof(uint16_t) + 1,
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+ IMX2_WDT_WCR = 0x0000, /* Control Register */
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+ IMX2_WDT_WSR = 0x0002, /* Service Register */
34
+
37
+ IMX2_WDT_WRSR = 0x0004, /* Reset Status Register */
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
+ IMX2_WDT_WICR = 0x0006, /* Interrupt Control Register */
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+ IMX2_WDT_WMCR = 0x0008, /* Misc Register */
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
};
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
39
+
42
+#define IMX2_WDT_MMIO_SIZE 0x000a
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+/* Control Register definitions */
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
+#define IMX2_WDT_WCR_WT (0xFF << 8) /* Watchdog Timeout Field */
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+#define IMX2_WDT_WCR_WDW BIT(7) /* WDOG Disable for Wait */
44
+
47
+#define IMX2_WDT_WCR_WDA BIT(5) /* WDOG Assertion */
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
+#define IMX2_WDT_WCR_SRS BIT(4) /* Software Reset Signal */
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
+#define IMX2_WDT_WCR_WDT BIT(3) /* WDOG Timeout Assertion */
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
+#define IMX2_WDT_WCR_WDE BIT(2) /* Watchdog Enable */
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
+#define IMX2_WDT_WCR_WDBG BIT(1) /* Watchdog Debug Enable */
49
+
52
+#define IMX2_WDT_WCR_WDZST BIT(0) /* Watchdog Timer Suspend */
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
+
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
54
+#define IMX2_WDT_WCR_LOCK_MASK (IMX2_WDT_WCR_WDZST | IMX2_WDT_WCR_WDBG \
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
55
+ | IMX2_WDT_WCR_WDW)
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
56
+
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
57
+/* Service Register definitions */
55
index XXXXXXX..XXXXXXX 100644
58
+#define IMX2_WDT_SEQ1 0x5555 /* service sequence 1 */
56
--- a/target/arm/mve.decode
59
+#define IMX2_WDT_SEQ2 0xAAAA /* service sequence 2 */
57
+++ b/target/arm/mve.decode
60
+
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
61
+/* Reset Status Register definitions */
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
62
+#define IMX2_WDT_WRSR_TOUT BIT(1) /* Reset due to Timeout */
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
63
+#define IMX2_WDT_WRSR_SFTW BIT(0) /* Reset due to software reset */
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
64
+
62
+
65
+/* Interrupt Control Register definitions */
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
66
+#define IMX2_WDT_WICR_WIE BIT(15) /* Interrupt Enable */
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
67
+#define IMX2_WDT_WICR_WTIS BIT(14) /* Interrupt Status */
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
68
+#define IMX2_WDT_WICR_WICT 0xff /* Interrupt Timeout */
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
69
+#define IMX2_WDT_WICR_WICT_DEF 0x04 /* Default interrupt timeout (2s) */
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
70
+
68
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
71
+#define IMX2_WDT_WICR_LOCK_MASK (IMX2_WDT_WICR_WIE | IMX2_WDT_WICR_WICT)
69
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
72
+
70
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
73
+/* Misc Control Register definitions */
71
+
74
+#define IMX2_WDT_WMCR_PDE BIT(0) /* Power-Down Enable */
72
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
75
73
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
76
typedef struct IMX2WdtState {
74
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
77
/* <private> */
75
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
78
SysBusDevice parent_obj;
76
+
79
77
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
80
+ /*< public >*/
78
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
81
MemoryRegion mmio;
79
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
82
+ qemu_irq irq;
80
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
83
+
81
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
84
+ struct ptimer_state *timer;
82
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
85
+ struct ptimer_state *itimer;
83
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
86
+
84
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
87
+ bool pretimeout_support;
85
+
88
+ bool wicr_locked;
86
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
89
+
87
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
90
+ uint16_t wcr;
88
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
91
+ uint16_t wsr;
89
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
92
+ uint16_t wrsr;
90
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
93
+ uint16_t wicr;
91
index XXXXXXX..XXXXXXX 100644
94
+ uint16_t wmcr;
92
--- a/target/arm/mve_helper.c
95
+
93
+++ b/target/arm/mve_helper.c
96
+ bool wcr_locked; /* affects WDZST, WDBG, and WDW */
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
97
+ bool wcr_wde_locked; /* affects WDE */
95
}
98
+ bool wcr_wdt_locked; /* affects WDT (never cleared) */
96
}
99
} IMX2WdtState;
97
100
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
101
#endif /* IMX2_WDT_H */
102
diff --git a/hw/watchdog/wdt_imx2.c b/hw/watchdog/wdt_imx2.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/hw/watchdog/wdt_imx2.c
105
+++ b/hw/watchdog/wdt_imx2.c
106
@@ -XXX,XX +XXX,XX @@
107
#include "qemu/bitops.h"
108
#include "qemu/module.h"
109
#include "sysemu/watchdog.h"
110
+#include "migration/vmstate.h"
111
+#include "hw/qdev-properties.h"
112
113
#include "hw/watchdog/wdt_imx2.h"
114
115
-#define IMX2_WDT_WCR_WDA BIT(5) /* -> External Reset WDOG_B */
116
-#define IMX2_WDT_WCR_SRS BIT(4) /* -> Software Reset Signal */
117
-
118
-static uint64_t imx2_wdt_read(void *opaque, hwaddr addr,
119
- unsigned int size)
120
+static void imx2_wdt_interrupt(void *opaque)
121
{
122
+ IMX2WdtState *s = IMX2_WDT(opaque);
123
+
124
+ s->wicr |= IMX2_WDT_WICR_WTIS;
125
+ qemu_set_irq(s->irq, 1);
126
+}
127
+
128
+static void imx2_wdt_expired(void *opaque)
129
+{
99
+{
130
+ IMX2WdtState *s = IMX2_WDT(opaque);
100
+ if (likely(sh < 64)) {
131
+
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
132
+ s->wrsr = IMX2_WDT_WRSR_TOUT;
102
+ } else {
133
+
103
+ /* Rounding the sign bit always produces 0. */
134
+ /* Perform watchdog action if watchdog is enabled */
104
+ return 0;
135
+ if (s->wcr & IMX2_WDT_WCR_WDE) {
136
+ s->wrsr = IMX2_WDT_WRSR_TOUT;
137
+ watchdog_perform_action();
138
+ }
105
+ }
139
+}
106
+}
140
+
107
+
141
+static void imx2_wdt_reset(DeviceState *dev)
108
DO_VSHRN_ALL(vshrn, DO_SHR)
109
DO_VSHRN_ALL(vrshrn, do_urshr)
110
+
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
112
+ bool *satp)
142
+{
113
+{
143
+ IMX2WdtState *s = IMX2_WDT(dev);
114
+ if (val > max) {
144
+
115
+ *satp = true;
145
+ ptimer_transaction_begin(s->timer);
116
+ return max;
146
+ ptimer_stop(s->timer);
117
+ } else if (val < min) {
147
+ ptimer_transaction_commit(s->timer);
118
+ *satp = true;
148
+
119
+ return min;
149
+ if (s->pretimeout_support) {
120
+ } else {
150
+ ptimer_transaction_begin(s->itimer);
121
+ return val;
151
+ ptimer_stop(s->itimer);
152
+ ptimer_transaction_commit(s->itimer);
153
+ }
154
+
155
+ s->wicr_locked = false;
156
+ s->wcr_locked = false;
157
+ s->wcr_wde_locked = false;
158
+
159
+ s->wcr = IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS;
160
+ s->wsr = 0;
161
+ s->wrsr &= ~(IMX2_WDT_WRSR_TOUT | IMX2_WDT_WRSR_SFTW);
162
+ s->wicr = IMX2_WDT_WICR_WICT_DEF;
163
+ s->wmcr = IMX2_WDT_WMCR_PDE;
164
+}
165
+
166
+static uint64_t imx2_wdt_read(void *opaque, hwaddr addr, unsigned int size)
167
+{
168
+ IMX2WdtState *s = IMX2_WDT(opaque);
169
+
170
+ switch (addr) {
171
+ case IMX2_WDT_WCR:
172
+ return s->wcr;
173
+ case IMX2_WDT_WSR:
174
+ return s->wsr;
175
+ case IMX2_WDT_WRSR:
176
+ return s->wrsr;
177
+ case IMX2_WDT_WICR:
178
+ return s->wicr;
179
+ case IMX2_WDT_WMCR:
180
+ return s->wmcr;
181
+ }
182
return 0;
183
}
184
185
+static void imx_wdt2_update_itimer(IMX2WdtState *s, bool start)
186
+{
187
+ bool running = (s->wcr & IMX2_WDT_WCR_WDE) && (s->wcr & IMX2_WDT_WCR_WT);
188
+ bool enabled = s->wicr & IMX2_WDT_WICR_WIE;
189
+
190
+ ptimer_transaction_begin(s->itimer);
191
+ if (start || !enabled) {
192
+ ptimer_stop(s->itimer);
193
+ }
194
+ if (running && enabled) {
195
+ int count = ptimer_get_count(s->timer);
196
+ int pretimeout = s->wicr & IMX2_WDT_WICR_WICT;
197
+
198
+ /*
199
+ * Only (re-)start pretimeout timer if its counter value is larger
200
+ * than 0. Otherwise it will fire right away and we'll get an
201
+ * interrupt loop.
202
+ */
203
+ if (count > pretimeout) {
204
+ ptimer_set_count(s->itimer, count - pretimeout);
205
+ if (start) {
206
+ ptimer_run(s->itimer, 1);
207
+ }
208
+ }
209
+ }
210
+ ptimer_transaction_commit(s->itimer);
211
+}
212
+
213
+static void imx_wdt2_update_timer(IMX2WdtState *s, bool start)
214
+{
215
+ ptimer_transaction_begin(s->timer);
216
+ if (start) {
217
+ ptimer_stop(s->timer);
218
+ }
219
+ if ((s->wcr & IMX2_WDT_WCR_WDE) && (s->wcr & IMX2_WDT_WCR_WT)) {
220
+ int count = (s->wcr & IMX2_WDT_WCR_WT) >> 8;
221
+
222
+ /* A value of 0 reflects one period (0.5s). */
223
+ ptimer_set_count(s->timer, count + 1);
224
+ if (start) {
225
+ ptimer_run(s->timer, 1);
226
+ }
227
+ }
228
+ ptimer_transaction_commit(s->timer);
229
+ if (s->pretimeout_support) {
230
+ imx_wdt2_update_itimer(s, start);
231
+ }
122
+ }
232
+}
123
+}
233
+
124
+
234
static void imx2_wdt_write(void *opaque, hwaddr addr,
125
+/* Saturating narrowing right shifts */
235
uint64_t value, unsigned int size)
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
236
{
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
237
- if (addr == IMX2_WDT_WCR &&
128
+ void *vm, uint32_t shift) \
238
- (~value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) {
129
+ { \
239
- watchdog_perform_action();
130
+ LTYPE *m = vm; \
240
+ IMX2WdtState *s = IMX2_WDT(opaque);
131
+ TYPE *d = vd; \
241
+
132
+ uint16_t mask = mve_element_mask(env); \
242
+ switch (addr) {
133
+ bool qc = false; \
243
+ case IMX2_WDT_WCR:
134
+ unsigned le; \
244
+ if (s->wcr_locked) {
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
245
+ value &= ~IMX2_WDT_WCR_LOCK_MASK;
136
+ bool sat = false; \
246
+ value |= (s->wicr & IMX2_WDT_WCR_LOCK_MASK);
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
247
+ }
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
248
+ s->wcr_locked = true;
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
249
+ if (s->wcr_wde_locked) {
140
+ } \
250
+ value &= ~IMX2_WDT_WCR_WDE;
141
+ if (qc) { \
251
+ value |= (s->wicr & ~IMX2_WDT_WCR_WDE);
142
+ env->vfp.qc[0] = qc; \
252
+ } else if (value & IMX2_WDT_WCR_WDE) {
143
+ } \
253
+ s->wcr_wde_locked = true;
144
+ mve_advance_vpt(env); \
254
+ }
255
+ if (s->wcr_wdt_locked) {
256
+ value &= ~IMX2_WDT_WCR_WDT;
257
+ value |= (s->wicr & ~IMX2_WDT_WCR_WDT);
258
+ } else if (value & IMX2_WDT_WCR_WDT) {
259
+ s->wcr_wdt_locked = true;
260
+ }
261
+
262
+ s->wcr = value;
263
+ if (!(value & IMX2_WDT_WCR_SRS)) {
264
+ s->wrsr = IMX2_WDT_WRSR_SFTW;
265
+ }
266
+ if (!(value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS)) ||
267
+ (!(value & IMX2_WDT_WCR_WT) && (value & IMX2_WDT_WCR_WDE))) {
268
+ watchdog_perform_action();
269
+ }
270
+ s->wcr |= IMX2_WDT_WCR_SRS;
271
+ imx_wdt2_update_timer(s, true);
272
+ break;
273
+ case IMX2_WDT_WSR:
274
+ if (s->wsr == IMX2_WDT_SEQ1 && value == IMX2_WDT_SEQ2) {
275
+ imx_wdt2_update_timer(s, false);
276
+ }
277
+ s->wsr = value;
278
+ break;
279
+ case IMX2_WDT_WRSR:
280
+ break;
281
+ case IMX2_WDT_WICR:
282
+ if (!s->pretimeout_support) {
283
+ return;
284
+ }
285
+ value &= IMX2_WDT_WICR_LOCK_MASK | IMX2_WDT_WICR_WTIS;
286
+ if (s->wicr_locked) {
287
+ value &= IMX2_WDT_WICR_WTIS;
288
+ value |= (s->wicr & IMX2_WDT_WICR_LOCK_MASK);
289
+ }
290
+ s->wicr = value | (s->wicr & IMX2_WDT_WICR_WTIS);
291
+ if (value & IMX2_WDT_WICR_WTIS) {
292
+ s->wicr &= ~IMX2_WDT_WICR_WTIS;
293
+ qemu_set_irq(s->irq, 0);
294
+ }
295
+ imx_wdt2_update_itimer(s, true);
296
+ s->wicr_locked = true;
297
+ break;
298
+ case IMX2_WDT_WMCR:
299
+ s->wmcr = value & IMX2_WDT_WMCR_PDE;
300
+ break;
301
}
302
}
303
304
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps imx2_wdt_ops = {
305
* real device but in practice there is no reason for a guest
306
* to access this device unaligned.
307
*/
308
- .min_access_size = 4,
309
- .max_access_size = 4,
310
+ .min_access_size = 2,
311
+ .max_access_size = 2,
312
.unaligned = false,
313
},
314
};
315
316
+static const VMStateDescription vmstate_imx2_wdt = {
317
+ .name = "imx2.wdt",
318
+ .fields = (VMStateField[]) {
319
+ VMSTATE_PTIMER(timer, IMX2WdtState),
320
+ VMSTATE_PTIMER(itimer, IMX2WdtState),
321
+ VMSTATE_BOOL(wicr_locked, IMX2WdtState),
322
+ VMSTATE_BOOL(wcr_locked, IMX2WdtState),
323
+ VMSTATE_BOOL(wcr_wde_locked, IMX2WdtState),
324
+ VMSTATE_BOOL(wcr_wdt_locked, IMX2WdtState),
325
+ VMSTATE_UINT16(wcr, IMX2WdtState),
326
+ VMSTATE_UINT16(wsr, IMX2WdtState),
327
+ VMSTATE_UINT16(wrsr, IMX2WdtState),
328
+ VMSTATE_UINT16(wmcr, IMX2WdtState),
329
+ VMSTATE_UINT16(wicr, IMX2WdtState),
330
+ VMSTATE_END_OF_LIST()
331
+ }
145
+ }
332
+};
146
+
333
+
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
334
static void imx2_wdt_realize(DeviceState *dev, Error **errp)
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
335
{
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
336
IMX2WdtState *s = IMX2_WDT(dev);
150
+
337
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
338
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
339
memory_region_init_io(&s->mmio, OBJECT(dev),
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
340
&imx2_wdt_ops, s,
154
+
341
- TYPE_IMX2_WDT".mmio",
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
342
- IMX2_WDT_REG_NUM * sizeof(uint16_t));
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
343
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
344
+ TYPE_IMX2_WDT,
158
+
345
+ IMX2_WDT_MMIO_SIZE);
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
346
+ sysbus_init_mmio(sbd, &s->mmio);
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
347
+ sysbus_init_irq(sbd, &s->irq);
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
348
+
162
+
349
+ s->timer = ptimer_init(imx2_wdt_expired, s,
163
+#define DO_SHRN_SB(N, M, SATP) \
350
+ PTIMER_POLICY_NO_IMMEDIATE_TRIGGER |
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
351
+ PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
165
+#define DO_SHRN_UB(N, M, SATP) \
352
+ PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
353
+ ptimer_transaction_begin(s->timer);
167
+#define DO_SHRUN_B(N, M, SATP) \
354
+ ptimer_set_freq(s->timer, 2);
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
355
+ ptimer_set_limit(s->timer, 0xff, 1);
169
+
356
+ ptimer_transaction_commit(s->timer);
170
+#define DO_SHRN_SH(N, M, SATP) \
357
+ if (s->pretimeout_support) {
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
358
+ s->itimer = ptimer_init(imx2_wdt_interrupt, s,
172
+#define DO_SHRN_UH(N, M, SATP) \
359
+ PTIMER_POLICY_NO_IMMEDIATE_TRIGGER |
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
360
+ PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
174
+#define DO_SHRUN_H(N, M, SATP) \
361
+ PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
362
+ ptimer_transaction_begin(s->itimer);
176
+
363
+ ptimer_set_freq(s->itimer, 2);
177
+#define DO_RSHRN_SB(N, M, SATP) \
364
+ ptimer_set_limit(s->itimer, 0xff, 1);
178
+ do_sat_bhs(do_srshr(N, M), INT8_MIN, INT8_MAX, SATP)
365
+ ptimer_transaction_commit(s->itimer);
179
+#define DO_RSHRN_UB(N, M, SATP) \
366
+ }
180
+ do_sat_bhs(do_urshr(N, M), 0, UINT8_MAX, SATP)
367
}
181
+#define DO_RSHRUN_B(N, M, SATP) \
368
182
+ do_sat_bhs(do_srshr(N, M), 0, UINT8_MAX, SATP)
369
+static Property imx2_wdt_properties[] = {
183
+
370
+ DEFINE_PROP_BOOL("pretimeout-support", IMX2WdtState, pretimeout_support,
184
+#define DO_RSHRN_SH(N, M, SATP) \
371
+ false),
185
+ do_sat_bhs(do_srshr(N, M), INT16_MIN, INT16_MAX, SATP)
372
+};
186
+#define DO_RSHRN_UH(N, M, SATP) \
373
+
187
+ do_sat_bhs(do_urshr(N, M), 0, UINT16_MAX, SATP)
374
static void imx2_wdt_class_init(ObjectClass *klass, void *data)
188
+#define DO_RSHRUN_H(N, M, SATP) \
375
{
189
+ do_sat_bhs(do_srshr(N, M), 0, UINT16_MAX, SATP)
376
DeviceClass *dc = DEVICE_CLASS(klass);
190
+
377
191
+DO_VSHRN_SAT_SB(vqshrnb_sb, vqshrnt_sb, DO_SHRN_SB)
378
+ device_class_set_props(dc, imx2_wdt_properties);
192
+DO_VSHRN_SAT_SH(vqshrnb_sh, vqshrnt_sh, DO_SHRN_SH)
379
dc->realize = imx2_wdt_realize;
193
+DO_VSHRN_SAT_UB(vqshrnb_ub, vqshrnt_ub, DO_SHRN_UB)
380
+ dc->reset = imx2_wdt_reset;
194
+DO_VSHRN_SAT_UH(vqshrnb_uh, vqshrnt_uh, DO_SHRN_UH)
381
+ dc->vmsd = &vmstate_imx2_wdt;
195
+DO_VSHRN_SAT_SB(vqshrunbb, vqshruntb, DO_SHRUN_B)
382
+ dc->desc = "i.MX watchdog timer";
196
+DO_VSHRN_SAT_SH(vqshrunbh, vqshrunth, DO_SHRUN_H)
383
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
197
+
384
}
198
+DO_VSHRN_SAT_SB(vqrshrnb_sb, vqrshrnt_sb, DO_RSHRN_SB)
385
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)
386
--
224
--
387
2.20.1
225
2.20.1
388
226
389
227
diff view generated by jsdifflib
1
The Arm signal-handling code has some parts ifdeffed with a
1
Implement the MVE VSHLC insn, which performs a shift left of the
2
TARGET_CONFIG_CPU_32, which is always defined. This is a leftover
2
entire vector with carry in bits provided from a general purpose
3
from when this code's structure was based on the Linux kernel
3
register and carry out bits written back to that register.
4
signal handling code, where it was intended to support 26-bit
5
Arm CPUs. The kernel dropped its CONFIG_CPU_32 in kernel commit
6
4da8b8208eded0ba21e3 in 2009.
7
8
QEMU has never had 26-bit CPU support and is unlikely to ever
9
add it; we certainly aren't going to support 26-bit Linux
10
binaries via linux-user mode. The ifdef is just unhelpful
11
noise, so remove it entirely.
12
4
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20200518143014.20689-1-peter.maydell@linaro.org
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
16
---
8
---
17
linux-user/arm/signal.c | 6 ------
9
target/arm/helper-mve.h | 2 ++
18
1 file changed, 6 deletions(-)
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(+)
19
14
20
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/linux-user/arm/signal.c
17
--- a/target/arm/helper-mve.h
23
+++ b/linux-user/arm/signal.c
18
+++ b/target/arm/helper-mve.h
24
@@ -XXX,XX +XXX,XX @@ struct rt_sigframe_v2
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
abi_ulong retcode[4];
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
};
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
-#define TARGET_CONFIG_CPU_32 1
23
+
29
-
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
30
/*
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
31
* For ARM syscalls, we encode the syscall number into the instruction.
26
index XXXXXXX..XXXXXXX 100644
32
*/
27
--- a/target/arm/mve.decode
33
@@ -XXX,XX +XXX,XX @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
28
+++ b/target/arm/mve.decode
34
__put_user(env->regs[13], &sc->arm_sp);
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
35
__put_user(env->regs[14], &sc->arm_lr);
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
36
__put_user(env->regs[15], &sc->arm_pc);
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
37
-#ifdef TARGET_CONFIG_CPU_32
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
38
__put_user(cpsr_read(env), &sc->arm_cpsr);
33
+
39
-#endif
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
40
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
41
__put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
36
index XXXXXXX..XXXXXXX 100644
42
__put_user(/* current->thread.error_code */ 0, &sc->error_code);
37
--- a/target/arm/mve_helper.c
43
@@ -XXX,XX +XXX,XX @@ restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
38
+++ b/target/arm/mve_helper.c
44
__get_user(env->regs[13], &sc->arm_sp);
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
45
__get_user(env->regs[14], &sc->arm_lr);
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
46
__get_user(env->regs[15], &sc->arm_pc);
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
47
-#ifdef TARGET_CONFIG_CPU_32
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
48
__get_user(cpsr, &sc->arm_cpsr);
43
+
49
cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
50
arm_rebuild_hflags(env);
45
+ uint32_t shift)
51
-#endif
46
+{
52
47
+ uint32_t *d = vd;
53
err |= !valid_user_regs(env);
48
+ uint16_t mask = mve_element_mask(env);
54
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;
109
+ }
110
+
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;
118
+}
55
--
119
--
56
2.20.1
120
2.20.1
57
121
58
122
diff view generated by jsdifflib
1
Using the MSR instruction to write to CPSR.E is deprecated, but it is
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
2
required to work from any mode including unprivileged code. We were
2
that it accumulates 32-bit elements into a 64-bit accumulator
3
incorrectly forbidding usermode code from writing it because
3
stored in a pair of general-purpose registers.
4
CPSR_USER did not include the CPSR_E bit.
5
6
We use CPSR_USER in only three places:
7
* as the mask of what to allow userspace MSR to write to CPSR
8
* when deciding what bits a linux-user signal-return should be
9
able to write from the sigcontext structure
10
* in target_user_copy_regs() when we set up the initial
11
registers for the linux-user process
12
13
In the first two cases not being able to update CPSR.E is a bug, and
14
in the third case it doesn't matter because CPSR.E is always 0 there.
15
So we can fix both bugs by adding CPSR_E to CPSR_USER.
16
17
Because the cpsr_write() in restore_sigcontext() is now changing
18
a CPSR bit which is cached in hflags, we need to add an
19
arm_rebuild_hflags() call there; the callsite in
20
target_user_copy_regs() was already rebuilding hflags for other
21
reasons.
22
23
(The recommended way to change CPSR.E is to use the 'SETEND'
24
instruction, which we do correctly allow from usermode code.)
25
4
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
28
Message-id: 20200518142801.20503-1-peter.maydell@linaro.org
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
29
---
8
---
30
target/arm/cpu.h | 2 +-
9
target/arm/helper-mve.h | 3 ++
31
linux-user/arm/signal.c | 1 +
10
target/arm/mve.decode | 6 +++-
32
2 files changed, 2 insertions(+), 1 deletion(-)
11
target/arm/mve_helper.c | 19 ++++++++++++
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
13
4 files changed, 90 insertions(+), 1 deletion(-)
33
14
34
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
35
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu.h
17
--- a/target/arm/helper-mve.h
37
+++ b/target/arm/cpu.h
18
+++ b/target/arm/helper-mve.h
38
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
39
#define CACHED_CPSR_BITS (CPSR_T | CPSR_AIF | CPSR_GE | CPSR_IT | CPSR_Q \
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
40
| CPSR_NZCV)
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
41
/* Bits writable in user mode. */
22
42
-#define CPSR_USER (CPSR_NZCV | CPSR_Q | CPSR_GE)
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
43
+#define CPSR_USER (CPSR_NZCV | CPSR_Q | CPSR_GE | CPSR_E)
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
44
/* Execution state bits. MRS read as zero, MSR writes ignored. */
25
+
45
#define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J | CPSR_IL)
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
46
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
47
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
48
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
49
--- a/linux-user/arm/signal.c
31
--- a/target/arm/mve.decode
50
+++ b/linux-user/arm/signal.c
32
+++ b/target/arm/mve.decode
51
@@ -XXX,XX +XXX,XX @@ restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
52
#ifdef TARGET_CONFIG_CPU_32
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
53
__get_user(cpsr, &sc->arm_cpsr);
35
54
cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
36
# Vector add across vector
55
+ arm_rebuild_hflags(env);
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
56
#endif
38
+{
57
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
58
err |= !valid_user_regs(env);
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
41
+ rdahi=%rdahi rdalo=%rdalo
42
+}
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;
82
}
83
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
85
+{
86
+ /*
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;
95
+
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)) {
107
+ return true;
108
+ }
109
+
110
+ /*
111
+ * This insn is subject to beat-wise execution. Partial execution
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.
114
+ */
115
+ if (a->a || mve_skip_first_beat(s)) {
116
+ /* Accumulate input from RdaHi:RdaLo */
117
+ rda = tcg_temp_new_i64();
118
+ rdalo = load_reg(s, a->rdalo);
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);
126
+ }
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);
144
+ return true;
145
+}
146
+
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
148
{
149
TCGv_ptr qd;
59
--
150
--
60
2.20.1
151
2.20.1
61
152
62
153
diff view generated by jsdifflib
1
The GEN_NEON_INTEGER_OP macro is no longer used; remove it.
1
The MVE extension to v8.1M includes some new shift instructions which
2
sit entirely within the non-coprocessor part of the encoding space
3
and which operate only on general-purpose registers. They take up
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
with Rm == 13 or 15.
6
7
Implement the long shifts by immediate, which perform shifts on a
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.
2
23
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
5
---
27
---
6
target/arm/translate.c | 23 -----------------------
28
target/arm/helper-mve.h | 3 ++
7
1 file changed, 23 deletions(-)
29
target/arm/translate.h | 1 +
8
30
target/arm/t32.decode | 28 +++++++++++++
31
target/arm/mve_helper.c | 10 +++++
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
33
5 files changed, 132 insertions(+)
34
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
62
@@ -XXX,XX +XXX,XX @@
63
&mcr !extern cp opc1 crn crm opc2 rt
64
&mcrr !extern cp opc1 crm rt rt2
65
66
+&mve_shl_ri rdalo rdahi shim
67
+
68
+# rdahi: bits [3:1] from insn, bit 0 is 1
69
+# rdalo: bits [3:1] from insn, bit 0 is 0
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
+
83
{
84
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
85
AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi
86
}
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
88
{
89
+ # The v8.1M MVE shift insns overlap in encoding with MOVS/ORRS
90
+ # and are distinguished by having Rm==13 or 15. Those are UNPREDICTABLE
91
+ # cases for MOVS/ORRS. We decode the MVE cases first, ensuring that
92
+ # they explicitly call unallocated_encoding() for cases that must UNDEF
93
+ # (eg "using a new shift insn on a v8.1M CPU without MVE"), and letting
94
+ # the rest fall through (where ORR_rrri and MOV_rxri will end up
95
+ # handling them as r13 and r15 accesses with the same semantics as A32).
96
+ [
97
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
98
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
99
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
100
+
101
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
102
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
103
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
104
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
105
+ ]
106
+
107
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
108
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
109
}
110
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/mve_helper.c
113
+++ b/target/arm/mve_helper.c
114
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
115
mve_advance_vpt(env);
116
return rdm;
117
}
118
+
119
+uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
120
+{
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
122
+}
123
+
124
+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
+}
9
diff --git a/target/arm/translate.c b/target/arm/translate.c
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
10
index XXXXXXX..XXXXXXX 100644
129
index XXXXXXX..XXXXXXX 100644
11
--- a/target/arm/translate.c
130
--- a/target/arm/translate.c
12
+++ b/target/arm/translate.c
131
+++ b/target/arm/translate.c
13
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
14
default: return 1; \
133
return true;
15
}} while (0)
134
}
16
135
17
-#define GEN_NEON_INTEGER_OP(name) do { \
136
+/*
18
- switch ((size << 1) | u) { \
137
+ * v8.1M MVE wide-shifts
19
- case 0: \
138
+ */
20
- gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
21
- break; \
140
+ WideShiftImmFn *fn)
22
- case 1: \
141
+{
23
- gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
142
+ TCGv_i64 rda;
24
- break; \
143
+ TCGv_i32 rdalo, rdahi;
25
- case 2: \
144
+
26
- gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
27
- break; \
146
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
28
- case 3: \
147
+ return false;
29
- gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
148
+ }
30
- break; \
149
+ if (a->rdahi == 15) {
31
- case 4: \
150
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
32
- gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
151
+ return false;
33
- break; \
152
+ }
34
- case 5: \
153
+ if (!dc_isar_feature(aa32_mve, s) ||
35
- gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
154
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
36
- break; \
155
+ a->rdahi == 13) {
37
- default: return 1; \
156
+ /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
38
- }} while (0)
157
+ unallocated_encoding(s);
39
-
158
+ return true;
40
static TCGv_i32 neon_load_scratch(int scratch)
159
+ }
41
{
160
+
42
TCGv_i32 tmp = tcg_temp_new_i32();
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);
224
+}
225
+
226
/*
227
* Multiply and multiply accumulate
228
*/
43
--
229
--
44
2.20.1
230
2.20.1
45
231
46
232
diff view generated by jsdifflib
1
Sort the board index into alphabetical order. (Note that we need to
1
Implement the MVE long shifts by register, which perform shifts on a
2
sort alphabetically by the title text of each file, which isn't the
2
pair of general-purpose registers treated as a 64-bit quantity, with
3
same ordering as sorting by the filename.)
3
the shift count in another general-purpose register, which might be
4
either positive or negative.
5
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
we have to move the CSEL pattern into the same decodetree group.
4
11
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20200507151819.28444-3-peter.maydell@linaro.org
10
---
15
---
11
docs/system/target-arm.rst | 17 +++++++++++------
16
target/arm/helper-mve.h | 6 +++
12
1 file changed, 11 insertions(+), 6 deletions(-)
17
target/arm/translate.h | 1 +
13
18
target/arm/t32.decode | 16 +++++--
14
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
15
index XXXXXXX..XXXXXXX 100644
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
16
--- a/docs/system/target-arm.rst
21
5 files changed, 182 insertions(+), 3 deletions(-)
17
+++ b/docs/system/target-arm.rst
22
18
@@ -XXX,XX +XXX,XX @@ Unfortunately many of the Arm boards QEMU supports are currently
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
19
undocumented; you can get a complete list by running
24
index XXXXXXX..XXXXXXX 100644
20
``qemu-system-aarch64 --machine help``.
25
--- a/target/arm/helper-mve.h
21
26
+++ b/target/arm/helper-mve.h
22
+..
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
+ This table of contents should be kept sorted alphabetically
28
24
+ by the title text of each file, which isn't the same ordering
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
25
+ as an alphabetical sort by filename.
30
26
+
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
27
.. toctree::
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
28
:maxdepth: 1
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
29
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
30
arm/integratorcp
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
31
- arm/versatile
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
arm/realview
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
33
- arm/xscale
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
34
- arm/palm
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
35
- arm/nseries
40
index XXXXXXX..XXXXXXX 100644
36
- arm/stellaris
41
--- a/target/arm/translate.h
37
+ arm/versatile
42
+++ b/target/arm/translate.h
38
arm/musicpal
43
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
39
- arm/sx1
44
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
40
+ arm/nseries
45
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
41
arm/orangepi
46
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
42
+ arm/palm
47
+typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
43
+ arm/xscale
48
44
+ arm/sx1
49
/**
45
+ arm/stellaris
50
* arm_tbflags_from_tb:
46
51
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
47
Arm CPU features
52
index XXXXXXX..XXXXXXX 100644
48
================
53
--- a/target/arm/t32.decode
54
+++ b/target/arm/t32.decode
55
@@ -XXX,XX +XXX,XX @@
56
&mcrr !extern cp opc1 crm rt rt2
57
58
&mve_shl_ri rdalo rdahi shim
59
+&mve_shl_rr rdalo rdahi rm
60
61
# rdahi: bits [3:1] from insn, bit 0 is 1
62
# rdalo: bits [3:1] from insn, bit 0 is 0
63
@@ -XXX,XX +XXX,XX @@
64
65
@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
66
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
67
+@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
68
+ &mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
69
70
{
71
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
72
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
73
URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
74
SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
75
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
76
+
77
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
78
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
79
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
80
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
81
+ UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
82
+ SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
83
]
84
85
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
86
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
87
+
88
+ # v8.1M CSEL and friends
89
+ CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
90
}
91
{
92
MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi
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
+}
211
diff --git a/target/arm/translate.c b/target/arm/translate.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/arm/translate.c
214
+++ b/target/arm/translate.c
215
@@ -XXX,XX +XXX,XX @@ static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
216
return do_mve_shl_ri(s, a, gen_urshr64_i64);
217
}
218
219
+static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
220
+{
221
+ TCGv_i64 rda;
222
+ TCGv_i32 rdalo, rdahi;
223
+
224
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
225
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
226
+ return false;
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
*/
49
--
291
--
50
2.20.1
292
2.20.1
51
293
52
294
diff view generated by jsdifflib
1
Add 'Arm' to the Integrator/CP document title, for consistency with
1
Implement the MVE shifts by immediate, which perform shifts
2
the titling of the other documentation of Arm devboard models
2
on a single general-purpose register.
3
(versatile, realview).
3
4
These patterns overlap with the long-shift-by-immediates,
5
so we have to rearrange the grouping a little here.
4
6
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20200507151819.28444-2-peter.maydell@linaro.org
10
---
10
---
11
docs/system/arm/integratorcp.rst | 4 ++--
11
target/arm/helper-mve.h | 3 ++
12
1 file changed, 2 insertions(+), 2 deletions(-)
12
target/arm/translate.h | 1 +
13
13
target/arm/t32.decode | 31 ++++++++++++++-----
14
diff --git a/docs/system/arm/integratorcp.rst b/docs/system/arm/integratorcp.rst
14
target/arm/mve_helper.c | 10 ++++++
15
index XXXXXXX..XXXXXXX 100644
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
16
--- a/docs/system/arm/integratorcp.rst
16
5 files changed, 104 insertions(+), 9 deletions(-)
17
+++ b/docs/system/arm/integratorcp.rst
17
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-mve.h
21
+++ b/target/arm/helper-mve.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
26
+
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate.h
32
+++ b/target/arm/translate.h
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
37
+typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
38
39
/**
40
* arm_tbflags_from_tb:
41
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/t32.decode
44
+++ b/target/arm/t32.decode
18
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@
19
-Integrator/CP (``integratorcp``)
46
20
-================================
47
&mve_shl_ri rdalo rdahi shim
21
+Arm Integrator/CP (``integratorcp``)
48
&mve_shl_rr rdalo rdahi rm
22
+====================================
49
+&mve_sh_ri rda shim
23
50
24
The Arm Integrator/CP board is emulated with the following devices:
51
# rdahi: bits [3:1] from insn, bit 0 is 1
25
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);
130
+ return;
131
+ }
132
+ t = tcg_temp_new_i32();
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
134
tcg_gen_sari_i32(d, a, sh);
135
tcg_gen_add_i32(d, d, t);
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
137
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
139
{
140
- TCGv_i32 t = tcg_temp_new_i32();
141
+ TCGv_i32 t;
142
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
144
+ if (sh == 32) {
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
146
+ return;
147
+ }
148
+ t = tcg_temp_new_i32();
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
150
tcg_gen_shri_i32(d, a, sh);
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);
154
}
155
156
+static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
157
+{
158
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
159
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
160
+ return false;
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
*/
26
--
211
--
27
2.20.1
212
2.20.1
28
213
29
214
diff view generated by jsdifflib
Deleted patch
1
Add basic documentation of the MPS2 board models.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20200507151819.28444-5-peter.maydell@linaro.org
8
---
9
docs/system/arm/mps2.rst | 29 +++++++++++++++++++++++++++++
10
docs/system/target-arm.rst | 1 +
11
MAINTAINERS | 1 +
12
3 files changed, 31 insertions(+)
13
create mode 100644 docs/system/arm/mps2.rst
14
15
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
16
new file mode 100644
17
index XXXXXXX..XXXXXXX
18
--- /dev/null
19
+++ b/docs/system/arm/mps2.rst
20
@@ -XXX,XX +XXX,XX @@
21
+Arm MPS2 boards (``mps2-an385``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``)
22
+================================================================================
23
+
24
+These board models all use Arm M-profile CPUs.
25
+
26
+The Arm MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
27
+FPGA but is otherwise the same as the 2). Since the CPU itself
28
+and most of the devices are in the FPGA, the details of the board
29
+as seen by the guest depend significantly on the FPGA image.
30
+
31
+QEMU models the following FPGA images:
32
+
33
+``mps2-an385``
34
+ Cortex-M3 as documented in ARM Application Note AN385
35
+``mps2-an511``
36
+ Cortex-M3 'DesignStart' as documented in AN511
37
+``mps2-an505``
38
+ Cortex-M33 as documented in ARM Application Note AN505
39
+``mps2-an521``
40
+ Dual Cortex-M33 as documented in Application Note AN521
41
+
42
+Differences between QEMU and real hardware:
43
+
44
+- AN385 remapping of low 16K of memory to either ZBT SSRAM1 or to
45
+ block RAM is unimplemented (QEMU always maps this to ZBT SSRAM1, as
46
+ if zbt_boot_ctrl is always zero)
47
+- QEMU provides a LAN9118 ethernet rather than LAN9220; the only guest
48
+ visible difference is that the LAN9118 doesn't support checksum
49
+ offloading
50
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
51
index XXXXXXX..XXXXXXX 100644
52
--- a/docs/system/target-arm.rst
53
+++ b/docs/system/target-arm.rst
54
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
55
:maxdepth: 1
56
57
arm/integratorcp
58
+ arm/mps2
59
arm/realview
60
arm/versatile
61
arm/vexpress
62
diff --git a/MAINTAINERS b/MAINTAINERS
63
index XXXXXXX..XXXXXXX 100644
64
--- a/MAINTAINERS
65
+++ b/MAINTAINERS
66
@@ -XXX,XX +XXX,XX @@ F: hw/misc/armsse-cpuid.c
67
F: include/hw/misc/armsse-cpuid.h
68
F: hw/misc/armsse-mhu.c
69
F: include/hw/misc/armsse-mhu.h
70
+F: docs/system/arm/mps2.rst
71
72
Musca
73
M: Peter Maydell <peter.maydell@linaro.org>
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
Deleted patch
1
In linux-user/arm/cpu-loop.c we incorrectly treat EXCP_BKPT similarly
2
to EXCP_SWI, which means that if the guest executes a BKPT insn then
3
QEMU will perform a syscall for it (which syscall depends on what
4
value happens to be in r7...). The correct behaviour is that the
5
guest process should take a SIGTRAP.
6
1
7
This code has been like this (more or less) since commit
8
06c949e62a098f in 2006 which added BKPT in the first place. This is
9
probably because at the time the same code path was used to handle
10
both Linux syscalls and semihosting calls, and (on M profile) BKPT
11
with a suitable magic number is used for semihosting calls. But
12
these days we've moved handling of semihosting out to an entirely
13
different codepath, so we can fix this bug by simply removing this
14
handling of EXCP_BKPT and instead making it deliver a SIGTRAP like
15
EXCP_DEBUG (as we do already on aarch64).
16
17
Reported-by: <omerg681@gmail.com>
18
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
19
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Message-id: 20200420212206.12776-2-peter.maydell@linaro.org
22
Fixes: https://bugs.launchpad.net/qemu/+bug/1873898
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
25
linux-user/arm/cpu_loop.c | 30 ++++++++----------------------
26
1 file changed, 8 insertions(+), 22 deletions(-)
27
28
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/linux-user/arm/cpu_loop.c
31
+++ b/linux-user/arm/cpu_loop.c
32
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
33
}
34
break;
35
case EXCP_SWI:
36
- case EXCP_BKPT:
37
{
38
env->eabi = 1;
39
/* system call */
40
- if (trapnr == EXCP_BKPT) {
41
- if (env->thumb) {
42
- /* FIXME - what to do if get_user() fails? */
43
- get_user_code_u16(insn, env->regs[15], env);
44
- n = insn & 0xff;
45
- env->regs[15] += 2;
46
- } else {
47
- /* FIXME - what to do if get_user() fails? */
48
- get_user_code_u32(insn, env->regs[15], env);
49
- n = (insn & 0xf) | ((insn >> 4) & 0xff0);
50
- env->regs[15] += 4;
51
- }
52
+ if (env->thumb) {
53
+ /* FIXME - what to do if get_user() fails? */
54
+ get_user_code_u16(insn, env->regs[15] - 2, env);
55
+ n = insn & 0xff;
56
} else {
57
- if (env->thumb) {
58
- /* FIXME - what to do if get_user() fails? */
59
- get_user_code_u16(insn, env->regs[15] - 2, env);
60
- n = insn & 0xff;
61
- } else {
62
- /* FIXME - what to do if get_user() fails? */
63
- get_user_code_u32(insn, env->regs[15] - 4, env);
64
- n = insn & 0xffffff;
65
- }
66
+ /* FIXME - what to do if get_user() fails? */
67
+ get_user_code_u32(insn, env->regs[15] - 4, env);
68
+ n = insn & 0xffffff;
69
}
70
71
if (n == ARM_NR_cacheflush) {
72
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
73
}
74
break;
75
case EXCP_DEBUG:
76
+ case EXCP_BKPT:
77
excp_debug:
78
info.si_signo = TARGET_SIGTRAP;
79
info.si_errno = 0;
80
--
81
2.20.1
82
83
diff view generated by jsdifflib
Deleted patch
1
From: Guenter Roeck <linux@roeck-us.net>
2
1
3
In preparation for a full implementation, move i.MX watchdog driver
4
from hw/misc to hw/watchdog. While at it, add the watchdog files
5
to MAINTAINERS.
6
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Message-id: 20200517162135.110364-2-linux@roeck-us.net
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/fsl-imx6.h | 2 +-
13
include/hw/arm/fsl-imx6ul.h | 2 +-
14
include/hw/arm/fsl-imx7.h | 2 +-
15
include/hw/{misc/imx2_wdt.h => watchdog/wdt_imx2.h} | 0
16
hw/{misc/imx2_wdt.c => watchdog/wdt_imx2.c} | 2 +-
17
MAINTAINERS | 2 ++
18
hw/arm/Kconfig | 3 +++
19
hw/misc/Makefile.objs | 1 -
20
hw/watchdog/Kconfig | 3 +++
21
hw/watchdog/Makefile.objs | 1 +
22
10 files changed, 13 insertions(+), 5 deletions(-)
23
rename include/hw/{misc/imx2_wdt.h => watchdog/wdt_imx2.h} (100%)
24
rename hw/{misc/imx2_wdt.c => watchdog/wdt_imx2.c} (98%)
25
26
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/arm/fsl-imx6.h
29
+++ b/include/hw/arm/fsl-imx6.h
30
@@ -XXX,XX +XXX,XX @@
31
#include "hw/cpu/a9mpcore.h"
32
#include "hw/misc/imx6_ccm.h"
33
#include "hw/misc/imx6_src.h"
34
-#include "hw/misc/imx2_wdt.h"
35
+#include "hw/watchdog/wdt_imx2.h"
36
#include "hw/char/imx_serial.h"
37
#include "hw/timer/imx_gpt.h"
38
#include "hw/timer/imx_epit.h"
39
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/include/hw/arm/fsl-imx6ul.h
42
+++ b/include/hw/arm/fsl-imx6ul.h
43
@@ -XXX,XX +XXX,XX @@
44
#include "hw/misc/imx7_snvs.h"
45
#include "hw/misc/imx7_gpr.h"
46
#include "hw/intc/imx_gpcv2.h"
47
-#include "hw/misc/imx2_wdt.h"
48
+#include "hw/watchdog/wdt_imx2.h"
49
#include "hw/gpio/imx_gpio.h"
50
#include "hw/char/imx_serial.h"
51
#include "hw/timer/imx_gpt.h"
52
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/include/hw/arm/fsl-imx7.h
55
+++ b/include/hw/arm/fsl-imx7.h
56
@@ -XXX,XX +XXX,XX @@
57
#include "hw/misc/imx7_snvs.h"
58
#include "hw/misc/imx7_gpr.h"
59
#include "hw/misc/imx6_src.h"
60
-#include "hw/misc/imx2_wdt.h"
61
+#include "hw/watchdog/wdt_imx2.h"
62
#include "hw/gpio/imx_gpio.h"
63
#include "hw/char/imx_serial.h"
64
#include "hw/timer/imx_gpt.h"
65
diff --git a/include/hw/misc/imx2_wdt.h b/include/hw/watchdog/wdt_imx2.h
66
similarity index 100%
67
rename from include/hw/misc/imx2_wdt.h
68
rename to include/hw/watchdog/wdt_imx2.h
69
diff --git a/hw/misc/imx2_wdt.c b/hw/watchdog/wdt_imx2.c
70
similarity index 98%
71
rename from hw/misc/imx2_wdt.c
72
rename to hw/watchdog/wdt_imx2.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/misc/imx2_wdt.c
75
+++ b/hw/watchdog/wdt_imx2.c
76
@@ -XXX,XX +XXX,XX @@
77
#include "qemu/module.h"
78
#include "sysemu/watchdog.h"
79
80
-#include "hw/misc/imx2_wdt.h"
81
+#include "hw/watchdog/wdt_imx2.h"
82
83
#define IMX2_WDT_WCR_WDA BIT(5) /* -> External Reset WDOG_B */
84
#define IMX2_WDT_WCR_SRS BIT(4) /* -> Software Reset Signal */
85
diff --git a/MAINTAINERS b/MAINTAINERS
86
index XXXXXXX..XXXXXXX 100644
87
--- a/MAINTAINERS
88
+++ b/MAINTAINERS
89
@@ -XXX,XX +XXX,XX @@ S: Odd Fixes
90
F: hw/arm/fsl-imx25.c
91
F: hw/arm/imx25_pdk.c
92
F: hw/misc/imx25_ccm.c
93
+F: hw/watchdog/wdt_imx2.c
94
F: include/hw/arm/fsl-imx25.h
95
F: include/hw/misc/imx25_ccm.h
96
+F: include/hw/watchdog/wdt_imx2.h
97
98
i.MX31 (kzm)
99
M: Peter Chubb <peter.chubb@nicta.com.au>
100
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
101
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/arm/Kconfig
103
+++ b/hw/arm/Kconfig
104
@@ -XXX,XX +XXX,XX @@ config FSL_IMX6
105
select IMX_FEC
106
select IMX_I2C
107
select IMX_USBPHY
108
+ select WDT_IMX2
109
select SDHCI
110
111
config ASPEED_SOC
112
@@ -XXX,XX +XXX,XX @@ config FSL_IMX7
113
select IMX
114
select IMX_FEC
115
select IMX_I2C
116
+ select WDT_IMX2
117
select PCI_EXPRESS_DESIGNWARE
118
select SDHCI
119
select UNIMP
120
@@ -XXX,XX +XXX,XX @@ config FSL_IMX6UL
121
select IMX
122
select IMX_FEC
123
select IMX_I2C
124
+ select WDT_IMX2
125
select SDHCI
126
select UNIMP
127
128
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
129
index XXXXXXX..XXXXXXX 100644
130
--- a/hw/misc/Makefile.objs
131
+++ b/hw/misc/Makefile.objs
132
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_IMX) += imx6_ccm.o
133
common-obj-$(CONFIG_IMX) += imx6ul_ccm.o
134
obj-$(CONFIG_IMX) += imx6_src.o
135
common-obj-$(CONFIG_IMX) += imx7_ccm.o
136
-common-obj-$(CONFIG_IMX) += imx2_wdt.o
137
common-obj-$(CONFIG_IMX) += imx7_snvs.o
138
common-obj-$(CONFIG_IMX) += imx7_gpr.o
139
common-obj-$(CONFIG_IMX) += imx_rngc.o
140
diff --git a/hw/watchdog/Kconfig b/hw/watchdog/Kconfig
141
index XXXXXXX..XXXXXXX 100644
142
--- a/hw/watchdog/Kconfig
143
+++ b/hw/watchdog/Kconfig
144
@@ -XXX,XX +XXX,XX @@ config WDT_IB700
145
146
config WDT_DIAG288
147
bool
148
+
149
+config WDT_IMX2
150
+ bool
151
diff --git a/hw/watchdog/Makefile.objs b/hw/watchdog/Makefile.objs
152
index XXXXXXX..XXXXXXX 100644
153
--- a/hw/watchdog/Makefile.objs
154
+++ b/hw/watchdog/Makefile.objs
155
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_WDT_IB6300ESB) += wdt_i6300esb.o
156
common-obj-$(CONFIG_WDT_IB700) += wdt_ib700.o
157
common-obj-$(CONFIG_WDT_DIAG288) += wdt_diag288.o
158
common-obj-$(CONFIG_ASPEED_SOC) += wdt_aspeed.o
159
+common-obj-$(CONFIG_WDT_IMX2) += wdt_imx2.o
160
--
161
2.20.1
162
163
diff view generated by jsdifflib
Deleted patch
1
From: Guenter Roeck <linux@roeck-us.net>
2
1
3
With this patch applied, the watchdog in the sabrelite emulation
4
is fully operational, including pretimeout support.
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20200517162135.110364-6-linux@roeck-us.net
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/fsl-imx6.c | 9 +++++++++
12
1 file changed, 9 insertions(+)
13
14
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/fsl-imx6.c
17
+++ b/hw/arm/fsl-imx6.c
18
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
19
FSL_IMX6_WDOG1_ADDR,
20
FSL_IMX6_WDOG2_ADDR,
21
};
22
+ static const int FSL_IMX6_WDOGn_IRQ[FSL_IMX6_NUM_WDTS] = {
23
+ FSL_IMX6_WDOG1_IRQ,
24
+ FSL_IMX6_WDOG2_IRQ,
25
+ };
26
27
+ object_property_set_bool(OBJECT(&s->wdt[i]), true, "pretimeout-support",
28
+ &error_abort);
29
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized",
30
&error_abort);
31
32
sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX6_WDOGn_ADDR[i]);
33
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0,
34
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore),
35
+ FSL_IMX6_WDOGn_IRQ[i]));
36
}
37
38
/* ROM memory */
39
--
40
2.20.1
41
42
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
Implement the MVE shifts by register, which perform
2
shifts on a single general-purpose register.
2
3
3
With this commit, the watchdog on mcimx6ul-evk is fully operational,
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
including pretimeout support.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
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(-)
5
14
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20200517162135.110364-7-linux@roeck-us.net
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/fsl-imx6ul.c | 10 ++++++++++
12
1 file changed, 10 insertions(+)
13
14
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/fsl-imx6ul.c
17
--- a/target/arm/helper-mve.h
17
+++ b/hw/arm/fsl-imx6ul.c
18
+++ b/target/arm/helper-mve.h
18
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
19
FSL_IMX6UL_WDOG2_ADDR,
20
20
FSL_IMX6UL_WDOG3_ADDR,
21
DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
21
};
22
DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
22
+ static const int FSL_IMX6UL_WDOGn_IRQ[FSL_IMX6UL_NUM_WDTS] = {
23
+DEF_HELPER_FLAGS_3(mve_uqrshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
23
+ FSL_IMX6UL_WDOG1_IRQ,
24
+DEF_HELPER_FLAGS_3(mve_sqrshr, TCG_CALL_NO_RWG, i32, env, i32, i32)
24
+ FSL_IMX6UL_WDOG2_IRQ,
25
diff --git a/target/arm/translate.h b/target/arm/translate.h
25
+ FSL_IMX6UL_WDOG3_IRQ,
26
index XXXXXXX..XXXXXXX 100644
26
+ };
27
--- a/target/arm/translate.h
27
28
+++ b/target/arm/translate.h
28
+ object_property_set_bool(OBJECT(&s->wdt[i]), true, "pretimeout-support",
29
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
29
+ &error_abort);
30
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
30
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized",
31
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
31
&error_abort);
32
typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
32
33
+typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
33
sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
34
34
FSL_IMX6UL_WDOGn_ADDR[i]);
35
/**
35
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0,
36
* arm_tbflags_from_tb:
36
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
37
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
37
+ FSL_IMX6UL_WDOGn_IRQ[i]));
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/t32.decode
40
+++ b/target/arm/t32.decode
41
@@ -XXX,XX +XXX,XX @@
42
&mve_shl_ri rdalo rdahi shim
43
&mve_shl_rr rdalo rdahi rm
44
&mve_sh_ri rda shim
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
38
}
59
}
39
60
40
/*
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
+ }
70
+
71
+ {
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)
90
+{
91
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, true, &env->QF);
92
+}
93
+
94
+uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
95
+{
96
+ return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
97
+}
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate.c
101
+++ b/target/arm/translate.c
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
104
}
105
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
107
+{
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
110
+ return false;
111
+ }
112
+ if (!dc_isar_feature(aa32_mve, s) ||
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
115
+ a->rm == a->rda) {
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
117
+ unallocated_encoding(s);
118
+ return true;
119
+ }
120
+
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
123
+ return true;
124
+}
125
+
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
127
+{
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
129
+}
130
+
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
132
+{
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
134
+}
135
+
136
/*
137
* Multiply and multiply accumulate
138
*/
41
--
139
--
42
2.20.1
140
2.20.1
43
141
44
142
diff view generated by jsdifflib
Deleted patch
1
From: Guenter Roeck <linux@roeck-us.net>
2
1
3
Instantiating PWM, CAN, CAAM, and OCOTP devices is necessary to avoid
4
crashes when booting mainline Linux.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20200517162135.110364-8-linux@roeck-us.net
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/fsl-imx7.h | 16 ++++++++++++++++
12
hw/arm/fsl-imx7.c | 24 ++++++++++++++++++++++++
13
2 files changed, 40 insertions(+)
14
15
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/fsl-imx7.h
18
+++ b/include/hw/arm/fsl-imx7.h
19
@@ -XXX,XX +XXX,XX @@ enum FslIMX7MemoryMap {
20
FSL_IMX7_IOMUXC_GPR_ADDR = 0x30340000,
21
FSL_IMX7_IOMUXCn_SIZE = 0x1000,
22
23
+ FSL_IMX7_OCOTP_ADDR = 0x30350000,
24
+ FSL_IMX7_OCOTP_SIZE = 0x10000,
25
+
26
FSL_IMX7_ANALOG_ADDR = 0x30360000,
27
FSL_IMX7_SNVS_ADDR = 0x30370000,
28
FSL_IMX7_CCM_ADDR = 0x30380000,
29
@@ -XXX,XX +XXX,XX @@ enum FslIMX7MemoryMap {
30
FSL_IMX7_ADC2_ADDR = 0x30620000,
31
FSL_IMX7_ADCn_SIZE = 0x1000,
32
33
+ FSL_IMX7_PWM1_ADDR = 0x30660000,
34
+ FSL_IMX7_PWM2_ADDR = 0x30670000,
35
+ FSL_IMX7_PWM3_ADDR = 0x30680000,
36
+ FSL_IMX7_PWM4_ADDR = 0x30690000,
37
+ FSL_IMX7_PWMn_SIZE = 0x10000,
38
+
39
FSL_IMX7_PCIE_PHY_ADDR = 0x306D0000,
40
FSL_IMX7_PCIE_PHY_SIZE = 0x10000,
41
42
FSL_IMX7_GPC_ADDR = 0x303A0000,
43
44
+ FSL_IMX7_CAAM_ADDR = 0x30900000,
45
+ FSL_IMX7_CAAM_SIZE = 0x40000,
46
+
47
+ FSL_IMX7_CAN1_ADDR = 0x30A00000,
48
+ FSL_IMX7_CAN2_ADDR = 0x30A10000,
49
+ FSL_IMX7_CANn_SIZE = 0x10000,
50
+
51
FSL_IMX7_I2C1_ADDR = 0x30A20000,
52
FSL_IMX7_I2C2_ADDR = 0x30A30000,
53
FSL_IMX7_I2C3_ADDR = 0x30A40000,
54
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/fsl-imx7.c
57
+++ b/hw/arm/fsl-imx7.c
58
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
59
*/
60
create_unimplemented_device("sdma", FSL_IMX7_SDMA_ADDR, FSL_IMX7_SDMA_SIZE);
61
62
+ /*
63
+ * CAAM
64
+ */
65
+ create_unimplemented_device("caam", FSL_IMX7_CAAM_ADDR, FSL_IMX7_CAAM_SIZE);
66
+
67
+ /*
68
+ * PWM
69
+ */
70
+ create_unimplemented_device("pwm1", FSL_IMX7_PWM1_ADDR, FSL_IMX7_PWMn_SIZE);
71
+ create_unimplemented_device("pwm2", FSL_IMX7_PWM2_ADDR, FSL_IMX7_PWMn_SIZE);
72
+ create_unimplemented_device("pwm3", FSL_IMX7_PWM3_ADDR, FSL_IMX7_PWMn_SIZE);
73
+ create_unimplemented_device("pwm4", FSL_IMX7_PWM4_ADDR, FSL_IMX7_PWMn_SIZE);
74
+
75
+ /*
76
+ * CAN
77
+ */
78
+ create_unimplemented_device("can1", FSL_IMX7_CAN1_ADDR, FSL_IMX7_CANn_SIZE);
79
+ create_unimplemented_device("can2", FSL_IMX7_CAN2_ADDR, FSL_IMX7_CANn_SIZE);
80
+
81
+ /*
82
+ * OCOTP
83
+ */
84
+ create_unimplemented_device("ocotp", FSL_IMX7_OCOTP_ADDR,
85
+ FSL_IMX7_OCOTP_SIZE);
86
87
object_property_set_bool(OBJECT(&s->gpr), true, "realized",
88
&error_abort);
89
--
90
2.20.1
91
92
diff view generated by jsdifflib