1
Less than a day of post-3.0 code review and already enough
1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
2
patches for another pullreq :-)
3
2
4
thanks
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
5
-- PMM
6
7
The following changes since commit c542a9f9794ec8e0bc3fcf5956d3cc8bce667789:
8
9
Merge remote-tracking branch 'remotes/armbru/tags/pull-tests-2018-08-16' into staging (2018-08-16 09:50:54 +0100)
10
4
11
are available in the Git repository at:
5
are available in the Git repository at:
12
6
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180816
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
14
8
15
for you to fetch changes up to fcf13ca556f462b52956059bf8fa622bc8575edb:
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
16
10
17
hw/arm/mps2-tz: Replace init_sysbus_child() with sysbus_init_child_obj() (2018-08-16 14:29:58 +0100)
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
18
12
19
----------------------------------------------------------------
13
----------------------------------------------------------------
20
target-arm queue:
14
target-arm queue:
21
* Fixes for various bugs in SVE instructions
15
* more MVE instructions
22
* Add model of Freescale i.MX6 UltraLite 14x14 EVK Board
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
23
* hw/arm: make bitbanded IO optional on ARMv7-M
17
* target/arm: Check NaN mode before silencing NaN
24
* Add model of Cortex-M0 CPU
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
25
* Add support for loading Intel HEX files to the generic loader
19
* hw/arm: Add basic power management to raspi.
26
* imx_spi: Unset XCH when TX FIFO becomes empty
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
27
* aspeed_sdmc: fix various bugs
28
* Fix bugs in Arm FP16 instruction support
29
* Fix aa64 FCADD and FCMLA decode
30
* softfloat: Fix missing inexact for floating-point add
31
* hw/arm/mps2-tz: Replace init_sysbus_child() with sysbus_init_child_obj()
32
21
33
----------------------------------------------------------------
22
----------------------------------------------------------------
34
Cédric Le Goater (1):
23
Joe Komlodi (1):
35
aspeed: add a max_ram_size property to the memory controller
24
target/arm: Check NaN mode before silencing NaN
36
25
37
Jean-Christophe Dubois (3):
26
Maxim Uvarov (1):
38
i.MX6UL: Add i.MX6UL specific CCM device
27
hw/gpio/gpio_pwr: use shutdown function for reboot
39
i.MX6UL: Add i.MX6UL SOC
40
i.MX6UL: Add Freescale i.MX6 UltraLite 14x14 EVK Board
41
28
42
Joel Stanley (5):
29
Nolan Leake (1):
43
aspeed_sdmc: Extend number of valid registers
30
hw/arm: Add basic power management to raspi.
44
aspeed_sdmc: Fix saved values
45
aspeed_sdmc: Set 'cache initial sequence' always true
46
aspeed_sdmc: Init status always idle
47
aspeed_sdmc: Handle ECC training
48
31
49
Richard Henderson (13):
32
Patrick Venture (2):
50
target/arm: Fix typo in helper_sve_ld1hss_r
33
docs/system/arm: Add quanta-q7l1-bmc reference
51
target/arm: Fix sign-extension in sve do_ldr/do_str
34
docs/system/arm: Add quanta-gbs-bmc reference
52
target/arm: Fix offset for LD1R instructions
53
target/arm: Fix offset scaling for LD_zprr and ST_zprr
54
target/arm: Reformat integer register dump
55
target/arm: Dump SVE state if enabled
56
target/arm: Add sve-max-vq cpu property to -cpu max
57
target/arm: Adjust FPCR_MASK for FZ16
58
target/arm: Ignore float_flag_input_denormal from fp_status_f16
59
target/arm: Use fp_status_fp16 for do_fmpa_zpzzz_h
60
target/arm: Use FZ not FZ16 for SVE FCVT single-half and double-half
61
target/arm: Fix aa64 FCADD and FCMLA decode
62
softfloat: Fix missing inexact for floating-point add
63
35
64
Stefan Hajnoczi (4):
36
Peter Maydell (18):
65
hw/arm: make bitbanded IO optional on ARMv7-M
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
66
target/arm: add "cortex-m0" CPU model
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
67
loader: extract rom_free() function
39
target/arm: Make asimd_imm_const() public
68
loader: add rom transaction API
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
69
55
70
Su Hang (2):
56
Philippe Mathieu-Daudé (1):
71
loader: Implement .hex file loader
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
72
Add QTest testcase for the Intel Hexadecimal
73
58
74
Thomas Huth (1):
59
docs/system/arm/aspeed.rst | 1 +
75
hw/arm/mps2-tz: Replace init_sysbus_child() with sysbus_init_child_obj()
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
76
82
77
Trent Piepho (1):
78
imx_spi: Unset XCH when TX FIFO becomes empty
79
80
configure | 4 +
81
hw/arm/Makefile.objs | 1 +
82
hw/misc/Makefile.objs | 1 +
83
tests/Makefile.include | 2 +
84
include/hw/arm/armv7m.h | 2 +
85
include/hw/arm/fsl-imx6ul.h | 339 ++++++++++++++
86
include/hw/loader.h | 31 ++
87
include/hw/misc/aspeed_sdmc.h | 4 +-
88
include/hw/misc/imx6ul_ccm.h | 226 +++++++++
89
target/arm/cpu.h | 5 +-
90
fpu/softfloat.c | 2 +-
91
hw/arm/armv7m.c | 37 +-
92
hw/arm/aspeed.c | 31 ++
93
hw/arm/aspeed_soc.c | 2 +
94
hw/arm/fsl-imx6ul.c | 617 ++++++++++++++++++++++++
95
hw/arm/mcimx6ul-evk.c | 85 ++++
96
hw/arm/mps2-tz.c | 32 +-
97
hw/arm/mps2.c | 1 +
98
hw/arm/msf2-soc.c | 1 +
99
hw/arm/stellaris.c | 1 +
100
hw/arm/stm32f205_soc.c | 1 +
101
hw/core/generic-loader.c | 4 +
102
hw/core/loader.c | 302 +++++++++++-
103
hw/misc/aspeed_sdmc.c | 55 ++-
104
hw/misc/imx6ul_ccm.c | 886 +++++++++++++++++++++++++++++++++++
105
hw/ssi/imx_spi.c | 3 +-
106
linux-user/syscall.c | 19 +-
107
target/arm/cpu.c | 17 +-
108
target/arm/cpu64.c | 29 ++
109
target/arm/helper.c | 18 +-
110
target/arm/sve_helper.c | 4 +-
111
target/arm/translate-a64.c | 120 ++++-
112
target/arm/translate-sve.c | 30 +-
113
tests/hexloader-test.c | 45 ++
114
MAINTAINERS | 6 +
115
default-configs/arm-softmmu.mak | 1 +
116
hw/misc/trace-events | 7 +
117
tests/hex-loader-check-data/test.hex | 18 +
118
38 files changed, 2863 insertions(+), 126 deletions(-)
119
create mode 100644 include/hw/arm/fsl-imx6ul.h
120
create mode 100644 include/hw/misc/imx6ul_ccm.h
121
create mode 100644 hw/arm/fsl-imx6ul.c
122
create mode 100644 hw/arm/mcimx6ul-evk.c
123
create mode 100644 hw/misc/imx6ul_ccm.c
124
create mode 100644 tests/hexloader-test.c
125
create mode 100644 tests/hex-loader-check-data/test.hex
126
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Cc: qemu-stable@nongnu.org (3.0.1)
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/sve_helper.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/sve_helper.c
14
+++ b/target/arm/sve_helper.c
15
@@ -XXX,XX +XXX,XX @@ DO_LD1(sve_ld1bdu_r, cpu_ldub_data_ra, uint64_t, uint8_t, )
16
DO_LD1(sve_ld1bds_r, cpu_ldsb_data_ra, uint64_t, int8_t, )
17
18
DO_LD1(sve_ld1hsu_r, cpu_lduw_data_ra, uint32_t, uint16_t, H1_4)
19
-DO_LD1(sve_ld1hss_r, cpu_ldsw_data_ra, uint32_t, int8_t, H1_4)
20
+DO_LD1(sve_ld1hss_r, cpu_ldsw_data_ra, uint32_t, int16_t, H1_4)
21
DO_LD1(sve_ld1hdu_r, cpu_lduw_data_ra, uint64_t, uint16_t, )
22
DO_LD1(sve_ld1hds_r, cpu_ldsw_data_ra, uint64_t, int16_t, )
23
24
--
25
2.18.0
26
27
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: Patrick Venture <venture@google.com>
2
2
3
The SDRAM training routine sets the 'Enable cache initial' bit, and then
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
4
waits for the 'cache initial sequence' to be done.
4
entry.
5
5
6
Have it always return done, as there is no other side effects that the
6
Signed-off-by: Patrick Venture <venture@google.com>
7
model needs to implement. This allows the upstream u-boot training to
8
proceed on the ast2500-evb board.
9
10
Signed-off-by: Joel Stanley <joel@jms.id.au>
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
Tested-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20210615192848.1065297-2-venture@google.com
13
Message-id: 20180807075757.7242-4-joel@jms.id.au
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
hw/misc/aspeed_sdmc.c | 1 +
11
docs/system/arm/aspeed.rst | 1 +
17
1 file changed, 1 insertion(+)
12
1 file changed, 1 insertion(+)
18
13
19
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/misc/aspeed_sdmc.c
16
--- a/docs/system/arm/aspeed.rst
22
+++ b/hw/misc/aspeed_sdmc.c
17
+++ b/docs/system/arm/aspeed.rst
23
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ etc.
24
s->ram_bits = ast2500_rambits(s);
19
AST2400 SoC based machines :
25
s->fixed_conf = ASPEED_SDMC_HW_VERSION(1) |
20
26
ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
27
+ ASPEED_SDMC_CACHE_INITIAL_DONE |
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
28
ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
23
29
break;
24
AST2500 SoC based machines :
30
default:
25
31
--
26
--
32
2.18.0
27
2.20.1
33
28
34
29
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Patrick Venture <venture@google.com>
2
2
3
For 0x1.0000000000003p+0 + 0x1.ffffffep+14 = 0x1.0001fffp+15
3
Add line item reference to quanta-gbs-bmc machine.
4
we dropped the sticky bit and so failed to raise inexact.
5
4
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
5
Signed-off-by: Patrick Venture <venture@google.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Message-id: 20210615192848.1065297-3-venture@google.com
9
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
[PMM: fixed underline Sphinx warning]
10
Message-id: 20180810193129.1556-7-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
fpu/softfloat.c | 2 +-
11
docs/system/arm/nuvoton.rst | 5 +++--
14
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 3 insertions(+), 2 deletions(-)
15
13
16
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/fpu/softfloat.c
16
--- a/docs/system/arm/nuvoton.rst
19
+++ b/fpu/softfloat.c
17
+++ b/docs/system/arm/nuvoton.rst
20
@@ -XXX,XX +XXX,XX @@ static FloatParts addsub_floats(FloatParts a, FloatParts b, bool subtract,
18
@@ -XXX,XX +XXX,XX @@
21
}
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
22
a.frac += b.frac;
20
-=====================================================
23
if (a.frac & DECOMPOSED_OVERFLOW_BIT) {
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
24
- a.frac >>= 1;
22
+================================================================
25
+ shift64RightJamming(a.frac, 1, &a.frac);
23
26
a.exp += 1;
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
27
}
25
designed to be used as Baseboard Management Controllers (BMCs) in various
28
return a;
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
28
Hyperscale applications. The following machines are based on this chip :
29
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
31
- ``quanta-gsj`` Quanta GSJ server BMC
32
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
29
--
34
--
30
2.18.0
35
2.20.1
31
36
32
37
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
From: Nolan Leake <nolan@sigbus.net>
2
2
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
3
This is just enough to make reboot and poweroff work. Works for
4
Message-id: 34b6704ceb81b49e35ce1ad162bf758e5141ff87.1532984236.git.jcd@tribudubois.net
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
5
[PMM: fixed some comment typos etc]
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
do what linux does for reset.
7
8
The watchdog timer functionality is not yet implemented.
9
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20210625210209.1870217-1-nolan@sigbus.net
15
[PMM: tweaked commit title; fixed region size to 0x200;
16
moved header file to include/]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
18
---
9
hw/misc/Makefile.objs | 1 +
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
10
include/hw/misc/imx6ul_ccm.h | 226 +++++++++
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
11
hw/misc/imx6ul_ccm.c | 886 +++++++++++++++++++++++++++++++++++
21
hw/arm/bcm2835_peripherals.c | 13 ++-
12
hw/misc/trace-events | 7 +
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
13
4 files changed, 1120 insertions(+)
23
hw/misc/meson.build | 1 +
14
create mode 100644 include/hw/misc/imx6ul_ccm.h
24
5 files changed, 204 insertions(+), 2 deletions(-)
15
create mode 100644 hw/misc/imx6ul_ccm.c
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
16
26
create mode 100644 hw/misc/bcm2835_powermgt.c
17
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
27
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
18
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/misc/Makefile.objs
30
--- a/include/hw/arm/bcm2835_peripherals.h
20
+++ b/hw/misc/Makefile.objs
31
+++ b/include/hw/arm/bcm2835_peripherals.h
21
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx_ccm.o
32
@@ -XXX,XX +XXX,XX @@
22
obj-$(CONFIG_IMX) += imx31_ccm.o
33
#include "hw/misc/bcm2835_mphi.h"
23
obj-$(CONFIG_IMX) += imx25_ccm.o
34
#include "hw/misc/bcm2835_thermal.h"
24
obj-$(CONFIG_IMX) += imx6_ccm.o
35
#include "hw/misc/bcm2835_cprman.h"
25
+obj-$(CONFIG_IMX) += imx6ul_ccm.o
36
+#include "hw/misc/bcm2835_powermgt.h"
26
obj-$(CONFIG_IMX) += imx6_src.o
37
#include "hw/sd/sdhci.h"
27
obj-$(CONFIG_IMX) += imx7_ccm.o
38
#include "hw/sd/bcm2835_sdhost.h"
28
obj-$(CONFIG_IMX) += imx2_wdt.o
39
#include "hw/gpio/bcm2835_gpio.h"
29
diff --git a/include/hw/misc/imx6ul_ccm.h b/include/hw/misc/imx6ul_ccm.h
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
30
new file mode 100644
50
new file mode 100644
31
index XXXXXXX..XXXXXXX
51
index XXXXXXX..XXXXXXX
32
--- /dev/null
52
--- /dev/null
33
+++ b/include/hw/misc/imx6ul_ccm.h
53
+++ b/include/hw/misc/bcm2835_powermgt.h
34
@@ -XXX,XX +XXX,XX @@
54
@@ -XXX,XX +XXX,XX @@
35
+/*
55
+/*
36
+ * IMX6UL Clock Control Module
56
+ * BCM2835 Power Management emulation
37
+ *
57
+ *
38
+ * Copyright (C) 2018 by Jean-Christophe Dubois <jcd@tribudubois.net>
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
39
+ *
60
+ *
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
41
+ * See the COPYING file in the top-level directory.
62
+ * See the COPYING file in the top-level directory.
42
+ */
63
+ */
43
+
64
+
44
+#ifndef IMX6UL_CCM_H
65
+#ifndef BCM2835_POWERMGT_H
45
+#define IMX6UL_CCM_H
66
+#define BCM2835_POWERMGT_H
46
+
67
+
47
+#include "hw/misc/imx_ccm.h"
68
+#include "hw/sysbus.h"
48
+#include "qemu/bitops.h"
69
+#include "qom/object.h"
49
+
70
+
50
+#define CCM_CCR 0
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
51
+#define CCM_CCDR 1
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
52
+#define CCM_CSR 2
73
+
53
+#define CCM_CCSR 3
74
+struct BCM2835PowerMgtState {
54
+#define CCM_CACRR 4
75
+ SysBusDevice busdev;
55
+#define CCM_CBCDR 5
76
+ MemoryRegion iomem;
56
+#define CCM_CBCMR 6
77
+
57
+#define CCM_CSCMR1 7
78
+ uint32_t rstc;
58
+#define CCM_CSCMR2 8
79
+ uint32_t rsts;
59
+#define CCM_CSCDR1 9
80
+ uint32_t wdog;
60
+#define CCM_CS1CDR 10
81
+};
61
+#define CCM_CS2CDR 11
82
+
62
+#define CCM_CDCDR 12
83
+#endif
63
+#define CCM_CHSCCDR 13
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
64
+#define CCM_CSCDR2 14
85
index XXXXXXX..XXXXXXX 100644
65
+#define CCM_CSCDR3 15
86
--- a/hw/arm/bcm2835_peripherals.c
66
+#define CCM_CDHIPR 18
87
+++ b/hw/arm/bcm2835_peripherals.c
67
+#define CCM_CTOR 20
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
68
+#define CCM_CLPCR 21
89
69
+#define CCM_CISR 22
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
70
+#define CCM_CIMR 23
91
OBJECT(&s->gpu_bus_mr));
71
+#define CCM_CCOSR 24
92
+
72
+#define CCM_CGPR 25
93
+ /* Power Management */
73
+#define CCM_CCGR0 26
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
74
+#define CCM_CCGR1 27
95
+ TYPE_BCM2835_POWERMGT);
75
+#define CCM_CCGR2 28
96
}
76
+#define CCM_CCGR3 29
97
77
+#define CCM_CCGR4 30
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
78
+#define CCM_CCGR5 31
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
79
+#define CCM_CCGR6 32
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
80
+#define CCM_CMEOR 34
101
INTERRUPT_USB));
81
+#define CCM_MAX 35
102
82
+
103
+ /* Power Management */
83
+#define CCM_ANALOG_PLL_ARM 0
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
84
+#define CCM_ANALOG_PLL_ARM_SET 1
105
+ return;
85
+#define CCM_ANALOG_PLL_ARM_CLR 2
106
+ }
86
+#define CCM_ANALOG_PLL_ARM_TOG 3
107
+
87
+#define CCM_ANALOG_PLL_USB1 4
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
88
+#define CCM_ANALOG_PLL_USB1_SET 5
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
89
+#define CCM_ANALOG_PLL_USB1_CLR 6
110
+
90
+#define CCM_ANALOG_PLL_USB1_TOG 7
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
91
+#define CCM_ANALOG_PLL_USB2 8
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
92
+#define CCM_ANALOG_PLL_USB2_SET 9
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
93
+#define CCM_ANALOG_PLL_USB2_CLR 10
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
94
+#define CCM_ANALOG_PLL_USB2_TOG 11
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
95
+#define CCM_ANALOG_PLL_SYS 12
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
96
+#define CCM_ANALOG_PLL_SYS_SET 13
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
97
+#define CCM_ANALOG_PLL_SYS_CLR 14
98
+#define CCM_ANALOG_PLL_SYS_TOG 15
99
+#define CCM_ANALOG_PLL_SYS_SS 16
100
+#define CCM_ANALOG_PLL_SYS_NUM 20
101
+#define CCM_ANALOG_PLL_SYS_DENOM 24
102
+#define CCM_ANALOG_PLL_AUDIO 28
103
+#define CCM_ANALOG_PLL_AUDIO_SET 29
104
+#define CCM_ANALOG_PLL_AUDIO_CLR 30
105
+#define CCM_ANALOG_PLL_AUDIO_TOG 31
106
+#define CCM_ANALOG_PLL_AUDIO_NUM 32
107
+#define CCM_ANALOG_PLL_AUDIO_DENOM 36
108
+#define CCM_ANALOG_PLL_VIDEO 40
109
+#define CCM_ANALOG_PLL_VIDEO_SET 41
110
+#define CCM_ANALOG_PLL_VIDEO_CLR 42
111
+#define CCM_ANALOG_PLL_VIDEO_TOG 44
112
+#define CCM_ANALOG_PLL_VIDEO_NUM 46
113
+#define CCM_ANALOG_PLL_VIDEO_DENOM 48
114
+#define CCM_ANALOG_PLL_ENET 56
115
+#define CCM_ANALOG_PLL_ENET_SET 57
116
+#define CCM_ANALOG_PLL_ENET_CLR 58
117
+#define CCM_ANALOG_PLL_ENET_TOG 59
118
+#define CCM_ANALOG_PFD_480 60
119
+#define CCM_ANALOG_PFD_480_SET 61
120
+#define CCM_ANALOG_PFD_480_CLR 62
121
+#define CCM_ANALOG_PFD_480_TOG 63
122
+#define CCM_ANALOG_PFD_528 64
123
+#define CCM_ANALOG_PFD_528_SET 65
124
+#define CCM_ANALOG_PFD_528_CLR 66
125
+#define CCM_ANALOG_PFD_528_TOG 67
126
+
127
+/* PMU registers */
128
+#define PMU_REG_1P1 68
129
+#define PMU_REG_3P0 72
130
+#define PMU_REG_2P5 76
131
+#define PMU_REG_CORE 80
132
+
133
+#define CCM_ANALOG_MISC0 84
134
+#define PMU_MISC0 CCM_ANALOG_MISC0
135
+#define CCM_ANALOG_MISC0_SET 85
136
+#define PMU_MISC0_SET CCM_ANALOG_MISC0_SET
137
+#define CCM_ANALOG_MISC0_CLR 86
138
+#define PMU_MISC0_CLR CCM_ANALOG_MISC0_CLR
139
+#define CCM_ANALOG_MISC0_TOG 87
140
+#define PMU_MISC0_TOG CCM_ANALOG_MISC0_TOG
141
+
142
+#define CCM_ANALOG_MISC1 88
143
+#define PMU_MISC1 CCM_ANALOG_MISC1
144
+#define CCM_ANALOG_MISC1_SET 89
145
+#define PMU_MISC1_SET CCM_ANALOG_MISC1_SET
146
+#define CCM_ANALOG_MISC1_CLR 90
147
+#define PMU_MISC1_CLR CCM_ANALOG_MISC1_CLR
148
+#define CCM_ANALOG_MISC1_TOG 91
149
+#define PMU_MISC1_TOG CCM_ANALOG_MISC1_TOG
150
+
151
+#define CCM_ANALOG_MISC2 92
152
+#define PMU_MISC2 CCM_ANALOG_MISC2
153
+#define CCM_ANALOG_MISC2_SET 93
154
+#define PMU_MISC2_SET CCM_ANALOG_MISC2_SET
155
+#define CCM_ANALOG_MISC2_CLR 94
156
+#define PMU_MISC2_CLR CCM_ANALOG_MISC2_CLR
157
+#define CCM_ANALOG_MISC2_TOG 95
158
+#define PMU_MISC2_TOG CCM_ANALOG_MISC2_TOG
159
+
160
+#define TEMPMON_TEMPSENSE0 96
161
+#define TEMPMON_TEMPSENSE0_SET 97
162
+#define TEMPMON_TEMPSENSE0_CLR 98
163
+#define TEMPMON_TEMPSENSE0_TOG 99
164
+#define TEMPMON_TEMPSENSE1 100
165
+#define TEMPMON_TEMPSENSE1_SET 101
166
+#define TEMPMON_TEMPSENSE1_CLR 102
167
+#define TEMPMON_TEMPSENSE1_TOG 103
168
+#define TEMPMON_TEMPSENSE2 164
169
+#define TEMPMON_TEMPSENSE2_SET 165
170
+#define TEMPMON_TEMPSENSE2_CLR 166
171
+#define TEMPMON_TEMPSENSE2_TOG 167
172
+
173
+#define PMU_LOWPWR_CTRL 155
174
+#define PMU_LOWPWR_CTRL_SET 156
175
+#define PMU_LOWPWR_CTRL_CLR 157
176
+#define PMU_LOWPWR_CTRL_TOG 158
177
+
178
+#define USB_ANALOG_USB1_VBUS_DETECT 104
179
+#define USB_ANALOG_USB1_VBUS_DETECT_SET 105
180
+#define USB_ANALOG_USB1_VBUS_DETECT_CLR 106
181
+#define USB_ANALOG_USB1_VBUS_DETECT_TOG 107
182
+#define USB_ANALOG_USB1_CHRG_DETECT 108
183
+#define USB_ANALOG_USB1_CHRG_DETECT_SET 109
184
+#define USB_ANALOG_USB1_CHRG_DETECT_CLR 110
185
+#define USB_ANALOG_USB1_CHRG_DETECT_TOG 111
186
+#define USB_ANALOG_USB1_VBUS_DETECT_STAT 112
187
+#define USB_ANALOG_USB1_CHRG_DETECT_STAT 116
188
+#define USB_ANALOG_USB1_MISC 124
189
+#define USB_ANALOG_USB1_MISC_SET 125
190
+#define USB_ANALOG_USB1_MISC_CLR 126
191
+#define USB_ANALOG_USB1_MISC_TOG 127
192
+#define USB_ANALOG_USB2_VBUS_DETECT 128
193
+#define USB_ANALOG_USB2_VBUS_DETECT_SET 129
194
+#define USB_ANALOG_USB2_VBUS_DETECT_CLR 130
195
+#define USB_ANALOG_USB2_VBUS_DETECT_TOG 131
196
+#define USB_ANALOG_USB2_CHRG_DETECT 132
197
+#define USB_ANALOG_USB2_CHRG_DETECT_SET 133
198
+#define USB_ANALOG_USB2_CHRG_DETECT_CLR 134
199
+#define USB_ANALOG_USB2_CHRG_DETECT_TOG 135
200
+#define USB_ANALOG_USB2_VBUS_DETECT_STAT 136
201
+#define USB_ANALOG_USB2_CHRG_DETECT_STAT 140
202
+#define USB_ANALOG_USB2_MISC 148
203
+#define USB_ANALOG_USB2_MISC_SET 149
204
+#define USB_ANALOG_USB2_MISC_CLR 150
205
+#define USB_ANALOG_USB2_MISC_TOG 151
206
+#define USB_ANALOG_DIGPROG 152
207
+#define CCM_ANALOG_MAX 4096
208
+
209
+/* CCM_CBCMR */
210
+#define R_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT (18)
211
+#define R_CBCMR_PRE_PERIPH_CLK_SEL_LENGTH (2)
212
+#define R_CBCMR_PERIPH_CLK2_SEL_SHIFT (12)
213
+#define R_CBCMR_PERIPH_CLK2_SEL_LENGTH (2)
214
+
215
+/* CCM_CBCDR */
216
+#define R_CBCDR_AHB_PODF_SHIFT (10)
217
+#define R_CBCDR_AHB_PODF_LENGTH (3)
218
+#define R_CBCDR_IPG_PODF_SHIFT (8)
219
+#define R_CBCDR_IPG_PODF_LENGTH (2)
220
+#define R_CBCDR_PERIPH_CLK_SEL_SHIFT (25)
221
+#define R_CBCDR_PERIPH_CLK_SEL_LENGTH (1)
222
+#define R_CBCDR_PERIPH_CLK2_PODF_SHIFT (27)
223
+#define R_CBCDR_PERIPH_CLK2_PODF_LENGTH (3)
224
+
225
+/* CCM_CSCMR1 */
226
+#define R_CSCMR1_PERCLK_PODF_SHIFT (0)
227
+#define R_CSCMR1_PERCLK_PODF_LENGTH (6)
228
+#define R_CSCMR1_PERCLK_CLK_SEL_SHIFT (6)
229
+#define R_CSCMR1_PERCLK_CLK_SEL_LENGTH (1)
230
+
231
+/* CCM_ANALOG_PFD_528 */
232
+#define R_ANALOG_PFD_528_PFD0_FRAC_SHIFT (0)
233
+#define R_ANALOG_PFD_528_PFD0_FRAC_LENGTH (6)
234
+#define R_ANALOG_PFD_528_PFD2_FRAC_SHIFT (16)
235
+#define R_ANALOG_PFD_528_PFD2_FRAC_LENGTH (6)
236
+
237
+/* CCM_ANALOG_PLL_SYS */
238
+#define R_ANALOG_PLL_SYS_DIV_SELECT_SHIFT (0)
239
+#define R_ANALOG_PLL_SYS_DIV_SELECT_LENGTH (1)
240
+
241
+#define CCM_ANALOG_PLL_LOCK (1 << 31);
242
+
243
+#define TYPE_IMX6UL_CCM "imx6ul.ccm"
244
+#define IMX6UL_CCM(obj) OBJECT_CHECK(IMX6ULCCMState, (obj), TYPE_IMX6UL_CCM)
245
+
246
+typedef struct IMX6ULCCMState {
247
+ /* <private> */
248
+ IMXCCMState parent_obj;
249
+
250
+ /* <public> */
251
+ MemoryRegion container;
252
+ MemoryRegion ioccm;
253
+ MemoryRegion ioanalog;
254
+
255
+ uint32_t ccm[CCM_MAX];
256
+ uint32_t analog[CCM_ANALOG_MAX];
257
+
258
+} IMX6ULCCMState;
259
+
260
+#endif /* IMX6UL_CCM_H */
261
diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
262
new file mode 100644
118
new file mode 100644
263
index XXXXXXX..XXXXXXX
119
index XXXXXXX..XXXXXXX
264
--- /dev/null
120
--- /dev/null
265
+++ b/hw/misc/imx6ul_ccm.c
121
+++ b/hw/misc/bcm2835_powermgt.c
266
@@ -XXX,XX +XXX,XX @@
122
@@ -XXX,XX +XXX,XX @@
267
+/*
123
+/*
268
+ * IMX6UL Clock Control Module
124
+ * BCM2835 Power Management emulation
269
+ *
125
+ *
270
+ * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net>
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
271
+ *
128
+ *
272
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
273
+ * See the COPYING file in the top-level directory.
130
+ * See the COPYING file in the top-level directory.
274
+ *
275
+ * To get the timer frequencies right, we need to emulate at least part of
276
+ * the CCM.
277
+ */
131
+ */
278
+
132
+
279
+#include "qemu/osdep.h"
133
+#include "qemu/osdep.h"
280
+#include "hw/registerfields.h"
281
+#include "hw/misc/imx6ul_ccm.h"
282
+#include "qemu/log.h"
134
+#include "qemu/log.h"
283
+
135
+#include "qemu/module.h"
284
+#include "trace.h"
136
+#include "hw/misc/bcm2835_powermgt.h"
285
+
137
+#include "migration/vmstate.h"
286
+static const char *imx6ul_ccm_reg_name(uint32_t reg)
138
+#include "sysemu/runstate.h"
287
+{
139
+
288
+ static char unknown[20];
140
+#define PASSWORD 0x5a000000
289
+
141
+#define PASSWORD_MASK 0xff000000
290
+ switch (reg) {
142
+
291
+ case CCM_CCR:
143
+#define R_RSTC 0x1c
292
+ return "CCR";
144
+#define V_RSTC_RESET 0x20
293
+ case CCM_CCDR:
145
+#define R_RSTS 0x20
294
+ return "CCDR";
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
295
+ case CCM_CSR:
147
+#define R_WDOG 0x24
296
+ return "CSR";
148
+
297
+ case CCM_CCSR:
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
298
+ return "CCSR";
150
+ unsigned size)
299
+ case CCM_CACRR:
151
+{
300
+ return "CACRR";
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
301
+ case CCM_CBCDR:
153
+ uint32_t res = 0;
302
+ return "CBCDR";
154
+
303
+ case CCM_CBCMR:
155
+ switch (offset) {
304
+ return "CBCMR";
156
+ case R_RSTC:
305
+ case CCM_CSCMR1:
157
+ res = s->rstc;
306
+ return "CSCMR1";
158
+ break;
307
+ case CCM_CSCMR2:
159
+ case R_RSTS:
308
+ return "CSCMR2";
160
+ res = s->rsts;
309
+ case CCM_CSCDR1:
161
+ break;
310
+ return "CSCDR1";
162
+ case R_WDOG:
311
+ case CCM_CS1CDR:
163
+ res = s->wdog;
312
+ return "CS1CDR";
164
+ break;
313
+ case CCM_CS2CDR:
165
+
314
+ return "CS2CDR";
315
+ case CCM_CDCDR:
316
+ return "CDCDR";
317
+ case CCM_CHSCCDR:
318
+ return "CHSCCDR";
319
+ case CCM_CSCDR2:
320
+ return "CSCDR2";
321
+ case CCM_CSCDR3:
322
+ return "CSCDR3";
323
+ case CCM_CDHIPR:
324
+ return "CDHIPR";
325
+ case CCM_CTOR:
326
+ return "CTOR";
327
+ case CCM_CLPCR:
328
+ return "CLPCR";
329
+ case CCM_CISR:
330
+ return "CISR";
331
+ case CCM_CIMR:
332
+ return "CIMR";
333
+ case CCM_CCOSR:
334
+ return "CCOSR";
335
+ case CCM_CGPR:
336
+ return "CGPR";
337
+ case CCM_CCGR0:
338
+ return "CCGR0";
339
+ case CCM_CCGR1:
340
+ return "CCGR1";
341
+ case CCM_CCGR2:
342
+ return "CCGR2";
343
+ case CCM_CCGR3:
344
+ return "CCGR3";
345
+ case CCM_CCGR4:
346
+ return "CCGR4";
347
+ case CCM_CCGR5:
348
+ return "CCGR5";
349
+ case CCM_CCGR6:
350
+ return "CCGR6";
351
+ case CCM_CMEOR:
352
+ return "CMEOR";
353
+ default:
166
+ default:
354
+ sprintf(unknown, "%d ?", reg);
167
+ qemu_log_mask(LOG_UNIMP,
355
+ return unknown;
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
356
+ }
169
+ "\n", offset);
357
+}
170
+ res = 0;
358
+
171
+ break;
359
+static const char *imx6ul_analog_reg_name(uint32_t reg)
172
+ }
360
+{
173
+
361
+ static char unknown[20];
174
+ return res;
362
+
175
+}
363
+ switch (reg) {
176
+
364
+ case CCM_ANALOG_PLL_ARM:
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
365
+ return "PLL_ARM";
178
+ uint64_t value, unsigned size)
366
+ case CCM_ANALOG_PLL_ARM_SET:
179
+{
367
+ return "PLL_ARM_SET";
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
368
+ case CCM_ANALOG_PLL_ARM_CLR:
181
+
369
+ return "PLL_ARM_CLR";
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
370
+ case CCM_ANALOG_PLL_ARM_TOG:
183
+ qemu_log_mask(LOG_GUEST_ERROR,
371
+ return "PLL_ARM_TOG";
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
372
+ case CCM_ANALOG_PLL_USB1:
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
373
+ return "PLL_USB1";
186
+ value, offset);
374
+ case CCM_ANALOG_PLL_USB1_SET:
187
+ return;
375
+ return "PLL_USB1_SET";
188
+ }
376
+ case CCM_ANALOG_PLL_USB1_CLR:
189
+
377
+ return "PLL_USB1_CLR";
190
+ value = value & ~PASSWORD_MASK;
378
+ case CCM_ANALOG_PLL_USB1_TOG:
191
+
379
+ return "PLL_USB1_TOG";
192
+ switch (offset) {
380
+ case CCM_ANALOG_PLL_USB2:
193
+ case R_RSTC:
381
+ return "PLL_USB2";
194
+ s->rstc = value;
382
+ case CCM_ANALOG_PLL_USB2_SET:
195
+ if (value & V_RSTC_RESET) {
383
+ return "PLL_USB2_SET";
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
384
+ case CCM_ANALOG_PLL_USB2_CLR:
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
385
+ return "PLL_USB2_CLR";
198
+ } else {
386
+ case CCM_ANALOG_PLL_USB2_TOG:
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
387
+ return "PLL_USB2_TOG";
200
+ }
388
+ case CCM_ANALOG_PLL_SYS:
201
+ }
389
+ return "PLL_SYS";
202
+ break;
390
+ case CCM_ANALOG_PLL_SYS_SET:
203
+ case R_RSTS:
391
+ return "PLL_SYS_SET";
204
+ qemu_log_mask(LOG_UNIMP,
392
+ case CCM_ANALOG_PLL_SYS_CLR:
205
+ "bcm2835_powermgt_write: RSTS\n");
393
+ return "PLL_SYS_CLR";
206
+ s->rsts = value;
394
+ case CCM_ANALOG_PLL_SYS_TOG:
207
+ break;
395
+ return "PLL_SYS_TOG";
208
+ case R_WDOG:
396
+ case CCM_ANALOG_PLL_SYS_SS:
209
+ qemu_log_mask(LOG_UNIMP,
397
+ return "PLL_SYS_SS";
210
+ "bcm2835_powermgt_write: WDOG\n");
398
+ case CCM_ANALOG_PLL_SYS_NUM:
211
+ s->wdog = value;
399
+ return "PLL_SYS_NUM";
212
+ break;
400
+ case CCM_ANALOG_PLL_SYS_DENOM:
213
+
401
+ return "PLL_SYS_DENOM";
402
+ case CCM_ANALOG_PLL_AUDIO:
403
+ return "PLL_AUDIO";
404
+ case CCM_ANALOG_PLL_AUDIO_SET:
405
+ return "PLL_AUDIO_SET";
406
+ case CCM_ANALOG_PLL_AUDIO_CLR:
407
+ return "PLL_AUDIO_CLR";
408
+ case CCM_ANALOG_PLL_AUDIO_TOG:
409
+ return "PLL_AUDIO_TOG";
410
+ case CCM_ANALOG_PLL_AUDIO_NUM:
411
+ return "PLL_AUDIO_NUM";
412
+ case CCM_ANALOG_PLL_AUDIO_DENOM:
413
+ return "PLL_AUDIO_DENOM";
414
+ case CCM_ANALOG_PLL_VIDEO:
415
+ return "PLL_VIDEO";
416
+ case CCM_ANALOG_PLL_VIDEO_SET:
417
+ return "PLL_VIDEO_SET";
418
+ case CCM_ANALOG_PLL_VIDEO_CLR:
419
+ return "PLL_VIDEO_CLR";
420
+ case CCM_ANALOG_PLL_VIDEO_TOG:
421
+ return "PLL_VIDEO_TOG";
422
+ case CCM_ANALOG_PLL_VIDEO_NUM:
423
+ return "PLL_VIDEO_NUM";
424
+ case CCM_ANALOG_PLL_VIDEO_DENOM:
425
+ return "PLL_VIDEO_DENOM";
426
+ case CCM_ANALOG_PLL_ENET:
427
+ return "PLL_ENET";
428
+ case CCM_ANALOG_PLL_ENET_SET:
429
+ return "PLL_ENET_SET";
430
+ case CCM_ANALOG_PLL_ENET_CLR:
431
+ return "PLL_ENET_CLR";
432
+ case CCM_ANALOG_PLL_ENET_TOG:
433
+ return "PLL_ENET_TOG";
434
+ case CCM_ANALOG_PFD_480:
435
+ return "PFD_480";
436
+ case CCM_ANALOG_PFD_480_SET:
437
+ return "PFD_480_SET";
438
+ case CCM_ANALOG_PFD_480_CLR:
439
+ return "PFD_480_CLR";
440
+ case CCM_ANALOG_PFD_480_TOG:
441
+ return "PFD_480_TOG";
442
+ case CCM_ANALOG_PFD_528:
443
+ return "PFD_528";
444
+ case CCM_ANALOG_PFD_528_SET:
445
+ return "PFD_528_SET";
446
+ case CCM_ANALOG_PFD_528_CLR:
447
+ return "PFD_528_CLR";
448
+ case CCM_ANALOG_PFD_528_TOG:
449
+ return "PFD_528_TOG";
450
+ case CCM_ANALOG_MISC0:
451
+ return "MISC0";
452
+ case CCM_ANALOG_MISC0_SET:
453
+ return "MISC0_SET";
454
+ case CCM_ANALOG_MISC0_CLR:
455
+ return "MISC0_CLR";
456
+ case CCM_ANALOG_MISC0_TOG:
457
+ return "MISC0_TOG";
458
+ case CCM_ANALOG_MISC2:
459
+ return "MISC2";
460
+ case CCM_ANALOG_MISC2_SET:
461
+ return "MISC2_SET";
462
+ case CCM_ANALOG_MISC2_CLR:
463
+ return "MISC2_CLR";
464
+ case CCM_ANALOG_MISC2_TOG:
465
+ return "MISC2_TOG";
466
+ case PMU_REG_1P1:
467
+ return "PMU_REG_1P1";
468
+ case PMU_REG_3P0:
469
+ return "PMU_REG_3P0";
470
+ case PMU_REG_2P5:
471
+ return "PMU_REG_2P5";
472
+ case PMU_REG_CORE:
473
+ return "PMU_REG_CORE";
474
+ case PMU_MISC1:
475
+ return "PMU_MISC1";
476
+ case PMU_MISC1_SET:
477
+ return "PMU_MISC1_SET";
478
+ case PMU_MISC1_CLR:
479
+ return "PMU_MISC1_CLR";
480
+ case PMU_MISC1_TOG:
481
+ return "PMU_MISC1_TOG";
482
+ case USB_ANALOG_DIGPROG:
483
+ return "USB_ANALOG_DIGPROG";
484
+ default:
214
+ default:
485
+ sprintf(unknown, "%d ?", reg);
215
+ qemu_log_mask(LOG_UNIMP,
486
+ return unknown;
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
487
+ }
217
+ "\n", offset);
488
+}
218
+ break;
489
+
219
+ }
490
+#define CKIH_FREQ 24000000 /* 24MHz crystal input */
220
+}
491
+
221
+
492
+static const VMStateDescription vmstate_imx6ul_ccm = {
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
493
+ .name = TYPE_IMX6UL_CCM,
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,
494
+ .version_id = 1,
232
+ .version_id = 1,
495
+ .minimum_version_id = 1,
233
+ .minimum_version_id = 1,
496
+ .fields = (VMStateField[]) {
234
+ .fields = (VMStateField[]) {
497
+ VMSTATE_UINT32_ARRAY(ccm, IMX6ULCCMState, CCM_MAX),
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
498
+ VMSTATE_UINT32_ARRAY(analog, IMX6ULCCMState, CCM_ANALOG_MAX),
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
499
+ VMSTATE_END_OF_LIST()
238
+ VMSTATE_END_OF_LIST()
500
+ },
239
+ }
501
+};
240
+};
502
+
241
+
503
+static uint64_t imx6ul_analog_get_osc_clk(IMX6ULCCMState *dev)
242
+static void bcm2835_powermgt_init(Object *obj)
504
+{
243
+{
505
+ uint64_t freq = CKIH_FREQ;
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
506
+
245
+
507
+ trace_ccm_freq((uint32_t)freq);
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
508
+
247
+ TYPE_BCM2835_POWERMGT, 0x200);
509
+ return freq;
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
510
+}
249
+}
511
+
250
+
512
+static uint64_t imx6ul_analog_get_pll2_clk(IMX6ULCCMState *dev)
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
513
+{
252
+{
514
+ uint64_t freq = imx6ul_analog_get_osc_clk(dev);
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
515
+
254
+
516
+ if (FIELD_EX32(dev->analog[CCM_ANALOG_PLL_SYS],
255
+ /* https://elinux.org/BCM2835_registers#PM */
517
+ ANALOG_PLL_SYS, DIV_SELECT)) {
256
+ s->rstc = 0x00000102;
518
+ freq *= 22;
257
+ s->rsts = 0x00001000;
519
+ } else {
258
+ s->wdog = 0x00000000;
520
+ freq *= 20;
259
+}
521
+ }
260
+
522
+
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
523
+ trace_ccm_freq((uint32_t)freq);
524
+
525
+ return freq;
526
+}
527
+
528
+static uint64_t imx6ul_analog_get_pll3_clk(IMX6ULCCMState *dev)
529
+{
530
+ uint64_t freq = imx6ul_analog_get_osc_clk(dev) * 20;
531
+
532
+ trace_ccm_freq((uint32_t)freq);
533
+
534
+ return freq;
535
+}
536
+
537
+static uint64_t imx6ul_analog_get_pll2_pfd0_clk(IMX6ULCCMState *dev)
538
+{
539
+ uint64_t freq = 0;
540
+
541
+ freq = imx6ul_analog_get_pll2_clk(dev) * 18
542
+ / FIELD_EX32(dev->analog[CCM_ANALOG_PFD_528],
543
+ ANALOG_PFD_528, PFD0_FRAC);
544
+
545
+ trace_ccm_freq((uint32_t)freq);
546
+
547
+ return freq;
548
+}
549
+
550
+static uint64_t imx6ul_analog_get_pll2_pfd2_clk(IMX6ULCCMState *dev)
551
+{
552
+ uint64_t freq = 0;
553
+
554
+ freq = imx6ul_analog_get_pll2_clk(dev) * 18
555
+ / FIELD_EX32(dev->analog[CCM_ANALOG_PFD_528],
556
+ ANALOG_PFD_528, PFD2_FRAC);
557
+
558
+ trace_ccm_freq((uint32_t)freq);
559
+
560
+ return freq;
561
+}
562
+
563
+static uint64_t imx6ul_analog_pll2_bypass_clk(IMX6ULCCMState *dev)
564
+{
565
+ uint64_t freq = 0;
566
+
567
+ trace_ccm_freq((uint32_t)freq);
568
+
569
+ return freq;
570
+}
571
+
572
+static uint64_t imx6ul_ccm_get_periph_clk2_sel_clk(IMX6ULCCMState *dev)
573
+{
574
+ uint64_t freq = 0;
575
+
576
+ switch (FIELD_EX32(dev->ccm[CCM_CBCMR], CBCMR, PERIPH_CLK2_SEL)) {
577
+ case 0:
578
+ freq = imx6ul_analog_get_pll3_clk(dev);
579
+ break;
580
+ case 1:
581
+ freq = imx6ul_analog_get_osc_clk(dev);
582
+ break;
583
+ case 2:
584
+ freq = imx6ul_analog_pll2_bypass_clk(dev);
585
+ break;
586
+ case 3:
587
+ /* We should never get there as 3 is a reserved value */
588
+ qemu_log_mask(LOG_GUEST_ERROR,
589
+ "[%s]%s: unsupported PERIPH_CLK2_SEL value 3\n",
590
+ TYPE_IMX6UL_CCM, __func__);
591
+ /* freq is set to 0 as we don't know what it should be */
592
+ break;
593
+ default:
594
+ g_assert_not_reached();
595
+ }
596
+
597
+ trace_ccm_freq((uint32_t)freq);
598
+
599
+ return freq;
600
+}
601
+
602
+static uint64_t imx6ul_ccm_get_periph_clk_sel_clk(IMX6ULCCMState *dev)
603
+{
604
+ uint64_t freq = 0;
605
+
606
+ switch (FIELD_EX32(dev->ccm[CCM_CBCMR], CBCMR, PRE_PERIPH_CLK_SEL)) {
607
+ case 0:
608
+ freq = imx6ul_analog_get_pll2_clk(dev);
609
+ break;
610
+ case 1:
611
+ freq = imx6ul_analog_get_pll2_pfd2_clk(dev);
612
+ break;
613
+ case 2:
614
+ freq = imx6ul_analog_get_pll2_pfd0_clk(dev);
615
+ break;
616
+ case 3:
617
+ freq = imx6ul_analog_get_pll2_pfd2_clk(dev) / 2;
618
+ break;
619
+ default:
620
+ g_assert_not_reached();
621
+ }
622
+
623
+ trace_ccm_freq((uint32_t)freq);
624
+
625
+ return freq;
626
+}
627
+
628
+static uint64_t imx6ul_ccm_get_periph_clk2_clk(IMX6ULCCMState *dev)
629
+{
630
+ uint64_t freq = 0;
631
+
632
+ freq = imx6ul_ccm_get_periph_clk2_sel_clk(dev)
633
+ / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, PERIPH_CLK2_PODF));
634
+
635
+ trace_ccm_freq((uint32_t)freq);
636
+
637
+ return freq;
638
+}
639
+
640
+static uint64_t imx6ul_ccm_get_periph_sel_clk(IMX6ULCCMState *dev)
641
+{
642
+ uint64_t freq = 0;
643
+
644
+ switch (FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, PERIPH_CLK_SEL)) {
645
+ case 0:
646
+ freq = imx6ul_ccm_get_periph_clk_sel_clk(dev);
647
+ break;
648
+ case 1:
649
+ freq = imx6ul_ccm_get_periph_clk2_clk(dev);
650
+ break;
651
+ default:
652
+ g_assert_not_reached();
653
+ }
654
+
655
+ trace_ccm_freq((uint32_t)freq);
656
+
657
+ return freq;
658
+}
659
+
660
+static uint64_t imx6ul_ccm_get_ahb_clk(IMX6ULCCMState *dev)
661
+{
662
+ uint64_t freq = 0;
663
+
664
+ freq = imx6ul_ccm_get_periph_sel_clk(dev)
665
+ / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, AHB_PODF));
666
+
667
+ trace_ccm_freq((uint32_t)freq);
668
+
669
+ return freq;
670
+}
671
+
672
+static uint64_t imx6ul_ccm_get_ipg_clk(IMX6ULCCMState *dev)
673
+{
674
+ uint64_t freq = 0;
675
+
676
+ freq = imx6ul_ccm_get_ahb_clk(dev)
677
+ / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, IPG_PODF));
678
+
679
+ trace_ccm_freq((uint32_t)freq);
680
+
681
+ return freq;
682
+}
683
+
684
+static uint64_t imx6ul_ccm_get_per_sel_clk(IMX6ULCCMState *dev)
685
+{
686
+ uint64_t freq = 0;
687
+
688
+ switch (FIELD_EX32(dev->ccm[CCM_CSCMR1], CSCMR1, PERCLK_CLK_SEL)) {
689
+ case 0:
690
+ freq = imx6ul_ccm_get_ipg_clk(dev);
691
+ break;
692
+ case 1:
693
+ freq = imx6ul_analog_get_osc_clk(dev);
694
+ break;
695
+ default:
696
+ g_assert_not_reached();
697
+ }
698
+
699
+ trace_ccm_freq((uint32_t)freq);
700
+
701
+ return freq;
702
+}
703
+
704
+static uint64_t imx6ul_ccm_get_per_clk(IMX6ULCCMState *dev)
705
+{
706
+ uint64_t freq = 0;
707
+
708
+ freq = imx6ul_ccm_get_per_sel_clk(dev)
709
+ / (1 + FIELD_EX32(dev->ccm[CCM_CSCMR1], CSCMR1, PERCLK_PODF));
710
+
711
+ trace_ccm_freq((uint32_t)freq);
712
+
713
+ return freq;
714
+}
715
+
716
+static uint32_t imx6ul_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
717
+{
718
+ uint32_t freq = 0;
719
+ IMX6ULCCMState *s = IMX6UL_CCM(dev);
720
+
721
+ switch (clock) {
722
+ case CLK_NONE:
723
+ break;
724
+ case CLK_IPG:
725
+ freq = imx6ul_ccm_get_ipg_clk(s);
726
+ break;
727
+ case CLK_IPG_HIGH:
728
+ freq = imx6ul_ccm_get_per_clk(s);
729
+ break;
730
+ case CLK_32k:
731
+ freq = CKIL_FREQ;
732
+ break;
733
+ case CLK_HIGH:
734
+ freq = CKIH_FREQ;
735
+ break;
736
+ case CLK_HIGH_DIV:
737
+ freq = CKIH_FREQ / 8;
738
+ break;
739
+ default:
740
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
741
+ TYPE_IMX6UL_CCM, __func__, clock);
742
+ break;
743
+ }
744
+
745
+ trace_ccm_clock_freq(clock, freq);
746
+
747
+ return freq;
748
+}
749
+
750
+static void imx6ul_ccm_reset(DeviceState *dev)
751
+{
752
+ IMX6ULCCMState *s = IMX6UL_CCM(dev);
753
+
754
+ trace_ccm_entry();
755
+
756
+ s->ccm[CCM_CCR] = 0x0401167F;
757
+ s->ccm[CCM_CCDR] = 0x00000000;
758
+ s->ccm[CCM_CSR] = 0x00000010;
759
+ s->ccm[CCM_CCSR] = 0x00000100;
760
+ s->ccm[CCM_CACRR] = 0x00000000;
761
+ s->ccm[CCM_CBCDR] = 0x00018D00;
762
+ s->ccm[CCM_CBCMR] = 0x24860324;
763
+ s->ccm[CCM_CSCMR1] = 0x04900080;
764
+ s->ccm[CCM_CSCMR2] = 0x03192F06;
765
+ s->ccm[CCM_CSCDR1] = 0x00490B00;
766
+ s->ccm[CCM_CS1CDR] = 0x0EC102C1;
767
+ s->ccm[CCM_CS2CDR] = 0x000336C1;
768
+ s->ccm[CCM_CDCDR] = 0x33F71F92;
769
+ s->ccm[CCM_CHSCCDR] = 0x000248A4;
770
+ s->ccm[CCM_CSCDR2] = 0x00029B48;
771
+ s->ccm[CCM_CSCDR3] = 0x00014841;
772
+ s->ccm[CCM_CDHIPR] = 0x00000000;
773
+ s->ccm[CCM_CTOR] = 0x00000000;
774
+ s->ccm[CCM_CLPCR] = 0x00000079;
775
+ s->ccm[CCM_CISR] = 0x00000000;
776
+ s->ccm[CCM_CIMR] = 0xFFFFFFFF;
777
+ s->ccm[CCM_CCOSR] = 0x000A0001;
778
+ s->ccm[CCM_CGPR] = 0x0000FE62;
779
+ s->ccm[CCM_CCGR0] = 0xFFFFFFFF;
780
+ s->ccm[CCM_CCGR1] = 0xFFFFFFFF;
781
+ s->ccm[CCM_CCGR2] = 0xFC3FFFFF;
782
+ s->ccm[CCM_CCGR3] = 0xFFFFFFFF;
783
+ s->ccm[CCM_CCGR4] = 0xFFFFFFFF;
784
+ s->ccm[CCM_CCGR5] = 0xFFFFFFFF;
785
+ s->ccm[CCM_CCGR6] = 0xFFFFFFFF;
786
+ s->ccm[CCM_CMEOR] = 0xFFFFFFFF;
787
+
788
+ s->analog[CCM_ANALOG_PLL_ARM] = 0x00013063;
789
+ s->analog[CCM_ANALOG_PLL_USB1] = 0x00012000;
790
+ s->analog[CCM_ANALOG_PLL_USB2] = 0x00012000;
791
+ s->analog[CCM_ANALOG_PLL_SYS] = 0x00013001;
792
+ s->analog[CCM_ANALOG_PLL_SYS_SS] = 0x00000000;
793
+ s->analog[CCM_ANALOG_PLL_SYS_NUM] = 0x00000000;
794
+ s->analog[CCM_ANALOG_PLL_SYS_DENOM] = 0x00000012;
795
+ s->analog[CCM_ANALOG_PLL_AUDIO] = 0x00011006;
796
+ s->analog[CCM_ANALOG_PLL_AUDIO_NUM] = 0x05F5E100;
797
+ s->analog[CCM_ANALOG_PLL_AUDIO_DENOM] = 0x2964619C;
798
+ s->analog[CCM_ANALOG_PLL_VIDEO] = 0x0001100C;
799
+ s->analog[CCM_ANALOG_PLL_VIDEO_NUM] = 0x05F5E100;
800
+ s->analog[CCM_ANALOG_PLL_VIDEO_DENOM] = 0x10A24447;
801
+ s->analog[CCM_ANALOG_PLL_ENET] = 0x00011001;
802
+ s->analog[CCM_ANALOG_PFD_480] = 0x1311100C;
803
+ s->analog[CCM_ANALOG_PFD_528] = 0x1018101B;
804
+
805
+ s->analog[PMU_REG_1P1] = 0x00001073;
806
+ s->analog[PMU_REG_3P0] = 0x00000F74;
807
+ s->analog[PMU_REG_2P5] = 0x00001073;
808
+ s->analog[PMU_REG_CORE] = 0x00482012;
809
+ s->analog[PMU_MISC0] = 0x04000000;
810
+ s->analog[PMU_MISC1] = 0x00000000;
811
+ s->analog[PMU_MISC2] = 0x00272727;
812
+ s->analog[PMU_LOWPWR_CTRL] = 0x00004009;
813
+
814
+ s->analog[USB_ANALOG_USB1_VBUS_DETECT] = 0x01000004;
815
+ s->analog[USB_ANALOG_USB1_CHRG_DETECT] = 0x00000000;
816
+ s->analog[USB_ANALOG_USB1_VBUS_DETECT_STAT] = 0x00000000;
817
+ s->analog[USB_ANALOG_USB1_CHRG_DETECT_STAT] = 0x00000000;
818
+ s->analog[USB_ANALOG_USB1_MISC] = 0x00000002;
819
+ s->analog[USB_ANALOG_USB2_VBUS_DETECT] = 0x01000004;
820
+ s->analog[USB_ANALOG_USB2_CHRG_DETECT] = 0x00000000;
821
+ s->analog[USB_ANALOG_USB2_MISC] = 0x00000002;
822
+ s->analog[USB_ANALOG_DIGPROG] = 0x00640000;
823
+
824
+ /* all PLLs need to be locked */
825
+ s->analog[CCM_ANALOG_PLL_ARM] |= CCM_ANALOG_PLL_LOCK;
826
+ s->analog[CCM_ANALOG_PLL_USB1] |= CCM_ANALOG_PLL_LOCK;
827
+ s->analog[CCM_ANALOG_PLL_USB2] |= CCM_ANALOG_PLL_LOCK;
828
+ s->analog[CCM_ANALOG_PLL_SYS] |= CCM_ANALOG_PLL_LOCK;
829
+ s->analog[CCM_ANALOG_PLL_AUDIO] |= CCM_ANALOG_PLL_LOCK;
830
+ s->analog[CCM_ANALOG_PLL_VIDEO] |= CCM_ANALOG_PLL_LOCK;
831
+ s->analog[CCM_ANALOG_PLL_ENET] |= CCM_ANALOG_PLL_LOCK;
832
+
833
+ s->analog[TEMPMON_TEMPSENSE0] = 0x00000001;
834
+ s->analog[TEMPMON_TEMPSENSE1] = 0x00000001;
835
+ s->analog[TEMPMON_TEMPSENSE2] = 0x00000000;
836
+}
837
+
838
+static uint64_t imx6ul_ccm_read(void *opaque, hwaddr offset, unsigned size)
839
+{
840
+ uint32_t value = 0;
841
+ uint32_t index = offset >> 2;
842
+ IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
843
+
844
+ assert(index < CCM_MAX);
845
+
846
+ value = s->ccm[index];
847
+
848
+ trace_ccm_read_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
849
+
850
+ return (uint64_t)value;
851
+}
852
+
853
+static void imx6ul_ccm_write(void *opaque, hwaddr offset, uint64_t value,
854
+ unsigned size)
855
+{
856
+ uint32_t index = offset >> 2;
857
+ IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
858
+
859
+ assert(index < CCM_MAX);
860
+
861
+ trace_ccm_write_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
862
+
863
+ /*
864
+ * We will do a better implementation later. In particular some bits
865
+ * cannot be written to.
866
+ */
867
+ s->ccm[index] = (uint32_t)value;
868
+}
869
+
870
+static uint64_t imx6ul_analog_read(void *opaque, hwaddr offset, unsigned size)
871
+{
872
+ uint32_t value;
873
+ uint32_t index = offset >> 2;
874
+ IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
875
+
876
+ assert(index < CCM_ANALOG_MAX);
877
+
878
+ switch (index) {
879
+ case CCM_ANALOG_PLL_ARM_SET:
880
+ case CCM_ANALOG_PLL_USB1_SET:
881
+ case CCM_ANALOG_PLL_USB2_SET:
882
+ case CCM_ANALOG_PLL_SYS_SET:
883
+ case CCM_ANALOG_PLL_AUDIO_SET:
884
+ case CCM_ANALOG_PLL_VIDEO_SET:
885
+ case CCM_ANALOG_PLL_ENET_SET:
886
+ case CCM_ANALOG_PFD_480_SET:
887
+ case CCM_ANALOG_PFD_528_SET:
888
+ case CCM_ANALOG_MISC0_SET:
889
+ case PMU_MISC1_SET:
890
+ case CCM_ANALOG_MISC2_SET:
891
+ case USB_ANALOG_USB1_VBUS_DETECT_SET:
892
+ case USB_ANALOG_USB1_CHRG_DETECT_SET:
893
+ case USB_ANALOG_USB1_MISC_SET:
894
+ case USB_ANALOG_USB2_VBUS_DETECT_SET:
895
+ case USB_ANALOG_USB2_CHRG_DETECT_SET:
896
+ case USB_ANALOG_USB2_MISC_SET:
897
+ case TEMPMON_TEMPSENSE0_SET:
898
+ case TEMPMON_TEMPSENSE1_SET:
899
+ case TEMPMON_TEMPSENSE2_SET:
900
+ /*
901
+ * All REG_NAME_SET register access are in fact targeting
902
+ * the REG_NAME register.
903
+ */
904
+ value = s->analog[index - 1];
905
+ break;
906
+ case CCM_ANALOG_PLL_ARM_CLR:
907
+ case CCM_ANALOG_PLL_USB1_CLR:
908
+ case CCM_ANALOG_PLL_USB2_CLR:
909
+ case CCM_ANALOG_PLL_SYS_CLR:
910
+ case CCM_ANALOG_PLL_AUDIO_CLR:
911
+ case CCM_ANALOG_PLL_VIDEO_CLR:
912
+ case CCM_ANALOG_PLL_ENET_CLR:
913
+ case CCM_ANALOG_PFD_480_CLR:
914
+ case CCM_ANALOG_PFD_528_CLR:
915
+ case CCM_ANALOG_MISC0_CLR:
916
+ case PMU_MISC1_CLR:
917
+ case CCM_ANALOG_MISC2_CLR:
918
+ case USB_ANALOG_USB1_VBUS_DETECT_CLR:
919
+ case USB_ANALOG_USB1_CHRG_DETECT_CLR:
920
+ case USB_ANALOG_USB1_MISC_CLR:
921
+ case USB_ANALOG_USB2_VBUS_DETECT_CLR:
922
+ case USB_ANALOG_USB2_CHRG_DETECT_CLR:
923
+ case USB_ANALOG_USB2_MISC_CLR:
924
+ case TEMPMON_TEMPSENSE0_CLR:
925
+ case TEMPMON_TEMPSENSE1_CLR:
926
+ case TEMPMON_TEMPSENSE2_CLR:
927
+ /*
928
+ * All REG_NAME_CLR register access are in fact targeting
929
+ * the REG_NAME register.
930
+ */
931
+ value = s->analog[index - 2];
932
+ break;
933
+ case CCM_ANALOG_PLL_ARM_TOG:
934
+ case CCM_ANALOG_PLL_USB1_TOG:
935
+ case CCM_ANALOG_PLL_USB2_TOG:
936
+ case CCM_ANALOG_PLL_SYS_TOG:
937
+ case CCM_ANALOG_PLL_AUDIO_TOG:
938
+ case CCM_ANALOG_PLL_VIDEO_TOG:
939
+ case CCM_ANALOG_PLL_ENET_TOG:
940
+ case CCM_ANALOG_PFD_480_TOG:
941
+ case CCM_ANALOG_PFD_528_TOG:
942
+ case CCM_ANALOG_MISC0_TOG:
943
+ case PMU_MISC1_TOG:
944
+ case CCM_ANALOG_MISC2_TOG:
945
+ case USB_ANALOG_USB1_VBUS_DETECT_TOG:
946
+ case USB_ANALOG_USB1_CHRG_DETECT_TOG:
947
+ case USB_ANALOG_USB1_MISC_TOG:
948
+ case USB_ANALOG_USB2_VBUS_DETECT_TOG:
949
+ case USB_ANALOG_USB2_CHRG_DETECT_TOG:
950
+ case USB_ANALOG_USB2_MISC_TOG:
951
+ case TEMPMON_TEMPSENSE0_TOG:
952
+ case TEMPMON_TEMPSENSE1_TOG:
953
+ case TEMPMON_TEMPSENSE2_TOG:
954
+ /*
955
+ * All REG_NAME_TOG register access are in fact targeting
956
+ * the REG_NAME register.
957
+ */
958
+ value = s->analog[index - 3];
959
+ break;
960
+ default:
961
+ value = s->analog[index];
962
+ break;
963
+ }
964
+
965
+ trace_ccm_read_reg(imx6ul_analog_reg_name(index), (uint32_t)value);
966
+
967
+ return (uint64_t)value;
968
+}
969
+
970
+static void imx6ul_analog_write(void *opaque, hwaddr offset, uint64_t value,
971
+ unsigned size)
972
+{
973
+ uint32_t index = offset >> 2;
974
+ IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
975
+
976
+ assert(index < CCM_ANALOG_MAX);
977
+
978
+ trace_ccm_write_reg(imx6ul_analog_reg_name(index), (uint32_t)value);
979
+
980
+ switch (index) {
981
+ case CCM_ANALOG_PLL_ARM_SET:
982
+ case CCM_ANALOG_PLL_USB1_SET:
983
+ case CCM_ANALOG_PLL_USB2_SET:
984
+ case CCM_ANALOG_PLL_SYS_SET:
985
+ case CCM_ANALOG_PLL_AUDIO_SET:
986
+ case CCM_ANALOG_PLL_VIDEO_SET:
987
+ case CCM_ANALOG_PLL_ENET_SET:
988
+ case CCM_ANALOG_PFD_480_SET:
989
+ case CCM_ANALOG_PFD_528_SET:
990
+ case CCM_ANALOG_MISC0_SET:
991
+ case PMU_MISC1_SET:
992
+ case CCM_ANALOG_MISC2_SET:
993
+ case USB_ANALOG_USB1_VBUS_DETECT_SET:
994
+ case USB_ANALOG_USB1_CHRG_DETECT_SET:
995
+ case USB_ANALOG_USB1_MISC_SET:
996
+ case USB_ANALOG_USB2_VBUS_DETECT_SET:
997
+ case USB_ANALOG_USB2_CHRG_DETECT_SET:
998
+ case USB_ANALOG_USB2_MISC_SET:
999
+ /*
1000
+ * All REG_NAME_SET register access are in fact targeting
1001
+ * the REG_NAME register. So we change the value of the
1002
+ * REG_NAME register, setting bits passed in the value.
1003
+ */
1004
+ s->analog[index - 1] |= value;
1005
+ break;
1006
+ case CCM_ANALOG_PLL_ARM_CLR:
1007
+ case CCM_ANALOG_PLL_USB1_CLR:
1008
+ case CCM_ANALOG_PLL_USB2_CLR:
1009
+ case CCM_ANALOG_PLL_SYS_CLR:
1010
+ case CCM_ANALOG_PLL_AUDIO_CLR:
1011
+ case CCM_ANALOG_PLL_VIDEO_CLR:
1012
+ case CCM_ANALOG_PLL_ENET_CLR:
1013
+ case CCM_ANALOG_PFD_480_CLR:
1014
+ case CCM_ANALOG_PFD_528_CLR:
1015
+ case CCM_ANALOG_MISC0_CLR:
1016
+ case PMU_MISC1_CLR:
1017
+ case CCM_ANALOG_MISC2_CLR:
1018
+ case USB_ANALOG_USB1_VBUS_DETECT_CLR:
1019
+ case USB_ANALOG_USB1_CHRG_DETECT_CLR:
1020
+ case USB_ANALOG_USB1_MISC_CLR:
1021
+ case USB_ANALOG_USB2_VBUS_DETECT_CLR:
1022
+ case USB_ANALOG_USB2_CHRG_DETECT_CLR:
1023
+ case USB_ANALOG_USB2_MISC_CLR:
1024
+ /*
1025
+ * All REG_NAME_CLR register access are in fact targeting
1026
+ * the REG_NAME register. So we change the value of the
1027
+ * REG_NAME register, unsetting bits passed in the value.
1028
+ */
1029
+ s->analog[index - 2] &= ~value;
1030
+ break;
1031
+ case CCM_ANALOG_PLL_ARM_TOG:
1032
+ case CCM_ANALOG_PLL_USB1_TOG:
1033
+ case CCM_ANALOG_PLL_USB2_TOG:
1034
+ case CCM_ANALOG_PLL_SYS_TOG:
1035
+ case CCM_ANALOG_PLL_AUDIO_TOG:
1036
+ case CCM_ANALOG_PLL_VIDEO_TOG:
1037
+ case CCM_ANALOG_PLL_ENET_TOG:
1038
+ case CCM_ANALOG_PFD_480_TOG:
1039
+ case CCM_ANALOG_PFD_528_TOG:
1040
+ case CCM_ANALOG_MISC0_TOG:
1041
+ case PMU_MISC1_TOG:
1042
+ case CCM_ANALOG_MISC2_TOG:
1043
+ case USB_ANALOG_USB1_VBUS_DETECT_TOG:
1044
+ case USB_ANALOG_USB1_CHRG_DETECT_TOG:
1045
+ case USB_ANALOG_USB1_MISC_TOG:
1046
+ case USB_ANALOG_USB2_VBUS_DETECT_TOG:
1047
+ case USB_ANALOG_USB2_CHRG_DETECT_TOG:
1048
+ case USB_ANALOG_USB2_MISC_TOG:
1049
+ /*
1050
+ * All REG_NAME_TOG register access are in fact targeting
1051
+ * the REG_NAME register. So we change the value of the
1052
+ * REG_NAME register, toggling bits passed in the value.
1053
+ */
1054
+ s->analog[index - 3] ^= value;
1055
+ break;
1056
+ default:
1057
+ /*
1058
+ * We will do a better implementation later. In particular some bits
1059
+ * cannot be written to.
1060
+ */
1061
+ s->analog[index] = value;
1062
+ break;
1063
+ }
1064
+}
1065
+
1066
+static const struct MemoryRegionOps imx6ul_ccm_ops = {
1067
+ .read = imx6ul_ccm_read,
1068
+ .write = imx6ul_ccm_write,
1069
+ .endianness = DEVICE_NATIVE_ENDIAN,
1070
+ .valid = {
1071
+ /*
1072
+ * Our device would not work correctly if the guest was doing
1073
+ * unaligned access. This might not be a limitation on the real
1074
+ * device but in practice there is no reason for a guest to access
1075
+ * this device unaligned.
1076
+ */
1077
+ .min_access_size = 4,
1078
+ .max_access_size = 4,
1079
+ .unaligned = false,
1080
+ },
1081
+};
1082
+
1083
+static const struct MemoryRegionOps imx6ul_analog_ops = {
1084
+ .read = imx6ul_analog_read,
1085
+ .write = imx6ul_analog_write,
1086
+ .endianness = DEVICE_NATIVE_ENDIAN,
1087
+ .valid = {
1088
+ /*
1089
+ * Our device would not work correctly if the guest was doing
1090
+ * unaligned access. This might not be a limitation on the real
1091
+ * device but in practice there is no reason for a guest to access
1092
+ * this device unaligned.
1093
+ */
1094
+ .min_access_size = 4,
1095
+ .max_access_size = 4,
1096
+ .unaligned = false,
1097
+ },
1098
+};
1099
+
1100
+static void imx6ul_ccm_init(Object *obj)
1101
+{
1102
+ DeviceState *dev = DEVICE(obj);
1103
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
1104
+ IMX6ULCCMState *s = IMX6UL_CCM(obj);
1105
+
1106
+ /* initialize a container for the all memory range */
1107
+ memory_region_init(&s->container, OBJECT(dev), TYPE_IMX6UL_CCM, 0x8000);
1108
+
1109
+ /* We initialize an IO memory region for the CCM part */
1110
+ memory_region_init_io(&s->ioccm, OBJECT(dev), &imx6ul_ccm_ops, s,
1111
+ TYPE_IMX6UL_CCM ".ccm", CCM_MAX * sizeof(uint32_t));
1112
+
1113
+ /* Add the CCM as a subregion at offset 0 */
1114
+ memory_region_add_subregion(&s->container, 0, &s->ioccm);
1115
+
1116
+ /* We initialize an IO memory region for the ANALOG part */
1117
+ memory_region_init_io(&s->ioanalog, OBJECT(dev), &imx6ul_analog_ops, s,
1118
+ TYPE_IMX6UL_CCM ".analog",
1119
+ CCM_ANALOG_MAX * sizeof(uint32_t));
1120
+
1121
+ /* Add the ANALOG as a subregion at offset 0x4000 */
1122
+ memory_region_add_subregion(&s->container, 0x4000, &s->ioanalog);
1123
+
1124
+ sysbus_init_mmio(sd, &s->container);
1125
+}
1126
+
1127
+static void imx6ul_ccm_class_init(ObjectClass *klass, void *data)
1128
+{
262
+{
1129
+ DeviceClass *dc = DEVICE_CLASS(klass);
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
1130
+ IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
264
+
1131
+
265
+ dc->reset = bcm2835_powermgt_reset;
1132
+ dc->reset = imx6ul_ccm_reset;
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
1133
+ dc->vmsd = &vmstate_imx6ul_ccm;
267
+}
1134
+ dc->desc = "i.MX6UL Clock Control Module";
268
+
1135
+
269
+static TypeInfo bcm2835_powermgt_info = {
1136
+ ccm->get_clock_frequency = imx6ul_ccm_get_clock_frequency;
270
+ .name = TYPE_BCM2835_POWERMGT,
1137
+}
271
+ .parent = TYPE_SYS_BUS_DEVICE,
1138
+
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
1139
+static const TypeInfo imx6ul_ccm_info = {
273
+ .class_init = bcm2835_powermgt_class_init,
1140
+ .name = TYPE_IMX6UL_CCM,
274
+ .instance_init = bcm2835_powermgt_init,
1141
+ .parent = TYPE_IMX_CCM,
275
+};
1142
+ .instance_size = sizeof(IMX6ULCCMState),
276
+
1143
+ .instance_init = imx6ul_ccm_init,
277
+static void bcm2835_powermgt_register_types(void)
1144
+ .class_init = imx6ul_ccm_class_init,
278
+{
1145
+};
279
+ type_register_static(&bcm2835_powermgt_info);
1146
+
280
+}
1147
+static void imx6ul_ccm_register_types(void)
281
+
1148
+{
282
+type_init(bcm2835_powermgt_register_types)
1149
+ type_register_static(&imx6ul_ccm_info);
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
1150
+}
1151
+
1152
+type_init(imx6ul_ccm_register_types)
1153
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
1154
index XXXXXXX..XXXXXXX 100644
284
index XXXXXXX..XXXXXXX 100644
1155
--- a/hw/misc/trace-events
285
--- a/hw/misc/meson.build
1156
+++ b/hw/misc/trace-events
286
+++ b/hw/misc/meson.build
1157
@@ -XXX,XX +XXX,XX @@ iotkit_secctl_s_write(uint32_t offset, uint64_t data, unsigned size) "IoTKit Sec
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
1158
iotkit_secctl_ns_read(uint32_t offset, uint64_t data, unsigned size) "IoTKit SecCtl NS regs read: offset 0x%x data 0x%" PRIx64 " size %u"
288
'bcm2835_rng.c',
1159
iotkit_secctl_ns_write(uint32_t offset, uint64_t data, unsigned size) "IoTKit SecCtl NS regs write: offset 0x%x data 0x%" PRIx64 " size %u"
289
'bcm2835_thermal.c',
1160
iotkit_secctl_reset(void) "IoTKit SecCtl: reset"
290
'bcm2835_cprman.c',
1161
+
291
+ 'bcm2835_powermgt.c',
1162
+# hw/misc/imx6ul_ccm.c
292
))
1163
+ccm_entry(void) "\n"
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
1164
+ccm_freq(uint32_t freq) "freq = %d\n"
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
1165
+ccm_clock_freq(uint32_t clock, uint32_t freq) "(Clock = %d) = %d\n"
1166
+ccm_read_reg(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32 "\n"
1167
+ccm_write_reg(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32 "\n"
1168
--
295
--
1169
2.18.0
296
2.20.1
1170
297
1171
298
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
We were using the wrong flush-to-zero bit for the non-half input.
3
Add a test booting and quickly shutdown a raspi2 machine,
4
to test the power management model:
4
5
5
Fixes: 46d33d1e3c9
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
6
Cc: qemu-stable@nongnu.org (3.0.1)
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
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
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
console: [ 0.000000] CPU: div instructions available: patching division code
10
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
11
Message-id: 20180810193129.1556-5-richard.henderson@linaro.org
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
44
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
49
---
14
target/arm/translate-sve.c | 4 ++--
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
15
1 file changed, 2 insertions(+), 2 deletions(-)
51
1 file changed, 43 insertions(+)
16
52
17
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
18
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-sve.c
55
--- a/tests/acceptance/boot_linux_console.py
20
+++ b/target/arm/translate-sve.c
56
+++ b/tests/acceptance/boot_linux_console.py
21
@@ -XXX,XX +XXX,XX @@ static bool do_zpz_ptr(DisasContext *s, int rd, int rn, int pg,
57
@@ -XXX,XX +XXX,XX @@
22
58
from avocado import skip
23
static bool trans_FCVT_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
59
from avocado import skipUnless
24
{
60
from avocado_qemu import Test
25
- return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_sh);
61
+from avocado_qemu import exec_command
26
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_sh);
62
from avocado_qemu import exec_command_and_wait_for_pattern
27
}
63
from avocado_qemu import interrupt_interactive_console_until_pattern
28
64
from avocado_qemu import wait_for_console_pattern
29
static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
30
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
66
"""
31
67
self.do_test_arm_raspi2(0)
32
static bool trans_FCVT_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
68
33
{
69
+ def test_arm_raspi2_initrd(self):
34
- return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_dh);
70
+ """
35
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_dh);
71
+ :avocado: tags=arch:arm
36
}
72
+ :avocado: tags=machine:raspi2
37
73
+ """
38
static bool trans_FCVT_hd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
75
+ 'pool/main/r/raspberrypi-firmware/'
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
81
+
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
84
+ 'arm/rootfs-armv7a.cpio.gz')
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
89
+
90
+ self.vm.set_console()
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
93
+ 'panic=-1 noreboot ' +
94
+ 'dwc_otg.fiq_fsm_enable=0')
95
+ self.vm.add_args('-kernel', kernel_path,
96
+ '-dtb', dtb_path,
97
+ '-initrd', initrd_path,
98
+ '-append', kernel_command_line,
99
+ '-no-reboot')
100
+ self.vm.launch()
101
+ self.wait_for_console_pattern('Boot successful.')
102
+
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
39
--
114
--
40
2.18.0
115
2.20.1
41
116
42
117
diff view generated by jsdifflib
1
From: Trent Piepho <tpiepho@impinj.com>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
The current emulation will clear the XCH bit when a burst finishes.
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
4
This is not quite correct. According to the i.MX7d referemce manual,
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
5
Rev 0.1, §10.1.7.3:
5
assert due to fpst->default_nan_mode being set.
6
6
7
This bit [XCH] is cleared automatically when all data in the TXFIFO
7
To avoid this, we check to see what NaN mode we're running in before we call
8
and the shift register has been shifted out.
8
floatxx_silence_nan().
9
9
10
So XCH should be cleared when the FIFO empties, not on completion of a
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
11
burst. The FIFO is 64 x 32 bits = 2048 bits, while the max burst size
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
is larger at 4096 bits. So it's possible that the burst is not finished
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
13
after the TXFIFO empties.
14
15
Sending a large block (> 2048 bits) with the Linux driver will use a
16
burst that is larger than the TXFIFO. After the TXFIFO has emptied XCH
17
does not become unset, as the burst is not yet finished.
18
19
What should happen after the TXFIFO empties is the driver will refill it
20
and set XCH. The rising edge of XCH will trigger another transfer to
21
begin. However, since the emulation does not set XCH to 0, there is no
22
rising edge and the next trasfer never begins.
23
24
Signed-off-by: Trent Piepho <tpiepho@impinj.com>
25
Message-id: 20180731201056.29257-1-tpiepho@impinj.com
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
---
15
---
29
hw/ssi/imx_spi.c | 3 +--
16
target/arm/helper-a64.c | 12 +++++++++---
30
1 file changed, 1 insertion(+), 2 deletions(-)
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
18
2 files changed, 27 insertions(+), 9 deletions(-)
31
19
32
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
33
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/ssi/imx_spi.c
22
--- a/target/arm/helper-a64.c
35
+++ b/hw/ssi/imx_spi.c
23
+++ b/target/arm/helper-a64.c
36
@@ -XXX,XX +XXX,XX @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
25
float16 nan = a;
26
if (float16_is_signaling_nan(a, fpst)) {
27
float_raise(float_flag_invalid, fpst);
28
- nan = float16_silence_nan(a, fpst);
29
+ if (!fpst->default_nan_mode) {
30
+ nan = float16_silence_nan(a, fpst);
31
+ }
37
}
32
}
38
33
if (fpst->default_nan_mode) {
39
if (s->burst_length <= 0) {
34
nan = float16_default_nan(fpst);
40
- s->regs[ECSPI_CONREG] &= ~ECSPI_CONREG_XCH;
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
41
-
36
float32 nan = a;
42
if (!imx_spi_is_multiple_master_burst(s)) {
37
if (float32_is_signaling_nan(a, fpst)) {
43
s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
38
float_raise(float_flag_invalid, fpst);
44
break;
39
- nan = float32_silence_nan(a, fpst);
45
@@ -XXX,XX +XXX,XX @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
40
+ if (!fpst->default_nan_mode) {
46
41
+ nan = float32_silence_nan(a, fpst);
47
if (fifo32_is_empty(&s->tx_fifo)) {
42
+ }
48
s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
43
}
49
+ s->regs[ECSPI_CONREG] &= ~ECSPI_CONREG_XCH;
44
if (fpst->default_nan_mode) {
50
}
45
nan = float32_default_nan(fpst);
51
46
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
52
/* TODO: We should also use TDR and RDR bits */
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
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/vfp_helper.c
60
+++ b/target/arm/vfp_helper.c
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
62
float16 nan = f16;
63
if (float16_is_signaling_nan(f16, fpst)) {
64
float_raise(float_flag_invalid, fpst);
65
- nan = float16_silence_nan(f16, fpst);
66
+ if (!fpst->default_nan_mode) {
67
+ nan = float16_silence_nan(f16, fpst);
68
+ }
69
}
70
if (fpst->default_nan_mode) {
71
nan = float16_default_nan(fpst);
72
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
73
float32 nan = f32;
74
if (float32_is_signaling_nan(f32, fpst)) {
75
float_raise(float_flag_invalid, fpst);
76
- nan = float32_silence_nan(f32, fpst);
77
+ if (!fpst->default_nan_mode) {
78
+ nan = float32_silence_nan(f32, fpst);
79
+ }
80
}
81
if (fpst->default_nan_mode) {
82
nan = float32_default_nan(fpst);
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);
53
--
127
--
54
2.18.0
128
2.20.1
55
129
56
130
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
The next patch will need to free a rom. There is already code to do
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
4
this in rom_add_file().
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
Note that rom_add_file() uses:
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
rom = g_malloc0(sizeof(*rom));
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
9
...
10
[PMM: tweaked commit message]
10
if (rom->fw_dir) {
11
g_free(rom->fw_dir);
12
g_free(rom->fw_file);
13
}
14
15
The conditional is unnecessary since g_free(NULL) is a no-op.
16
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Message-id: 20180814162739.11814-4-stefanha@redhat.com
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
12
---
23
hw/core/loader.c | 21 ++++++++++++---------
13
hw/gpio/gpio_pwr.c | 2 +-
24
1 file changed, 12 insertions(+), 9 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
25
15
26
diff --git a/hw/core/loader.c b/hw/core/loader.c
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
27
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/core/loader.c
18
--- a/hw/gpio/gpio_pwr.c
29
+++ b/hw/core/loader.c
19
+++ b/hw/gpio/gpio_pwr.c
30
@@ -XXX,XX +XXX,XX @@ struct Rom {
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
31
static FWCfgState *fw_cfg;
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
32
static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
33
34
+/* rom->data must be heap-allocated (do not use with rom_add_elf_program()) */
35
+static void rom_free(Rom *rom)
36
+{
37
+ g_free(rom->data);
38
+ g_free(rom->path);
39
+ g_free(rom->name);
40
+ g_free(rom->fw_dir);
41
+ g_free(rom->fw_file);
42
+ g_free(rom);
43
+}
44
+
45
static inline bool rom_order_compare(Rom *rom, Rom *item)
46
{
22
{
47
return ((uintptr_t)(void *)rom->as > (uintptr_t)(void *)item->as) ||
23
if (level) {
48
@@ -XXX,XX +XXX,XX @@ err:
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
49
if (fd != -1)
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
50
close(fd);
26
}
51
52
- g_free(rom->data);
53
- g_free(rom->path);
54
- g_free(rom->name);
55
- if (fw_dir) {
56
- g_free(rom->fw_dir);
57
- g_free(rom->fw_file);
58
- }
59
- g_free(rom);
60
-
61
+ rom_free(rom);
62
return -1;
63
}
27
}
64
28
65
--
29
--
66
2.18.0
30
2.20.1
67
31
68
32
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
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
Some ARM CPUs have bitbanded IO, a memory region that allows convenient
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
bit access via 32-bit memory loads/stores. This eliminates the need for
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
read-modify-update instruction sequences.
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(-)
6
12
7
This patch makes this optional feature an ARMv7MState qdev property,
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
8
allowing boards to choose whether they want bitbanding or not.
9
10
Status of boards:
11
* iotkit (Cortex M33), no bitband
12
* mps2 (Cortex M3), bitband
13
* msf2 (Cortex M3), bitband
14
* stellaris (Cortex M3), bitband
15
* stm32f205 (Cortex M3), bitband
16
17
As a side-effect of this patch, Peter Maydell noted that the Ethernet
18
controller on mps2 board is now accessible. Previously they were hidden
19
by the bitband region (which does not exist on the real board).
20
21
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
23
Message-id: 20180814162739.11814-2-stefanha@redhat.com
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
26
include/hw/arm/armv7m.h | 2 ++
27
hw/arm/armv7m.c | 37 ++++++++++++++++++++-----------------
28
hw/arm/mps2.c | 1 +
29
hw/arm/msf2-soc.c | 1 +
30
hw/arm/stellaris.c | 1 +
31
hw/arm/stm32f205_soc.c | 1 +
32
6 files changed, 26 insertions(+), 17 deletions(-)
33
34
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
35
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/armv7m.h
15
--- a/target/arm/translate-mve.c
37
+++ b/include/hw/arm/armv7m.h
16
+++ b/target/arm/translate-mve.c
38
@@ -XXX,XX +XXX,XX @@ typedef struct {
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
39
* devices will be automatically layered on top of this view.)
40
* + Property "idau": IDAU interface (forwarded to CPU object)
41
* + Property "init-svtor": secure VTOR reset value (forwarded to CPU object)
42
+ * + Property "enable-bitband": expose bitbanded IO
43
*/
44
typedef struct ARMv7MState {
45
/*< private >*/
46
@@ -XXX,XX +XXX,XX @@ typedef struct ARMv7MState {
47
MemoryRegion *board_memory;
48
Object *idau;
49
uint32_t init_svtor;
50
+ bool enable_bitband;
51
} ARMv7MState;
52
53
#endif
54
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/armv7m.c
57
+++ b/hw/arm/armv7m.c
58
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
59
memory_region_add_subregion(&s->container, 0xe000e000,
60
sysbus_mmio_get_region(sbd, 0));
61
62
- for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
63
- Object *obj = OBJECT(&s->bitband[i]);
64
- SysBusDevice *sbd = SYS_BUS_DEVICE(&s->bitband[i]);
65
+ if (s->enable_bitband) {
66
+ for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
67
+ Object *obj = OBJECT(&s->bitband[i]);
68
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->bitband[i]);
69
70
- object_property_set_int(obj, bitband_input_addr[i], "base", &err);
71
- if (err != NULL) {
72
- error_propagate(errp, err);
73
- return;
74
- }
75
- object_property_set_link(obj, OBJECT(s->board_memory),
76
- "source-memory", &error_abort);
77
- object_property_set_bool(obj, true, "realized", &err);
78
- if (err != NULL) {
79
- error_propagate(errp, err);
80
- return;
81
- }
82
+ object_property_set_int(obj, bitband_input_addr[i], "base", &err);
83
+ if (err != NULL) {
84
+ error_propagate(errp, err);
85
+ return;
86
+ }
87
+ object_property_set_link(obj, OBJECT(s->board_memory),
88
+ "source-memory", &error_abort);
89
+ object_property_set_bool(obj, true, "realized", &err);
90
+ if (err != NULL) {
91
+ error_propagate(errp, err);
92
+ return;
93
+ }
94
95
- memory_region_add_subregion(&s->container, bitband_output_addr[i],
96
- sysbus_mmio_get_region(sbd, 0));
97
+ memory_region_add_subregion(&s->container, bitband_output_addr[i],
98
+ sysbus_mmio_get_region(sbd, 0));
99
+ }
100
}
18
}
101
}
19
}
102
20
103
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
104
MemoryRegion *),
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
105
DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
23
+ unsigned msize)
106
DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
24
{
107
+ DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
25
TCGv_i32 addr;
108
DEFINE_PROP_END_OF_LIST(),
26
uint32_t offset;
109
};
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
110
28
return true;
111
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/hw/arm/mps2.c
114
+++ b/hw/arm/mps2.c
115
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
116
g_assert_not_reached();
117
}
29
}
118
qdev_prop_set_string(armv7m, "cpu-type", machine->cpu_type);
30
119
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
31
- offset = a->imm << a->size;
120
object_property_set_link(OBJECT(&mms->armv7m), OBJECT(system_memory),
32
+ offset = a->imm << msize;
121
"memory", &error_abort);
33
if (!a->a) {
122
object_property_set_bool(OBJECT(&mms->armv7m), true, "realized",
34
offset = -offset;
123
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
35
}
124
index XXXXXXX..XXXXXXX 100644
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
125
--- a/hw/arm/msf2-soc.c
37
{ gen_helper_mve_vstrw, gen_helper_mve_vldrw },
126
+++ b/hw/arm/msf2-soc.c
38
{ NULL, NULL }
127
@@ -XXX,XX +XXX,XX @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
39
};
128
armv7m = DEVICE(&s->armv7m);
40
- return do_ldst(s, a, ldstfns[a->size][a->l]);
129
qdev_prop_set_uint32(armv7m, "num-irq", 81);
41
+ return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
130
qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
42
}
131
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
43
132
object_property_set_link(OBJECT(&s->armv7m), OBJECT(get_system_memory()),
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
133
"memory", &error_abort);
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
134
object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
135
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
47
{ \
136
index XXXXXXX..XXXXXXX 100644
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
137
--- a/hw/arm/stellaris.c
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
138
+++ b/hw/arm/stellaris.c
50
{ NULL, gen_helper_mve_##ULD }, \
139
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
51
}; \
140
nvic = qdev_create(NULL, TYPE_ARMV7M);
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
141
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
142
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
54
}
143
+ qdev_prop_set_bit(nvic, "enable-bitband", true);
55
144
object_property_set_link(OBJECT(nvic), OBJECT(get_system_memory()),
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
145
"memory", &error_abort);
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
146
/* This will exit with an error if the user passed us a bad cpu_type */
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
147
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
148
index XXXXXXX..XXXXXXX 100644
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
149
--- a/hw/arm/stm32f205_soc.c
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
150
+++ b/hw/arm/stm32f205_soc.c
62
151
@@ -XXX,XX +XXX,XX @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
152
armv7m = DEVICE(&s->armv7m);
64
{
153
qdev_prop_set_uint32(armv7m, "num-irq", 96);
154
qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
155
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
156
object_property_set_link(OBJECT(&s->armv7m), OBJECT(get_system_memory()),
157
"memory", &error_abort);
158
object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
159
--
65
--
160
2.18.0
66
2.20.1
161
67
162
68
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The initial implementation of the MVE VRMLALDAVH and VRMLSLDAVH
2
insns had some bugs:
3
* the 32x32 multiply of elements was being done as 32x32->32,
4
not 32x32->64
5
* we were incorrectly maintaining the accumulator in its full
6
72-bit form across all 4 beats of the insn; in the pseudocode
7
it is squashed back into the 64 bits of the RdaHi:RdaLo
8
registers after each beat
2
9
3
The expression (int) imm + (uint32_t) len_align turns into uint32_t
10
In particular, fixing the second of these allows us to recast
4
and thus with negative imm produces a memory operation at the wrong
11
the implementation to avoid 128-bit arithmetic entirely.
5
offset. None of the numbers involved are particularly large, so
6
change everything to use int.
7
12
8
Cc: qemu-stable@nongnu.org (3.0.1)
13
Since the element size here is always 4, we can also drop the
9
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
14
parameterization of ESIZE to make the code a little more readable.
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
13
---
20
---
14
target/arm/translate-sve.c | 18 ++++++++----------
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
15
1 file changed, 8 insertions(+), 10 deletions(-)
22
1 file changed, 21 insertions(+), 17 deletions(-)
16
23
17
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
18
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-sve.c
26
--- a/target/arm/mve_helper.c
20
+++ b/target/arm/translate-sve.c
27
+++ b/target/arm/mve_helper.c
21
@@ -XXX,XX +XXX,XX @@ static bool trans_UCVTF_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
28
@@ -XXX,XX +XXX,XX @@
22
* The load should begin at the address Rn + IMM.
23
*/
29
*/
24
30
25
-static void do_ldr(DisasContext *s, uint32_t vofs, uint32_t len,
31
#include "qemu/osdep.h"
26
- int rn, int imm)
32
-#include "qemu/int128.h"
27
+static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
33
#include "cpu.h"
28
{
34
#include "internals.h"
29
- uint32_t len_align = QEMU_ALIGN_DOWN(len, 8);
35
#include "vec_internal.h"
30
- uint32_t len_remain = len % 8;
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
31
- uint32_t nparts = len / 8 + ctpop8(len_remain);
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
32
+ int len_align = QEMU_ALIGN_DOWN(len, 8);
38
33
+ int len_remain = len % 8;
39
/*
34
+ int nparts = len / 8 + ctpop8(len_remain);
40
- * Rounding multiply add long dual accumulate high: we must keep
35
int midx = get_mem_index(s);
41
- * a 72-bit internal accumulator value and return the top 64 bits.
36
TCGv_i64 addr, t0, t1;
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
37
43
+ * this is implemented with a 72-bit internal accumulator value of which
38
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, uint32_t len,
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
46
+ * is squashed back into 64-bits after each beat.
41
/* Similarly for stores. */
47
*/
42
-static void do_str(DisasContext *s, uint32_t vofs, uint32_t len,
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
43
- int rn, int imm)
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
44
+static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
45
{
51
void *vm, uint64_t a) \
46
- uint32_t len_align = QEMU_ALIGN_DOWN(len, 8);
52
{ \
47
- uint32_t len_remain = len % 8;
53
uint16_t mask = mve_element_mask(env); \
48
- uint32_t nparts = len / 8 + ctpop8(len_remain);
54
unsigned e; \
49
+ int len_align = QEMU_ALIGN_DOWN(len, 8);
55
TYPE *n = vn, *m = vm; \
50
+ int len_remain = len % 8;
56
- Int128 acc = int128_lshift(TO128(a), 8); \
51
+ int nparts = len / 8 + ctpop8(len_remain);
57
- for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
52
int midx = get_mem_index(s);
58
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
53
TCGv_i64 addr, t0;
59
if (mask & 1) { \
54
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) \
55
--
98
--
56
2.18.0
99
2.20.1
57
100
58
101
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The immediate should be scaled by the size of the memory reference,
4
not the size of the elements into which it is loaded.
5
6
Cc: qemu-stable@nongnu.org (3.0.1)
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate-sve.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-sve.c
19
+++ b/target/arm/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
21
unsigned vsz = vec_full_reg_size(s);
22
unsigned psz = pred_full_reg_size(s);
23
unsigned esz = dtype_esz[a->dtype];
24
+ unsigned msz = dtype_msz(a->dtype);
25
TCGLabel *over = gen_new_label();
26
TCGv_i64 temp;
27
28
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
29
30
/* Load the data. */
31
temp = tcg_temp_new_i64();
32
- tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << esz);
33
+ tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << msz);
34
tcg_gen_qemu_ld_i64(temp, temp, get_mem_index(s),
35
s->be_data | dtype_mop[a->dtype]);
36
37
--
38
2.18.0
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The scaling should be solely on the memory operation size; the number
4
of registers being loaded does not come in to the initial computation.
5
6
Cc: qemu-stable@nongnu.org (3.0.1)
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate-sve.c | 5 ++---
14
1 file changed, 2 insertions(+), 3 deletions(-)
15
16
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-sve.c
19
+++ b/target/arm/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@ static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a, uint32_t insn)
21
}
22
if (sve_access_check(s)) {
23
TCGv_i64 addr = new_tmp_a64(s);
24
- tcg_gen_muli_i64(addr, cpu_reg(s, a->rm),
25
- (a->nreg + 1) << dtype_msz(a->dtype));
26
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype));
27
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
28
do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg);
29
}
30
@@ -XXX,XX +XXX,XX @@ static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a, uint32_t insn)
31
}
32
if (sve_access_check(s)) {
33
TCGv_i64 addr = new_tmp_a64(s);
34
- tcg_gen_muli_i64(addr, cpu_reg(s, a->rm), (a->nreg + 1) << a->msz);
35
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->msz);
36
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
37
do_st_zpa(s, a->rd, a->pg, addr, a->msz, a->esz, a->nreg);
38
}
39
--
40
2.18.0
41
42
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
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
Now that we've got the common sysbus_init_child_obj() function, we do
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
not need the local init_sysbus_child() anymore.
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
Signed-off-by: Thomas Huth <thuth@redhat.com>
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
7
Message-id: 1534420566-15799-1-git-send-email-thuth@redhat.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/mps2-tz.c | 32 +++++++++++---------------------
12
1 file changed, 11 insertions(+), 21 deletions(-)
13
14
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/mps2-tz.c
17
--- a/target/arm/translate.h
17
+++ b/hw/arm/mps2-tz.c
18
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
19
memory_region_add_subregion(get_system_memory(), base, mr);
20
return opc | s->be_data;
20
}
21
}
21
22
22
-static void init_sysbus_child(Object *parent, const char *childname,
23
+/**
23
- void *child, size_t childsize,
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
24
- const char *childtype)
25
+ *
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
29
+ *
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
31
+ * callers must catch this.
32
+ *
33
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
34
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
35
+ * we produce an immediate constant value of 0 in these cases.
36
+ */
37
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.c
43
+++ b/target/arm/translate-neon.c
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
47
48
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
25
-{
49
-{
26
- object_initialize(child, childsize, childtype);
50
- /*
27
- object_property_add_child(parent, childname, OBJECT(child), &error_abort);
51
- * Expand the encoded constant.
28
- qdev_set_parent_bus(DEVICE(child), sysbus_get_default());
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;
29
-
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);
30
-}
109
-}
31
-
110
-
32
/* Most of the devices in the AN505 FPGA image sit behind
111
static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
33
* Peripheral Protection Controllers. These data structures
112
GVecGen2iFn *fn)
34
* define the layout of which devices sit behind which PPCs.
113
{
35
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
36
*/
115
index XXXXXXX..XXXXXXX 100644
37
UnimplementedDeviceState *uds = opaque;
116
--- a/target/arm/translate.c
38
117
+++ b/target/arm/translate.c
39
- init_sysbus_child(OBJECT(mms), name, uds,
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
40
- sizeof(UnimplementedDeviceState),
119
a64_translate_init();
41
- TYPE_UNIMPLEMENTED_DEVICE);
120
}
42
+ sysbus_init_child_obj(OBJECT(mms), name, uds,
121
43
+ sizeof(UnimplementedDeviceState),
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
44
+ TYPE_UNIMPLEMENTED_DEVICE);
123
+{
45
qdev_prop_set_string(DEVICE(uds), "name", name);
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
46
qdev_prop_set_uint64(DEVICE(uds), "size", size);
125
+ switch (cmode) {
47
object_property_set_bool(OBJECT(uds), true, "realized", &error_fatal);
126
+ case 0: case 1:
48
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
127
+ /* no-op */
49
DeviceState *iotkitdev = DEVICE(&mms->iotkit);
128
+ break;
50
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
129
+ case 2: case 3:
51
130
+ imm <<= 8;
52
- init_sysbus_child(OBJECT(mms), name, uart,
131
+ break;
53
- sizeof(mms->uart[0]), TYPE_CMSDK_APB_UART);
132
+ case 4: case 5:
54
+ sysbus_init_child_obj(OBJECT(mms), name, uart, sizeof(mms->uart[0]),
133
+ imm <<= 16;
55
+ TYPE_CMSDK_APB_UART);
134
+ break;
56
qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
135
+ case 6: case 7:
57
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
136
+ imm <<= 24;
58
object_property_set_bool(OBJECT(uart), true, "realized", &error_fatal);
137
+ break;
59
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
138
+ case 8: case 9:
60
139
+ imm |= imm << 16;
61
memory_region_init_ram(ssram, NULL, name, ramsize[i], &error_fatal);
140
+ break;
62
141
+ case 10: case 11:
63
- init_sysbus_child(OBJECT(mms), mpcname, mpc,
142
+ imm = (imm << 8) | (imm << 24);
64
- sizeof(mms->ssram_mpc[0]), TYPE_TZ_MPC);
143
+ break;
65
+ sysbus_init_child_obj(OBJECT(mms), mpcname, mpc, sizeof(mms->ssram_mpc[0]),
144
+ case 12:
66
+ TYPE_TZ_MPC);
145
+ imm = (imm << 8) | 0xff;
67
object_property_set_link(OBJECT(mpc), OBJECT(ssram),
146
+ break;
68
"downstream", &error_fatal);
147
+ case 13:
69
object_property_set_bool(OBJECT(mpc), true, "realized", &error_fatal);
148
+ imm = (imm << 16) | 0xffff;
70
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
149
+ break;
71
exit(1);
150
+ case 14:
72
}
151
+ if (op) {
73
152
+ /*
74
- init_sysbus_child(OBJECT(machine), "iotkit", &mms->iotkit,
153
+ * This is the only case where the top and bottom 32 bits
75
- sizeof(mms->iotkit), TYPE_IOTKIT);
154
+ * of the encoded constant differ.
76
+ sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
155
+ */
77
+ sizeof(mms->iotkit), TYPE_IOTKIT);
156
+ uint64_t imm64 = 0;
78
iotkitdev = DEVICE(&mms->iotkit);
157
+ int n;
79
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
158
+
80
"memory", &error_abort);
159
+ for (n = 0; n < 8; n++) {
81
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
160
+ if (imm & (1 << n)) {
82
int port;
161
+ imm64 |= (0xffULL << (n * 8));
83
char *gpioname;
162
+ }
84
163
+ }
85
- init_sysbus_child(OBJECT(machine), ppcinfo->name, ppc,
164
+ return imm64;
86
- sizeof(TZPPC), TYPE_TZ_PPC);
165
+ }
87
+ sysbus_init_child_obj(OBJECT(machine), ppcinfo->name, ppc,
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
88
+ sizeof(TZPPC), TYPE_TZ_PPC);
167
+ break;
89
ppcdev = DEVICE(ppc);
168
+ case 15:
90
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
91
for (port = 0; port < TZ_NUM_PORTS; port++) {
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
171
+ break;
172
+ }
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.18.0
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
With PC, there are 33 registers. Three per line lines up nicely
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
without overflowing 80 columns.
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
Cc: qemu-stable@nongnu.org (3.0.1)
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
Reviewed-by: Alex Bennée <alex.bennee@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 | 13 ++++++-------
20
* VMVN and VBIC (when cmode < 14 && op == 1).
12
1 file changed, 6 insertions(+), 7 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 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
19
int el = arm_current_el(env);
34
{
20
const char *ns_status;
35
int rd = extract32(insn, 0, 5);
21
36
int cmode = extract32(insn, 12, 4);
22
- cpu_fprintf(f, "PC=%016"PRIx64" SP=%016"PRIx64"\n",
37
- int cmode_3_1 = extract32(cmode, 1, 3);
23
- env->pc, env->xregs[31]);
38
- int cmode_0 = extract32(cmode, 0, 1);
24
- for (i = 0; i < 31; i++) {
39
int o2 = extract32(insn, 11, 1);
25
- cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
26
- if ((i % 4) == 3) {
41
bool is_neg = extract32(insn, 29, 1);
27
- cpu_fprintf(f, "\n");
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
28
+ cpu_fprintf(f, " PC=%016" PRIx64 " ", env->pc);
43
return;
29
+ for (i = 0; i < 32; i++) {
30
+ if (i == 31) {
31
+ cpu_fprintf(f, " SP=%016" PRIx64 "\n", env->xregs[i]);
32
} else {
33
- cpu_fprintf(f, " ");
34
+ cpu_fprintf(f, "X%02d=%016" PRIx64 "%s", i, env->xregs[i],
35
+ (i + 2) % 3 ? " " : "\n");
36
}
37
}
44
}
38
45
46
- /* See AdvSIMDExpandImm() in ARM ARM */
47
- switch (cmode_3_1) {
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
51
- case 3: /* Replicate(imm8:Zeros(24), 2) */
52
- {
53
- int shift = cmode_3_1 * 8;
54
- imm = bitfield_replicate(abcdefgh << shift, 32);
55
- break;
56
- }
57
- case 4: /* Replicate(Zeros(8):imm8, 4) */
58
- case 5: /* Replicate(imm8:Zeros(8), 4) */
59
- {
60
- int shift = (cmode_3_1 & 0x1) * 8;
61
- imm = bitfield_replicate(abcdefgh << shift, 16);
62
- break;
63
- }
64
- case 6:
65
- if (cmode_0) {
66
- /* Replicate(Zeros(8):imm8:Ones(16), 2) */
67
- imm = (abcdefgh << 16) | 0xffff;
68
- } else {
69
- /* Replicate(Zeros(16):imm8:Ones(8), 2) */
70
- imm = (abcdefgh << 8) | 0xff;
71
- }
72
- imm = bitfield_replicate(imm, 32);
73
- break;
74
- case 7:
75
- if (!cmode_0 && !is_neg) {
76
- imm = bitfield_replicate(abcdefgh, 8);
77
- } else if (!cmode_0 && is_neg) {
78
- int i;
79
- imm = 0;
80
- for (i = 0; i < 8; i++) {
81
- if ((abcdefgh) & (1 << i)) {
82
- imm |= 0xffULL << (i * 8);
83
- }
84
- }
85
- } else if (cmode_0) {
86
- if (is_neg) {
87
- imm = (abcdefgh & 0x3f) << 48;
88
- if (abcdefgh & 0x80) {
89
- imm |= 0x8000000000000000ULL;
90
- }
91
- if (abcdefgh & 0x40) {
92
- imm |= 0x3fc0000000000000ULL;
93
- } else {
94
- imm |= 0x4000000000000000ULL;
95
- }
96
- } else {
97
- if (o2) {
98
- /* FMOV (vector, immediate) - half-precision */
99
- imm = vfp_expand_imm(MO_16, abcdefgh);
100
- /* now duplicate across the lanes */
101
- imm = bitfield_replicate(imm, 16);
102
- } else {
103
- imm = (abcdefgh & 0x3f) << 19;
104
- if (abcdefgh & 0x80) {
105
- imm |= 0x80000000;
106
- }
107
- if (abcdefgh & 0x40) {
108
- imm |= 0x3e000000;
109
- } else {
110
- imm |= 0x40000000;
111
- }
112
- imm |= (imm << 32);
113
- }
114
- }
115
- }
116
- break;
117
- default:
118
- g_assert_not_reached();
119
- }
120
-
121
- if (cmode_3_1 != 7 && is_neg) {
122
- imm = ~imm;
123
+ if (cmode == 15 && o2 && !is_neg) {
124
+ /* FMOV (vector, immediate) - half-precision */
125
+ imm = vfp_expand_imm(MO_16, abcdefgh);
126
+ /* now duplicate across the lanes */
127
+ imm = bitfield_replicate(imm, 16);
128
+ } else {
129
+ imm = asimd_imm_const(abcdefgh, cmode, is_neg);
130
}
131
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/target/arm/translate.c
136
+++ b/target/arm/translate.c
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
138
case 14:
139
if (op) {
140
/*
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;
164
+ }
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
167
break;
39
--
168
--
40
2.18.0
169
2.20.1
41
170
42
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
These insns require u=1; failed to include that in the switch
4
(We can't replace the other use of bitfield_replicate() in this file,
4
cases. This probably happened during one of the rebases just
5
in logic_imm_decode_wmask(), because that location needs to handle 2
5
before final commit.
6
and 4 bit elements, which dup_const() cannot.)
6
7
7
Fixes: d17b7cdcf4e
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20180810193129.1556-6-richard.henderson@linaro.org
11
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
12
---
11
---
13
target/arm/translate-a64.c | 12 ++++++------
12
target/arm/translate-a64.c | 2 +-
14
1 file changed, 6 insertions(+), 6 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
15
14
16
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
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate-a64.c
19
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
21
}
20
/* FMOV (vector, immediate) - half-precision */
22
feature = ARM_FEATURE_V8_DOTPROD;
21
imm = vfp_expand_imm(MO_16, abcdefgh);
23
break;
22
/* now duplicate across the lanes */
24
- case 0x8: /* FCMLA, #0 */
23
- imm = bitfield_replicate(imm, 16);
25
- case 0x9: /* FCMLA, #90 */
24
+ imm = dup_const(MO_16, imm);
26
- case 0xa: /* FCMLA, #180 */
25
} else {
27
- case 0xb: /* FCMLA, #270 */
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
28
- case 0xc: /* FCADD, #90 */
27
}
29
- case 0xe: /* FCADD, #270 */
30
+ case 0x18: /* FCMLA, #0 */
31
+ case 0x19: /* FCMLA, #90 */
32
+ case 0x1a: /* FCMLA, #180 */
33
+ case 0x1b: /* FCMLA, #270 */
34
+ case 0x1c: /* FCADD, #90 */
35
+ case 0x1e: /* FCADD, #270 */
36
if (size == 0
37
|| (size == 1 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))
38
|| (size == 3 && !is_q)) {
39
--
28
--
40
2.18.0
29
2.20.1
41
30
42
31
diff view generated by jsdifflib
1
From: Su Hang <suhang16@mails.ucas.ac.cn>
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
2
VORR and VBIC). These have essentially the same encoding
3
as their Neon equivalents, and we implement the decode
4
in the same way.
2
5
3
This patch adds Intel Hexadecimal Object File format support to the
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
generic loader device. The file format specification is available here:
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
http://www.piclist.com/techref/fileext/hex/intel.htm
8
Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
9
---
10
target/arm/helper-mve.h | 4 +++
11
target/arm/mve.decode | 17 +++++++++++++
12
target/arm/mve_helper.c | 24 ++++++++++++++++++
13
target/arm/translate-mve.c | 50 ++++++++++++++++++++++++++++++++++++++
14
4 files changed, 95 insertions(+)
6
15
7
This file format is often used with microcontrollers such as the
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
micro:bit, Arduino, STM32, etc. Users expect to be able to run .hex
9
files directly with without first converting them to ELF. Most
10
micro:bit code is developed in web-based IDEs without direct user access
11
to binutils so it is important for QEMU to handle this file format
12
natively.
13
14
Signed-off-by: Su Hang <suhang16@mails.ucas.ac.cn>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
16
Acked-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-id: 20180814162739.11814-6-stefanha@redhat.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
include/hw/loader.h | 12 ++
21
hw/core/generic-loader.c | 4 +
22
hw/core/loader.c | 249 +++++++++++++++++++++++++++++++++++++++
23
3 files changed, 265 insertions(+)
24
25
diff --git a/include/hw/loader.h b/include/hw/loader.h
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/loader.h
18
--- a/target/arm/helper-mve.h
28
+++ b/include/hw/loader.h
19
+++ b/target/arm/helper-mve.h
29
@@ -XXX,XX +XXX,XX @@ ssize_t load_image_size(const char *filename, void *addr, size_t size);
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
30
int load_image_targphys_as(const char *filename,
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
31
hwaddr addr, uint64_t max_sz, AddressSpace *as);
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
32
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
33
+/**load_targphys_hex_as:
24
+
34
+ * @filename: Path to the .hex file
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
35
+ * @entry: Store the entry point given by the .hex file
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
36
+ * @as: The AddressSpace to load the .hex file to. The value of
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
37
+ * address_space_memory is used if nothing is supplied here.
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
38
+ *
29
index XXXXXXX..XXXXXXX 100644
39
+ * Load a fixed .hex file into memory.
30
--- a/target/arm/mve.decode
40
+ *
31
+++ b/target/arm/mve.decode
41
+ * Returns the size of the loaded .hex file on success, -1 otherwise.
32
@@ -XXX,XX +XXX,XX @@
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
34
%size_28 28:1 !function=plus_1
35
36
+# 1imm format immediate
37
+%imm_28_16_0 28:1 16:3 0:4
38
+
39
&vldr_vstr rn qd imm p a w size l u
40
&1op qd qm size
41
&2op qd qm qn size
42
&2scalar qd qn rm size
43
+&1imm qd imm cmode op
44
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
46
# Note that both Rn and Qd are 3 bits only (no D bit)
47
@@ -XXX,XX +XXX,XX @@
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
50
size=%size_28
51
+@1imm .... .... .... .... .... cmode:4 .. op:1 . .... &1imm qd=%qd imm=%imm_28_16_0
52
53
# The _rev suffix indicates that Vn and Vm are reversed. This is
54
# the case for shifts. In the Arm ARM these insns are documented
55
@@ -XXX,XX +XXX,XX @@ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rd
56
# Predicate operations
57
%mask_22_13 22:1 13:3
58
VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
59
+
60
+# Logical immediate operations (1 reg and modified-immediate)
61
+
62
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMVN, but
63
+# not in a way we can conveniently represent in decodetree without
64
+# a lot of repetition:
65
+# VORR: op=0, (cmode & 1) && cmode < 12
66
+# VBIC: op=1, (cmode & 1) && cmode < 12
67
+# VMOV: everything else
68
+# So we have a single decode line and check the cmode/op in the
69
+# trans function.
70
+Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
71
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/mve_helper.c
74
+++ b/target/arm/mve_helper.c
75
@@ -XXX,XX +XXX,XX @@ DO_1OP(vnegw, 4, int32_t, DO_NEG)
76
DO_1OP(vfnegh, 8, uint64_t, DO_FNEGH)
77
DO_1OP(vfnegs, 8, uint64_t, DO_FNEGS)
78
79
+/*
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
81
+ * All these insns work at 64-bit widths.
42
+ */
82
+ */
43
+int load_targphys_hex_as(const char *filename, hwaddr *entry, AddressSpace *as);
83
+#define DO_1OP_IMM(OP, FN) \
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
85
+ { \
86
+ uint64_t *da = vda; \
87
+ uint16_t mask = mve_element_mask(env); \
88
+ unsigned e; \
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
91
+ } \
92
+ mve_advance_vpt(env); \
93
+ }
44
+
94
+
45
/** load_image_targphys:
95
+#define DO_MOVI(N, I) (I)
46
* Same as load_image_targphys_as(), but doesn't allow the caller to specify
96
+#define DO_ANDI(N, I) ((N) & (I))
47
* an AddressSpace.
97
+#define DO_ORRI(N, I) ((N) | (I))
48
diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
98
+
99
+DO_1OP_IMM(vmovi, DO_MOVI)
100
+DO_1OP_IMM(vandi, DO_ANDI)
101
+DO_1OP_IMM(vorri, DO_ORRI)
102
+
103
#define DO_2OP(OP, ESIZE, TYPE, FN) \
104
void HELPER(glue(mve_, OP))(CPUARMState *env, \
105
void *vd, void *vn, void *vm) \
106
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
49
index XXXXXXX..XXXXXXX 100644
107
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/core/generic-loader.c
108
--- a/target/arm/translate-mve.c
51
+++ b/hw/core/generic-loader.c
109
+++ b/target/arm/translate-mve.c
52
@@ -XXX,XX +XXX,XX @@ static void generic_loader_realize(DeviceState *dev, Error **errp)
110
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
53
size = load_uimage_as(s->file, &entry, NULL, NULL, NULL, NULL,
111
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
54
as);
112
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
55
}
113
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
56
+
114
+typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
57
+ if (size < 0) {
115
58
+ size = load_targphys_hex_as(s->file, &entry, as);
116
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
59
+ }
117
static inline long mve_qreg_offset(unsigned reg)
60
}
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
61
119
mve_update_eci(s);
62
if (size < 0 || s->force_raw) {
120
return true;
63
diff --git a/hw/core/loader.c b/hw/core/loader.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/core/loader.c
66
+++ b/hw/core/loader.c
67
@@ -XXX,XX +XXX,XX @@ void hmp_info_roms(Monitor *mon, const QDict *qdict)
68
}
69
}
70
}
121
}
71
+
122
+
72
+typedef enum HexRecord HexRecord;
123
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
73
+enum HexRecord {
124
+{
74
+ DATA_RECORD = 0,
125
+ TCGv_ptr qd;
75
+ EOF_RECORD,
126
+ uint64_t imm;
76
+ EXT_SEG_ADDR_RECORD,
77
+ START_SEG_ADDR_RECORD,
78
+ EXT_LINEAR_ADDR_RECORD,
79
+ START_LINEAR_ADDR_RECORD,
80
+};
81
+
127
+
82
+/* Each record contains a 16-bit address which is combined with the upper 16
128
+ if (!dc_isar_feature(aa32_mve, s) ||
83
+ * bits of the implicit "next address" to form a 32-bit address.
129
+ !mve_check_qreg_bank(s, a->qd) ||
84
+ */
130
+ !fn) {
85
+#define NEXT_ADDR_MASK 0xffff0000
131
+ return false;
86
+
132
+ }
87
+#define DATA_FIELD_MAX_LEN 0xff
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
88
+#define LEN_EXCEPT_DATA 0x5
89
+/* 0x5 = sizeof(byte_count) + sizeof(address) + sizeof(record_type) +
90
+ * sizeof(checksum) */
91
+typedef struct {
92
+ uint8_t byte_count;
93
+ uint16_t address;
94
+ uint8_t record_type;
95
+ uint8_t data[DATA_FIELD_MAX_LEN];
96
+ uint8_t checksum;
97
+} HexLine;
98
+
99
+/* return 0 or -1 if error */
100
+static bool parse_record(HexLine *line, uint8_t *our_checksum, const uint8_t c,
101
+ uint32_t *index, const bool in_process)
102
+{
103
+ /* +-------+---------------+-------+---------------------+--------+
104
+ * | byte | |record | | |
105
+ * | count | address | type | data |checksum|
106
+ * +-------+---------------+-------+---------------------+--------+
107
+ * ^ ^ ^ ^ ^ ^
108
+ * |1 byte | 2 bytes |1 byte | 0-255 bytes | 1 byte |
109
+ */
110
+ uint8_t value = 0;
111
+ uint32_t idx = *index;
112
+ /* ignore space */
113
+ if (g_ascii_isspace(c)) {
114
+ return true;
134
+ return true;
115
+ }
135
+ }
116
+ if (!g_ascii_isxdigit(c) || !in_process) {
136
+
117
+ return false;
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
118
+ }
138
+
119
+ value = g_ascii_xdigit_value(c);
139
+ qd = mve_qreg_ptr(a->qd);
120
+ value = (idx & 0x1) ? (value & 0xf) : (value << 4);
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
121
+ if (idx < 2) {
141
+ tcg_temp_free_ptr(qd);
122
+ line->byte_count |= value;
142
+ mve_update_eci(s);
123
+ } else if (2 <= idx && idx < 6) {
124
+ line->address <<= 4;
125
+ line->address += g_ascii_xdigit_value(c);
126
+ } else if (6 <= idx && idx < 8) {
127
+ line->record_type |= value;
128
+ } else if (8 <= idx && idx < 8 + 2 * line->byte_count) {
129
+ line->data[(idx - 8) >> 1] |= value;
130
+ } else if (8 + 2 * line->byte_count <= idx &&
131
+ idx < 10 + 2 * line->byte_count) {
132
+ line->checksum |= value;
133
+ } else {
134
+ return false;
135
+ }
136
+ *our_checksum += value;
137
+ ++(*index);
138
+ return true;
143
+ return true;
139
+}
144
+}
140
+
145
+
141
+typedef struct {
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
142
+ const char *filename;
147
+{
143
+ HexLine line;
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
144
+ uint8_t *bin_buf;
149
+ MVEGenOneOpImmFn *fn;
145
+ hwaddr *start_addr;
146
+ int total_size;
147
+ uint32_t next_address_to_write;
148
+ uint32_t current_address;
149
+ uint32_t current_rom_index;
150
+ uint32_t rom_start_address;
151
+ AddressSpace *as;
152
+} HexParser;
153
+
150
+
154
+/* return size or -1 if error */
151
+ if ((a->cmode & 1) && a->cmode < 12) {
155
+static int handle_record_type(HexParser *parser)
152
+ if (a->op) {
156
+{
153
+ /*
157
+ HexLine *line = &(parser->line);
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
158
+ switch (line->record_type) {
155
+ * so the VBIC becomes a logical AND operation.
159
+ case DATA_RECORD:
156
+ */
160
+ parser->current_address =
157
+ fn = gen_helper_mve_vandi;
161
+ (parser->next_address_to_write & NEXT_ADDR_MASK) | line->address;
158
+ } else {
162
+ /* verify this is a contiguous block of memory */
159
+ fn = gen_helper_mve_vorri;
163
+ if (parser->current_address != parser->next_address_to_write) {
164
+ if (parser->current_rom_index != 0) {
165
+ rom_add_blob_fixed_as(parser->filename, parser->bin_buf,
166
+ parser->current_rom_index,
167
+ parser->rom_start_address, parser->as);
168
+ }
169
+ parser->rom_start_address = parser->current_address;
170
+ parser->current_rom_index = 0;
171
+ }
160
+ }
172
+
161
+ } else {
173
+ /* copy from line buffer to output bin_buf */
162
+ /* There is one unallocated cmode/op combination in this space */
174
+ memcpy(parser->bin_buf + parser->current_rom_index, line->data,
163
+ if (a->cmode == 15 && a->op == 1) {
175
+ line->byte_count);
164
+ return false;
176
+ parser->current_rom_index += line->byte_count;
177
+ parser->total_size += line->byte_count;
178
+ /* save next address to write */
179
+ parser->next_address_to_write =
180
+ parser->current_address + line->byte_count;
181
+ break;
182
+
183
+ case EOF_RECORD:
184
+ if (parser->current_rom_index != 0) {
185
+ rom_add_blob_fixed_as(parser->filename, parser->bin_buf,
186
+ parser->current_rom_index,
187
+ parser->rom_start_address, parser->as);
188
+ }
165
+ }
189
+ return parser->total_size;
166
+ /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
190
+ case EXT_SEG_ADDR_RECORD:
167
+ fn = gen_helper_mve_vmovi;
191
+ case EXT_LINEAR_ADDR_RECORD:
192
+ if (line->byte_count != 2 && line->address != 0) {
193
+ return -1;
194
+ }
195
+
196
+ if (parser->current_rom_index != 0) {
197
+ rom_add_blob_fixed_as(parser->filename, parser->bin_buf,
198
+ parser->current_rom_index,
199
+ parser->rom_start_address, parser->as);
200
+ }
201
+
202
+ /* save next address to write,
203
+ * in case of non-contiguous block of memory */
204
+ parser->next_address_to_write = (line->data[0] << 12) |
205
+ (line->data[1] << 4);
206
+ if (line->record_type == EXT_LINEAR_ADDR_RECORD) {
207
+ parser->next_address_to_write <<= 12;
208
+ }
209
+
210
+ parser->rom_start_address = parser->next_address_to_write;
211
+ parser->current_rom_index = 0;
212
+ break;
213
+
214
+ case START_SEG_ADDR_RECORD:
215
+ if (line->byte_count != 4 && line->address != 0) {
216
+ return -1;
217
+ }
218
+
219
+ /* x86 16-bit CS:IP segmented addressing */
220
+ *(parser->start_addr) = (((line->data[0] << 8) | line->data[1]) << 4) +
221
+ ((line->data[2] << 8) | line->data[3]);
222
+ break;
223
+
224
+ case START_LINEAR_ADDR_RECORD:
225
+ if (line->byte_count != 4 && line->address != 0) {
226
+ return -1;
227
+ }
228
+
229
+ *(parser->start_addr) = ldl_be_p(line->data);
230
+ break;
231
+
232
+ default:
233
+ return -1;
234
+ }
168
+ }
235
+
169
+ return do_1imm(s, a, fn);
236
+ return parser->total_size;
237
+}
238
+
239
+/* return size or -1 if error */
240
+static int parse_hex_blob(const char *filename, hwaddr *addr, uint8_t *hex_blob,
241
+ size_t hex_blob_size, AddressSpace *as)
242
+{
243
+ bool in_process = false; /* avoid re-enter and
244
+ * check whether record begin with ':' */
245
+ uint8_t *end = hex_blob + hex_blob_size;
246
+ uint8_t our_checksum = 0;
247
+ uint32_t record_index = 0;
248
+ HexParser parser = {
249
+ .filename = filename,
250
+ .bin_buf = g_malloc(hex_blob_size),
251
+ .start_addr = addr,
252
+ .as = as,
253
+ };
254
+
255
+ rom_transaction_begin();
256
+
257
+ for (; hex_blob < end; ++hex_blob) {
258
+ switch (*hex_blob) {
259
+ case '\r':
260
+ case '\n':
261
+ if (!in_process) {
262
+ break;
263
+ }
264
+
265
+ in_process = false;
266
+ if ((LEN_EXCEPT_DATA + parser.line.byte_count) * 2 !=
267
+ record_index ||
268
+ our_checksum != 0) {
269
+ parser.total_size = -1;
270
+ goto out;
271
+ }
272
+
273
+ if (handle_record_type(&parser) == -1) {
274
+ parser.total_size = -1;
275
+ goto out;
276
+ }
277
+ break;
278
+
279
+ /* start of a new record. */
280
+ case ':':
281
+ memset(&parser.line, 0, sizeof(HexLine));
282
+ in_process = true;
283
+ record_index = 0;
284
+ break;
285
+
286
+ /* decoding lines */
287
+ default:
288
+ if (!parse_record(&parser.line, &our_checksum, *hex_blob,
289
+ &record_index, in_process)) {
290
+ parser.total_size = -1;
291
+ goto out;
292
+ }
293
+ break;
294
+ }
295
+ }
296
+
297
+out:
298
+ g_free(parser.bin_buf);
299
+ rom_transaction_end(parser.total_size != -1);
300
+ return parser.total_size;
301
+}
302
+
303
+/* return size or -1 if error */
304
+int load_targphys_hex_as(const char *filename, hwaddr *entry, AddressSpace *as)
305
+{
306
+ gsize hex_blob_size;
307
+ gchar *hex_blob;
308
+ int total_size = 0;
309
+
310
+ if (!g_file_get_contents(filename, &hex_blob, &hex_blob_size, NULL)) {
311
+ return -1;
312
+ }
313
+
314
+ total_size = parse_hex_blob(filename, entry, (uint8_t *)hex_blob,
315
+ hex_blob_size, as);
316
+
317
+ g_free(hex_blob);
318
+ return total_size;
319
+}
170
+}
320
--
171
--
321
2.18.0
172
2.20.1
322
173
323
174
diff view generated by jsdifflib
1
From: Su Hang <suhang16@mails.ucas.ac.cn>
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
2
2
and VQSHLU.
3
'test.hex' file is a memory test pattern stored in Hexadecimal Object
3
4
Format. It loads at 0x10000 in RAM and contains values from 0 through
4
The size-and-immediate encoding here is the same as Neon, and we
5
255.
5
handle it the same way neon-dp.decode does.
6
6
7
The test case verifies that the expected memory test pattern was loaded.
8
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Suggested-by: Steffen Gortz <qemu.ml@steffen-goertz.de>
11
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Signed-off-by: Su Hang <suhang16@mails.ucas.ac.cn>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
[PMM: changed qtest_startf() to qtest_initf() to work with
16
current master after the refactoring in commit 88b988c895e3c2]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
18
---
10
---
19
configure | 4 +++
11
target/arm/helper-mve.h | 16 +++++++++++
20
tests/Makefile.include | 2 ++
12
target/arm/mve.decode | 23 +++++++++++++++
21
tests/hexloader-test.c | 45 ++++++++++++++++++++++++++++
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
22
MAINTAINERS | 6 ++++
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
23
tests/hex-loader-check-data/test.hex | 18 +++++++++++
15
4 files changed, 147 insertions(+)
24
5 files changed, 75 insertions(+)
16
25
create mode 100644 tests/hexloader-test.c
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
26
create mode 100644 tests/hex-loader-check-data/test.hex
18
index XXXXXXX..XXXXXXX 100644
27
19
--- a/target/arm/helper-mve.h
28
diff --git a/configure b/configure
20
+++ b/target/arm/helper-mve.h
29
index XXXXXXX..XXXXXXX 100755
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
30
--- a/configure
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
31
+++ b/configure
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
32
@@ -XXX,XX +XXX,XX @@ for test_file in $(find $source_path/tests/acpi-test-data -type f)
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
33
do
25
+
34
FILES="$FILES tests/acpi-test-data$(echo $test_file | sed -e 's/.*acpi-test-data//')"
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
done
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+for test_file in $(find $source_path/tests/hex-loader-check-data -type f)
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+do
29
+
38
+ FILES="$FILES tests/hex-loader-check-data$(echo $test_file | sed -e 's/.*hex-loader-check-data//')"
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+done
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
mkdir -p $DIRS
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
for f in $FILES ; do
33
+
42
if [ -e "$source_path/$f" ] && [ "$pwd_is_source_path" != "y" ]; then
34
+DEF_HELPER_FLAGS_4(mve_vqshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
diff --git a/tests/Makefile.include b/tests/Makefile.include
35
+DEF_HELPER_FLAGS_4(mve_vqshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
index XXXXXXX..XXXXXXX 100644
36
+DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
--- a/tests/Makefile.include
37
+
46
+++ b/tests/Makefile.include
38
+DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
@@ -XXX,XX +XXX,XX @@ check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
39
+DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
gcov-files-arm-y += hw/timer/arm_mptimer.c
40
+DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
check-qtest-arm-y += tests/boot-serial-test$(EXESUF)
41
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
50
check-qtest-arm-y += tests/sdhci-test$(EXESUF)
42
index XXXXXXX..XXXXXXX 100644
51
+check-qtest-arm-y += tests/hexloader-test$(EXESUF)
43
--- a/target/arm/mve.decode
52
44
+++ b/target/arm/mve.decode
53
check-qtest-aarch64-y = tests/numa-test$(EXESUF)
54
check-qtest-aarch64-y += tests/sdhci-test$(EXESUF)
55
@@ -XXX,XX +XXX,XX @@ tests/qmp-test$(EXESUF): tests/qmp-test.o
56
tests/device-introspect-test$(EXESUF): tests/device-introspect-test.o
57
tests/rtc-test$(EXESUF): tests/rtc-test.o
58
tests/m48t59-test$(EXESUF): tests/m48t59-test.o
59
+tests/hexloader-test$(EXESUF): tests/hexloader-test.o
60
tests/endianness-test$(EXESUF): tests/endianness-test.o
61
tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y)
62
tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
63
diff --git a/tests/hexloader-test.c b/tests/hexloader-test.c
64
new file mode 100644
65
index XXXXXXX..XXXXXXX
66
--- /dev/null
67
+++ b/tests/hexloader-test.c
68
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@
69
+/*
46
&2op qd qm qn size
70
+ * QTest testcase for the Intel Hexadecimal Object File Loader
47
&2scalar qd qn rm size
71
+ *
48
&1imm qd imm cmode op
72
+ * Authors:
49
+&2shift qd qm shift size
73
+ * Su Hang <suhang16@mails.ucas.ac.cn> 2018
50
74
+ *
51
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
75
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
# Note that both Rn and Qd are 3 bits only (no D bit)
76
+ * See the COPYING file in the top-level directory.
53
@@ -XXX,XX +XXX,XX @@
77
+ *
54
@2scalar .... .... .. size:2 .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
78
+ */
55
@2scalar_nosz .... .... .... .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
79
+
56
80
+#include "qemu/osdep.h"
57
+@2_shl_b .... .... .. 001 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
81
+#include "libqtest.h"
58
+@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
82
+
59
+@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
83
+/* Load 'test.hex' and verify that the in-memory contents are as expected.
60
+
84
+ * 'test.hex' is a memory test pattern stored in Hexadecimal Object
61
# Vector loads and stores
85
+ * format. It loads at 0x10000 in RAM and contains values from 0 through
62
86
+ * 255.
63
# Widening loads and narrowing stores:
87
+ */
64
@@ -XXX,XX +XXX,XX @@ VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
88
+static void hex_loader_test(void)
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)
89
+{
177
+{
90
+ unsigned int i;
178
+ TCGv_ptr qd, qm;
91
+ const unsigned int base_addr = 0x00010000;
179
+ int shift = a->shift;
92
+
180
+
93
+ QTestState *s = qtest_initf(
181
+ if (!dc_isar_feature(aa32_mve, s) ||
94
+ "-M vexpress-a9 -nographic -device loader,file=tests/hex-loader-check-data/test.hex");
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
95
+
183
+ !fn) {
96
+ for (i = 0; i < 256; ++i) {
184
+ return false;
97
+ uint8_t val = qtest_readb(s, base_addr + i);
185
+ }
98
+ g_assert_cmpuint(i, ==, val);
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
99
+ }
187
+ return true;
100
+ qtest_quit(s);
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;
101
+}
206
+}
102
+
207
+
103
+int main(int argc, char **argv)
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
104
+{
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
105
+ int ret;
210
+ { \
106
+
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
107
+ g_test_init(&argc, &argv, NULL);
212
+ gen_helper_mve_##FN##b, \
108
+
213
+ gen_helper_mve_##FN##h, \
109
+ qtest_add_func("/tmp/hex_loader", hex_loader_test);
214
+ gen_helper_mve_##FN##w, \
110
+ ret = g_test_run();
215
+ NULL, \
111
+
216
+ }; \
112
+ return ret;
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
113
+}
218
+ }
114
diff --git a/MAINTAINERS b/MAINTAINERS
219
+
115
index XXXXXXX..XXXXXXX 100644
220
+DO_2SHIFT(VSHLI, vshli_u, false)
116
--- a/MAINTAINERS
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
117
+++ b/MAINTAINERS
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
118
@@ -XXX,XX +XXX,XX @@ F: hw/core/generic-loader.c
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
119
F: include/hw/core/generic-loader.h
120
F: docs/generic-loader.txt
121
122
+Intel Hexadecimal Object File Loader
123
+M: Su Hang <suhang16@mails.ucas.ac.cn>
124
+S: Maintained
125
+F: tests/hexloader-test.c
126
+F: tests/hex-loader-check-data/test.hex
127
+
128
CHRP NVRAM
129
M: Thomas Huth <thuth@redhat.com>
130
S: Maintained
131
diff --git a/tests/hex-loader-check-data/test.hex b/tests/hex-loader-check-data/test.hex
132
new file mode 100644
133
index XXXXXXX..XXXXXXX
134
--- /dev/null
135
+++ b/tests/hex-loader-check-data/test.hex
136
@@ -XXX,XX +XXX,XX @@
137
+:020000040001F9
138
+:10000000000102030405060708090a0b0c0d0e0f78
139
+:10001000101112131415161718191a1b1c1d1e1f68
140
+:10002000202122232425262728292a2b2c2d2e2f58
141
+:10003000303132333435363738393a3b3c3d3e3f48
142
+:10004000404142434445464748494a4b4c4d4e4f38
143
+:10005000505152535455565758595a5b5c5d5e5f28
144
+:10006000606162636465666768696a6b6c6d6e6f18
145
+:10007000707172737475767778797a7b7c7d7e7f08
146
+:10008000808182838485868788898a8b8c8d8e8ff8
147
+:10009000909192939495969798999a9b9c9d9e9fe8
148
+:1000a000a0a1a2a3a4a5a6a7a8a9aaabacadaeafd8
149
+:1000b000b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc8
150
+:1000c000c0c1c2c3c4c5c6c7c8c9cacbcccdcecfb8
151
+:1000d000d0d1d2d3d4d5d6d7d8d9dadbdcdddedfa8
152
+:1000e000e0e1e2e3e4e5e6e7e8e9eaebecedeeef98
153
+:1000f000f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff88
154
+:00000001FF
155
--
224
--
156
2.18.0
225
2.20.1
157
226
158
227
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE vector shift right by immediate insns VSHRI and
2
VRSHRI. As with Neon, we implement these by using helper functions
3
which perform left shifts but allow negative shift counts to indicate
4
right shifts.
2
5
3
This allows the default (and maximum) vector length to be set
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
from the command-line. Which is extraordinarily helpful in
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
debugging problems depending on vector length without having to
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
6
bake knowledge of PR_SET_SVE_VL into every guest binary.
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(-)
7
17
8
Cc: qemu-stable@nongnu.org (3.0.1)
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Tested-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/cpu.h | 3 +++
15
linux-user/syscall.c | 19 +++++++++++++------
16
target/arm/cpu.c | 6 +++---
17
target/arm/cpu64.c | 29 +++++++++++++++++++++++++++++
18
target/arm/helper.c | 7 +++++--
19
5 files changed, 53 insertions(+), 11 deletions(-)
20
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
20
--- a/target/arm/helper-mve.h
24
+++ b/target/arm/cpu.h
21
+++ b/target/arm/helper-mve.h
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
26
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
27
/* Used to synchronize KVM and QEMU in-kernel device levels */
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
28
uint8_t device_irq_level;
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
+
29
+
30
+ /* Used to set the maximum vector length the cpu will support. */
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+ uint32_t sve_max_vq;
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
};
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
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
36
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
37
--- a/linux-user/syscall.c
47
--- a/target/arm/translate.h
38
+++ b/linux-user/syscall.c
48
+++ b/target/arm/translate.h
39
@@ -XXX,XX +XXX,XX @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
40
#endif
50
return x * 2 + 1;
41
#ifdef TARGET_AARCH64
42
case TARGET_PR_SVE_SET_VL:
43
- /* We cannot support either PR_SVE_SET_VL_ONEXEC
44
- or PR_SVE_VL_INHERIT. Therefore, anything above
45
- ARM_MAX_VQ results in EINVAL. */
46
+ /*
47
+ * We cannot support either PR_SVE_SET_VL_ONEXEC or
48
+ * PR_SVE_VL_INHERIT. Note the kernel definition
49
+ * of sve_vl_valid allows for VQ=512, i.e. VL=8192,
50
+ * even though the current architectural maximum is VQ=16.
51
+ */
52
ret = -TARGET_EINVAL;
53
if (arm_feature(cpu_env, ARM_FEATURE_SVE)
54
- && arg2 >= 0 && arg2 <= ARM_MAX_VQ * 16 && !(arg2 & 15)) {
55
+ && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
56
CPUARMState *env = cpu_env;
57
- int old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
58
- int vq = MAX(arg2 / 16, 1);
59
+ ARMCPU *cpu = arm_env_get_cpu(env);
60
+ uint32_t vq, old_vq;
61
+
62
+ old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
63
+ vq = MAX(arg2 / 16, 1);
64
+ vq = MIN(vq, cpu->sve_max_vq);
65
66
if (vq < old_vq) {
67
aarch64_sve_narrow_vq(env, vq);
68
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/cpu.c
71
+++ b/target/arm/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
73
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
74
env->cp15.cptr_el[3] |= CPTR_EZ;
75
/* with maximum vector length */
76
- env->vfp.zcr_el[1] = ARM_MAX_VQ - 1;
77
- env->vfp.zcr_el[2] = ARM_MAX_VQ - 1;
78
- env->vfp.zcr_el[3] = ARM_MAX_VQ - 1;
79
+ env->vfp.zcr_el[1] = cpu->sve_max_vq - 1;
80
+ env->vfp.zcr_el[2] = env->vfp.zcr_el[1];
81
+ env->vfp.zcr_el[3] = env->vfp.zcr_el[1];
82
#else
83
/* Reset into the highest available EL */
84
if (arm_feature(env, ARM_FEATURE_EL3)) {
85
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/cpu64.c
88
+++ b/target/arm/cpu64.c
89
@@ -XXX,XX +XXX,XX @@
90
#include "sysemu/sysemu.h"
91
#include "sysemu/kvm.h"
92
#include "kvm_arm.h"
93
+#include "qapi/visitor.h"
94
95
static inline void set_feature(CPUARMState *env, int feature)
96
{
97
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
98
define_arm_cp_regs(cpu, cortex_a57_a53_cp_reginfo);
99
}
51
}
100
52
101
+static void cpu_max_get_sve_vq(Object *obj, Visitor *v, const char *name,
53
+static inline int rsub_64(DisasContext *s, int x)
102
+ void *opaque, Error **errp)
103
+{
54
+{
104
+ ARMCPU *cpu = ARM_CPU(obj);
55
+ return 64 - x;
105
+ visit_type_uint32(v, name, &cpu->sve_max_vq, errp);
106
+}
56
+}
107
+
57
+
108
+static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
58
+static inline int rsub_32(DisasContext *s, int x)
109
+ void *opaque, Error **errp)
110
+{
59
+{
111
+ ARMCPU *cpu = ARM_CPU(obj);
60
+ return 32 - x;
112
+ Error *err = NULL;
113
+
114
+ visit_type_uint32(v, name, &cpu->sve_max_vq, &err);
115
+
116
+ if (!err && (cpu->sve_max_vq == 0 || cpu->sve_max_vq > ARM_MAX_VQ)) {
117
+ error_setg(&err, "unsupported SVE vector length");
118
+ error_append_hint(&err, "Valid sve-max-vq in range [1-%d]\n",
119
+ ARM_MAX_VQ);
120
+ }
121
+ error_propagate(errp, err);
122
+}
61
+}
123
+
62
+
124
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
63
+static inline int rsub_16(DisasContext *s, int x)
125
* otherwise, a CPU with as many features enabled as our emulation supports.
64
+{
126
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
65
+ return 16 - x;
127
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
66
+}
128
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
129
cpu->dcz_blocksize = 7; /* 512 bytes */
130
#endif
131
+
67
+
132
+ cpu->sve_max_vq = ARM_MAX_VQ;
68
+static inline int rsub_8(DisasContext *s, int x)
133
+ object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_vq,
69
+{
134
+ cpu_max_set_sve_vq, NULL, NULL, &error_fatal);
70
+ return 8 - x;
135
}
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
80
@@ -XXX,XX +XXX,XX @@
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
83
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
85
+%rshift_i5 16:5 !function=rsub_32
86
+%rshift_i4 16:4 !function=rsub_16
87
+%rshift_i3 16:3 !function=rsub_8
88
+
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
90
+ size=0 shift=%rshift_i3
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
92
+ size=1 shift=%rshift_i4
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
94
+ size=2 shift=%rshift_i5
95
+
96
# Vector loads and stores
97
98
# Widening loads and narrowing stores:
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
103
+
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
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
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/mve_helper.c
122
+++ b/target/arm/mve_helper.c
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
127
+#define DO_2SHIFT_S(OP, FN) \
128
+ DO_2SHIFT(OP##b, 1, int8_t, FN) \
129
+ DO_2SHIFT(OP##h, 2, int16_t, FN) \
130
+ DO_2SHIFT(OP##w, 4, int32_t, FN)
131
132
#define DO_2SHIFT_SAT_U(OP, FN) \
133
DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
134
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
135
DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
136
137
DO_2SHIFT_U(vshli_u, DO_VSHLU)
138
+DO_2SHIFT_S(vshli_s, DO_VSHLS)
139
DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
140
DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
141
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
142
+DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
143
+DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
144
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-mve.c
147
+++ b/target/arm/translate-mve.c
148
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHLI, vshli_u, false)
149
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
150
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
151
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
152
+/* These right shifts use a left-shift helper with negated shift count */
153
+DO_2SHIFT(VSHRI_S, vshli_s, true)
154
+DO_2SHIFT(VSHRI_U, vshli_u, true)
155
+DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
+DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/translate-neon.c
160
+++ b/target/arm/translate-neon.c
161
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
162
return x + 1;
136
}
163
}
137
164
138
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
165
-static inline int rsub_64(DisasContext *s, int x)
139
uint64_t pmask;
166
-{
140
167
- return 64 - x;
141
assert(vq >= 1 && vq <= ARM_MAX_VQ);
168
-}
142
+ assert(vq <= arm_env_get_cpu(env)->sve_max_vq);
169
-
143
170
-static inline int rsub_32(DisasContext *s, int x)
144
/* Zap the high bits of the zregs. */
171
-{
145
for (i = 0; i < 32; i++) {
172
- return 32 - x;
146
diff --git a/target/arm/helper.c b/target/arm/helper.c
173
-}
147
index XXXXXXX..XXXXXXX 100644
174
-static inline int rsub_16(DisasContext *s, int x)
148
--- a/target/arm/helper.c
175
-{
149
+++ b/target/arm/helper.c
176
- return 16 - x;
150
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
177
-}
151
zcr_len = 0;
178
-static inline int rsub_8(DisasContext *s, int x)
152
} else {
179
-{
153
int current_el = arm_current_el(env);
180
- return 8 - x;
154
+ ARMCPU *cpu = arm_env_get_cpu(env);
181
-}
155
182
-
156
- zcr_len = env->vfp.zcr_el[current_el <= 1 ? 1 : current_el];
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
157
- zcr_len &= 0xf;
184
{
158
+ zcr_len = cpu->sve_max_vq - 1;
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
159
+ if (current_el <= 1) {
160
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
161
+ }
162
if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
163
zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
164
}
165
--
186
--
166
2.18.0
187
2.20.1
167
188
168
189
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Implement the MVE VHLL (vector shift left long) insn. This has two
2
encodings: the T1 encoding is the usual shift-by-immediate format,
3
and the T2 encoding is a special case where the shift count is always
4
equal to the element size.
2
5
3
This will be used to construct a memory region beyond the RAM region
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
to let firmwares scan the address space with load/store to guess how
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
much RAM the SoC has.
8
Message-id: 20210628135835.6690-10-peter.maydell@linaro.org
9
---
10
target/arm/helper-mve.h | 9 +++++++
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
13
target/arm/translate-mve.c | 15 +++++++++++
14
4 files changed, 105 insertions(+), 4 deletions(-)
6
15
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
Signed-off-by: Joel Stanley <joel@jms.id.au>
9
Tested-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 20180807075757.7242-7-joel@jms.id.au
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
include/hw/misc/aspeed_sdmc.h | 1 +
15
hw/arm/aspeed.c | 31 +++++++++++++++++++++++++++++++
16
hw/arm/aspeed_soc.c | 2 ++
17
hw/misc/aspeed_sdmc.c | 3 +++
18
4 files changed, 37 insertions(+)
19
20
diff --git a/include/hw/misc/aspeed_sdmc.h b/include/hw/misc/aspeed_sdmc.h
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/misc/aspeed_sdmc.h
18
--- a/target/arm/helper-mve.h
23
+++ b/include/hw/misc/aspeed_sdmc.h
19
+++ b/target/arm/helper-mve.h
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSDMCState {
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
uint32_t silicon_rev;
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
uint32_t ram_bits;
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
uint64_t ram_size;
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+ uint64_t max_ram_size;
24
+
29
uint32_t fixed_conf;
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
} AspeedSDMCState;
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
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
33
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/aspeed.c
35
--- a/target/arm/mve.decode
35
+++ b/hw/arm/aspeed.c
36
+++ b/target/arm/mve.decode
36
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info aspeed_board_binfo = {
37
@@ -XXX,XX +XXX,XX @@
37
typedef struct AspeedBoardState {
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
38
AspeedSoCState soc;
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
39
MemoryRegion ram;
40
40
+ MemoryRegion max_ram;
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
41
} AspeedBoardState;
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
42
43
+# VSHLL encoding T2 where shift == esize
43
typedef struct AspeedBoardConfig {
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
44
@@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = {
45
+ qd=%qd qm=%qm size=0 shift=8
45
},
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
46
};
47
+ qd=%qd qm=%qm size=1 shift=16
47
48
+
48
+/*
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
49
+ * The max ram region is for firmwares that scan the address space
50
%rshift_i5 16:5 !function=rsub_32
50
+ * with load/store to guess how much RAM the SoC has.
51
%rshift_i4 16:4 !function=rsub_16
51
+ */
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
52
+static uint64_t max_ram_read(void *opaque, hwaddr offset, unsigned size)
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
53
+{
60
+{
54
+ return 0;
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
62
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
63
64
-VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
65
-VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
66
+ VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
55
+}
67
+}
56
+
68
+
57
+static void max_ram_write(void *opaque, hwaddr offset, uint64_t value,
58
+ unsigned size)
59
+{
69
+{
60
+ /* Discard writes */
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
72
+
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
61
+}
74
+}
62
+
75
+
63
+static const MemoryRegionOps max_ram_ops = {
76
+{
64
+ .read = max_ram_read,
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
65
+ .write = max_ram_write,
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
66
+ .endianness = DEVICE_NATIVE_ENDIAN,
67
+};
68
+
79
+
69
#define FIRMWARE_ADDR 0x0
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
70
81
+}
71
static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size,
72
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
73
AspeedBoardState *bmc;
74
AspeedSoCClass *sc;
75
DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
76
+ ram_addr_t max_ram_size;
77
78
bmc = g_new0(AspeedBoardState, 1);
79
object_initialize(&bmc->soc, (sizeof(bmc->soc)), cfg->soc_name);
80
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
81
object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
82
&error_abort);
83
84
+ max_ram_size = object_property_get_uint(OBJECT(&bmc->soc), "max-ram-size",
85
+ &error_abort);
86
+ memory_region_init_io(&bmc->max_ram, NULL, &max_ram_ops, NULL,
87
+ "max_ram", max_ram_size - ram_size);
88
+ memory_region_add_subregion(get_system_memory(),
89
+ sc->info->sdram_base + ram_size,
90
+ &bmc->max_ram);
91
+
82
+
92
aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort);
83
+{
93
aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort);
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
94
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
95
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
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
96
index XXXXXXX..XXXXXXX 100644
110
index XXXXXXX..XXXXXXX 100644
97
--- a/hw/arm/aspeed_soc.c
111
--- a/target/arm/mve_helper.c
98
+++ b/hw/arm/aspeed_soc.c
112
+++ b/target/arm/mve_helper.c
99
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
100
sc->info->silicon_rev);
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
101
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
102
"ram-size", &error_abort);
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
103
+ object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc),
117
+
104
+ "max-ram-size", &error_abort);
118
+/*
105
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
106
for (i = 0; i < sc->info->wdts_num; i++) {
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
107
object_initialize(&s->wdt[i], sizeof(s->wdt[i]), TYPE_ASPEED_WDT);
121
+ * the input, and LESIZE, LTYPE for the output.
108
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
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
109
index XXXXXXX..XXXXXXX 100644
150
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/misc/aspeed_sdmc.c
151
--- a/target/arm/translate-mve.c
111
+++ b/hw/misc/aspeed_sdmc.c
152
+++ b/target/arm/translate-mve.c
112
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
153
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_S, vshli_s, true)
113
case AST2400_A0_SILICON_REV:
154
DO_2SHIFT(VSHRI_U, vshli_u, true)
114
case AST2400_A1_SILICON_REV:
155
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
115
s->ram_bits = ast2400_rambits(s);
156
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
116
+ s->max_ram_size = 512 << 20;
157
+
117
s->fixed_conf = ASPEED_SDMC_VGA_COMPAT |
158
+#define DO_VSHLL(INSN, FN) \
118
ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
159
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
119
break;
160
+ { \
120
case AST2500_A0_SILICON_REV:
161
+ static MVEGenTwoOpShiftFn * const fns[] = { \
121
case AST2500_A1_SILICON_REV:
162
+ gen_helper_mve_##FN##b, \
122
s->ram_bits = ast2500_rambits(s);
163
+ gen_helper_mve_##FN##h, \
123
+ s->max_ram_size = 1024 << 20;
164
+ }; \
124
s->fixed_conf = ASPEED_SDMC_HW_VERSION(1) |
165
+ return do_2shift(s, a, fns[a->size], false); \
125
ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
166
+ }
126
ASPEED_SDMC_CACHE_INITIAL_DONE |
167
+
127
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_sdmc = {
168
+DO_VSHLL(VSHLL_BS, vshllbs)
128
static Property aspeed_sdmc_properties[] = {
169
+DO_VSHLL(VSHLL_BU, vshllbu)
129
DEFINE_PROP_UINT32("silicon-rev", AspeedSDMCState, silicon_rev, 0),
170
+DO_VSHLL(VSHLL_TS, vshllts)
130
DEFINE_PROP_UINT64("ram-size", AspeedSDMCState, ram_size, 0),
171
+DO_VSHLL(VSHLL_TU, vshlltu)
131
+ DEFINE_PROP_UINT64("max-ram-size", AspeedSDMCState, max_ram_size, 0),
132
DEFINE_PROP_END_OF_LIST(),
133
};
134
135
--
172
--
136
2.18.0
173
2.20.1
137
174
138
175
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE VSRI and VSLI insns, which perform a
2
shift-and-insert operation.
2
3
3
This makes float16_muladd correctly use FZ16 not FZ.
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
7
---
8
target/arm/helper-mve.h | 8 ++++++++
9
target/arm/mve.decode | 9 ++++++++
10
target/arm/mve_helper.c | 42 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-mve.c | 3 +++
12
4 files changed, 62 insertions(+)
4
13
5
Fixes: 6ceabaad110
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
6
Cc: qemu-stable@nongnu.org (3.0.1)
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
11
Message-id: 20180810193129.1556-4-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/sve_helper.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
17
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/sve_helper.c
16
--- a/target/arm/helper-mve.h
20
+++ b/target/arm/sve_helper.c
17
+++ b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@ static void do_fmla_zpzzz_h(CPUARMState *env, void *vg, uint32_t desc,
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
e1 = *(uint16_t *)(vn + H1_2(i)) ^ neg1;
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
e2 = *(uint16_t *)(vm + H1_2(i));
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
e3 = *(uint16_t *)(va + H1_2(i)) ^ neg3;
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
- r = float16_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
22
+
26
+ r = float16_muladd(e1, e2, e3, 0, &env->vfp.fp_status_f16);
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
*(uint16_t *)(vd + H1_2(i)) = r;
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
}
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
} while (i & 63);
26
+
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/mve.decode
33
+++ b/target/arm/mve.decode
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
35
36
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
37
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
38
+
39
+# Shift-and-insert
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
43
+
44
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
45
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
46
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
47
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/mve_helper.c
50
+++ b/target/arm/mve_helper.c
51
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
52
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
53
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
54
55
+/* Shift-and-insert; we always work with 64 bits at a time */
56
+#define DO_2SHIFT_INSERT(OP, ESIZE, SHIFTFN, MASKFN) \
57
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
58
+ void *vm, uint32_t shift) \
59
+ { \
60
+ uint64_t *d = vd, *m = vm; \
61
+ uint16_t mask; \
62
+ uint64_t shiftmask; \
63
+ unsigned e; \
64
+ if (shift == 0 || shift == ESIZE * 8) { \
65
+ /* \
66
+ * Only VSLI can shift by 0; only VSRI can shift by <dt>. \
67
+ * The generic logic would give the right answer for 0 but \
68
+ * fails for <dt>. \
69
+ */ \
70
+ goto done; \
71
+ } \
72
+ assert(shift < ESIZE * 8); \
73
+ mask = mve_element_mask(env); \
74
+ /* ESIZE / 2 gives the MO_* value if ESIZE is in [1,2,4] */ \
75
+ shiftmask = dup_const(ESIZE / 2, MASKFN(ESIZE * 8, shift)); \
76
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
77
+ uint64_t r = (SHIFTFN(m[H8(e)], shift) & shiftmask) | \
78
+ (d[H8(e)] & ~shiftmask); \
79
+ mergemask(&d[H8(e)], r, mask); \
80
+ } \
81
+done: \
82
+ mve_advance_vpt(env); \
83
+ }
84
+
85
+#define DO_SHL(N, SHIFT) ((N) << (SHIFT))
86
+#define DO_SHR(N, SHIFT) ((N) >> (SHIFT))
87
+#define SHL_MASK(EBITS, SHIFT) MAKE_64BIT_MASK((SHIFT), (EBITS) - (SHIFT))
88
+#define SHR_MASK(EBITS, SHIFT) MAKE_64BIT_MASK(0, (EBITS) - (SHIFT))
89
+
90
+DO_2SHIFT_INSERT(vsrib, 1, DO_SHR, SHR_MASK)
91
+DO_2SHIFT_INSERT(vsrih, 2, DO_SHR, SHR_MASK)
92
+DO_2SHIFT_INSERT(vsriw, 4, DO_SHR, SHR_MASK)
93
+DO_2SHIFT_INSERT(vslib, 1, DO_SHL, SHL_MASK)
94
+DO_2SHIFT_INSERT(vslih, 2, DO_SHL, SHL_MASK)
95
+DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
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
{ \
30
--
114
--
31
2.18.0
115
2.20.1
32
116
33
117
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
2
2
3
Tested by booting linux 4.18 (built using imx_v6_v7_defconfig) on the
3
do_urshr() is borrowed from sve_helper.c.
4
emulated board.
5
4
6
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
7
Message-id: 3f8eb4300206634dc01e04b12f65b73c0ad2f955.1532984236.git.jcd@tribudubois.net
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
10
---
8
---
11
hw/arm/Makefile.objs | 2 +-
9
target/arm/helper-mve.h | 10 ++++++++++
12
hw/arm/mcimx6ul-evk.c | 85 +++++++++++++++++++++++++++++++++++++++++++
10
target/arm/mve.decode | 11 +++++++++++
13
2 files changed, 86 insertions(+), 1 deletion(-)
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
14
create mode 100644 hw/arm/mcimx6ul-evk.c
12
target/arm/translate-mve.c | 15 ++++++++++++++
13
4 files changed, 76 insertions(+)
15
14
16
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/Makefile.objs
17
--- a/target/arm/helper-mve.h
19
+++ b/hw/arm/Makefile.objs
18
+++ b/target/arm/helper-mve.h
20
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
obj-$(CONFIG_IOTKIT) += iotkit.o
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
-obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o
23
+
25
+obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o mcimx6ul-evk.o
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
new file mode 100644
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
index XXXXXXX..XXXXXXX
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
--- /dev/null
28
+
30
+++ b/hw/arm/mcimx6ul-evk.c
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
@@ -XXX,XX +XXX,XX @@
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
41
+
42
+# Narrowing shifts (which only support b and h sizes)
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
46
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
47
+
48
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
49
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
50
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
51
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
52
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/mve_helper.c
55
+++ b/target/arm/mve_helper.c
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
57
58
DO_VSHLL_ALL(vshllb, false)
59
DO_VSHLL_ALL(vshllt, true)
60
+
32
+/*
61
+/*
33
+ * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net>
62
+ * Narrowing right shifts, taking a double sized input, shifting it
34
+ *
63
+ * and putting the result in either the top or bottom half of the output.
35
+ * MCIMX6UL_EVK Board System emulation.
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
36
+ *
37
+ * This code is licensed under the GPL, version 2 or later.
38
+ * See the file `COPYING' in the top level directory.
39
+ *
40
+ * It (partially) emulates a mcimx6ul_evk board, with a Freescale
41
+ * i.MX6ul SoC
42
+ */
65
+ */
43
+
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
44
+#include "qemu/osdep.h"
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
45
+#include "qapi/error.h"
68
+ void *vm, uint32_t shift) \
46
+#include "qemu-common.h"
69
+ { \
47
+#include "hw/arm/fsl-imx6ul.h"
70
+ LTYPE *m = vm; \
48
+#include "hw/boards.h"
71
+ TYPE *d = vd; \
49
+#include "sysemu/sysemu.h"
72
+ uint16_t mask = mve_element_mask(env); \
50
+#include "qemu/error-report.h"
73
+ unsigned le; \
51
+#include "sysemu/qtest.h"
74
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
52
+
75
+ TYPE r = FN(m[H##LESIZE(le)], shift); \
53
+typedef struct {
76
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
54
+ FslIMX6ULState soc;
77
+ } \
55
+ MemoryRegion ram;
78
+ mve_advance_vpt(env); \
56
+} MCIMX6ULEVK;
57
+
58
+static void mcimx6ul_evk_init(MachineState *machine)
59
+{
60
+ static struct arm_boot_info boot_info;
61
+ MCIMX6ULEVK *s = g_new0(MCIMX6ULEVK, 1);
62
+ int i;
63
+
64
+ if (machine->ram_size > FSL_IMX6UL_MMDC_SIZE) {
65
+ error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)",
66
+ machine->ram_size, FSL_IMX6UL_MMDC_SIZE);
67
+ exit(1);
68
+ }
79
+ }
69
+
80
+
70
+ boot_info = (struct arm_boot_info) {
81
+#define DO_VSHRN_ALL(OP, FN) \
71
+ .loader_start = FSL_IMX6UL_MMDC_ADDR,
82
+ DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
72
+ .board_id = -1,
83
+ DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
73
+ .ram_size = machine->ram_size,
84
+ DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
74
+ .kernel_filename = machine->kernel_filename,
85
+ DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
75
+ .kernel_cmdline = machine->kernel_cmdline,
76
+ .initrd_filename = machine->initrd_filename,
77
+ .nb_cpus = smp_cpus,
78
+ };
79
+
86
+
80
+ object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
81
+ TYPE_FSL_IMX6UL, &error_fatal, NULL);
88
+{
82
+
89
+ if (likely(sh < 64)) {
83
+ object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
84
+
91
+ } else if (sh == 64) {
85
+ memory_region_allocate_system_memory(&s->ram, NULL, "mcimx6ul-evk.ram",
92
+ return x >> 63;
86
+ machine->ram_size);
93
+ } else {
87
+ memory_region_add_subregion(get_system_memory(),
94
+ return 0;
88
+ FSL_IMX6UL_MMDC_ADDR, &s->ram);
89
+
90
+ for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
91
+ BusState *bus;
92
+ DeviceState *carddev;
93
+ DriveInfo *di;
94
+ BlockBackend *blk;
95
+
96
+ di = drive_get_next(IF_SD);
97
+ blk = di ? blk_by_legacy_dinfo(di) : NULL;
98
+ bus = qdev_get_child_bus(DEVICE(&s->soc.usdhc[i]), "sd-bus");
99
+ carddev = qdev_create(bus, TYPE_SD_CARD);
100
+ qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
101
+ object_property_set_bool(OBJECT(carddev), true,
102
+ "realized", &error_fatal);
103
+ }
104
+
105
+ if (!qtest_enabled()) {
106
+ arm_load_kernel(&s->soc.cpu[0], &boot_info);
107
+ }
95
+ }
108
+}
96
+}
109
+
97
+
110
+static void mcimx6ul_evk_machine_init(MachineClass *mc)
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
111
+{
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
112
+ mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex A7)";
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
113
+ mc->init = mcimx6ul_evk_init;
101
index XXXXXXX..XXXXXXX 100644
114
+ mc->max_cpus = FSL_IMX6UL_NUM_CPUS;
102
--- a/target/arm/translate-mve.c
115
+}
103
+++ b/target/arm/translate-mve.c
116
+DEFINE_MACHINE("mcimx6ul-evk", mcimx6ul_evk_machine_init)
104
@@ -XXX,XX +XXX,XX @@ DO_VSHLL(VSHLL_BS, vshllbs)
105
DO_VSHLL(VSHLL_BU, vshllbu)
106
DO_VSHLL(VSHLL_TS, vshllts)
107
DO_VSHLL(VSHLL_TU, vshlltu)
108
+
109
+#define DO_2SHIFT_N(INSN, FN) \
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
111
+ { \
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
113
+ gen_helper_mve_##FN##b, \
114
+ gen_helper_mve_##FN##h, \
115
+ }; \
116
+ return do_2shift(s, a, fns[a->size], false); \
117
+ }
118
+
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
117
--
123
--
118
2.18.0
124
2.20.1
119
125
120
126
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
Implement the MVE saturating shift-right-and-narrow insns
2
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
Image file loaders may add a series of roms. If an error occurs partway
3
4
through loading there is no easy way to drop previously added roms.
4
do_srshr() is borrowed from sve_helper.c.
5
5
6
This patch adds a transaction mechanism that works like this:
7
8
rom_transaction_begin();
9
...call rom_add_*()...
10
rom_transaction_end(ok);
11
12
If ok is false then roms added in this transaction are dropped.
13
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20180814162739.11814-5-stefanha@redhat.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-13-peter.maydell@linaro.org
18
---
9
---
19
include/hw/loader.h | 19 +++++++++++++++++++
10
target/arm/helper-mve.h | 30 +++++++++++
20
hw/core/loader.c | 32 ++++++++++++++++++++++++++++++++
11
target/arm/mve.decode | 28 ++++++++++
21
2 files changed, 51 insertions(+)
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
22
13
target/arm/translate-mve.c | 12 +++++
23
diff --git a/include/hw/loader.h b/include/hw/loader.h
14
4 files changed, 174 insertions(+)
24
index XXXXXXX..XXXXXXX 100644
15
25
--- a/include/hw/loader.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
26
+++ b/include/hw/loader.h
17
index XXXXXXX..XXXXXXX 100644
27
@@ -XXX,XX +XXX,XX @@ int rom_check_and_register_reset(void);
18
--- a/target/arm/helper-mve.h
28
void rom_set_fw(FWCfgState *f);
19
+++ b/target/arm/helper-mve.h
29
void rom_set_order_override(int order);
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
void rom_reset_order_override(void);
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+/**
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+ * rom_transaction_begin:
24
+
34
+ *
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+ * Call this before of a series of rom_add_*() calls. Call
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+ * rom_transaction_end() afterwards to commit or abort. These functions are
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+ * useful for undoing a series of rom_add_*() calls if image file loading fails
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
+ * partway through.
29
+
39
+ */
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+void rom_transaction_begin(void);
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
+/**
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+ * rom_transaction_end:
34
+
44
+ * @commit: true to commit added roms, false to drop added roms
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
+ *
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+ * Call this after a series of rom_add_*() calls. See rom_transaction_begin().
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
+ */
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
+void rom_transaction_end(bool commit);
39
+
49
+
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
void *rom_ptr(hwaddr addr, size_t size);
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
void hmp_info_roms(Monitor *mon, const QDict *qdict);
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
diff --git a/hw/core/loader.c b/hw/core/loader.c
44
+
54
index XXXXXXX..XXXXXXX 100644
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
55
--- a/hw/core/loader.c
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
56
+++ b/hw/core/loader.c
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
57
@@ -XXX,XX +XXX,XX @@ struct Rom {
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
58
char *fw_dir;
49
+
59
char *fw_file;
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
60
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
61
+ bool committed;
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
62
+
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
63
hwaddr addr;
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
64
QTAILQ_ENTRY(Rom) next;
55
index XXXXXXX..XXXXXXX 100644
65
};
56
--- a/target/arm/mve.decode
66
@@ -XXX,XX +XXX,XX @@ static void rom_insert(Rom *rom)
57
+++ b/target/arm/mve.decode
67
rom->as = &address_space_memory;
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
62
+
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
68
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
69
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
70
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
71
+
72
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
73
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
74
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
75
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
76
+
77
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
78
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
79
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
80
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
81
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
82
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
83
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
84
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
85
+
86
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
87
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
88
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
89
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
90
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/mve_helper.c
93
+++ b/target/arm/mve_helper.c
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
68
}
95
}
69
70
+ rom->committed = false;
71
+
72
/* List is ordered by load address in the same address space */
73
QTAILQ_FOREACH(item, &roms, next) {
74
if (rom_order_compare(rom, item)) {
75
@@ -XXX,XX +XXX,XX @@ void rom_reset_order_override(void)
76
fw_cfg_reset_order_override(fw_cfg);
77
}
96
}
78
97
79
+void rom_transaction_begin(void)
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
80
+{
99
+{
81
+ Rom *rom;
100
+ if (likely(sh < 64)) {
82
+
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
83
+ /* Ignore ROMs added without the transaction API */
102
+ } else {
84
+ QTAILQ_FOREACH(rom, &roms, next) {
103
+ /* Rounding the sign bit always produces 0. */
85
+ rom->committed = true;
104
+ return 0;
86
+ }
105
+ }
87
+}
106
+}
88
+
107
+
89
+void rom_transaction_end(bool commit)
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)
90
+{
113
+{
91
+ Rom *rom;
114
+ if (val > max) {
92
+ Rom *tmp;
115
+ *satp = true;
93
+
116
+ return max;
94
+ QTAILQ_FOREACH_SAFE(rom, &roms, next, tmp) {
117
+ } else if (val < min) {
95
+ if (rom->committed) {
118
+ *satp = true;
96
+ continue;
119
+ return min;
97
+ }
120
+ } else {
98
+ if (commit) {
121
+ return val;
99
+ rom->committed = true;
100
+ } else {
101
+ QTAILQ_REMOVE(&roms, rom, next);
102
+ rom_free(rom);
103
+ }
104
+ }
122
+ }
105
+}
123
+}
106
+
124
+
107
static Rom *find_rom(hwaddr addr, size_t size)
125
+/* Saturating narrowing right shifts */
108
{
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
109
Rom *rom;
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
128
+ void *vm, uint32_t shift) \
129
+ { \
130
+ LTYPE *m = vm; \
131
+ TYPE *d = vd; \
132
+ uint16_t mask = mve_element_mask(env); \
133
+ bool qc = false; \
134
+ unsigned le; \
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
136
+ bool sat = false; \
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
140
+ } \
141
+ if (qc) { \
142
+ env->vfp.qc[0] = qc; \
143
+ } \
144
+ mve_advance_vpt(env); \
145
+ }
146
+
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
150
+
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
154
+
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
158
+
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
162
+
163
+#define DO_SHRN_SB(N, M, SATP) \
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
165
+#define DO_SHRN_UB(N, M, SATP) \
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
167
+#define DO_SHRUN_B(N, M, SATP) \
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
169
+
170
+#define DO_SHRN_SH(N, M, SATP) \
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
172
+#define DO_SHRN_UH(N, M, SATP) \
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
174
+#define DO_SHRUN_H(N, M, SATP) \
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
176
+
177
+#define DO_RSHRN_SB(N, M, SATP) \
178
+ do_sat_bhs(do_srshr(N, M), INT8_MIN, INT8_MAX, SATP)
179
+#define DO_RSHRN_UB(N, M, SATP) \
180
+ do_sat_bhs(do_urshr(N, M), 0, UINT8_MAX, SATP)
181
+#define DO_RSHRUN_B(N, M, SATP) \
182
+ do_sat_bhs(do_srshr(N, M), 0, UINT8_MAX, SATP)
183
+
184
+#define DO_RSHRN_SH(N, M, SATP) \
185
+ do_sat_bhs(do_srshr(N, M), INT16_MIN, INT16_MAX, SATP)
186
+#define DO_RSHRN_UH(N, M, SATP) \
187
+ do_sat_bhs(do_urshr(N, M), 0, UINT16_MAX, SATP)
188
+#define DO_RSHRUN_H(N, M, SATP) \
189
+ do_sat_bhs(do_srshr(N, M), 0, UINT16_MAX, SATP)
190
+
191
+DO_VSHRN_SAT_SB(vqshrnb_sb, vqshrnt_sb, DO_SHRN_SB)
192
+DO_VSHRN_SAT_SH(vqshrnb_sh, vqshrnt_sh, DO_SHRN_SH)
193
+DO_VSHRN_SAT_UB(vqshrnb_ub, vqshrnt_ub, DO_SHRN_UB)
194
+DO_VSHRN_SAT_UH(vqshrnb_uh, vqshrnt_uh, DO_SHRN_UH)
195
+DO_VSHRN_SAT_SB(vqshrunbb, vqshruntb, DO_SHRUN_B)
196
+DO_VSHRN_SAT_SH(vqshrunbh, vqshrunth, DO_SHRUN_H)
197
+
198
+DO_VSHRN_SAT_SB(vqrshrnb_sb, vqrshrnt_sb, DO_RSHRN_SB)
199
+DO_VSHRN_SAT_SH(vqrshrnb_sh, vqrshrnt_sh, DO_RSHRN_SH)
200
+DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
201
+DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
202
+DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
203
+DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
204
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/arm/translate-mve.c
207
+++ b/target/arm/translate-mve.c
208
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VSHRNB, vshrnb)
209
DO_2SHIFT_N(VSHRNT, vshrnt)
210
DO_2SHIFT_N(VRSHRNB, vrshrnb)
211
DO_2SHIFT_N(VRSHRNT, vrshrnt)
212
+DO_2SHIFT_N(VQSHRNB_S, vqshrnb_s)
213
+DO_2SHIFT_N(VQSHRNT_S, vqshrnt_s)
214
+DO_2SHIFT_N(VQSHRNB_U, vqshrnb_u)
215
+DO_2SHIFT_N(VQSHRNT_U, vqshrnt_u)
216
+DO_2SHIFT_N(VQSHRUNB, vqshrunb)
217
+DO_2SHIFT_N(VQSHRUNT, vqshrunt)
218
+DO_2SHIFT_N(VQRSHRNB_S, vqrshrnb_s)
219
+DO_2SHIFT_N(VQRSHRNT_S, vqrshrnt_s)
220
+DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
221
+DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
222
+DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
223
+DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
110
--
224
--
111
2.18.0
225
2.20.1
112
226
113
227
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE VSHLC insn, which performs a shift left of the
2
entire vector with carry in bits provided from a general purpose
3
register and carry out bits written back to that register.
2
4
3
When support for FZ16 was added, we failed to include the bit
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
within FPCR_MASK, which means that it could never be set.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Continue to zero FZ16 when ARMv8.2-FP16 is not enabled.
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
8
---
9
target/arm/helper-mve.h | 2 ++
10
target/arm/mve.decode | 2 ++
11
target/arm/mve_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-mve.c | 30 ++++++++++++++++++++++++++++++
13
4 files changed, 72 insertions(+)
6
14
7
Fixes: d81ce0ef2c4
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
Cc: qemu-stable@nongnu.org (3.0.1)
9
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
13
Message-id: 20180810193129.1556-2-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/cpu.h | 2 +-
17
target/arm/helper.c | 5 +++++
18
2 files changed, 6 insertions(+), 1 deletion(-)
19
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
17
--- a/target/arm/helper-mve.h
23
+++ b/target/arm/cpu.h
18
+++ b/target/arm/helper-mve.h
24
@@ -XXX,XX +XXX,XX @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
* we store the underlying state in fpscr and just mask on read/write.
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
#define FPSR_MASK 0xf800009f
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
-#define FPCR_MASK 0x07f79f00
23
+
29
+#define FPCR_MASK 0x07ff9f00
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
#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
32
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
33
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/helper.c
27
--- a/target/arm/mve.decode
36
+++ b/target/arm/helper.c
28
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
38
int i;
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
39
uint32_t changed;
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
40
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
41
+ /* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
33
+
42
+ if (!arm_feature(env, ARM_FEATURE_V8_FP16)) {
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
43
+ val &= ~FPCR_FZ16;
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/mve_helper.c
38
+++ b/target/arm/mve_helper.c
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
43
+
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
45
+ uint32_t shift)
46
+{
47
+ uint32_t *d = vd;
48
+ uint16_t mask = mve_element_mask(env);
49
+ unsigned e;
50
+ uint32_t r;
51
+
52
+ /*
53
+ * For each 32-bit element, we shift it left, bringing in the
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
55
+ * the top become the new rdm, if the predicate mask permits.
56
+ * The final rdm value is returned to update the register.
57
+ * shift == 0 here means "shift by 32 bits".
58
+ */
59
+ if (shift == 0) {
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
61
+ r = rdm;
62
+ if (mask & 1) {
63
+ rdm = d[H4(e)];
64
+ }
65
+ mergemask(&d[H4(e)], r, mask);
66
+ }
67
+ } else {
68
+ uint32_t shiftmask = MAKE_64BIT_MASK(0, shift);
69
+
70
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
71
+ r = (d[H4(e)] << shift) | (rdm & shiftmask);
72
+ if (mask & 1) {
73
+ rdm = d[H4(e)] >> (32 - shift);
74
+ }
75
+ mergemask(&d[H4(e)], r, mask);
76
+ }
77
+ }
78
+ mve_advance_vpt(env);
79
+ return rdm;
80
+}
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/translate-mve.c
84
+++ b/target/arm/translate-mve.c
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
86
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
87
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
88
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
89
+
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
91
+{
92
+ /*
93
+ * Whole Vector Left Shift with Carry. The carry is taken
94
+ * from a general purpose register and written back there.
95
+ * An imm of 0 means "shift by 32".
96
+ */
97
+ TCGv_ptr qd;
98
+ TCGv_i32 rdm;
99
+
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
101
+ return false;
102
+ }
103
+ if (a->rdm == 13 || a->rdm == 15) {
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
105
+ return false;
106
+ }
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
108
+ return true;
44
+ }
109
+ }
45
+
110
+
46
changed = env->vfp.xregs[ARM_VFP_FPSCR];
111
+ qd = mve_qreg_ptr(a->qd);
47
env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
112
+ rdm = load_reg(s, a->rdm);
48
env->vfp.vec_len = (val >> 16) & 7;
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
+}
49
--
119
--
50
2.18.0
120
2.20.1
51
121
52
122
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
2
that it accumulates 32-bit elements into a 64-bit accumulator
3
stored in a pair of general-purpose registers.
2
4
3
Define a "cortex-m0" ARMv6-M CPU model.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
8
---
9
target/arm/helper-mve.h | 3 ++
10
target/arm/mve.decode | 6 +++-
11
target/arm/mve_helper.c | 19 ++++++++++++
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
13
4 files changed, 90 insertions(+), 1 deletion(-)
4
14
5
Most of the register reset values set by other CPU models are not
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
6
relevant for the cut-down ARMv6-M architecture.
7
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20180814162739.11814-3-stefanha@redhat.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/cpu.c | 11 +++++++++++
15
1 file changed, 11 insertions(+)
16
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.c
17
--- a/target/arm/helper-mve.h
20
+++ b/target/arm/cpu.c
18
+++ b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
cpu->reset_auxcr = 1;
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
25
+
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
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
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/mve.decode
32
+++ b/target/arm/mve.decode
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
35
36
# Vector add across vector
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
38
+{
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
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;
23
}
82
}
24
83
25
+static void cortex_m0_initfn(Object *obj)
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
26
+{
85
+{
27
+ ARMCPU *cpu = ARM_CPU(obj);
86
+ /*
28
+ set_feature(&cpu->env, ARM_FEATURE_V6);
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
29
+ set_feature(&cpu->env, ARM_FEATURE_M);
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;
30
+
95
+
31
+ cpu->midr = 0x410cc200;
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;
32
+}
145
+}
33
+
146
+
34
static void cortex_m3_initfn(Object *obj)
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
35
{
148
{
36
ARMCPU *cpu = ARM_CPU(obj);
149
TCGv_ptr qd;
37
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
38
{ .name = "arm1136", .initfn = arm1136_initfn },
39
{ .name = "arm1176", .initfn = arm1176_initfn },
40
{ .name = "arm11mpcore", .initfn = arm11mpcore_initfn },
41
+ { .name = "cortex-m0", .initfn = cortex_m0_initfn,
42
+ .class_init = arm_v7m_class_init },
43
{ .name = "cortex-m3", .initfn = cortex_m3_initfn,
44
.class_init = arm_v7m_class_init },
45
{ .name = "cortex-m4", .initfn = cortex_m4_initfn,
46
--
150
--
47
2.18.0
151
2.20.1
48
152
49
153
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
The MVE extension to v8.1M includes some new shift instructions which
2
2
sit entirely within the non-coprocessor part of the encoding space
3
This is required to ensure u-boot SDRAM training completes.
3
and which operate only on general-purpose registers. They take up
4
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
5
with Rm == 13 or 15.
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
7
Tested-by: Cédric Le Goater <clg@kaod.org>
7
Implement the long shifts by immediate, which perform shifts on a
8
Message-id: 20180807075757.7242-6-joel@jms.id.au
8
pair of general-purpose registers treated as a 64-bit quantity, with
9
an immediate shift count between 1 and 32.
10
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
14
is too difficult, because the functions that generate the code are
15
shared between a dozen different kinds of arithmetic or logical
16
instruction for all A32, T16 and T32 encodings, and for some insns
17
and some encodings Rm==13,15 are valid.)
18
19
We make the helper functions we need for UQSHLL and SQSHLL take
20
a 32-bit value which the helper casts to int8_t because we'll need
21
these helpers also for the shift-by-register insns, where the shift
22
count might be < 0 or > 32.
23
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
10
---
27
---
11
hw/misc/aspeed_sdmc.c | 9 +++++++++
28
target/arm/helper-mve.h | 3 ++
12
1 file changed, 9 insertions(+)
29
target/arm/translate.h | 1 +
13
30
target/arm/t32.decode | 28 +++++++++++++
14
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
31
target/arm/mve_helper.c | 10 +++++
15
index XXXXXXX..XXXXXXX 100644
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
16
--- a/hw/misc/aspeed_sdmc.c
33
5 files changed, 132 insertions(+)
17
+++ b/hw/misc/aspeed_sdmc.c
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
18
@@ -XXX,XX +XXX,XX @@
62
@@ -XXX,XX +XXX,XX @@
19
#define R_STATUS1 (0x60 / 4)
63
&mcr !extern cp opc1 crn crm opc2 rt
20
#define PHY_BUSY_STATE BIT(0)
64
&mcrr !extern cp opc1 crm rt rt2
21
65
22
+#define R_ECC_TEST_CTRL (0x70 / 4)
66
+&mve_shl_ri rdalo rdahi shim
23
+#define ECC_TEST_FINISHED BIT(12)
67
+
24
+#define ECC_TEST_FAIL BIT(13)
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
+}
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate.c
131
+++ b/target/arm/translate.c
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
133
return true;
134
}
135
136
+/*
137
+ * v8.1M MVE wide-shifts
138
+ */
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
140
+ WideShiftImmFn *fn)
141
+{
142
+ TCGv_i64 rda;
143
+ TCGv_i32 rdalo, rdahi;
144
+
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
146
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
147
+ return false;
148
+ }
149
+ if (a->rdahi == 15) {
150
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
151
+ return false;
152
+ }
153
+ if (!dc_isar_feature(aa32_mve, s) ||
154
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
155
+ a->rdahi == 13) {
156
+ /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
157
+ unallocated_encoding(s);
158
+ return true;
159
+ }
160
+
161
+ if (a->shim == 0) {
162
+ a->shim = 32;
163
+ }
164
+
165
+ rda = tcg_temp_new_i64();
166
+ rdalo = load_reg(s, a->rdalo);
167
+ rdahi = load_reg(s, a->rdahi);
168
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
169
+
170
+ fn(rda, rda, a->shim);
171
+
172
+ tcg_gen_extrl_i64_i32(rdalo, rda);
173
+ tcg_gen_extrh_i64_i32(rdahi, rda);
174
+ store_reg(s, a->rdalo, rdalo);
175
+ store_reg(s, a->rdahi, rdahi);
176
+ tcg_temp_free_i64(rda);
177
+
178
+ return true;
179
+}
180
+
181
+static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
182
+{
183
+ return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
184
+}
185
+
186
+static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
187
+{
188
+ return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
189
+}
190
+
191
+static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
192
+{
193
+ return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
194
+}
195
+
196
+static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
197
+{
198
+ gen_helper_mve_sqshll(r, cpu_env, n, tcg_constant_i32(shift));
199
+}
200
+
201
+static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
202
+{
203
+ return do_mve_shl_ri(s, a, gen_mve_sqshll);
204
+}
205
+
206
+static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
207
+{
208
+ gen_helper_mve_uqshll(r, cpu_env, n, tcg_constant_i32(shift));
209
+}
210
+
211
+static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
212
+{
213
+ return do_mve_shl_ri(s, a, gen_mve_uqshll);
214
+}
215
+
216
+static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
217
+{
218
+ return do_mve_shl_ri(s, a, gen_srshr64_i64);
219
+}
220
+
221
+static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
222
+{
223
+ return do_mve_shl_ri(s, a, gen_urshr64_i64);
224
+}
25
+
225
+
26
/*
226
/*
27
* Configuration register Ox4 (for Aspeed AST2400 SOC)
227
* Multiply and multiply accumulate
28
*
228
*/
29
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
30
/* Will never return 'busy' */
31
data &= ~PHY_BUSY_STATE;
32
break;
33
+ case R_ECC_TEST_CTRL:
34
+ /* Always done, always happy */
35
+ data |= ECC_TEST_FINISHED;
36
+ data &= ~ECC_TEST_FAIL;
37
+ break;
38
default:
39
break;
40
}
41
--
229
--
42
2.18.0
230
2.20.1
43
231
44
232
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
Implement the MVE long shifts by register, which perform shifts on a
2
2
pair of general-purpose registers treated as a 64-bit quantity, with
3
The ast2500 SDRAM training routine busy waits on the 'init cycle busy
3
the shift count in another general-purpose register, which might be
4
state' bit in DDR PHY Control/Status register #1 (MCR60).
4
either positive or negative.
5
5
6
This ensures the bit always reads zero, and allows training to
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
complete with upstream u-boot on the ast2500-evb.
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
Reviewed-by: Cédric Le Goater <clg@kaod.org>
10
we have to move the CSEL pattern into the same decodetree group.
11
Tested-by: Cédric Le Goater <clg@kaod.org>
11
12
Message-id: 20180807075757.7242-5-joel@jms.id.au
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
14
---
15
---
15
hw/misc/aspeed_sdmc.c | 15 +++++++++++++++
16
target/arm/helper-mve.h | 6 +++
16
1 file changed, 15 insertions(+)
17
target/arm/translate.h | 1 +
17
18
target/arm/t32.decode | 16 +++++--
18
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
19
index XXXXXXX..XXXXXXX 100644
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
20
--- a/hw/misc/aspeed_sdmc.c
21
5 files changed, 182 insertions(+), 3 deletions(-)
21
+++ b/hw/misc/aspeed_sdmc.c
22
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-mve.h
26
+++ b/target/arm/helper-mve.h
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
30
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate.h
42
+++ b/target/arm/translate.h
43
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
44
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
45
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
46
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
47
+typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
48
49
/**
50
* arm_tbflags_from_tb:
51
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/t32.decode
54
+++ b/target/arm/t32.decode
22
@@ -XXX,XX +XXX,XX @@
55
@@ -XXX,XX +XXX,XX @@
23
/* Configuration Register */
56
&mcrr !extern cp opc1 crm rt rt2
24
#define R_CONF (0x04 / 4)
57
25
58
&mve_shl_ri rdalo rdahi shim
26
+/* Control/Status Register #1 (ast2500) */
59
+&mve_shl_rr rdalo rdahi rm
27
+#define R_STATUS1 (0x60 / 4)
60
28
+#define PHY_BUSY_STATE BIT(0)
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
+}
29
+
287
+
30
/*
288
/*
31
* Configuration register Ox4 (for Aspeed AST2400 SOC)
289
* Multiply and multiply accumulate
32
*
290
*/
33
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
34
g_assert_not_reached();
35
}
36
}
37
+ if (s->silicon_rev == AST2500_A0_SILICON_REV ||
38
+ s->silicon_rev == AST2500_A1_SILICON_REV) {
39
+ switch (addr) {
40
+ case R_STATUS1:
41
+ /* Will never return 'busy' */
42
+ data &= ~PHY_BUSY_STATE;
43
+ break;
44
+ default:
45
+ break;
46
+ }
47
+ }
48
49
s->regs[addr] = data;
50
}
51
--
291
--
52
2.18.0
292
2.20.1
53
293
54
294
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE shifts by immediate, which perform shifts
2
2
on a single general-purpose register.
3
Also fold the FPCR/FPSR state onto the same line as PSTATE,
3
4
and mention but do not dump disabled FPU state.
4
These patterns overlap with the long-shift-by-immediates,
5
5
so we have to rearrange the grouping a little here.
6
Cc: qemu-stable@nongnu.org (3.0.1)
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
11
---
10
---
12
target/arm/translate-a64.c | 95 +++++++++++++++++++++++++++++++++-----
11
target/arm/helper-mve.h | 3 ++
13
1 file changed, 83 insertions(+), 12 deletions(-)
12
target/arm/translate.h | 1 +
14
13
target/arm/t32.decode | 31 ++++++++++++++-----
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
target/arm/mve_helper.c | 10 ++++++
16
index XXXXXXX..XXXXXXX 100644
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
17
--- a/target/arm/translate-a64.c
16
5 files changed, 104 insertions(+), 9 deletions(-)
18
+++ b/target/arm/translate-a64.c
17
19
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
20
} else {
19
index XXXXXXX..XXXXXXX 100644
21
ns_status = "";
20
--- a/target/arm/helper-mve.h
22
}
21
+++ b/target/arm/helper-mve.h
23
-
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
24
- cpu_fprintf(f, "\nPSTATE=%08x %c%c%c%c %sEL%d%c\n",
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
25
+ cpu_fprintf(f, "PSTATE=%08x %c%c%c%c %sEL%d%c",
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
26
psr,
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
27
psr & PSTATE_N ? 'N' : '-',
26
+
28
psr & PSTATE_Z ? 'Z' : '-',
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
29
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
30
el,
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
psr & PSTATE_SP ? 'h' : 't');
30
index XXXXXXX..XXXXXXX 100644
32
31
--- a/target/arm/translate.h
33
- if (flags & CPU_DUMP_FPU) {
32
+++ b/target/arm/translate.h
34
- int numvfpregs = 32;
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
35
- for (i = 0; i < numvfpregs; i++) {
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
36
- uint64_t *q = aa64_vfp_qreg(env, i);
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
37
- uint64_t vlo = q[0];
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
38
- uint64_t vhi = q[1];
37
+typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
39
- cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "%c",
38
40
- i, vhi, vlo, (i & 1 ? '\n' : ' '));
39
/**
41
+ if (!(flags & CPU_DUMP_FPU)) {
40
* arm_tbflags_from_tb:
42
+ cpu_fprintf(f, "\n");
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
45
@@ -XXX,XX +XXX,XX @@
46
47
&mve_shl_ri rdalo rdahi shim
48
&mve_shl_rr rdalo rdahi rm
49
+&mve_sh_ri rda shim
50
51
# rdahi: bits [3:1] from insn, bit 0 is 1
52
# rdalo: bits [3:1] from insn, bit 0 is 0
53
@@ -XXX,XX +XXX,XX @@
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
58
+ &mve_sh_ri shim=%imm5_12_6
59
60
{
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
62
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
63
# the rest fall through (where ORR_rrri and MOV_rxri will end up
64
# handling them as r13 and r15 accesses with the same semantics as A32).
65
[
66
- LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
67
- LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
68
- ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
69
+ {
70
+ UQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 00 1111 @mve_sh_ri
71
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
72
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
73
+ }
74
75
- UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
76
- URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
77
- SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
78
- SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
79
+ {
80
+ URSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 01 1111 @mve_sh_ri
81
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
82
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
83
+ }
84
+
85
+ {
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
89
+ }
90
+
91
+ {
92
+ SQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 11 1111 @mve_sh_ri
93
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
94
+ }
95
96
LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
97
ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
98
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/mve_helper.c
101
+++ b/target/arm/mve_helper.c
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
103
{
104
return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
105
}
106
+
107
+uint32_t HELPER(mve_uqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
108
+{
109
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
110
+}
111
+
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
113
+{
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
115
+}
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/translate.c
119
+++ b/target/arm/translate.c
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
121
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
123
{
124
- TCGv_i32 t = tcg_temp_new_i32();
125
+ TCGv_i32 t;
126
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
128
+ if (sh == 32) {
129
+ tcg_gen_movi_i32(d, 0);
43
+ return;
130
+ return;
44
+ }
131
+ }
45
+ cpu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
132
+ t = tcg_temp_new_i32();
46
+ vfp_get_fpcr(env), vfp_get_fpsr(env));
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
47
+
134
tcg_gen_sari_i32(d, a, sh);
48
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
135
tcg_gen_add_i32(d, d, t);
49
+ int j, zcr_len = env->vfp.zcr_el[1] & 0xf; /* fix for system mode */
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
50
+
137
51
+ for (i = 0; i <= FFR_PRED_NUM; i++) {
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
52
+ bool eol;
139
{
53
+ if (i == FFR_PRED_NUM) {
140
- TCGv_i32 t = tcg_temp_new_i32();
54
+ cpu_fprintf(f, "FFR=");
141
+ TCGv_i32 t;
55
+ /* It's last, so end the line. */
142
56
+ eol = true;
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
57
+ } else {
144
+ if (sh == 32) {
58
+ cpu_fprintf(f, "P%02d=", i);
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
59
+ switch (zcr_len) {
146
+ return;
60
+ case 0:
147
+ }
61
+ eol = i % 8 == 7;
148
+ t = tcg_temp_new_i32();
62
+ break;
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
63
+ case 1:
150
tcg_gen_shri_i32(d, a, sh);
64
+ eol = i % 6 == 5;
151
tcg_gen_add_i32(d, d, t);
65
+ break;
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
66
+ case 2:
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
67
+ case 3:
68
+ eol = i % 3 == 2;
69
+ break;
70
+ default:
71
+ /* More than one quadword per predicate. */
72
+ eol = true;
73
+ break;
74
+ }
75
+ }
76
+ for (j = zcr_len / 4; j >= 0; j--) {
77
+ int digits;
78
+ if (j * 4 + 4 <= zcr_len + 1) {
79
+ digits = 16;
80
+ } else {
81
+ digits = (zcr_len % 4 + 1) * 4;
82
+ }
83
+ cpu_fprintf(f, "%0*" PRIx64 "%s", digits,
84
+ env->vfp.pregs[i].p[j],
85
+ j ? ":" : eol ? "\n" : " ");
86
+ }
87
+ }
88
+
89
+ for (i = 0; i < 32; i++) {
90
+ if (zcr_len == 0) {
91
+ cpu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64 "%s",
92
+ i, env->vfp.zregs[i].d[1],
93
+ env->vfp.zregs[i].d[0], i & 1 ? "\n" : " ");
94
+ } else if (zcr_len == 1) {
95
+ cpu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64
96
+ ":%016" PRIx64 ":%016" PRIx64 "\n",
97
+ i, env->vfp.zregs[i].d[3], env->vfp.zregs[i].d[2],
98
+ env->vfp.zregs[i].d[1], env->vfp.zregs[i].d[0]);
99
+ } else {
100
+ for (j = zcr_len; j >= 0; j--) {
101
+ bool odd = (zcr_len - j) % 2 != 0;
102
+ if (j == zcr_len) {
103
+ cpu_fprintf(f, "Z%02d[%x-%x]=", i, j, j - 1);
104
+ } else if (!odd) {
105
+ if (j > 0) {
106
+ cpu_fprintf(f, " [%x-%x]=", j, j - 1);
107
+ } else {
108
+ cpu_fprintf(f, " [%x]=", j);
109
+ }
110
+ }
111
+ cpu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%s",
112
+ env->vfp.zregs[i].d[j * 2 + 1],
113
+ env->vfp.zregs[i].d[j * 2],
114
+ odd || j == 0 ? "\n" : ":");
115
+ }
116
+ }
117
+ }
118
+ } else {
119
+ for (i = 0; i < 32; i++) {
120
+ uint64_t *q = aa64_vfp_qreg(env, i);
121
+ cpu_fprintf(f, "Q%02d=%016" PRIx64 ":%016" PRIx64 "%s",
122
+ i, q[1], q[0], (i & 1 ? "\n" : " "));
123
}
124
- cpu_fprintf(f, "FPCR: %08x FPSR: %08x\n",
125
- vfp_get_fpcr(env), vfp_get_fpsr(env));
126
}
127
}
154
}
128
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
*/
129
--
211
--
130
2.18.0
212
2.20.1
131
213
132
214
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
Implement the MVE shifts by register, which perform
2
shifts on a single general-purpose register.
2
3
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
4
Message-id: 3853ec555d68e7e25d726170833b775796151a07.1532984236.git.jcd@tribudubois.net
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
7
---
7
---
8
hw/arm/Makefile.objs | 1 +
8
target/arm/helper-mve.h | 2 ++
9
include/hw/arm/fsl-imx6ul.h | 339 ++++++++++++++++++
9
target/arm/translate.h | 1 +
10
hw/arm/fsl-imx6ul.c | 617 ++++++++++++++++++++++++++++++++
10
target/arm/t32.decode | 18 ++++++++++++++----
11
default-configs/arm-softmmu.mak | 1 +
11
target/arm/mve_helper.c | 10 ++++++++++
12
4 files changed, 958 insertions(+)
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
create mode 100644 include/hw/arm/fsl-imx6ul.h
13
5 files changed, 57 insertions(+), 4 deletions(-)
14
create mode 100644 hw/arm/fsl-imx6ul.c
15
14
16
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/Makefile.objs
17
--- a/target/arm/helper-mve.h
19
+++ b/hw/arm/Makefile.objs
18
+++ b/target/arm/helper-mve.h
20
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
21
obj-$(CONFIG_IOTKIT) += iotkit.o
20
22
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
21
DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
23
obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
22
DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
24
+obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o
23
+DEF_HELPER_FLAGS_3(mve_uqrshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
25
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
24
+DEF_HELPER_FLAGS_3(mve_sqrshr, TCG_CALL_NO_RWG, i32, env, i32, i32)
26
new file mode 100644
25
diff --git a/target/arm/translate.h b/target/arm/translate.h
27
index XXXXXXX..XXXXXXX
26
index XXXXXXX..XXXXXXX 100644
28
--- /dev/null
27
--- a/target/arm/translate.h
29
+++ b/include/hw/arm/fsl-imx6ul.h
28
+++ b/target/arm/translate.h
29
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
30
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
31
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
32
typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
33
+typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
34
35
/**
36
* arm_tbflags_from_tb:
37
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/t32.decode
40
+++ b/target/arm/t32.decode
30
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@
31
+/*
42
&mve_shl_ri rdalo rdahi shim
32
+ * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net>
43
&mve_shl_rr rdalo rdahi rm
33
+ *
44
&mve_sh_ri rda shim
34
+ * i.MX6ul SoC definitions
45
+&mve_sh_rr rda rm
35
+ *
46
36
+ * This program is free software; you can redistribute it and/or modify
47
# rdahi: bits [3:1] from insn, bit 0 is 1
37
+ * it under the terms of the GNU General Public License as published by
48
# rdalo: bits [3:1] from insn, bit 0 is 0
38
+ * the Free Software Foundation; either version 2 of the License, or
39
+ * (at your option) any later version.
40
+ *
41
+ * This program is distributed in the hope that it will be useful,
42
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
43
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44
+ * GNU General Public License for more details.
45
+ */
46
+
47
+#ifndef FSL_IMX6UL_H
48
+#define FSL_IMX6UL_H
49
+
50
+#include "hw/arm/arm.h"
51
+#include "hw/cpu/a15mpcore.h"
52
+#include "hw/misc/imx6ul_ccm.h"
53
+#include "hw/misc/imx6_src.h"
54
+#include "hw/misc/imx7_snvs.h"
55
+#include "hw/misc/imx7_gpr.h"
56
+#include "hw/intc/imx_gpcv2.h"
57
+#include "hw/misc/imx2_wdt.h"
58
+#include "hw/gpio/imx_gpio.h"
59
+#include "hw/char/imx_serial.h"
60
+#include "hw/timer/imx_gpt.h"
61
+#include "hw/timer/imx_epit.h"
62
+#include "hw/i2c/imx_i2c.h"
63
+#include "hw/gpio/imx_gpio.h"
64
+#include "hw/sd/sdhci.h"
65
+#include "hw/ssi/imx_spi.h"
66
+#include "hw/net/imx_fec.h"
67
+#include "exec/memory.h"
68
+#include "cpu.h"
69
+
70
+#define TYPE_FSL_IMX6UL "fsl,imx6ul"
71
+#define FSL_IMX6UL(obj) OBJECT_CHECK(FslIMX6ULState, (obj), TYPE_FSL_IMX6UL)
72
+
73
+enum FslIMX6ULConfiguration {
74
+ FSL_IMX6UL_NUM_CPUS = 1,
75
+ FSL_IMX6UL_NUM_UARTS = 8,
76
+ FSL_IMX6UL_NUM_ETHS = 2,
77
+ FSL_IMX6UL_ETH_NUM_TX_RINGS = 2,
78
+ FSL_IMX6UL_NUM_USDHCS = 2,
79
+ FSL_IMX6UL_NUM_WDTS = 3,
80
+ FSL_IMX6UL_NUM_GPTS = 2,
81
+ FSL_IMX6UL_NUM_EPITS = 2,
82
+ FSL_IMX6UL_NUM_IOMUXCS = 2,
83
+ FSL_IMX6UL_NUM_GPIOS = 5,
84
+ FSL_IMX6UL_NUM_I2CS = 4,
85
+ FSL_IMX6UL_NUM_ECSPIS = 4,
86
+ FSL_IMX6UL_NUM_ADCS = 2,
87
+};
88
+
89
+typedef struct FslIMX6ULState {
90
+ /*< private >*/
91
+ DeviceState parent_obj;
92
+
93
+ /*< public >*/
94
+ ARMCPU cpu[FSL_IMX6UL_NUM_CPUS];
95
+ A15MPPrivState a7mpcore;
96
+ IMXGPTState gpt[FSL_IMX6UL_NUM_GPTS];
97
+ IMXEPITState epit[FSL_IMX6UL_NUM_EPITS];
98
+ IMXGPIOState gpio[FSL_IMX6UL_NUM_GPIOS];
99
+ IMX6ULCCMState ccm;
100
+ IMX6SRCState src;
101
+ IMX7SNVSState snvs;
102
+ IMXGPCv2State gpcv2;
103
+ IMX7GPRState gpr;
104
+ IMXSPIState spi[FSL_IMX6UL_NUM_ECSPIS];
105
+ IMXI2CState i2c[FSL_IMX6UL_NUM_I2CS];
106
+ IMXSerialState uart[FSL_IMX6UL_NUM_UARTS];
107
+ IMXFECState eth[FSL_IMX6UL_NUM_ETHS];
108
+ SDHCIState usdhc[FSL_IMX6UL_NUM_USDHCS];
109
+ IMX2WdtState wdt[FSL_IMX6UL_NUM_WDTS];
110
+ MemoryRegion rom;
111
+ MemoryRegion caam;
112
+ MemoryRegion ocram;
113
+ MemoryRegion ocram_alias;
114
+} FslIMX6ULState;
115
+
116
+enum FslIMX6ULMemoryMap {
117
+ FSL_IMX6UL_MMDC_ADDR = 0x80000000,
118
+ FSL_IMX6UL_MMDC_SIZE = 2 * 1024 * 1024 * 1024UL,
119
+
120
+ FSL_IMX6UL_QSPI1_MEM_ADDR = 0x60000000,
121
+ FSL_IMX6UL_EIM_ALIAS_ADDR = 0x58000000,
122
+ FSL_IMX6UL_EIM_CS_ADDR = 0x50000000,
123
+ FSL_IMX6UL_AES_ENCRYPT_ADDR = 0x10000000,
124
+ FSL_IMX6UL_QSPI1_RX_ADDR = 0x0C000000,
125
+
126
+ /* AIPS-2 */
127
+ FSL_IMX6UL_UART6_ADDR = 0x021FC000,
128
+ FSL_IMX6UL_I2C4_ADDR = 0x021F8000,
129
+ FSL_IMX6UL_UART5_ADDR = 0x021F4000,
130
+ FSL_IMX6UL_UART4_ADDR = 0x021F0000,
131
+ FSL_IMX6UL_UART3_ADDR = 0x021EC000,
132
+ FSL_IMX6UL_UART2_ADDR = 0x021E8000,
133
+ FSL_IMX6UL_WDOG3_ADDR = 0x021E4000,
134
+ FSL_IMX6UL_QSPI_ADDR = 0x021E0000,
135
+ FSL_IMX6UL_SYS_CNT_CTRL_ADDR = 0x021DC000,
136
+ FSL_IMX6UL_SYS_CNT_CMP_ADDR = 0x021D8000,
137
+ FSL_IMX6UL_SYS_CNT_RD_ADDR = 0x021D4000,
138
+ FSL_IMX6UL_TZASC_ADDR = 0x021D0000,
139
+ FSL_IMX6UL_PXP_ADDR = 0x021CC000,
140
+ FSL_IMX6UL_LCDIF_ADDR = 0x021C8000,
141
+ FSL_IMX6UL_CSI_ADDR = 0x021C4000,
142
+ FSL_IMX6UL_CSU_ADDR = 0x021C0000,
143
+ FSL_IMX6UL_OCOTP_CTRL_ADDR = 0x021BC000,
144
+ FSL_IMX6UL_EIM_ADDR = 0x021B8000,
145
+ FSL_IMX6UL_SIM2_ADDR = 0x021B4000,
146
+ FSL_IMX6UL_MMDC_CFG_ADDR = 0x021B0000,
147
+ FSL_IMX6UL_ROMCP_ADDR = 0x021AC000,
148
+ FSL_IMX6UL_I2C3_ADDR = 0x021A8000,
149
+ FSL_IMX6UL_I2C2_ADDR = 0x021A4000,
150
+ FSL_IMX6UL_I2C1_ADDR = 0x021A0000,
151
+ FSL_IMX6UL_ADC2_ADDR = 0x0219C000,
152
+ FSL_IMX6UL_ADC1_ADDR = 0x02198000,
153
+ FSL_IMX6UL_USDHC2_ADDR = 0x02194000,
154
+ FSL_IMX6UL_USDHC1_ADDR = 0x02190000,
155
+ FSL_IMX6UL_SIM1_ADDR = 0x0218C000,
156
+ FSL_IMX6UL_ENET1_ADDR = 0x02188000,
157
+ FSL_IMX6UL_USBO2_USBMISC_ADDR = 0x02184800,
158
+ FSL_IMX6UL_USBO2_USB_ADDR = 0x02184000,
159
+ FSL_IMX6UL_USBO2_PL301_ADDR = 0x02180000,
160
+ FSL_IMX6UL_AIPS2_CFG_ADDR = 0x0217C000,
161
+ FSL_IMX6UL_CAAM_ADDR = 0x02140000,
162
+ FSL_IMX6UL_A7MPCORE_DAP_ADDR = 0x02100000,
163
+
164
+ /* AIPS-1 */
165
+ FSL_IMX6UL_PWM8_ADDR = 0x020FC000,
166
+ FSL_IMX6UL_PWM7_ADDR = 0x020F8000,
167
+ FSL_IMX6UL_PWM6_ADDR = 0x020F4000,
168
+ FSL_IMX6UL_PWM5_ADDR = 0x020F0000,
169
+ FSL_IMX6UL_SDMA_ADDR = 0x020EC000,
170
+ FSL_IMX6UL_GPT2_ADDR = 0x020E8000,
171
+ FSL_IMX6UL_IOMUXC_GPR_ADDR = 0x020E4000,
172
+ FSL_IMX6UL_IOMUXC_ADDR = 0x020E0000,
173
+ FSL_IMX6UL_GPC_ADDR = 0x020DC000,
174
+ FSL_IMX6UL_SRC_ADDR = 0x020D8000,
175
+ FSL_IMX6UL_EPIT2_ADDR = 0x020D4000,
176
+ FSL_IMX6UL_EPIT1_ADDR = 0x020D0000,
177
+ FSL_IMX6UL_SNVS_HP_ADDR = 0x020CC000,
178
+ FSL_IMX6UL_ANALOG_ADDR = 0x020C8000,
179
+ FSL_IMX6UL_CCM_ADDR = 0x020C4000,
180
+ FSL_IMX6UL_WDOG2_ADDR = 0x020C0000,
181
+ FSL_IMX6UL_WDOG1_ADDR = 0x020BC000,
182
+ FSL_IMX6UL_KPP_ADDR = 0x020B8000,
183
+ FSL_IMX6UL_ENET2_ADDR = 0x020B4000,
184
+ FSL_IMX6UL_SNVS_LP_ADDR = 0x020B0000,
185
+ FSL_IMX6UL_GPIO5_ADDR = 0x020AC000,
186
+ FSL_IMX6UL_GPIO4_ADDR = 0x020A8000,
187
+ FSL_IMX6UL_GPIO3_ADDR = 0x020A4000,
188
+ FSL_IMX6UL_GPIO2_ADDR = 0x020A0000,
189
+ FSL_IMX6UL_GPIO1_ADDR = 0x0209C000,
190
+ FSL_IMX6UL_GPT1_ADDR = 0x02098000,
191
+ FSL_IMX6UL_CAN2_ADDR = 0x02094000,
192
+ FSL_IMX6UL_CAN1_ADDR = 0x02090000,
193
+ FSL_IMX6UL_PWM4_ADDR = 0x0208C000,
194
+ FSL_IMX6UL_PWM3_ADDR = 0x02088000,
195
+ FSL_IMX6UL_PWM2_ADDR = 0x02084000,
196
+ FSL_IMX6UL_PWM1_ADDR = 0x02080000,
197
+ FSL_IMX6UL_AIPS1_CFG_ADDR = 0x0207C000,
198
+ FSL_IMX6UL_BEE_ADDR = 0x02044000,
199
+ FSL_IMX6UL_TOUCH_CTRL_ADDR = 0x02040000,
200
+ FSL_IMX6UL_SPBA_ADDR = 0x0203C000,
201
+ FSL_IMX6UL_ASRC_ADDR = 0x02034000,
202
+ FSL_IMX6UL_SAI3_ADDR = 0x02030000,
203
+ FSL_IMX6UL_SAI2_ADDR = 0x0202C000,
204
+ FSL_IMX6UL_SAI1_ADDR = 0x02028000,
205
+ FSL_IMX6UL_UART8_ADDR = 0x02024000,
206
+ FSL_IMX6UL_UART1_ADDR = 0x02020000,
207
+ FSL_IMX6UL_UART7_ADDR = 0x02018000,
208
+ FSL_IMX6UL_ECSPI4_ADDR = 0x02014000,
209
+ FSL_IMX6UL_ECSPI3_ADDR = 0x02010000,
210
+ FSL_IMX6UL_ECSPI2_ADDR = 0x0200C000,
211
+ FSL_IMX6UL_ECSPI1_ADDR = 0x02008000,
212
+ FSL_IMX6UL_SPDIF_ADDR = 0x02004000,
213
+
214
+ FSL_IMX6UL_APBH_DMA_ADDR = 0x01804000,
215
+ FSL_IMX6UL_APBH_DMA_SIZE = (32 * 1024),
216
+
217
+ FSL_IMX6UL_A7MPCORE_ADDR = 0x00A00000,
218
+
219
+ FSL_IMX6UL_OCRAM_ALIAS_ADDR = 0x00920000,
220
+ FSL_IMX6UL_OCRAM_ALIAS_SIZE = 0x00060000,
221
+ FSL_IMX6UL_OCRAM_MEM_ADDR = 0x00900000,
222
+ FSL_IMX6UL_OCRAM_MEM_SIZE = 0x00020000,
223
+ FSL_IMX6UL_CAAM_MEM_ADDR = 0x00100000,
224
+ FSL_IMX6UL_CAAM_MEM_SIZE = 0x00008000,
225
+ FSL_IMX6UL_ROM_ADDR = 0x00000000,
226
+ FSL_IMX6UL_ROM_SIZE = 0x00018000,
227
+};
228
+
229
+enum FslIMX6ULIRQs {
230
+ FSL_IMX6UL_IOMUXC_IRQ = 0,
231
+ FSL_IMX6UL_DAP_IRQ = 1,
232
+ FSL_IMX6UL_SDMA_IRQ = 2,
233
+ FSL_IMX6UL_TSC_IRQ = 3,
234
+ FSL_IMX6UL_SNVS_IRQ = 4,
235
+ FSL_IMX6UL_LCDIF_IRQ = 5,
236
+ FSL_IMX6UL_BEE_IRQ = 6,
237
+ FSL_IMX6UL_CSI_IRQ = 7,
238
+ FSL_IMX6UL_PXP_IRQ = 8,
239
+ FSL_IMX6UL_SCTR1_IRQ = 9,
240
+ FSL_IMX6UL_SCTR2_IRQ = 10,
241
+ FSL_IMX6UL_WDOG3_IRQ = 11,
242
+ FSL_IMX6UL_APBH_DMA_IRQ = 13,
243
+ FSL_IMX6UL_WEIM_IRQ = 14,
244
+ FSL_IMX6UL_RAWNAND1_IRQ = 15,
245
+ FSL_IMX6UL_RAWNAND2_IRQ = 16,
246
+ FSL_IMX6UL_UART6_IRQ = 17,
247
+ FSL_IMX6UL_SRTC_IRQ = 19,
248
+ FSL_IMX6UL_SRTC_SEC_IRQ = 20,
249
+ FSL_IMX6UL_CSU_IRQ = 21,
250
+ FSL_IMX6UL_USDHC1_IRQ = 22,
251
+ FSL_IMX6UL_USDHC2_IRQ = 23,
252
+ FSL_IMX6UL_SAI3_IRQ = 24,
253
+ FSL_IMX6UL_SAI32_IRQ = 25,
254
+
255
+ FSL_IMX6UL_UART1_IRQ = 26,
256
+ FSL_IMX6UL_UART2_IRQ = 27,
257
+ FSL_IMX6UL_UART3_IRQ = 28,
258
+ FSL_IMX6UL_UART4_IRQ = 29,
259
+ FSL_IMX6UL_UART5_IRQ = 30,
260
+
261
+ FSL_IMX6UL_ECSPI1_IRQ = 31,
262
+ FSL_IMX6UL_ECSPI2_IRQ = 32,
263
+ FSL_IMX6UL_ECSPI3_IRQ = 33,
264
+ FSL_IMX6UL_ECSPI4_IRQ = 34,
265
+
266
+ FSL_IMX6UL_I2C4_IRQ = 35,
267
+ FSL_IMX6UL_I2C1_IRQ = 36,
268
+ FSL_IMX6UL_I2C2_IRQ = 37,
269
+ FSL_IMX6UL_I2C3_IRQ = 38,
270
+
271
+ FSL_IMX6UL_UART7_IRQ = 39,
272
+ FSL_IMX6UL_UART8_IRQ = 40,
273
+
274
+ FSL_IMX6UL_USB1_IRQ = 42,
275
+ FSL_IMX6UL_USB2_IRQ = 43,
276
+ FSL_IMX6UL_USB_PHY1_IRQ = 44,
277
+ FSL_IMX6UL_USB_PHY2_IRQ = 44,
278
+
279
+ FSL_IMX6UL_CAAM_JQ2_IRQ = 46,
280
+ FSL_IMX6UL_CAAM_ERR_IRQ = 47,
281
+ FSL_IMX6UL_CAAM_RTIC_IRQ = 48,
282
+ FSL_IMX6UL_TEMP_IRQ = 49,
283
+ FSL_IMX6UL_ASRC_IRQ = 50,
284
+ FSL_IMX6UL_SPDIF_IRQ = 52,
285
+ FSL_IMX6UL_PMU_REG_IRQ = 54,
286
+ FSL_IMX6UL_GPT1_IRQ = 55,
287
+
288
+ FSL_IMX6UL_EPIT1_IRQ = 56,
289
+ FSL_IMX6UL_EPIT2_IRQ = 57,
290
+
291
+ FSL_IMX6UL_GPIO1_INT7_IRQ = 58,
292
+ FSL_IMX6UL_GPIO1_INT6_IRQ = 59,
293
+ FSL_IMX6UL_GPIO1_INT5_IRQ = 60,
294
+ FSL_IMX6UL_GPIO1_INT4_IRQ = 61,
295
+ FSL_IMX6UL_GPIO1_INT3_IRQ = 62,
296
+ FSL_IMX6UL_GPIO1_INT2_IRQ = 63,
297
+ FSL_IMX6UL_GPIO1_INT1_IRQ = 64,
298
+ FSL_IMX6UL_GPIO1_INT0_IRQ = 65,
299
+ FSL_IMX6UL_GPIO1_LOW_IRQ = 66,
300
+ FSL_IMX6UL_GPIO1_HIGH_IRQ = 67,
301
+ FSL_IMX6UL_GPIO2_LOW_IRQ = 68,
302
+ FSL_IMX6UL_GPIO2_HIGH_IRQ = 69,
303
+ FSL_IMX6UL_GPIO3_LOW_IRQ = 70,
304
+ FSL_IMX6UL_GPIO3_HIGH_IRQ = 71,
305
+ FSL_IMX6UL_GPIO4_LOW_IRQ = 72,
306
+ FSL_IMX6UL_GPIO4_HIGH_IRQ = 73,
307
+ FSL_IMX6UL_GPIO5_LOW_IRQ = 74,
308
+ FSL_IMX6UL_GPIO5_HIGH_IRQ = 75,
309
+
310
+ FSL_IMX6UL_WDOG1_IRQ = 80,
311
+ FSL_IMX6UL_WDOG2_IRQ = 81,
312
+
313
+ FSL_IMX6UL_KPP_IRQ = 82,
314
+
315
+ FSL_IMX6UL_PWM1_IRQ = 83,
316
+ FSL_IMX6UL_PWM2_IRQ = 84,
317
+ FSL_IMX6UL_PWM3_IRQ = 85,
318
+ FSL_IMX6UL_PWM4_IRQ = 86,
319
+
320
+ FSL_IMX6UL_CCM1_IRQ = 87,
321
+ FSL_IMX6UL_CCM2_IRQ = 88,
322
+
323
+ FSL_IMX6UL_GPC_IRQ = 89,
324
+
325
+ FSL_IMX6UL_SRC_IRQ = 91,
326
+
327
+ FSL_IMX6UL_CPU_PERF_IRQ = 94,
328
+ FSL_IMX6UL_CPU_CTI_IRQ = 95,
329
+
330
+ FSL_IMX6UL_SRC_WDOG_IRQ = 96,
331
+
332
+ FSL_IMX6UL_SAI1_IRQ = 97,
333
+ FSL_IMX6UL_SAI2_IRQ = 98,
334
+
335
+ FSL_IMX6UL_ADC1_IRQ = 100,
336
+ FSL_IMX6UL_ADC2_IRQ = 101,
337
+
338
+ FSL_IMX6UL_SJC_IRQ = 104,
339
+
340
+ FSL_IMX6UL_CAAM_RING0_IRQ = 105,
341
+ FSL_IMX6UL_CAAM_RING1_IRQ = 106,
342
+
343
+ FSL_IMX6UL_QSPI_IRQ = 107,
344
+
345
+ FSL_IMX6UL_TZASC_IRQ = 108,
346
+
347
+ FSL_IMX6UL_GPT2_IRQ = 109,
348
+
349
+ FSL_IMX6UL_CAN1_IRQ = 110,
350
+ FSL_IMX6UL_CAN2_IRQ = 111,
351
+
352
+ FSL_IMX6UL_SIM1_IRQ = 112,
353
+ FSL_IMX6UL_SIM2_IRQ = 113,
354
+
355
+ FSL_IMX6UL_PWM5_IRQ = 114,
356
+ FSL_IMX6UL_PWM6_IRQ = 115,
357
+ FSL_IMX6UL_PWM7_IRQ = 116,
358
+ FSL_IMX6UL_PWM8_IRQ = 117,
359
+
360
+ FSL_IMX6UL_ENET1_IRQ = 118,
361
+ FSL_IMX6UL_ENET1_TIMER_IRQ = 119,
362
+ FSL_IMX6UL_ENET2_IRQ = 120,
363
+ FSL_IMX6UL_ENET2_TIMER_IRQ = 121,
364
+
365
+ FSL_IMX6UL_PMU_CORE_IRQ = 127,
366
+ FSL_IMX6UL_MAX_IRQ = 128,
367
+};
368
+
369
+#endif /* FSL_IMX6UL_H */
370
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
371
new file mode 100644
372
index XXXXXXX..XXXXXXX
373
--- /dev/null
374
+++ b/hw/arm/fsl-imx6ul.c
375
@@ -XXX,XX +XXX,XX @@
49
@@ -XXX,XX +XXX,XX @@
376
+/*
50
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
377
+ * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net>
51
@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
378
+ *
52
&mve_sh_ri shim=%imm5_12_6
379
+ * i.MX6UL SOC emulation.
53
+@mve_sh_rr ....... .... . rda:4 rm:4 .... .... .... &mve_sh_rr
380
+ *
54
381
+ * Based on hw/arm/fsl-imx7.c
55
{
382
+ *
56
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
383
+ * This program is free software; you can redistribute it and/or modify
57
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
384
+ * it under the terms of the GNU General Public License as published by
58
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
385
+ * the Free Software Foundation; either version 2 of the License, or
59
}
386
+ * (at your option) any later version.
60
387
+ *
61
- LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
388
+ * This program is distributed in the hope that it will be useful,
62
- ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
389
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
63
- UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
390
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
64
- SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
391
+ * GNU General Public License for more details.
65
+ {
392
+ */
66
+ UQRSHL_rr 1110101 0010 1 .... .... 1111 0000 1101 @mve_sh_rr
393
+
67
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
394
+#include "qemu/osdep.h"
68
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
395
+#include "qapi/error.h"
396
+#include "qemu-common.h"
397
+#include "hw/arm/fsl-imx6ul.h"
398
+#include "hw/misc/unimp.h"
399
+#include "sysemu/sysemu.h"
400
+#include "qemu/error-report.h"
401
+
402
+#define NAME_SIZE 20
403
+
404
+static void fsl_imx6ul_init(Object *obj)
405
+{
406
+ FslIMX6ULState *s = FSL_IMX6UL(obj);
407
+ char name[NAME_SIZE];
408
+ int i;
409
+
410
+ for (i = 0; i < MIN(smp_cpus, FSL_IMX6UL_NUM_CPUS); i++) {
411
+ snprintf(name, NAME_SIZE, "cpu%d", i);
412
+ object_initialize_child(obj, name, &s->cpu[i], sizeof(s->cpu[i]),
413
+ "cortex-a7-" TYPE_ARM_CPU, &error_abort, NULL);
414
+ }
69
+ }
415
+
70
+
416
+ /*
71
+ {
417
+ * A7MPCORE
72
+ SQRSHR_rr 1110101 0010 1 .... .... 1111 0010 1101 @mve_sh_rr
418
+ */
73
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
419
+ sysbus_init_child_obj(obj, "a7mpcore", &s->a7mpcore, sizeof(s->a7mpcore),
74
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
420
+ TYPE_A15MPCORE_PRIV);
421
+
422
+ /*
423
+ * CCM
424
+ */
425
+ sysbus_init_child_obj(obj, "ccm", &s->ccm, sizeof(s->ccm), TYPE_IMX6UL_CCM);
426
+
427
+ /*
428
+ * SRC
429
+ */
430
+ sysbus_init_child_obj(obj, "src", &s->src, sizeof(s->src), TYPE_IMX6_SRC);
431
+
432
+ /*
433
+ * GPCv2
434
+ */
435
+ sysbus_init_child_obj(obj, "gpcv2", &s->gpcv2, sizeof(s->gpcv2),
436
+ TYPE_IMX_GPCV2);
437
+
438
+ /*
439
+ * SNVS
440
+ */
441
+ sysbus_init_child_obj(obj, "snvs", &s->snvs, sizeof(s->snvs),
442
+ TYPE_IMX7_SNVS);
443
+
444
+ /*
445
+ * GPR
446
+ */
447
+ sysbus_init_child_obj(obj, "gpr", &s->gpr, sizeof(s->gpr),
448
+ TYPE_IMX7_GPR);
449
+
450
+ /*
451
+ * GPIOs 1 to 5
452
+ */
453
+ for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
454
+ snprintf(name, NAME_SIZE, "gpio%d", i);
455
+ sysbus_init_child_obj(obj, name, &s->gpio[i], sizeof(s->gpio[i]),
456
+ TYPE_IMX_GPIO);
457
+ }
75
+ }
458
+
76
+
459
+ /*
77
UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
460
+ * GPT 1, 2
78
SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
461
+ */
79
]
462
+ for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
80
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
463
+ snprintf(name, NAME_SIZE, "gpt%d", i);
81
index XXXXXXX..XXXXXXX 100644
464
+ sysbus_init_child_obj(obj, name, &s->gpt[i], sizeof(s->gpt[i]),
82
--- a/target/arm/mve_helper.c
465
+ TYPE_IMX7_GPT);
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;
466
+ }
119
+ }
467
+
120
+
468
+ /*
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
469
+ * EPIT 1, 2
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
470
+ */
123
+ return true;
471
+ for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
472
+ snprintf(name, NAME_SIZE, "epit%d", i + 1);
473
+ sysbus_init_child_obj(obj, name, &s->epit[i], sizeof(s->epit[i]),
474
+ TYPE_IMX_EPIT);
475
+ }
476
+
477
+ /*
478
+ * eCSPI
479
+ */
480
+ for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
481
+ snprintf(name, NAME_SIZE, "spi%d", i + 1);
482
+ sysbus_init_child_obj(obj, name, &s->spi[i], sizeof(s->spi[i]),
483
+ TYPE_IMX_SPI);
484
+ }
485
+
486
+ /*
487
+ * I2C
488
+ */
489
+ for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
490
+ snprintf(name, NAME_SIZE, "i2c%d", i + 1);
491
+ sysbus_init_child_obj(obj, name, &s->i2c[i], sizeof(s->i2c[i]),
492
+ TYPE_IMX_I2C);
493
+ }
494
+
495
+ /*
496
+ * UART
497
+ */
498
+ for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
499
+ snprintf(name, NAME_SIZE, "uart%d", i);
500
+ sysbus_init_child_obj(obj, name, &s->uart[i], sizeof(s->uart[i]),
501
+ TYPE_IMX_SERIAL);
502
+ }
503
+
504
+ /*
505
+ * Ethernet
506
+ */
507
+ for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
508
+ snprintf(name, NAME_SIZE, "eth%d", i);
509
+ sysbus_init_child_obj(obj, name, &s->eth[i], sizeof(s->eth[i]),
510
+ TYPE_IMX_ENET);
511
+ }
512
+
513
+ /*
514
+ * SDHCI
515
+ */
516
+ for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
517
+ snprintf(name, NAME_SIZE, "usdhc%d", i);
518
+ sysbus_init_child_obj(obj, name, &s->usdhc[i], sizeof(s->usdhc[i]),
519
+ TYPE_IMX_USDHC);
520
+ }
521
+
522
+ /*
523
+ * Watchdog
524
+ */
525
+ for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
526
+ snprintf(name, NAME_SIZE, "wdt%d", i);
527
+ sysbus_init_child_obj(obj, name, &s->wdt[i], sizeof(s->wdt[i]),
528
+ TYPE_IMX2_WDT);
529
+ }
530
+}
124
+}
531
+
125
+
532
+static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
533
+{
127
+{
534
+ FslIMX6ULState *s = FSL_IMX6UL(dev);
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
535
+ int i;
536
+ qemu_irq irq;
537
+ char name[NAME_SIZE];
538
+
539
+ if (smp_cpus > FSL_IMX6UL_NUM_CPUS) {
540
+ error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
541
+ TYPE_FSL_IMX6UL, FSL_IMX6UL_NUM_CPUS, smp_cpus);
542
+ return;
543
+ }
544
+
545
+ for (i = 0; i < smp_cpus; i++) {
546
+ Object *o = OBJECT(&s->cpu[i]);
547
+
548
+ object_property_set_int(o, QEMU_PSCI_CONDUIT_SMC,
549
+ "psci-conduit", &error_abort);
550
+
551
+ /* On uniprocessor, the CBAR is set to 0 */
552
+ if (smp_cpus > 1) {
553
+ object_property_set_int(o, FSL_IMX6UL_A7MPCORE_ADDR,
554
+ "reset-cbar", &error_abort);
555
+ }
556
+
557
+ if (i) {
558
+ /* Secondary CPUs start in PSCI powered-down state */
559
+ object_property_set_bool(o, true,
560
+ "start-powered-off", &error_abort);
561
+ }
562
+
563
+ object_property_set_bool(o, true, "realized", &error_abort);
564
+ }
565
+
566
+ /*
567
+ * A7MPCORE
568
+ */
569
+ object_property_set_int(OBJECT(&s->a7mpcore), smp_cpus, "num-cpu",
570
+ &error_abort);
571
+ object_property_set_int(OBJECT(&s->a7mpcore),
572
+ FSL_IMX6UL_MAX_IRQ + GIC_INTERNAL,
573
+ "num-irq", &error_abort);
574
+ object_property_set_bool(OBJECT(&s->a7mpcore), true, "realized",
575
+ &error_abort);
576
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX6UL_A7MPCORE_ADDR);
577
+
578
+ for (i = 0; i < smp_cpus; i++) {
579
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
580
+ DeviceState *d = DEVICE(qemu_get_cpu(i));
581
+
582
+ irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
583
+ sysbus_connect_irq(sbd, i, irq);
584
+ sysbus_connect_irq(sbd, i + smp_cpus, qdev_get_gpio_in(d, ARM_CPU_FIQ));
585
+ }
586
+
587
+ /*
588
+ * A7MPCORE DAP
589
+ */
590
+ create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
591
+ 0x100000);
592
+
593
+ /*
594
+ * GPT 1, 2
595
+ */
596
+ for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
597
+ static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
598
+ FSL_IMX6UL_GPT1_ADDR,
599
+ FSL_IMX6UL_GPT2_ADDR,
600
+ };
601
+
602
+ static const int FSL_IMX6UL_GPTn_IRQ[FSL_IMX6UL_NUM_GPTS] = {
603
+ FSL_IMX6UL_GPT1_IRQ,
604
+ FSL_IMX6UL_GPT2_IRQ,
605
+ };
606
+
607
+ s->gpt[i].ccm = IMX_CCM(&s->ccm);
608
+ object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized",
609
+ &error_abort);
610
+
611
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0,
612
+ FSL_IMX6UL_GPTn_ADDR[i]);
613
+
614
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
615
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
616
+ FSL_IMX6UL_GPTn_IRQ[i]));
617
+ }
618
+
619
+ /*
620
+ * EPIT 1, 2
621
+ */
622
+ for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
623
+ static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
624
+ FSL_IMX6UL_EPIT1_ADDR,
625
+ FSL_IMX6UL_EPIT2_ADDR,
626
+ };
627
+
628
+ static const int FSL_IMX6UL_EPITn_IRQ[FSL_IMX6UL_NUM_EPITS] = {
629
+ FSL_IMX6UL_EPIT1_IRQ,
630
+ FSL_IMX6UL_EPIT2_IRQ,
631
+ };
632
+
633
+ s->epit[i].ccm = IMX_CCM(&s->ccm);
634
+ object_property_set_bool(OBJECT(&s->epit[i]), true, "realized",
635
+ &error_abort);
636
+
637
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0,
638
+ FSL_IMX6UL_EPITn_ADDR[i]);
639
+
640
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
641
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
642
+ FSL_IMX6UL_EPITn_IRQ[i]));
643
+ }
644
+
645
+ /*
646
+ * GPIO
647
+ */
648
+ for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
649
+ static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
650
+ FSL_IMX6UL_GPIO1_ADDR,
651
+ FSL_IMX6UL_GPIO2_ADDR,
652
+ FSL_IMX6UL_GPIO3_ADDR,
653
+ FSL_IMX6UL_GPIO4_ADDR,
654
+ FSL_IMX6UL_GPIO5_ADDR,
655
+ };
656
+
657
+ static const int FSL_IMX6UL_GPIOn_LOW_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
658
+ FSL_IMX6UL_GPIO1_LOW_IRQ,
659
+ FSL_IMX6UL_GPIO2_LOW_IRQ,
660
+ FSL_IMX6UL_GPIO3_LOW_IRQ,
661
+ FSL_IMX6UL_GPIO4_LOW_IRQ,
662
+ FSL_IMX6UL_GPIO5_LOW_IRQ,
663
+ };
664
+
665
+ static const int FSL_IMX6UL_GPIOn_HIGH_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
666
+ FSL_IMX6UL_GPIO1_HIGH_IRQ,
667
+ FSL_IMX6UL_GPIO2_HIGH_IRQ,
668
+ FSL_IMX6UL_GPIO3_HIGH_IRQ,
669
+ FSL_IMX6UL_GPIO4_HIGH_IRQ,
670
+ FSL_IMX6UL_GPIO5_HIGH_IRQ,
671
+ };
672
+
673
+ object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized",
674
+ &error_abort);
675
+
676
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
677
+ FSL_IMX6UL_GPIOn_ADDR[i]);
678
+
679
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
680
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
681
+ FSL_IMX6UL_GPIOn_LOW_IRQ[i]));
682
+
683
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
684
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
685
+ FSL_IMX6UL_GPIOn_HIGH_IRQ[i]));
686
+ }
687
+
688
+ /*
689
+ * IOMUXC and IOMUXC_GPR
690
+ */
691
+ for (i = 0; i < 1; i++) {
692
+ static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = {
693
+ FSL_IMX6UL_IOMUXC_ADDR,
694
+ FSL_IMX6UL_IOMUXC_GPR_ADDR,
695
+ };
696
+
697
+ snprintf(name, NAME_SIZE, "iomuxc%d", i);
698
+ create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000);
699
+ }
700
+
701
+ /*
702
+ * CCM
703
+ */
704
+ object_property_set_bool(OBJECT(&s->ccm), true, "realized", &error_abort);
705
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX6UL_CCM_ADDR);
706
+
707
+ /*
708
+ * SRC
709
+ */
710
+ object_property_set_bool(OBJECT(&s->src), true, "realized", &error_abort);
711
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX6UL_SRC_ADDR);
712
+
713
+ /*
714
+ * GPCv2
715
+ */
716
+ object_property_set_bool(OBJECT(&s->gpcv2), true,
717
+ "realized", &error_abort);
718
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX6UL_GPC_ADDR);
719
+
720
+ /* Initialize all ECSPI */
721
+ for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
722
+ static const hwaddr FSL_IMX6UL_SPIn_ADDR[FSL_IMX6UL_NUM_ECSPIS] = {
723
+ FSL_IMX6UL_ECSPI1_ADDR,
724
+ FSL_IMX6UL_ECSPI2_ADDR,
725
+ FSL_IMX6UL_ECSPI3_ADDR,
726
+ FSL_IMX6UL_ECSPI4_ADDR,
727
+ };
728
+
729
+ static const int FSL_IMX6UL_SPIn_IRQ[FSL_IMX6UL_NUM_ECSPIS] = {
730
+ FSL_IMX6UL_ECSPI1_IRQ,
731
+ FSL_IMX6UL_ECSPI2_IRQ,
732
+ FSL_IMX6UL_ECSPI3_IRQ,
733
+ FSL_IMX6UL_ECSPI4_IRQ,
734
+ };
735
+
736
+ /* Initialize the SPI */
737
+ object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
738
+ &error_abort);
739
+
740
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
741
+ FSL_IMX6UL_SPIn_ADDR[i]);
742
+
743
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
744
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
745
+ FSL_IMX6UL_SPIn_IRQ[i]));
746
+ }
747
+
748
+ /*
749
+ * I2C
750
+ */
751
+ for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
752
+ static const hwaddr FSL_IMX6UL_I2Cn_ADDR[FSL_IMX6UL_NUM_I2CS] = {
753
+ FSL_IMX6UL_I2C1_ADDR,
754
+ FSL_IMX6UL_I2C2_ADDR,
755
+ FSL_IMX6UL_I2C3_ADDR,
756
+ FSL_IMX6UL_I2C4_ADDR,
757
+ };
758
+
759
+ static const int FSL_IMX6UL_I2Cn_IRQ[FSL_IMX6UL_NUM_I2CS] = {
760
+ FSL_IMX6UL_I2C1_IRQ,
761
+ FSL_IMX6UL_I2C2_IRQ,
762
+ FSL_IMX6UL_I2C3_IRQ,
763
+ FSL_IMX6UL_I2C4_IRQ,
764
+ };
765
+
766
+ object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized",
767
+ &error_abort);
768
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX6UL_I2Cn_ADDR[i]);
769
+
770
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
771
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
772
+ FSL_IMX6UL_I2Cn_IRQ[i]));
773
+ }
774
+
775
+ /*
776
+ * UART
777
+ */
778
+ for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
779
+ static const hwaddr FSL_IMX6UL_UARTn_ADDR[FSL_IMX6UL_NUM_UARTS] = {
780
+ FSL_IMX6UL_UART1_ADDR,
781
+ FSL_IMX6UL_UART2_ADDR,
782
+ FSL_IMX6UL_UART3_ADDR,
783
+ FSL_IMX6UL_UART4_ADDR,
784
+ FSL_IMX6UL_UART5_ADDR,
785
+ FSL_IMX6UL_UART6_ADDR,
786
+ FSL_IMX6UL_UART7_ADDR,
787
+ FSL_IMX6UL_UART8_ADDR,
788
+ };
789
+
790
+ static const int FSL_IMX6UL_UARTn_IRQ[FSL_IMX6UL_NUM_UARTS] = {
791
+ FSL_IMX6UL_UART1_IRQ,
792
+ FSL_IMX6UL_UART2_IRQ,
793
+ FSL_IMX6UL_UART3_IRQ,
794
+ FSL_IMX6UL_UART4_IRQ,
795
+ FSL_IMX6UL_UART5_IRQ,
796
+ FSL_IMX6UL_UART6_IRQ,
797
+ FSL_IMX6UL_UART7_IRQ,
798
+ FSL_IMX6UL_UART8_IRQ,
799
+ };
800
+
801
+ qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
802
+
803
+ object_property_set_bool(OBJECT(&s->uart[i]), true, "realized",
804
+ &error_abort);
805
+
806
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0,
807
+ FSL_IMX6UL_UARTn_ADDR[i]);
808
+
809
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
810
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
811
+ FSL_IMX6UL_UARTn_IRQ[i]));
812
+ }
813
+
814
+ /*
815
+ * Ethernet
816
+ */
817
+ for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
818
+ static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = {
819
+ FSL_IMX6UL_ENET1_ADDR,
820
+ FSL_IMX6UL_ENET2_ADDR,
821
+ };
822
+
823
+ static const int FSL_IMX6UL_ENETn_IRQ[FSL_IMX6UL_NUM_ETHS] = {
824
+ FSL_IMX6UL_ENET1_IRQ,
825
+ FSL_IMX6UL_ENET2_IRQ,
826
+ };
827
+
828
+ static const int FSL_IMX6UL_ENETn_TIMER_IRQ[FSL_IMX6UL_NUM_ETHS] = {
829
+ FSL_IMX6UL_ENET1_TIMER_IRQ,
830
+ FSL_IMX6UL_ENET2_TIMER_IRQ,
831
+ };
832
+
833
+ object_property_set_uint(OBJECT(&s->eth[i]),
834
+ FSL_IMX6UL_ETH_NUM_TX_RINGS,
835
+ "tx-ring-num", &error_abort);
836
+ qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
837
+ object_property_set_bool(OBJECT(&s->eth[i]), true, "realized",
838
+ &error_abort);
839
+
840
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0,
841
+ FSL_IMX6UL_ENETn_ADDR[i]);
842
+
843
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0,
844
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
845
+ FSL_IMX6UL_ENETn_IRQ[i]));
846
+
847
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1,
848
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
849
+ FSL_IMX6UL_ENETn_TIMER_IRQ[i]));
850
+ }
851
+
852
+ /*
853
+ * USDHC
854
+ */
855
+ for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
856
+ static const hwaddr FSL_IMX6UL_USDHCn_ADDR[FSL_IMX6UL_NUM_USDHCS] = {
857
+ FSL_IMX6UL_USDHC1_ADDR,
858
+ FSL_IMX6UL_USDHC2_ADDR,
859
+ };
860
+
861
+ static const int FSL_IMX6UL_USDHCn_IRQ[FSL_IMX6UL_NUM_USDHCS] = {
862
+ FSL_IMX6UL_USDHC1_IRQ,
863
+ FSL_IMX6UL_USDHC2_IRQ,
864
+ };
865
+
866
+ object_property_set_bool(OBJECT(&s->usdhc[i]), true, "realized",
867
+ &error_abort);
868
+
869
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
870
+ FSL_IMX6UL_USDHCn_ADDR[i]);
871
+
872
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
873
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
874
+ FSL_IMX6UL_USDHCn_IRQ[i]));
875
+ }
876
+
877
+ /*
878
+ * SNVS
879
+ */
880
+ object_property_set_bool(OBJECT(&s->snvs), true, "realized", &error_abort);
881
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6UL_SNVS_HP_ADDR);
882
+
883
+ /*
884
+ * Watchdog
885
+ */
886
+ for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
887
+ static const hwaddr FSL_IMX6UL_WDOGn_ADDR[FSL_IMX6UL_NUM_WDTS] = {
888
+ FSL_IMX6UL_WDOG1_ADDR,
889
+ FSL_IMX6UL_WDOG2_ADDR,
890
+ FSL_IMX6UL_WDOG3_ADDR,
891
+ };
892
+
893
+ object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized",
894
+ &error_abort);
895
+
896
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
897
+ FSL_IMX6UL_WDOGn_ADDR[i]);
898
+ }
899
+
900
+ /*
901
+ * GPR
902
+ */
903
+ object_property_set_bool(OBJECT(&s->gpr), true, "realized",
904
+ &error_abort);
905
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX6UL_IOMUXC_GPR_ADDR);
906
+
907
+ /*
908
+ * SDMA
909
+ */
910
+ create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR, 0x4000);
911
+
912
+ /*
913
+ * APHB_DMA
914
+ */
915
+ create_unimplemented_device("aphb_dma", FSL_IMX6UL_APBH_DMA_ADDR,
916
+ FSL_IMX6UL_APBH_DMA_SIZE);
917
+
918
+ /*
919
+ * ADCs
920
+ */
921
+ for (i = 0; i < FSL_IMX6UL_NUM_ADCS; i++) {
922
+ static const hwaddr FSL_IMX6UL_ADCn_ADDR[FSL_IMX6UL_NUM_ADCS] = {
923
+ FSL_IMX6UL_ADC1_ADDR,
924
+ FSL_IMX6UL_ADC2_ADDR,
925
+ };
926
+
927
+ snprintf(name, NAME_SIZE, "adc%d", i);
928
+ create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i], 0x4000);
929
+ }
930
+
931
+ /*
932
+ * LCD
933
+ */
934
+ create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR, 0x4000);
935
+
936
+ /*
937
+ * ROM memory
938
+ */
939
+ memory_region_init_rom(&s->rom, NULL, "imx6ul.rom",
940
+ FSL_IMX6UL_ROM_SIZE, &error_abort);
941
+ memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_ROM_ADDR,
942
+ &s->rom);
943
+
944
+ /*
945
+ * CAAM memory
946
+ */
947
+ memory_region_init_rom(&s->caam, NULL, "imx6ul.caam",
948
+ FSL_IMX6UL_CAAM_MEM_SIZE, &error_abort);
949
+ memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_CAAM_MEM_ADDR,
950
+ &s->caam);
951
+
952
+ /*
953
+ * OCRAM memory
954
+ */
955
+ memory_region_init_ram(&s->ocram, NULL, "imx6ul.ocram",
956
+ FSL_IMX6UL_OCRAM_MEM_SIZE,
957
+ &error_abort);
958
+ memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_OCRAM_MEM_ADDR,
959
+ &s->ocram);
960
+
961
+ /*
962
+ * internal OCRAM (128 KB) is aliased over 512 KB
963
+ */
964
+ memory_region_init_alias(&s->ocram_alias, NULL, "imx6ul.ocram_alias",
965
+ &s->ocram, 0, FSL_IMX6UL_OCRAM_ALIAS_SIZE);
966
+ memory_region_add_subregion(get_system_memory(),
967
+ FSL_IMX6UL_OCRAM_ALIAS_ADDR, &s->ocram_alias);
968
+}
129
+}
969
+
130
+
970
+static void fsl_imx6ul_class_init(ObjectClass *oc, void *data)
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
971
+{
132
+{
972
+ DeviceClass *dc = DEVICE_CLASS(oc);
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
973
+
974
+ dc->realize = fsl_imx6ul_realize;
975
+ dc->desc = "i.MX6UL SOC";
976
+ /* Reason: Uses serial_hds and nd_table in realize() directly */
977
+ dc->user_creatable = false;
978
+}
134
+}
979
+
135
+
980
+static const TypeInfo fsl_imx6ul_type_info = {
136
/*
981
+ .name = TYPE_FSL_IMX6UL,
137
* Multiply and multiply accumulate
982
+ .parent = TYPE_DEVICE,
138
*/
983
+ .instance_size = sizeof(FslIMX6ULState),
984
+ .instance_init = fsl_imx6ul_init,
985
+ .class_init = fsl_imx6ul_class_init,
986
+};
987
+
988
+static void fsl_imx6ul_register_types(void)
989
+{
990
+ type_register_static(&fsl_imx6ul_type_info);
991
+}
992
+type_init(fsl_imx6ul_register_types)
993
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
994
index XXXXXXX..XXXXXXX 100644
995
--- a/default-configs/arm-softmmu.mak
996
+++ b/default-configs/arm-softmmu.mak
997
@@ -XXX,XX +XXX,XX @@ CONFIG_FSL_IMX6=y
998
CONFIG_FSL_IMX31=y
999
CONFIG_FSL_IMX25=y
1000
CONFIG_FSL_IMX7=y
1001
+CONFIG_FSL_IMX6UL=y
1002
1003
CONFIG_IMX_I2C=y
1004
1005
--
139
--
1006
2.18.0
140
2.20.1
1007
141
1008
142
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
The SDMC on the ast2500 has 170 registers.
4
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Tested-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20180807075757.7242-2-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/misc/aspeed_sdmc.h | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/include/hw/misc/aspeed_sdmc.h b/include/hw/misc/aspeed_sdmc.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/misc/aspeed_sdmc.h
17
+++ b/include/hw/misc/aspeed_sdmc.h
18
@@ -XXX,XX +XXX,XX @@
19
#define TYPE_ASPEED_SDMC "aspeed.sdmc"
20
#define ASPEED_SDMC(obj) OBJECT_CHECK(AspeedSDMCState, (obj), TYPE_ASPEED_SDMC)
21
22
-#define ASPEED_SDMC_NR_REGS (0x8 >> 2)
23
+#define ASPEED_SDMC_NR_REGS (0x174 >> 2)
24
25
typedef struct AspeedSDMCState {
26
/*< private >*/
27
--
28
2.18.0
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
This fixes the intended protection of read-only values in the
4
configuration register. They were being always set to zero by mistake.
5
6
The read-only fields depend on the configured memory size of the system,
7
so they cannot be fixed at compile time. The most straight forward
8
option was to store them in the state structure.
9
10
Signed-off-by: Joel Stanley <joel@jms.id.au>
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
Tested-by: Cédric Le Goater <clg@kaod.org>
13
Message-id: 20180807075757.7242-3-joel@jms.id.au
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
include/hw/misc/aspeed_sdmc.h | 1 +
17
hw/misc/aspeed_sdmc.c | 27 ++++++++-------------------
18
2 files changed, 9 insertions(+), 19 deletions(-)
19
20
diff --git a/include/hw/misc/aspeed_sdmc.h b/include/hw/misc/aspeed_sdmc.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/misc/aspeed_sdmc.h
23
+++ b/include/hw/misc/aspeed_sdmc.h
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSDMCState {
25
uint32_t silicon_rev;
26
uint32_t ram_bits;
27
uint64_t ram_size;
28
+ uint32_t fixed_conf;
29
30
} AspeedSDMCState;
31
32
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/misc/aspeed_sdmc.c
35
+++ b/hw/misc/aspeed_sdmc.c
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
37
case AST2400_A0_SILICON_REV:
38
case AST2400_A1_SILICON_REV:
39
data &= ~ASPEED_SDMC_READONLY_MASK;
40
+ data |= s->fixed_conf;
41
break;
42
case AST2500_A0_SILICON_REV:
43
case AST2500_A1_SILICON_REV:
44
data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;
45
+ data |= s->fixed_conf;
46
break;
47
default:
48
g_assert_not_reached();
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_reset(DeviceState *dev)
50
memset(s->regs, 0, sizeof(s->regs));
51
52
/* Set ram size bit and defaults values */
53
- switch (s->silicon_rev) {
54
- case AST2400_A0_SILICON_REV:
55
- case AST2400_A1_SILICON_REV:
56
- s->regs[R_CONF] |=
57
- ASPEED_SDMC_VGA_COMPAT |
58
- ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
59
- break;
60
-
61
- case AST2500_A0_SILICON_REV:
62
- case AST2500_A1_SILICON_REV:
63
- s->regs[R_CONF] |=
64
- ASPEED_SDMC_HW_VERSION(1) |
65
- ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
66
- ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
67
- break;
68
-
69
- default:
70
- g_assert_not_reached();
71
- }
72
+ s->regs[R_CONF] = s->fixed_conf;
73
}
74
75
static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
76
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
77
case AST2400_A0_SILICON_REV:
78
case AST2400_A1_SILICON_REV:
79
s->ram_bits = ast2400_rambits(s);
80
+ s->fixed_conf = ASPEED_SDMC_VGA_COMPAT |
81
+ ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
82
break;
83
case AST2500_A0_SILICON_REV:
84
case AST2500_A1_SILICON_REV:
85
s->ram_bits = ast2500_rambits(s);
86
+ s->fixed_conf = ASPEED_SDMC_HW_VERSION(1) |
87
+ ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
88
+ ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
89
break;
90
default:
91
g_assert_not_reached();
92
--
93
2.18.0
94
95
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
When FZ is set, input_denormal exceptions are recognized, but this does
4
not happen with FZ16. The softfloat code has no way to distinguish
5
these bits and will raise such exceptions into fp_status_f16.flags,
6
so ignore them when computing the accumulated flags.
7
8
Cc: qemu-stable@nongnu.org (3.0.1)
9
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
13
Message-id: 20180810193129.1556-3-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/helper.c | 6 +++++-
17
1 file changed, 5 insertions(+), 1 deletion(-)
18
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
24
fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
25
| (env->vfp.vec_len << 16)
26
| (env->vfp.vec_stride << 20);
27
+
28
i = get_float_exception_flags(&env->vfp.fp_status);
29
i |= get_float_exception_flags(&env->vfp.standard_fp_status);
30
- i |= get_float_exception_flags(&env->vfp.fp_status_f16);
31
+ /* FZ16 does not generate an input denormal exception. */
32
+ i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
33
+ & ~float_flag_input_denormal);
34
+
35
fpscr |= vfp_exceptbits_from_host(i);
36
return fpscr;
37
}
38
--
39
2.18.0
40
41
diff view generated by jsdifflib