1
target-arm queue: mostly smallish stuff. I expect to send
1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
2
out another pullreq at the end of this week, but since this
3
is up to 32 patches already I'd rather send it out now
4
than accumulate a monster sized patchset.
5
2
6
thanks
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
7
-- PMM
8
9
10
The following changes since commit 0ab4c574a55448a37b9f616259b82950742c9427:
11
12
Merge remote-tracking branch 'remotes/kraxel/tags/ui-20180626-pull-request' into staging (2018-06-26 16:44:57 +0100)
13
4
14
are available in the Git repository at:
5
are available in the Git repository at:
15
6
16
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180626
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
17
8
18
for you to fetch changes up to 9b945a9ee36a34eaeca412ef9ef35fbfe33c2c85:
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
19
10
20
aspeed/timer: use the APB frequency from the SCU (2018-06-26 17:50:42 +0100)
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
21
12
22
----------------------------------------------------------------
13
----------------------------------------------------------------
23
target-arm queue:
14
target-arm queue:
24
* aspeed: set APB clocks correctly (fixes slowdown on palmetto)
15
* more MVE instructions
25
* smmuv3: cache config data and TLB entries
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
26
* v7m/v8m: support read/write from MPU regions smaller than 1K
17
* target/arm: Check NaN mode before silencing NaN
27
* various: clean up logging/debug messages
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
28
* xilinx_spips: Make dma transactions as per dma_burst_size
19
* hw/arm: Add basic power management to raspi.
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
29
21
30
----------------------------------------------------------------
22
----------------------------------------------------------------
31
Cédric Le Goater (6):
23
Joe Komlodi (1):
32
aspeed/smc: fix dummy cycles count when in dual IO mode
24
target/arm: Check NaN mode before silencing NaN
33
aspeed/smc: fix HW strapping
34
aspeed/smc: rename aspeed_smc_flash_send_addr() to aspeed_smc_flash_setup()
35
aspeed/scu: introduce clock frequencies
36
aspeed: initialize the SCU controller first
37
aspeed/timer: use the APB frequency from the SCU
38
25
39
Eric Auger (3):
26
Maxim Uvarov (1):
40
hw/arm/smmuv3: Cache/invalidate config data
27
hw/gpio/gpio_pwr: use shutdown function for reboot
41
hw/arm/smmuv3: IOTLB emulation
42
hw/arm/smmuv3: Add notifications on invalidation
43
28
44
Jia He (1):
29
Nolan Leake (1):
45
hw/arm/smmuv3: Fix translate error handling
30
hw/arm: Add basic power management to raspi.
46
31
47
Joel Stanley (1):
32
Patrick Venture (2):
48
MAINTAINERS: Add ASPEED BMCs
33
docs/system/arm: Add quanta-q7l1-bmc reference
34
docs/system/arm: Add quanta-gbs-bmc reference
49
35
50
Peter Maydell (3):
36
Peter Maydell (18):
51
tcg: Support MMU protection regions smaller than TARGET_PAGE_SIZE
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
52
target/arm: Set page (region) size in get_phys_addr_pmsav7()
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
53
target/arm: Handle small regions in get_phys_addr_pmsav8()
39
target/arm: Make asimd_imm_const() public
40
target/arm: Use asimd_imm_const for A64 decode
41
target/arm: Use dup_const() instead of bitfield_replicate()
42
target/arm: Implement MVE logical immediate insns
43
target/arm: Implement MVE vector shift left by immediate insns
44
target/arm: Implement MVE vector shift right by immediate insns
45
target/arm: Implement MVE VSHLL
46
target/arm: Implement MVE VSRI, VSLI
47
target/arm: Implement MVE VSHRN, VRSHRN
48
target/arm: Implement MVE saturating narrowing shifts
49
target/arm: Implement MVE VSHLC
50
target/arm: Implement MVE VADDLV
51
target/arm: Implement MVE long shifts by immediate
52
target/arm: Implement MVE long shifts by register
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
54
55
55
Philippe Mathieu-Daudé (17):
56
Philippe Mathieu-Daudé (1):
56
MAINTAINERS: Adopt the Gumstix computers-on-module machines
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
57
hw/input/pckbd: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
58
hw/input/tsc2005: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
59
hw/dma/omap_dma: Use qemu_log_mask(UNIMP) instead of printf
60
hw/dma/omap_dma: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
61
hw/ssi/omap_spi: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
62
hw/sd/omap_mmc: Use qemu_log_mask(UNIMP) instead of printf
63
hw/i2c/omap_i2c: Use qemu_log_mask(UNIMP) instead of fprintf
64
hw/arm/omap1: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
65
hw/arm/omap: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
66
hw/arm/stellaris: Use qemu_log_mask(UNIMP) instead of fprintf
67
hw/net/stellaris_enet: Fix a typo
68
hw/net/stellaris_enet: Use qemu_log_mask(GUEST_ERROR) instead of hw_error
69
hw/net/smc91c111: Use qemu_log_mask(GUEST_ERROR) instead of hw_error
70
hw/net/smc91c111: Use qemu_log_mask(UNIMP) instead of fprintf
71
hw/arm/stellaris: Fix gptm_write() error message
72
hw/arm/stellaris: Use HWADDR_PRIx to display register address
73
58
74
Sai Pavan Boddu (1):
59
docs/system/arm/aspeed.rst | 1 +
75
xilinx_spips: Make dma transactions as per dma_burst_size
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
accel/tcg/softmmu_template.h | 24 ++-
78
hw/arm/smmuv3-internal.h | 12 +-
79
include/exec/cpu-all.h | 5 +-
80
include/hw/arm/omap.h | 30 +--
81
include/hw/arm/smmu-common.h | 24 +++
82
include/hw/arm/smmuv3.h | 1 +
83
include/hw/misc/aspeed_scu.h | 70 ++++++-
84
include/hw/ssi/xilinx_spips.h | 5 +-
85
include/hw/timer/aspeed_timer.h | 4 +
86
accel/tcg/cputlb.c | 131 +++++++++++--
87
hw/arm/aspeed_soc.c | 42 ++--
88
hw/arm/omap1.c | 18 +-
89
hw/arm/smmu-common.c | 118 ++++++++++-
90
hw/arm/smmuv3.c | 420 ++++++++++++++++++++++++++++++++++++----
91
hw/arm/stellaris.c | 8 +-
92
hw/dma/omap_dma.c | 70 ++++---
93
hw/i2c/omap_i2c.c | 20 +-
94
hw/input/pckbd.c | 4 +-
95
hw/input/tsc2005.c | 13 +-
96
hw/misc/aspeed_scu.c | 106 ++++++++++
97
hw/net/smc91c111.c | 21 +-
98
hw/net/stellaris_enet.c | 11 +-
99
hw/sd/omap_mmc.c | 13 +-
100
hw/ssi/aspeed_smc.c | 48 ++---
101
hw/ssi/omap_spi.c | 15 +-
102
hw/ssi/xilinx_spips.c | 23 ++-
103
hw/timer/aspeed_timer.c | 19 +-
104
target/arm/helper.c | 115 +++++++----
105
MAINTAINERS | 14 +-
106
hw/arm/trace-events | 27 ++-
107
30 files changed, 1176 insertions(+), 255 deletions(-)
108
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Patrick Venture <venture@google.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
4
entry.
5
Message-id: 20180624040609.17572-6-f4bug@amsat.org
5
6
Signed-off-by: Patrick Venture <venture@google.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20210615192848.1065297-2-venture@google.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
hw/ssi/omap_spi.c | 15 ++++++++++-----
11
docs/system/arm/aspeed.rst | 1 +
9
1 file changed, 10 insertions(+), 5 deletions(-)
12
1 file changed, 1 insertion(+)
10
13
11
diff --git a/hw/ssi/omap_spi.c b/hw/ssi/omap_spi.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/ssi/omap_spi.c
16
--- a/docs/system/arm/aspeed.rst
14
+++ b/hw/ssi/omap_spi.c
17
+++ b/docs/system/arm/aspeed.rst
15
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ etc.
16
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
AST2400 SoC based machines :
17
*/
20
18
#include "qemu/osdep.h"
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
19
+#include "qemu/log.h"
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
20
#include "hw/hw.h"
23
21
#include "hw/arm/omap.h"
24
AST2500 SoC based machines :
22
23
@@ -XXX,XX +XXX,XX @@ static void omap_mcspi_write(void *opaque, hwaddr addr,
24
case 0x2c:    /* MCSPI_CHCONF */
25
if ((value ^ s->ch[ch].config) & (3 << 14))    /* DMAR | DMAW */
26
omap_mcspi_dmarequest_update(s->ch + ch);
27
- if (((value >> 12) & 3) == 3)            /* TRM */
28
- fprintf(stderr, "%s: invalid TRM value (3)\n", __func__);
29
- if (((value >> 7) & 0x1f) < 3)            /* WL */
30
- fprintf(stderr, "%s: invalid WL value (%" PRIx64 ")\n",
31
- __func__, (value >> 7) & 0x1f);
32
+ if (((value >> 12) & 3) == 3) { /* TRM */
33
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid TRM value (3)\n",
34
+ __func__);
35
+ }
36
+ if (((value >> 7) & 0x1f) < 3) { /* WL */
37
+ qemu_log_mask(LOG_GUEST_ERROR,
38
+ "%s: invalid WL value (%" PRIx64 ")\n",
39
+ __func__, (value >> 7) & 0x1f);
40
+ }
41
s->ch[ch].config = value & 0x7fffff;
42
break;
43
25
44
--
26
--
45
2.17.1
27
2.20.1
46
28
47
29
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Patrick Venture <venture@google.com>
2
2
3
The System Control Unit should be initialized first as it drives all
3
Add line item reference to quanta-gbs-bmc machine.
4
the configuration of the SoC and other device models.
5
4
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
5
Signed-off-by: Patrick Venture <venture@google.com>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Acked-by: Andrew Jeffery <andrew@aj.id.au>
7
Message-id: 20210615192848.1065297-3-venture@google.com
9
Message-id: 20180622075700.5923-3-clg@kaod.org
8
[PMM: fixed underline Sphinx warning]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/arm/aspeed_soc.c | 40 ++++++++++++++++++++--------------------
11
docs/system/arm/nuvoton.rst | 5 +++--
13
1 file changed, 20 insertions(+), 20 deletions(-)
12
1 file changed, 3 insertions(+), 2 deletions(-)
14
13
15
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/aspeed_soc.c
16
--- a/docs/system/arm/nuvoton.rst
18
+++ b/hw/arm/aspeed_soc.c
17
+++ b/docs/system/arm/nuvoton.rst
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
18
@@ -XXX,XX +XXX,XX @@
20
object_initialize(&s->cpu, sizeof(s->cpu), sc->info->cpu_type);
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
21
object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL);
20
-=====================================================
22
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
23
- object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
22
+================================================================
24
- object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
23
25
- qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
26
-
25
designed to be used as Baseboard Management Controllers (BMCs) in various
27
- object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
28
- object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
29
- qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
28
Hyperscale applications. The following machines are based on this chip :
30
-
29
31
- object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
32
- object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
31
- ``quanta-gsj`` Quanta GSJ server BMC
33
- qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
32
34
-
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
35
object_initialize(&s->scu, sizeof(s->scu), TYPE_ASPEED_SCU);
36
object_property_add_child(obj, "scu", OBJECT(&s->scu), NULL);
37
qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
38
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
39
object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
40
"hw-prot-key", &error_abort);
41
42
+ object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
43
+ object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
44
+ qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());
45
+
46
+ object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
47
+ object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
48
+ qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
49
+
50
+ object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
51
+ object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
52
+ qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
53
+
54
object_initialize(&s->fmc, sizeof(s->fmc), sc->info->fmc_typename);
55
object_property_add_child(obj, "fmc", OBJECT(&s->fmc), NULL);
56
qdev_set_parent_bus(DEVICE(&s->fmc), sysbus_get_default());
57
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
58
memory_region_add_subregion(get_system_memory(), ASPEED_SOC_SRAM_BASE,
59
&s->sram);
60
61
+ /* SCU */
62
+ object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
63
+ if (err) {
64
+ error_propagate(errp, err);
65
+ return;
66
+ }
67
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE);
68
+
69
/* VIC */
70
object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
71
if (err) {
72
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
73
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
74
}
75
76
- /* SCU */
77
- object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
78
- if (err) {
79
- error_propagate(errp, err);
80
- return;
81
- }
82
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE);
83
-
84
/* UART - attach an 8250 to the IO space as our UART5 */
85
if (serial_hd(0)) {
86
qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
87
--
34
--
88
2.17.1
35
2.20.1
89
36
90
37
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <saipava@xilinx.com>
1
From: Nolan Leake <nolan@sigbus.net>
2
2
3
Qspi dma has a burst length of 64 bytes, So limit the transactions w.r.t
3
This is just enough to make reboot and poweroff work. Works for
4
dma-burst-size property.
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
5
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
6
Signed-off-by: Sai Pavan Boddu <saipava@xilinx.com>
6
do what linux does for reset.
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
8
Message-id: 1529660880-30376-1-git-send-email-sai.pavan.boddu@xilinx.com
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/]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
18
---
11
include/hw/ssi/xilinx_spips.h | 5 ++++-
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
12
hw/ssi/xilinx_spips.c | 23 ++++++++++++++++++++---
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
13
2 files changed, 24 insertions(+), 4 deletions(-)
21
hw/arm/bcm2835_peripherals.c | 13 ++-
14
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
15
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
23
hw/misc/meson.build | 1 +
24
5 files changed, 204 insertions(+), 2 deletions(-)
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
26
create mode 100644 hw/misc/bcm2835_powermgt.c
27
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
16
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/xilinx_spips.h
30
--- a/include/hw/arm/bcm2835_peripherals.h
18
+++ b/include/hw/ssi/xilinx_spips.h
31
+++ b/include/hw/arm/bcm2835_peripherals.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct XilinxSPIPS XilinxSPIPS;
32
@@ -XXX,XX +XXX,XX @@
20
/* Bite off 4k chunks at a time */
33
#include "hw/misc/bcm2835_mphi.h"
21
#define LQSPI_CACHE_SIZE 1024
34
#include "hw/misc/bcm2835_thermal.h"
22
35
#include "hw/misc/bcm2835_cprman.h"
23
+#define QSPI_DMA_MAX_BURST_SIZE 2048
36
+#include "hw/misc/bcm2835_powermgt.h"
24
+
37
#include "hw/sd/sdhci.h"
25
typedef enum {
38
#include "hw/sd/bcm2835_sdhost.h"
26
READ = 0x3, READ_4 = 0x13,
39
#include "hw/gpio/bcm2835_gpio.h"
27
FAST_READ = 0xb, FAST_READ_4 = 0x0c,
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
28
@@ -XXX,XX +XXX,XX @@ typedef struct {
41
BCM2835MphiState mphi;
29
XilinxQSPIPS parent_obj;
42
UnimplementedDeviceState txp;
30
43
UnimplementedDeviceState armtmr;
31
StreamSlave *dma;
44
- UnimplementedDeviceState powermgt;
32
- uint8_t dma_buf[4];
45
+ BCM2835PowerMgtState powermgt;
33
int gqspi_irqline;
46
BCM2835CprmanState cprman;
34
47
PL011State uart0;
35
uint32_t regs[XLNX_ZYNQMP_SPIPS_R_MAX];
48
BCM2835AuxState aux;
36
@@ -XXX,XX +XXX,XX @@ typedef struct {
49
diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h
37
uint8_t rx_fifo_g_align;
50
new file mode 100644
38
uint8_t tx_fifo_g_align;
51
index XXXXXXX..XXXXXXX
39
bool man_start_com_g;
52
--- /dev/null
40
+ uint32_t dma_burst_size;
53
+++ b/include/hw/misc/bcm2835_powermgt.h
41
+ uint8_t dma_buf[QSPI_DMA_MAX_BURST_SIZE];
54
@@ -XXX,XX +XXX,XX @@
42
} XlnxZynqMPQSPIPS;
55
+/*
43
56
+ * BCM2835 Power Management emulation
44
typedef struct XilinxSPIPSClass {
57
+ *
45
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
60
+ *
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
62
+ * See the COPYING file in the top-level directory.
63
+ */
64
+
65
+#ifndef BCM2835_POWERMGT_H
66
+#define BCM2835_POWERMGT_H
67
+
68
+#include "hw/sysbus.h"
69
+#include "qom/object.h"
70
+
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
73
+
74
+struct BCM2835PowerMgtState {
75
+ SysBusDevice busdev;
76
+ MemoryRegion iomem;
77
+
78
+ uint32_t rstc;
79
+ uint32_t rsts;
80
+ uint32_t wdog;
81
+};
82
+
83
+#endif
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
46
index XXXXXXX..XXXXXXX 100644
85
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/ssi/xilinx_spips.c
86
--- a/hw/arm/bcm2835_peripherals.c
48
+++ b/hw/ssi/xilinx_spips.c
87
+++ b/hw/arm/bcm2835_peripherals.c
49
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_notify(void *opaque)
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
50
{
89
51
size_t ret;
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
52
uint32_t num;
91
OBJECT(&s->gpu_bus_mr));
53
- const void *rxd = pop_buf(recv_fifo, 4, &num);
92
+
54
+ const void *rxd;
93
+ /* Power Management */
55
+ int len;
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
56
+
95
+ TYPE_BCM2835_POWERMGT);
57
+ len = recv_fifo->num >= rq->dma_burst_size ? rq->dma_burst_size :
58
+ recv_fifo->num;
59
+ rxd = pop_buf(recv_fifo, len, &num);
60
61
memcpy(rq->dma_buf, rxd, num);
62
63
- ret = stream_push(rq->dma, rq->dma_buf, 4);
64
- assert(ret == 4);
65
+ ret = stream_push(rq->dma, rq->dma_buf, num);
66
+ assert(ret == num);
67
xlnx_zynqmp_qspips_check_flush(rq);
68
}
69
}
96
}
70
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_realize(DeviceState *dev, Error **errp)
97
71
XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(dev);
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
72
XilinxSPIPSClass *xsc = XILINX_SPIPS_GET_CLASS(s);
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
73
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
74
+ if (s->dma_burst_size > QSPI_DMA_MAX_BURST_SIZE) {
101
INTERRUPT_USB));
75
+ error_setg(errp,
102
76
+ "qspi dma burst size %u exceeds maximum limit %d",
103
+ /* Power Management */
77
+ s->dma_burst_size, QSPI_DMA_MAX_BURST_SIZE);
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
78
+ return;
105
+ return;
79
+ }
106
+ }
80
xilinx_qspips_realize(dev, errp);
107
+
81
fifo8_create(&s->rx_fifo_g, xsc->rx_fifo_size);
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
82
fifo8_create(&s->tx_fifo_g, xsc->tx_fifo_size);
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
83
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_xlnx_zynqmp_qspips = {
110
+
84
}
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
85
};
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
86
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
87
+static Property xilinx_zynqmp_qspips_properties[] = {
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
88
+ DEFINE_PROP_UINT32("dma-burst-size", XlnxZynqMPQSPIPS, dma_burst_size, 64),
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
89
+ DEFINE_PROP_END_OF_LIST(),
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
90
+};
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
91
+
118
new file mode 100644
92
static Property xilinx_qspips_properties[] = {
119
index XXXXXXX..XXXXXXX
93
/* We had to turn this off for 2.10 as it is not compatible with migration.
120
--- /dev/null
94
* It can be enabled but will prevent the device to be migrated.
121
+++ b/hw/misc/bcm2835_powermgt.c
95
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_class_init(ObjectClass *klass, void * data)
122
@@ -XXX,XX +XXX,XX @@
96
dc->realize = xlnx_zynqmp_qspips_realize;
123
+/*
97
dc->reset = xlnx_zynqmp_qspips_reset;
124
+ * BCM2835 Power Management emulation
98
dc->vmsd = &vmstate_xlnx_zynqmp_qspips;
125
+ *
99
+ dc->props = xilinx_zynqmp_qspips_properties;
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
100
xsc->reg_ops = &xlnx_zynqmp_qspips_ops;
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
101
xsc->rx_fifo_size = RXFF_A_Q;
128
+ *
102
xsc->tx_fifo_size = TXFF_A_Q;
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
130
+ * See the COPYING file in the top-level directory.
131
+ */
132
+
133
+#include "qemu/osdep.h"
134
+#include "qemu/log.h"
135
+#include "qemu/module.h"
136
+#include "hw/misc/bcm2835_powermgt.h"
137
+#include "migration/vmstate.h"
138
+#include "sysemu/runstate.h"
139
+
140
+#define PASSWORD 0x5a000000
141
+#define PASSWORD_MASK 0xff000000
142
+
143
+#define R_RSTC 0x1c
144
+#define V_RSTC_RESET 0x20
145
+#define R_RSTS 0x20
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
147
+#define R_WDOG 0x24
148
+
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
150
+ unsigned size)
151
+{
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
153
+ uint32_t res = 0;
154
+
155
+ switch (offset) {
156
+ case R_RSTC:
157
+ res = s->rstc;
158
+ break;
159
+ case R_RSTS:
160
+ res = s->rsts;
161
+ break;
162
+ case R_WDOG:
163
+ res = s->wdog;
164
+ break;
165
+
166
+ default:
167
+ qemu_log_mask(LOG_UNIMP,
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
169
+ "\n", offset);
170
+ res = 0;
171
+ break;
172
+ }
173
+
174
+ return res;
175
+}
176
+
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
178
+ uint64_t value, unsigned size)
179
+{
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
181
+
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
183
+ qemu_log_mask(LOG_GUEST_ERROR,
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
186
+ value, offset);
187
+ return;
188
+ }
189
+
190
+ value = value & ~PASSWORD_MASK;
191
+
192
+ switch (offset) {
193
+ case R_RSTC:
194
+ s->rstc = value;
195
+ if (value & V_RSTC_RESET) {
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
198
+ } else {
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
200
+ }
201
+ }
202
+ break;
203
+ case R_RSTS:
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "bcm2835_powermgt_write: RSTS\n");
206
+ s->rsts = value;
207
+ break;
208
+ case R_WDOG:
209
+ qemu_log_mask(LOG_UNIMP,
210
+ "bcm2835_powermgt_write: WDOG\n");
211
+ s->wdog = value;
212
+ break;
213
+
214
+ default:
215
+ qemu_log_mask(LOG_UNIMP,
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
217
+ "\n", offset);
218
+ break;
219
+ }
220
+}
221
+
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
223
+ .read = bcm2835_powermgt_read,
224
+ .write = bcm2835_powermgt_write,
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
226
+ .impl.min_access_size = 4,
227
+ .impl.max_access_size = 4,
228
+};
229
+
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
231
+ .name = TYPE_BCM2835_POWERMGT,
232
+ .version_id = 1,
233
+ .minimum_version_id = 1,
234
+ .fields = (VMStateField[]) {
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
238
+ VMSTATE_END_OF_LIST()
239
+ }
240
+};
241
+
242
+static void bcm2835_powermgt_init(Object *obj)
243
+{
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
245
+
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
247
+ TYPE_BCM2835_POWERMGT, 0x200);
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
249
+}
250
+
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
252
+{
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
254
+
255
+ /* https://elinux.org/BCM2835_registers#PM */
256
+ s->rstc = 0x00000102;
257
+ s->rsts = 0x00001000;
258
+ s->wdog = 0x00000000;
259
+}
260
+
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
262
+{
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
264
+
265
+ dc->reset = bcm2835_powermgt_reset;
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
267
+}
268
+
269
+static TypeInfo bcm2835_powermgt_info = {
270
+ .name = TYPE_BCM2835_POWERMGT,
271
+ .parent = TYPE_SYS_BUS_DEVICE,
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
273
+ .class_init = bcm2835_powermgt_class_init,
274
+ .instance_init = bcm2835_powermgt_init,
275
+};
276
+
277
+static void bcm2835_powermgt_register_types(void)
278
+{
279
+ type_register_static(&bcm2835_powermgt_info);
280
+}
281
+
282
+type_init(bcm2835_powermgt_register_types)
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
284
index XXXXXXX..XXXXXXX 100644
285
--- a/hw/misc/meson.build
286
+++ b/hw/misc/meson.build
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
288
'bcm2835_rng.c',
289
'bcm2835_thermal.c',
290
'bcm2835_cprman.c',
291
+ 'bcm2835_powermgt.c',
292
))
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
103
--
295
--
104
2.17.1
296
2.20.1
105
297
106
298
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Missed in df3692e04b2.
3
Add a test booting and quickly shutdown a raspi2 machine,
4
to test the power management model:
5
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
8
console: [ 0.000000] Linux version 4.14.98-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1200 SMP Tue Feb 12 20:27:48 GMT 2019
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
10
console: [ 0.000000] CPU: div instructions available: patching division code
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
12
console: [ 0.000000] OF: fdt: Machine model: Raspberry Pi 2 Model B
13
...
14
console: Boot successful.
15
console: cat /proc/cpuinfo
16
console: / # cat /proc/cpuinfo
17
...
18
console: processor : 3
19
console: model name : ARMv7 Processor rev 5 (v7l)
20
console: BogoMIPS : 125.00
21
console: Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
22
console: CPU implementer : 0x41
23
console: CPU architecture: 7
24
console: CPU variant : 0x0
25
console: CPU part : 0xc07
26
console: CPU revision : 5
27
console: Hardware : BCM2835
28
console: Revision : 0000
29
console: Serial : 0000000000000000
30
console: cat /proc/iomem
31
console: / # cat /proc/iomem
32
console: 00000000-3bffffff : System RAM
33
console: 00008000-00afffff : Kernel code
34
console: 00c00000-00d468ef : Kernel data
35
console: 3f006000-3f006fff : dwc_otg
36
console: 3f007000-3f007eff : /soc/dma@7e007000
37
console: 3f00b880-3f00b8bf : /soc/mailbox@7e00b880
38
console: 3f100000-3f100027 : /soc/watchdog@7e100000
39
console: 3f101000-3f102fff : /soc/cprman@7e101000
40
console: 3f200000-3f2000b3 : /soc/gpio@7e200000
41
PASS (24.59 s)
42
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
43
JOB TIME : 25.02 s
4
44
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20180624040609.17572-16-f4bug@amsat.org
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
49
---
10
hw/arm/stellaris.c | 2 +-
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
11
1 file changed, 1 insertion(+), 1 deletion(-)
51
1 file changed, 43 insertions(+)
12
52
13
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
14
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/stellaris.c
55
--- a/tests/acceptance/boot_linux_console.py
16
+++ b/hw/arm/stellaris.c
56
+++ b/tests/acceptance/boot_linux_console.py
17
@@ -XXX,XX +XXX,XX @@ static void gptm_write(void *opaque, hwaddr offset,
57
@@ -XXX,XX +XXX,XX @@
18
break;
58
from avocado import skip
19
default:
59
from avocado import skipUnless
20
qemu_log_mask(LOG_GUEST_ERROR,
60
from avocado_qemu import Test
21
- "GPTM: read at bad offset 0x%x\n", (int)offset);
61
+from avocado_qemu import exec_command
22
+ "GPTM: write at bad offset 0x%x\n", (int)offset);
62
from avocado_qemu import exec_command_and_wait_for_pattern
23
}
63
from avocado_qemu import interrupt_interactive_console_until_pattern
24
gptm_update_irq(s);
64
from avocado_qemu import wait_for_console_pattern
25
}
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
66
"""
67
self.do_test_arm_raspi2(0)
68
69
+ def test_arm_raspi2_initrd(self):
70
+ """
71
+ :avocado: tags=arch:arm
72
+ :avocado: tags=machine:raspi2
73
+ """
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
75
+ 'pool/main/r/raspberrypi-firmware/'
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
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
26
--
114
--
27
2.17.1
115
2.20.1
28
116
29
117
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
Suggested-by: Thomas Huth <thuth@redhat.com>
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
4
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
5
Message-id: 20180624040609.17572-17-f4bug@amsat.org
5
assert due to fpst->default_nan_mode being set.
6
7
To avoid this, we check to see what NaN mode we're running in before we call
8
floatxx_silence_nan().
9
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
15
---
9
hw/arm/stellaris.c | 6 ++++--
16
target/arm/helper-a64.c | 12 +++++++++---
10
1 file changed, 4 insertions(+), 2 deletions(-)
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
18
2 files changed, 27 insertions(+), 9 deletions(-)
11
19
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
13
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/stellaris.c
22
--- a/target/arm/helper-a64.c
15
+++ b/hw/arm/stellaris.c
23
+++ b/target/arm/helper-a64.c
16
@@ -XXX,XX +XXX,XX @@ static uint64_t gptm_read(void *opaque, hwaddr offset,
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
17
return 0;
25
float16 nan = a;
18
default:
26
if (float16_is_signaling_nan(a, fpst)) {
19
qemu_log_mask(LOG_GUEST_ERROR,
27
float_raise(float_flag_invalid, fpst);
20
- "GPTM: read at bad offset 0x%x\n", (int)offset);
28
- nan = float16_silence_nan(a, fpst);
21
+ "GPTM: read at bad offset 0x02%" HWADDR_PRIx "\n",
29
+ if (!fpst->default_nan_mode) {
22
+ offset);
30
+ nan = float16_silence_nan(a, fpst);
23
return 0;
31
+ }
24
}
32
}
25
}
33
if (fpst->default_nan_mode) {
26
@@ -XXX,XX +XXX,XX @@ static void gptm_write(void *opaque, hwaddr offset,
34
nan = float16_default_nan(fpst);
27
break;
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
28
default:
36
float32 nan = a;
29
qemu_log_mask(LOG_GUEST_ERROR,
37
if (float32_is_signaling_nan(a, fpst)) {
30
- "GPTM: write at bad offset 0x%x\n", (int)offset);
38
float_raise(float_flag_invalid, fpst);
31
+ "GPTM: write at bad offset 0x02%" HWADDR_PRIx "\n",
39
- nan = float32_silence_nan(a, fpst);
32
+ offset);
40
+ if (!fpst->default_nan_mode) {
33
}
41
+ nan = float32_silence_nan(a, fpst);
34
gptm_update_irq(s);
42
+ }
35
}
43
}
44
if (fpst->default_nan_mode) {
45
nan = float32_default_nan(fpst);
46
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
47
float64 nan = a;
48
if (float64_is_signaling_nan(a, fpst)) {
49
float_raise(float_flag_invalid, fpst);
50
- nan = float64_silence_nan(a, fpst);
51
+ if (!fpst->default_nan_mode) {
52
+ nan = float64_silence_nan(a, fpst);
53
+ }
54
}
55
if (fpst->default_nan_mode) {
56
nan = float64_default_nan(fpst);
57
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
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);
36
--
127
--
37
2.17.1
128
2.20.1
38
129
39
130
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
function has to be used for machine shutdown. Otherwise we cause
5
Message-id: 20180624040609.17572-3-f4bug@amsat.org
5
a reset with a bogus "cause" value, when we intended a shutdown.
6
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
10
[PMM: tweaked commit message]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
hw/input/tsc2005.c | 13 ++++++++-----
13
hw/gpio/gpio_pwr.c | 2 +-
9
1 file changed, 8 insertions(+), 5 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
10
15
11
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/input/tsc2005.c
18
--- a/hw/gpio/gpio_pwr.c
14
+++ b/hw/input/tsc2005.c
19
+++ b/hw/gpio/gpio_pwr.c
15
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
16
*/
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
17
22
{
18
#include "qemu/osdep.h"
23
if (level) {
19
+#include "qemu/log.h"
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
20
#include "hw/hw.h"
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
21
#include "qemu/timer.h"
22
#include "ui/console.h"
23
@@ -XXX,XX +XXX,XX @@ static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
24
}
25
s->nextprecision = (data >> 13) & 1;
26
s->timing[0] = data & 0x1fff;
27
- if ((s->timing[0] >> 11) == 3)
28
- fprintf(stderr, "%s: illegal conversion clock setting\n",
29
- __func__);
30
+ if ((s->timing[0] >> 11) == 3) {
31
+ qemu_log_mask(LOG_GUEST_ERROR,
32
+ "tsc2005_write: illegal conversion clock setting\n");
33
+ }
34
break;
35
case 0xd:    /* CFR1 */
36
s->timing[1] = data & 0xf07;
37
@@ -XXX,XX +XXX,XX @@ static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
38
break;
39
40
default:
41
- fprintf(stderr, "%s: write into read-only register %x\n",
42
- __func__, reg);
43
+ qemu_log_mask(LOG_GUEST_ERROR,
44
+ "%s: write into read-only register 0x%x\n",
45
+ __func__, reg);
46
}
26
}
47
}
27
}
48
28
49
--
29
--
50
2.17.1
30
2.20.1
51
31
52
32
diff view generated by jsdifflib
1
Allow ARMv8M to handle small MPU and SAU region sizes, by making
1
In do_ldst(), the calculation of the offset needs to be based on the
2
get_phys_add_pmsav8() set the page size to the 1 if the MPU or
2
size of the memory access, not the size of the elements in the
3
SAU region covers less than a TARGET_PAGE_SIZE.
3
vector. This meant we were getting it wrong for the widening and
4
4
narrowing variants of the various VLDR and VSTR insns.
5
We choose to use a size of 1 because it makes no difference to
6
the core code, and avoids having to track both the base and
7
limit for SAU and MPU and then convert into an artificially
8
restricted "page size" that the core code will then ignore.
9
10
Since the core TCG code can't handle execution from small
11
MPU regions, we strip the exec permission from them so that
12
any execution attempts will cause an MPU exception, rather
13
than allowing it to end up with a cpu_abort() in
14
get_page_addr_code().
15
16
(The previous code's intention was to make any small page be
17
treated as having no permissions, but unfortunately errors
18
in the implementation meant that it didn't behave that way.
19
It's possible that some binaries using small regions were
20
accidentally working with our old behaviour and won't now.)
21
22
We also retain an existing bug, where we ignored the possibility
23
that the SAU region might not cover the entire page, in the
24
case of executable regions. This is necessary because some
25
currently-working guest code images rely on being able to
26
execute from addresses which are covered by a page-sized
27
MPU region but a smaller SAU region. We can remove this
28
workaround if we ever support execution from small regions.
29
5
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Message-id: 20180620130619.11362-4-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
33
---
9
---
34
target/arm/helper.c | 78 ++++++++++++++++++++++++++++++++-------------
10
target/arm/translate-mve.c | 17 +++++++++--------
35
1 file changed, 55 insertions(+), 23 deletions(-)
11
1 file changed, 9 insertions(+), 8 deletions(-)
36
12
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
38
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
15
--- a/target/arm/translate-mve.c
40
+++ b/target/arm/helper.c
16
+++ b/target/arm/translate-mve.c
41
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
42
18
}
43
/* Security attributes for an address, as returned by v8m_security_lookup. */
19
}
44
typedef struct V8M_SAttributes {
20
45
+ bool subpage; /* true if these attrs don't cover the whole TARGET_PAGE */
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
46
bool ns;
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
47
bool nsc;
23
+ unsigned msize)
48
uint8_t sregion;
49
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
50
int r;
51
bool idau_exempt = false, idau_ns = true, idau_nsc = true;
52
int idau_region = IREGION_NOTVALID;
53
+ uint32_t addr_page_base = address & TARGET_PAGE_MASK;
54
+ uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
55
56
if (cpu->idau) {
57
IDAUInterfaceClass *iic = IDAU_INTERFACE_GET_CLASS(cpu->idau);
58
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
59
uint32_t limit = env->sau.rlar[r] | 0x1f;
60
61
if (base <= address && limit >= address) {
62
+ if (base > addr_page_base || limit < addr_page_limit) {
63
+ sattrs->subpage = true;
64
+ }
65
if (sattrs->srvalid) {
66
/* If we hit in more than one region then we must report
67
* as Secure, not NS-Callable, with no valid region
68
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
69
static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
70
MMUAccessType access_type, ARMMMUIdx mmu_idx,
71
hwaddr *phys_ptr, MemTxAttrs *txattrs,
72
- int *prot, ARMMMUFaultInfo *fi, uint32_t *mregion)
73
+ int *prot, bool *is_subpage,
74
+ ARMMMUFaultInfo *fi, uint32_t *mregion)
75
{
24
{
76
/* Perform a PMSAv8 MPU lookup (without also doing the SAU check
25
TCGv_i32 addr;
77
* that a full phys-to-virt translation does).
26
uint32_t offset;
78
* mregion is (if not NULL) set to the region number which matched,
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
79
* or -1 if no region number is returned (MPU off, address did not
28
return true;
80
* hit a region, address hit in multiple regions).
81
+ * We set is_subpage to true if the region hit doesn't cover the
82
+ * entire TARGET_PAGE the address is within.
83
*/
84
ARMCPU *cpu = arm_env_get_cpu(env);
85
bool is_user = regime_is_user(env, mmu_idx);
86
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
87
int n;
88
int matchregion = -1;
89
bool hit = false;
90
+ uint32_t addr_page_base = address & TARGET_PAGE_MASK;
91
+ uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
92
93
+ *is_subpage = false;
94
*phys_ptr = address;
95
*prot = 0;
96
if (mregion) {
97
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
98
continue;
99
}
100
101
+ if (base > addr_page_base || limit < addr_page_limit) {
102
+ *is_subpage = true;
103
+ }
104
+
105
if (hit) {
106
/* Multiple regions match -- always a failure (unlike
107
* PMSAv7 where highest-numbered-region wins)
108
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
109
110
matchregion = n;
111
hit = true;
112
-
113
- if (base & ~TARGET_PAGE_MASK) {
114
- qemu_log_mask(LOG_UNIMP,
115
- "MPU_RBAR[%d]: No support for MPU region base"
116
- "address of 0x%" PRIx32 ". Minimum alignment is "
117
- "%d\n",
118
- n, base, TARGET_PAGE_BITS);
119
- continue;
120
- }
121
- if ((limit + 1) & ~TARGET_PAGE_MASK) {
122
- qemu_log_mask(LOG_UNIMP,
123
- "MPU_RBAR[%d]: No support for MPU region limit"
124
- "address of 0x%" PRIx32 ". Minimum alignment is "
125
- "%d\n",
126
- n, limit, TARGET_PAGE_BITS);
127
- continue;
128
- }
129
}
130
}
29
}
131
30
132
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
31
- offset = a->imm << a->size;
133
32
+ offset = a->imm << msize;
134
fi->type = ARMFault_Permission;
33
if (!a->a) {
135
fi->level = 1;
34
offset = -offset;
136
+ /*
35
}
137
+ * Core QEMU code can't handle execution from small pages yet, so
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
138
+ * don't try it. This means any attempted execution will generate
37
{ gen_helper_mve_vstrw, gen_helper_mve_vldrw },
139
+ * an MPU exception, rather than eventually causing QEMU to exit in
38
{ NULL, NULL }
140
+ * get_page_addr_code().
39
};
141
+ */
40
- return do_ldst(s, a, ldstfns[a->size][a->l]);
142
+ if (*is_subpage && (*prot & PAGE_EXEC)) {
41
+ return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
143
+ qemu_log_mask(LOG_UNIMP,
144
+ "MPU: No support for execution from regions "
145
+ "smaller than 1K\n");
146
+ *prot &= ~PAGE_EXEC;
147
+ }
148
return !(*prot & (1 << access_type));
149
}
42
}
150
43
151
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
152
static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
153
MMUAccessType access_type, ARMMMUIdx mmu_idx,
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
154
hwaddr *phys_ptr, MemTxAttrs *txattrs,
47
{ \
155
- int *prot, ARMMMUFaultInfo *fi)
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
156
+ int *prot, target_ulong *page_size,
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
157
+ ARMMMUFaultInfo *fi)
50
{ NULL, gen_helper_mve_##ULD }, \
51
}; \
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
54
}
55
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
62
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
158
{
64
{
159
uint32_t secure = regime_is_secure(env, mmu_idx);
160
V8M_SAttributes sattrs = {};
161
+ bool ret;
162
+ bool mpu_is_subpage;
163
164
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
165
v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
166
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
167
} else {
168
fi->type = ARMFault_QEMU_SFault;
169
}
170
+ *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
171
*phys_ptr = address;
172
*prot = 0;
173
return true;
174
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
175
* for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
176
*/
177
fi->type = ARMFault_QEMU_SFault;
178
+ *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
179
*phys_ptr = address;
180
*prot = 0;
181
return true;
182
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
183
}
184
}
185
186
- return pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
187
- txattrs, prot, fi, NULL);
188
+ ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
189
+ txattrs, prot, &mpu_is_subpage, fi, NULL);
190
+ /*
191
+ * TODO: this is a temporary hack to ignore the fact that the SAU region
192
+ * is smaller than a page if this is an executable region. We never
193
+ * supported small MPU regions, but we did (accidentally) allow small
194
+ * SAU regions, and if we now made small SAU regions not be executable
195
+ * then this would break previously working guest code. We can't
196
+ * remove this until/unless we implement support for execution from
197
+ * small regions.
198
+ */
199
+ if (*prot & PAGE_EXEC) {
200
+ sattrs.subpage = false;
201
+ }
202
+ *page_size = sattrs.subpage || mpu_is_subpage ? 1 : TARGET_PAGE_SIZE;
203
+ return ret;
204
}
205
206
static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
207
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
208
if (arm_feature(env, ARM_FEATURE_V8)) {
209
/* PMSAv8 */
210
ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
211
- phys_ptr, attrs, prot, fi);
212
+ phys_ptr, attrs, prot, page_size, fi);
213
} else if (arm_feature(env, ARM_FEATURE_V7)) {
214
/* PMSAv7 */
215
ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
216
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
217
uint32_t mregion;
218
bool targetpriv;
219
bool targetsec = env->v7m.secure;
220
+ bool is_subpage;
221
222
/* Work out what the security state and privilege level we're
223
* interested in is...
224
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
225
if (arm_current_el(env) != 0 || alt) {
226
/* We can ignore the return value as prot is always set */
227
pmsav8_mpu_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
228
- &phys_addr, &attrs, &prot, &fi, &mregion);
229
+ &phys_addr, &attrs, &prot, &is_subpage,
230
+ &fi, &mregion);
231
if (mregion == -1) {
232
mrvalid = false;
233
mregion = 0;
234
--
65
--
235
2.17.1
66
2.20.1
236
67
237
68
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.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 timer controller can be driven by either an external 1MHz clock or
10
In particular, fixing the second of these allows us to recast
4
by the APB clock. Today, the model makes the assumption that the APB
11
the implementation to avoid 128-bit arithmetic entirely.
5
frequency is always set to 24MHz but this is incorrect.
6
12
7
The AST2400 SoC on the palmetto machines uses a 48MHz input clock
13
Since the element size here is always 4, we can also drop the
8
source and the APB can be set to 48MHz. The consequence is a general
14
parameterization of ESIZE to make the code a little more readable.
9
system slowdown. The QEMU machines using the AST2500 SoC do not seem
10
impacted today because the APB frequency is still set to 24MHz.
11
15
12
We fix the timer frequency for all SoCs by linking the Timer model to
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
13
the SCU model. The APB frequency driving the timers is now the one
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
configured for the SoC.
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
20
---
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
22
1 file changed, 21 insertions(+), 17 deletions(-)
15
23
16
Signed-off-by: Cédric Le Goater <clg@kaod.org>
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
17
Reviewed-by: Joel Stanley <joel@jms.id.au>
18
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
19
Message-id: 20180622075700.5923-4-clg@kaod.org
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
include/hw/timer/aspeed_timer.h | 4 ++++
23
hw/arm/aspeed_soc.c | 2 ++
24
hw/timer/aspeed_timer.c | 19 +++++++++++++++----
25
3 files changed, 21 insertions(+), 4 deletions(-)
26
27
diff --git a/include/hw/timer/aspeed_timer.h b/include/hw/timer/aspeed_timer.h
28
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
29
--- a/include/hw/timer/aspeed_timer.h
26
--- a/target/arm/mve_helper.c
30
+++ b/include/hw/timer/aspeed_timer.h
27
+++ b/target/arm/mve_helper.c
31
@@ -XXX,XX +XXX,XX @@
32
33
#include "qemu/timer.h"
34
35
+typedef struct AspeedSCUState AspeedSCUState;
36
+
37
#define ASPEED_TIMER(obj) \
38
OBJECT_CHECK(AspeedTimerCtrlState, (obj), TYPE_ASPEED_TIMER);
39
#define TYPE_ASPEED_TIMER "aspeed.timer"
40
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedTimerCtrlState {
41
uint32_t ctrl;
42
uint32_t ctrl2;
43
AspeedTimer timers[ASPEED_TIMER_NR_TIMERS];
44
+
45
+ AspeedSCUState *scu;
46
} AspeedTimerCtrlState;
47
48
#endif /* ASPEED_TIMER_H */
49
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/aspeed_soc.c
52
+++ b/hw/arm/aspeed_soc.c
53
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
54
55
object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
56
object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
57
+ object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
58
+ OBJECT(&s->scu), &error_abort);
59
qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
60
61
object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
62
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/timer/aspeed_timer.c
65
+++ b/hw/timer/aspeed_timer.c
66
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
67
*/
29
*/
68
30
69
#include "qemu/osdep.h"
31
#include "qemu/osdep.h"
70
+#include "qapi/error.h"
32
-#include "qemu/int128.h"
71
#include "hw/sysbus.h"
33
#include "cpu.h"
72
#include "hw/timer/aspeed_timer.h"
34
#include "internals.h"
73
+#include "hw/misc/aspeed_scu.h"
35
#include "vec_internal.h"
74
#include "qemu-common.h"
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
75
#include "qemu/bitops.h"
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
76
#include "qemu/timer.h"
38
77
@@ -XXX,XX +XXX,XX @@
39
/*
78
#define TIMER_CLOCK_USE_EXT true
40
- * Rounding multiply add long dual accumulate high: we must keep
79
#define TIMER_CLOCK_EXT_HZ 1000000
41
- * a 72-bit internal accumulator value and return the top 64 bits.
80
#define TIMER_CLOCK_USE_APB false
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
81
-#define TIMER_CLOCK_APB_HZ 24000000
43
+ * this is implemented with a 72-bit internal accumulator value of which
82
44
+ * the top 64 bits are returned. We optimize this to avoid having to
83
#define TIMER_REG_STATUS 0
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
84
#define TIMER_REG_RELOAD 1
46
+ * is squashed back into 64-bits after each beat.
85
@@ -XXX,XX +XXX,XX @@ static inline bool timer_external_clock(AspeedTimer *t)
47
*/
86
return timer_ctrl_status(t, op_external_clock);
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
87
}
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
88
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
89
-static uint32_t clock_rates[] = { TIMER_CLOCK_APB_HZ, TIMER_CLOCK_EXT_HZ };
51
void *vm, uint64_t a) \
90
-
52
{ \
91
static inline uint32_t calculate_rate(struct AspeedTimer *t)
53
uint16_t mask = mve_element_mask(env); \
92
{
54
unsigned e; \
93
- return clock_rates[timer_external_clock(t)];
55
TYPE *n = vn, *m = vm; \
94
+ AspeedTimerCtrlState *s = timer_to_ctrl(t);
56
- Int128 acc = int128_lshift(TO128(a), 8); \
95
+
57
- for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
96
+ return timer_external_clock(t) ? TIMER_CLOCK_EXT_HZ : s->scu->apb_freq;
58
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
97
}
59
if (mask & 1) { \
98
60
+ LTYPE mul; \
99
static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns)
61
if (e & 1) { \
100
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_realize(DeviceState *dev, Error **errp)
62
- acc = ODDACC(acc, TO128(n[H##ESIZE(e - 1 * XCHG)] * \
101
int i;
63
- m[H##ESIZE(e)])); \
102
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
64
+ mul = (LTYPE)n[H4(e - 1 * XCHG)] * m[H4(e)]; \
103
AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
65
+ if (SUB) { \
104
+ Object *obj;
66
+ mul = -mul; \
105
+ Error *err = NULL;
67
+ } \
106
+
68
} else { \
107
+ obj = object_property_get_link(OBJECT(dev), "scu", &err);
69
- acc = EVENACC(acc, TO128(n[H##ESIZE(e + 1 * XCHG)] * \
108
+ if (!obj) {
70
- m[H##ESIZE(e)])); \
109
+ error_propagate(errp, err);
71
+ mul = (LTYPE)n[H4(e + 1 * XCHG)] * m[H4(e)]; \
110
+ error_prepend(errp, "required link 'scu' not found: ");
72
} \
111
+ return;
73
- acc = int128_add(acc, int128_make64(1 << 7)); \
112
+ }
74
+ mul = (mul >> 8) + ((mul >> 7) & 1); \
113
+ s->scu = ASPEED_SCU(obj);
75
+ a += mul; \
114
76
} \
115
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
77
} \
116
aspeed_init_one_timer(s, i);
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) \
117
--
98
--
118
2.17.1
99
2.20.1
119
100
120
101
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The function asimd_imm_const() in translate-neon.c is an
2
implementation of the pseudocode AdvSIMDExpandImm(), which we will
3
also want for MVE. Move the implementation to translate.c, with a
4
prototype in translate.h.
2
5
3
hw_error() finally calls abort(), but there is no need to abort here.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
9
---
10
target/arm/translate.h | 16 ++++++++++
11
target/arm/translate-neon.c | 63 -------------------------------------
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
13
3 files changed, 73 insertions(+), 63 deletions(-)
4
14
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
6
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Message-id: 20180624040609.17572-14-f4bug@amsat.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/net/smc91c111.c | 9 +++++++--
11
1 file changed, 7 insertions(+), 2 deletions(-)
12
13
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/smc91c111.c
17
--- a/target/arm/translate.h
16
+++ b/hw/net/smc91c111.c
18
+++ b/target/arm/translate.h
17
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
18
#include "hw/sysbus.h"
20
return opc | s->be_data;
19
#include "net/net.h"
20
#include "hw/devices.h"
21
+#include "qemu/log.h"
22
/* For crc32 */
23
#include <zlib.h>
24
25
@@ -XXX,XX +XXX,XX @@ static void smc91c111_writeb(void *opaque, hwaddr offset,
26
}
27
break;
28
}
29
- hw_error("smc91c111_write: Bad reg %d:%x\n", s->bank, (int)offset);
30
+ qemu_log_mask(LOG_GUEST_ERROR, "smc91c111_write(bank:%d) Illegal register"
31
+ " 0x%" HWADDR_PRIx " = 0x%x\n",
32
+ s->bank, offset, value);
33
}
21
}
34
22
35
static uint32_t smc91c111_readb(void *opaque, hwaddr offset)
23
+/**
36
@@ -XXX,XX +XXX,XX @@ static uint32_t smc91c111_readb(void *opaque, hwaddr offset)
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
37
}
25
+ *
38
break;
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
39
}
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
40
- hw_error("smc91c111_read: Bad reg %d:%x\n", s->bank, (int)offset);
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
41
+ qemu_log_mask(LOG_GUEST_ERROR, "smc91c111_read(bank:%d) Illegal register"
29
+ *
42
+ " 0x%" HWADDR_PRIx "\n",
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
43
+ s->bank, offset);
31
+ * callers must catch this.
44
return 0;
32
+ *
33
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
34
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
35
+ * we produce an immediate constant value of 0 in these cases.
36
+ */
37
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.c
43
+++ b/target/arm/translate-neon.c
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
47
48
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
49
-{
50
- /*
51
- * Expand the encoded constant.
52
- * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
53
- * We choose to not special-case this and will behave as if a
54
- * valid constant encoding of 0 had been given.
55
- * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
56
- */
57
- switch (cmode) {
58
- case 0: case 1:
59
- /* no-op */
60
- break;
61
- case 2: case 3:
62
- imm <<= 8;
63
- break;
64
- case 4: case 5:
65
- imm <<= 16;
66
- break;
67
- case 6: case 7:
68
- imm <<= 24;
69
- break;
70
- case 8: case 9:
71
- imm |= imm << 16;
72
- break;
73
- case 10: case 11:
74
- imm = (imm << 8) | (imm << 24);
75
- break;
76
- case 12:
77
- imm = (imm << 8) | 0xff;
78
- break;
79
- case 13:
80
- imm = (imm << 16) | 0xffff;
81
- break;
82
- case 14:
83
- if (op) {
84
- /*
85
- * This is the only case where the top and bottom 32 bits
86
- * of the encoded constant differ.
87
- */
88
- uint64_t imm64 = 0;
89
- int n;
90
-
91
- for (n = 0; n < 8; n++) {
92
- if (imm & (1 << n)) {
93
- imm64 |= (0xffULL << (n * 8));
94
- }
95
- }
96
- return imm64;
97
- }
98
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
99
- break;
100
- case 15:
101
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
102
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
103
- break;
104
- }
105
- if (op) {
106
- imm = ~imm;
107
- }
108
- return dup_const(MO_32, imm);
109
-}
110
-
111
static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
112
GVecGen2iFn *fn)
113
{
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
117
+++ b/target/arm/translate.c
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
119
a64_translate_init();
45
}
120
}
46
121
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
123
+{
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
125
+ switch (cmode) {
126
+ case 0: case 1:
127
+ /* no-op */
128
+ break;
129
+ case 2: case 3:
130
+ imm <<= 8;
131
+ break;
132
+ case 4: case 5:
133
+ imm <<= 16;
134
+ break;
135
+ case 6: case 7:
136
+ imm <<= 24;
137
+ break;
138
+ case 8: case 9:
139
+ imm |= imm << 16;
140
+ break;
141
+ case 10: case 11:
142
+ imm = (imm << 8) | (imm << 24);
143
+ break;
144
+ case 12:
145
+ imm = (imm << 8) | 0xff;
146
+ break;
147
+ case 13:
148
+ imm = (imm << 16) | 0xffff;
149
+ break;
150
+ case 14:
151
+ if (op) {
152
+ /*
153
+ * This is the only case where the top and bottom 32 bits
154
+ * of the encoded constant differ.
155
+ */
156
+ uint64_t imm64 = 0;
157
+ int n;
158
+
159
+ for (n = 0; n < 8; n++) {
160
+ if (imm & (1 << n)) {
161
+ imm64 |= (0xffULL << (n * 8));
162
+ }
163
+ }
164
+ return imm64;
165
+ }
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
167
+ break;
168
+ case 15:
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
171
+ break;
172
+ }
173
+ if (op) {
174
+ imm = ~imm;
175
+ }
176
+ return dup_const(MO_32, imm);
177
+}
178
+
179
/* Generate a label used for skipping this instruction */
180
void arm_gen_condlabel(DisasContext *s)
181
{
47
--
182
--
48
2.17.1
183
2.20.1
49
184
50
185
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.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
Only the flash type is strapped by HW. The 4BYTE mode is set by
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
firmware when the flash device is detected.
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
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
7
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
8
Message-id: 20180612065716.10587-3-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/ssi/aspeed_smc.c | 8 +-------
12
1 file changed, 1 insertion(+), 7 deletions(-)
13
14
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ssi/aspeed_smc.c
17
--- a/target/arm/translate.h
17
+++ b/hw/ssi/aspeed_smc.c
18
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
19
aspeed_smc_segment_to_reg(&s->ctrl->segments[i]);
20
* VMVN and VBIC (when cmode < 14 && op == 1).
21
*
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;
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
34
{
35
int rd = extract32(insn, 0, 5);
36
int cmode = extract32(insn, 12, 4);
37
- int cmode_3_1 = extract32(cmode, 1, 3);
38
- int cmode_0 = extract32(cmode, 0, 1);
39
int o2 = extract32(insn, 11, 1);
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
41
bool is_neg = extract32(insn, 29, 1);
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
43
return;
20
}
44
}
21
45
22
- /* HW strapping for AST2500 FMC controllers */
46
- /* See AdvSIMDExpandImm() in ARM ARM */
23
+ /* HW strapping flash type for FMC controllers */
47
- switch (cmode_3_1) {
24
if (s->ctrl->segments == aspeed_segments_ast2500_fmc) {
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
25
/* flash type is fixed to SPI for CE0 and CE1 */
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
26
s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
27
s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1);
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
- }
28
-
120
-
29
- /* 4BYTE mode is autodetected for CE0. Let's force it to 1 for
121
- if (cmode_3_1 != 7 && is_neg) {
30
- * now */
122
- imm = ~imm;
31
- s->regs[s->r_ce_ctrl] |= (1 << (CTRL_EXTENDED0));
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);
32
}
130
}
33
131
34
/* HW strapping for AST2400 FMC controllers (SCU70). Let's use the
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
35
* configuration of the palmetto-bmc machine */
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
36
if (s->ctrl->segments == aspeed_segments_fmc) {
134
index XXXXXXX..XXXXXXX 100644
37
s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
135
--- a/target/arm/translate.c
38
-
136
+++ b/target/arm/translate.c
39
- s->regs[s->r_ce_ctrl] |= (1 << (CTRL_EXTENDED0));
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
40
}
138
case 14:
41
}
139
if (op) {
42
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;
43
--
168
--
44
2.17.1
169
2.20.1
45
170
46
171
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Use dup_const() instead of bitfield_replicate() in
2
disas_simd_mod_imm().
2
3
3
Suggested-by: Thomas Huth <thuth@redhat.com>
4
(We can't replace the other use of bitfield_replicate() in this file,
4
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
in logic_imm_decode_wmask(), because that location needs to handle 2
5
Message-id: 20180624040609.17572-12-f4bug@amsat.org
6
and 4 bit elements, which dup_const() cannot.)
7
6
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
7
---
11
---
8
hw/net/stellaris_enet.c | 2 +-
12
target/arm/translate-a64.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
10
14
11
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/net/stellaris_enet.c
17
--- a/target/arm/translate-a64.c
14
+++ b/hw/net/stellaris_enet.c
18
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static uint64_t stellaris_enet_read(void *opaque, hwaddr offset,
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
16
return s->np;
20
/* FMOV (vector, immediate) - half-precision */
17
case 0x38: /* TR */
21
imm = vfp_expand_imm(MO_16, abcdefgh);
18
return 0;
22
/* now duplicate across the lanes */
19
- case 0x3c: /* Undocuented: Timestamp? */
23
- imm = bitfield_replicate(imm, 16);
20
+ case 0x3c: /* Undocumented: Timestamp? */
24
+ imm = dup_const(MO_16, imm);
21
return 0;
25
} else {
22
default:
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
23
hw_error("stellaris_enet_read: Bad offset %x\n", (int)offset);
27
}
24
--
28
--
25
2.17.1
29
2.20.1
26
30
27
31
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
2
VORR and VBIC). These have essentially the same encoding
3
as their Neon equivalents, and we implement the decode
4
in the same way.
2
5
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-15-f4bug@amsat.org
6
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-7-peter.maydell@linaro.org
7
---
9
---
8
hw/net/smc91c111.c | 12 ++++++++----
10
target/arm/helper-mve.h | 4 +++
9
1 file changed, 8 insertions(+), 4 deletions(-)
11
target/arm/mve.decode | 17 +++++++++++++
12
target/arm/mve_helper.c | 24 ++++++++++++++++++
13
target/arm/translate-mve.c | 50 ++++++++++++++++++++++++++++++++++++++
14
4 files changed, 95 insertions(+)
10
15
11
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/net/smc91c111.c
18
--- a/target/arm/helper-mve.h
14
+++ b/hw/net/smc91c111.c
19
+++ b/target/arm/helper-mve.h
15
@@ -XXX,XX +XXX,XX @@ static void smc91c111_writeb(void *opaque, hwaddr offset,
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
16
SET_HIGH(gpr, value);
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
17
return;
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
18
case 12: /* Control */
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
19
- if (value & 1)
24
+
20
- fprintf(stderr, "smc91c111:EEPROM store not implemented\n");
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
21
- if (value & 2)
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
22
- fprintf(stderr, "smc91c111:EEPROM reload not implemented\n");
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
23
+ if (value & 1) {
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
24
+ qemu_log_mask(LOG_UNIMP,
29
index XXXXXXX..XXXXXXX 100644
25
+ "smc91c111: EEPROM store not implemented\n");
30
--- a/target/arm/mve.decode
26
+ }
31
+++ b/target/arm/mve.decode
27
+ if (value & 2) {
32
@@ -XXX,XX +XXX,XX @@
28
+ qemu_log_mask(LOG_UNIMP,
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
29
+ "smc91c111: EEPROM reload not implemented\n");
34
%size_28 28:1 !function=plus_1
30
+ }
35
31
value &= ~3;
36
+# 1imm format immediate
32
SET_LOW(ctr, value);
37
+%imm_28_16_0 28:1 16:3 0:4
33
return;
38
+
39
&vldr_vstr rn qd imm p a w size l u
40
&1op qd qm size
41
&2op qd qm qn size
42
&2scalar qd qn rm size
43
+&1imm qd imm cmode op
44
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
46
# Note that both Rn and Qd are 3 bits only (no D bit)
47
@@ -XXX,XX +XXX,XX @@
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
50
size=%size_28
51
+@1imm .... .... .... .... .... cmode:4 .. op:1 . .... &1imm qd=%qd imm=%imm_28_16_0
52
53
# The _rev suffix indicates that Vn and Vm are reversed. This is
54
# the case for shifts. In the Arm ARM these insns are documented
55
@@ -XXX,XX +XXX,XX @@ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rd
56
# Predicate operations
57
%mask_22_13 22:1 13:3
58
VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
59
+
60
+# Logical immediate operations (1 reg and modified-immediate)
61
+
62
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMVN, but
63
+# not in a way we can conveniently represent in decodetree without
64
+# a lot of repetition:
65
+# VORR: op=0, (cmode & 1) && cmode < 12
66
+# VBIC: op=1, (cmode & 1) && cmode < 12
67
+# VMOV: everything else
68
+# So we have a single decode line and check the cmode/op in the
69
+# trans function.
70
+Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
71
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/mve_helper.c
74
+++ b/target/arm/mve_helper.c
75
@@ -XXX,XX +XXX,XX @@ DO_1OP(vnegw, 4, int32_t, DO_NEG)
76
DO_1OP(vfnegh, 8, uint64_t, DO_FNEGH)
77
DO_1OP(vfnegs, 8, uint64_t, DO_FNEGS)
78
79
+/*
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
81
+ * All these insns work at 64-bit widths.
82
+ */
83
+#define DO_1OP_IMM(OP, FN) \
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
85
+ { \
86
+ uint64_t *da = vda; \
87
+ uint16_t mask = mve_element_mask(env); \
88
+ unsigned e; \
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
91
+ } \
92
+ mve_advance_vpt(env); \
93
+ }
94
+
95
+#define DO_MOVI(N, I) (I)
96
+#define DO_ANDI(N, I) ((N) & (I))
97
+#define DO_ORRI(N, I) ((N) | (I))
98
+
99
+DO_1OP_IMM(vmovi, DO_MOVI)
100
+DO_1OP_IMM(vandi, DO_ANDI)
101
+DO_1OP_IMM(vorri, DO_ORRI)
102
+
103
#define DO_2OP(OP, ESIZE, TYPE, FN) \
104
void HELPER(glue(mve_, OP))(CPUARMState *env, \
105
void *vd, void *vn, void *vm) \
106
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-mve.c
109
+++ b/target/arm/translate-mve.c
110
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
111
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
112
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
113
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
114
+typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
115
116
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
117
static inline long mve_qreg_offset(unsigned reg)
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
119
mve_update_eci(s);
120
return true;
121
}
122
+
123
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
124
+{
125
+ TCGv_ptr qd;
126
+ uint64_t imm;
127
+
128
+ if (!dc_isar_feature(aa32_mve, s) ||
129
+ !mve_check_qreg_bank(s, a->qd) ||
130
+ !fn) {
131
+ return false;
132
+ }
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
134
+ return true;
135
+ }
136
+
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
138
+
139
+ qd = mve_qreg_ptr(a->qd);
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
141
+ tcg_temp_free_ptr(qd);
142
+ mve_update_eci(s);
143
+ return true;
144
+}
145
+
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
147
+{
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
149
+ MVEGenOneOpImmFn *fn;
150
+
151
+ if ((a->cmode & 1) && a->cmode < 12) {
152
+ if (a->op) {
153
+ /*
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
155
+ * so the VBIC becomes a logical AND operation.
156
+ */
157
+ fn = gen_helper_mve_vandi;
158
+ } else {
159
+ fn = gen_helper_mve_vorri;
160
+ }
161
+ } else {
162
+ /* There is one unallocated cmode/op combination in this space */
163
+ if (a->cmode == 15 && a->op == 1) {
164
+ return false;
165
+ }
166
+ /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
167
+ fn = gen_helper_mve_vmovi;
168
+ }
169
+ return do_1imm(s, a, fn);
170
+}
34
--
171
--
35
2.17.1
172
2.20.1
36
173
37
174
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
2
2
and VQSHLU.
3
TCMI_VERBOSE is no more used, drop the OMAP_8/16/32B_REG macros.
3
4
4
The size-and-immediate encoding here is the same as Neon, and we
5
Suggested-by: Thomas Huth <thuth@redhat.com>
5
handle it the same way neon-dp.decode does.
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Message-id: 20180624040609.17572-9-f4bug@amsat.org
9
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
10
---
10
---
11
include/hw/arm/omap.h | 18 ------------------
11
target/arm/helper-mve.h | 16 +++++++++++
12
hw/arm/omap1.c | 18 ++++++++++++------
12
target/arm/mve.decode | 23 +++++++++++++++
13
2 files changed, 12 insertions(+), 24 deletions(-)
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
14
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
15
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
15
4 files changed, 147 insertions(+)
16
index XXXXXXX..XXXXXXX 100644
16
17
--- a/include/hw/arm/omap.h
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
18
+++ b/include/hw/arm/omap.h
18
index XXXXXXX..XXXXXXX 100644
19
@@ -XXX,XX +XXX,XX @@ enum {
19
--- a/target/arm/helper-mve.h
20
#define OMAP_GPIOSW_INVERTED    0x0001
20
+++ b/target/arm/helper-mve.h
21
#define OMAP_GPIOSW_OUTPUT    0x0002
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
23
-# define TCMI_VERBOSE            1
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
24
-
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
25
-# ifdef TCMI_VERBOSE
25
+
26
-# define OMAP_8B_REG(paddr)        \
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
- fprintf(stderr, "%s: 8-bit register " OMAP_FMT_plx "\n",    \
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
- __func__, paddr)
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
-# define OMAP_16B_REG(paddr)        \
29
+
30
- fprintf(stderr, "%s: 16-bit register " OMAP_FMT_plx "\n",    \
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
- __func__, paddr)
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
-# define OMAP_32B_REG(paddr)        \
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
- fprintf(stderr, "%s: 32-bit register " OMAP_FMT_plx "\n",    \
33
+
34
- __func__, paddr)
34
+DEF_HELPER_FLAGS_4(mve_vqshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
-# else
35
+DEF_HELPER_FLAGS_4(mve_vqshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
-# define OMAP_8B_REG(paddr)
36
+DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
-# define OMAP_16B_REG(paddr)
37
+
38
-# define OMAP_32B_REG(paddr)
38
+DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
-# endif
39
+DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
-
40
+DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
# define OMAP_MPUI_REG_MASK        0x000007ff
41
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
42
42
index XXXXXXX..XXXXXXX 100644
43
#endif /* hw_omap_h */
43
--- a/target/arm/mve.decode
44
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
44
+++ b/target/arm/mve.decode
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/omap1.c
47
+++ b/hw/arm/omap1.c
48
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@
49
#include "qemu/cutils.h"
46
&2op qd qm qn size
50
#include "qemu/bcd.h"
47
&2scalar qd qn rm size
51
48
&1imm qd imm cmode op
52
+static inline void omap_log_badwidth(const char *funcname, hwaddr addr, int sz)
49
+&2shift qd qm shift size
50
51
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
52
# Note that both Rn and Qd are 3 bits only (no D bit)
53
@@ -XXX,XX +XXX,XX @@
54
@2scalar .... .... .. size:2 .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
55
@2scalar_nosz .... .... .... .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
56
57
+@2_shl_b .... .... .. 001 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
58
+@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
59
+@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
60
+
61
# Vector loads and stores
62
63
# Widening loads and narrowing stores:
64
@@ -XXX,XX +XXX,XX @@ VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
65
# So we have a single decode line and check the cmode/op in the
66
# trans function.
67
Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
68
+
69
+# Shifts by immediate
70
+
71
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
72
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
73
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
74
+
75
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
76
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
77
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
78
+
79
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
80
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
81
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
82
+
83
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
84
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
85
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
86
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/mve_helper.c
89
+++ b/target/arm/mve_helper.c
90
@@ -XXX,XX +XXX,XX @@ DO_2OP_SAT(vqsubsw, 4, int32_t, DO_SQSUB_W)
91
WRAP_QRSHL_HELPER(do_sqrshl_bhs, N, M, true, satp)
92
#define DO_UQRSHL_OP(N, M, satp) \
93
WRAP_QRSHL_HELPER(do_uqrshl_bhs, N, M, true, satp)
94
+#define DO_SUQSHL_OP(N, M, satp) \
95
+ WRAP_QRSHL_HELPER(do_suqrshl_bhs, N, M, false, satp)
96
97
DO_2OP_SAT_S(vqshls, DO_SQSHL_OP)
98
DO_2OP_SAT_U(vqshlu, DO_UQSHL_OP)
99
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvsw, 4, uint32_t)
100
DO_VADDV(vaddvub, 1, uint8_t)
101
DO_VADDV(vaddvuh, 2, uint16_t)
102
DO_VADDV(vaddvuw, 4, uint32_t)
103
+
104
+/* Shifts by immediate */
105
+#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
106
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
107
+ void *vm, uint32_t shift) \
108
+ { \
109
+ TYPE *d = vd, *m = vm; \
110
+ uint16_t mask = mve_element_mask(env); \
111
+ unsigned e; \
112
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
113
+ mergemask(&d[H##ESIZE(e)], \
114
+ FN(m[H##ESIZE(e)], shift), mask); \
115
+ } \
116
+ mve_advance_vpt(env); \
117
+ }
118
+
119
+#define DO_2SHIFT_SAT(OP, ESIZE, TYPE, FN) \
120
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
121
+ void *vm, uint32_t shift) \
122
+ { \
123
+ TYPE *d = vd, *m = vm; \
124
+ uint16_t mask = mve_element_mask(env); \
125
+ unsigned e; \
126
+ bool qc = false; \
127
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
128
+ bool sat = false; \
129
+ mergemask(&d[H##ESIZE(e)], \
130
+ FN(m[H##ESIZE(e)], shift, &sat), mask); \
131
+ qc |= sat & mask & 1; \
132
+ } \
133
+ if (qc) { \
134
+ env->vfp.qc[0] = qc; \
135
+ } \
136
+ mve_advance_vpt(env); \
137
+ }
138
+
139
+/* provide unsigned 2-op shift helpers for all sizes */
140
+#define DO_2SHIFT_U(OP, FN) \
141
+ DO_2SHIFT(OP##b, 1, uint8_t, FN) \
142
+ DO_2SHIFT(OP##h, 2, uint16_t, FN) \
143
+ DO_2SHIFT(OP##w, 4, uint32_t, FN)
144
+
145
+#define DO_2SHIFT_SAT_U(OP, FN) \
146
+ DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
147
+ DO_2SHIFT_SAT(OP##h, 2, uint16_t, FN) \
148
+ DO_2SHIFT_SAT(OP##w, 4, uint32_t, FN)
149
+#define DO_2SHIFT_SAT_S(OP, FN) \
150
+ DO_2SHIFT_SAT(OP##b, 1, int8_t, FN) \
151
+ DO_2SHIFT_SAT(OP##h, 2, int16_t, FN) \
152
+ DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
153
+
154
+DO_2SHIFT_U(vshli_u, DO_VSHLU)
155
+DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
156
+DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
157
+DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
158
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/translate-mve.c
161
+++ b/target/arm/translate-mve.c
162
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
163
typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
164
typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
165
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
166
+typedef void MVEGenTwoOpShiftFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
167
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
168
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
169
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
170
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
171
}
172
return do_1imm(s, a, fn);
173
}
174
+
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
176
+ bool negateshift)
53
+{
177
+{
54
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: %d-bit register %#08" HWADDR_PRIx "\n",
178
+ TCGv_ptr qd, qm;
55
+ funcname, 8 * sz, addr);
179
+ int shift = a->shift;
180
+
181
+ if (!dc_isar_feature(aa32_mve, s) ||
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
183
+ !fn) {
184
+ return false;
185
+ }
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
187
+ return true;
188
+ }
189
+
190
+ /*
191
+ * When we handle a right shift insn using a left-shift helper
192
+ * which permits a negative shift count to indicate a right-shift,
193
+ * we must negate the shift count.
194
+ */
195
+ if (negateshift) {
196
+ shift = -shift;
197
+ }
198
+
199
+ qd = mve_qreg_ptr(a->qd);
200
+ qm = mve_qreg_ptr(a->qm);
201
+ fn(cpu_env, qd, qm, tcg_constant_i32(shift));
202
+ tcg_temp_free_ptr(qd);
203
+ tcg_temp_free_ptr(qm);
204
+ mve_update_eci(s);
205
+ return true;
56
+}
206
+}
57
+
207
+
58
/* Should signal the TCMI/GPMC */
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
59
uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
60
{
210
+ { \
61
uint8_t ret;
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
62
212
+ gen_helper_mve_##FN##b, \
63
- OMAP_8B_REG(addr);
213
+ gen_helper_mve_##FN##h, \
64
+ omap_log_badwidth(__func__, addr, 1);
214
+ gen_helper_mve_##FN##w, \
65
cpu_physical_memory_read(addr, &ret, 1);
215
+ NULL, \
66
return ret;
216
+ }; \
67
}
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
68
@@ -XXX,XX +XXX,XX @@ void omap_badwidth_write8(void *opaque, hwaddr addr,
218
+ }
69
{
219
+
70
uint8_t val8 = value;
220
+DO_2SHIFT(VSHLI, vshli_u, false)
71
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
72
- OMAP_8B_REG(addr);
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
73
+ omap_log_badwidth(__func__, addr, 1);
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
74
cpu_physical_memory_write(addr, &val8, 1);
75
}
76
77
@@ -XXX,XX +XXX,XX @@ uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
78
{
79
uint16_t ret;
80
81
- OMAP_16B_REG(addr);
82
+ omap_log_badwidth(__func__, addr, 2);
83
cpu_physical_memory_read(addr, &ret, 2);
84
return ret;
85
}
86
@@ -XXX,XX +XXX,XX @@ void omap_badwidth_write16(void *opaque, hwaddr addr,
87
{
88
uint16_t val16 = value;
89
90
- OMAP_16B_REG(addr);
91
+ omap_log_badwidth(__func__, addr, 2);
92
cpu_physical_memory_write(addr, &val16, 2);
93
}
94
95
@@ -XXX,XX +XXX,XX @@ uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
96
{
97
uint32_t ret;
98
99
- OMAP_32B_REG(addr);
100
+ omap_log_badwidth(__func__, addr, 4);
101
cpu_physical_memory_read(addr, &ret, 4);
102
return ret;
103
}
104
@@ -XXX,XX +XXX,XX @@ uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
105
void omap_badwidth_write32(void *opaque, hwaddr addr,
106
uint32_t value)
107
{
108
- OMAP_32B_REG(addr);
109
+ omap_log_badwidth(__func__, addr, 4);
110
cpu_physical_memory_write(addr, &value, 4);
111
}
112
113
--
224
--
114
2.17.1
225
2.20.1
115
226
116
227
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Implement the MVE vector shift right by immediate insns VSHRI and
2
VRSHRI. As with Neon, we implement these by using helper functions
3
which perform left shifts but allow negative shift counts to indicate
4
right shifts.
2
5
3
All Aspeed SoC clocks are driven by an input source clock which can
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
have different frequencies : 24MHz or 25MHz, and also, on the Aspeed
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
AST2400 SoC, 48MHz. The H-PLL (CPU) clock is defined from a
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
6
calculation using parameters in the H-PLL Parameter register or from a
9
---
7
predefined set of frequencies if the setting is strapped by hardware
10
target/arm/helper-mve.h | 12 ++++++++++++
8
(Aspeed AST2400 SoC). The other clocks of the SoC are then defined
11
target/arm/translate.h | 20 ++++++++++++++++++++
9
from the H-PLL using dividers.
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(-)
10
17
11
We introduce first the APB clock because it should be used to drive
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
12
the Aspeed timer model.
13
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
16
Message-id: 20180622075700.5923-2-clg@kaod.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
include/hw/misc/aspeed_scu.h | 70 +++++++++++++++++++++--
20
hw/misc/aspeed_scu.c | 106 +++++++++++++++++++++++++++++++++++
21
2 files changed, 172 insertions(+), 4 deletions(-)
22
23
diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
24
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/misc/aspeed_scu.h
20
--- a/target/arm/helper-mve.h
26
+++ b/include/hw/misc/aspeed_scu.h
21
+++ b/target/arm/helper-mve.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSCUState {
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
28
uint32_t hw_strap1;
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
29
uint32_t hw_strap2;
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
30
uint32_t hw_prot_key;
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)
31
+
29
+
32
+ uint32_t clkin;
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+ uint32_t hpll;
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+ uint32_t apb_freq;
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
} AspeedSCUState;
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
#define AST2400_A0_SILICON_REV 0x02000303U
35
DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
@@ -XXX,XX +XXX,XX @@ extern bool is_supported_silicon_rev(uint32_t silicon_rev);
36
DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
* 1. 2012/12/29 Ryan Chen Create
40
*/
41
42
-/* Hardware Strapping Register definition (for Aspeed AST2400 SOC)
43
+/* SCU08 Clock Selection Register
44
+ *
45
+ * 31 Enable Video Engine clock dynamic slow down
46
+ * 30:28 Video Engine clock slow down setting
47
+ * 27 2D Engine GCLK clock source selection
48
+ * 26 2D Engine GCLK clock throttling enable
49
+ * 25:23 APB PCLK divider selection
50
+ * 22:20 LPC Host LHCLK divider selection
51
+ * 19 LPC Host LHCLK clock generation/output enable control
52
+ * 18:16 MAC AHB bus clock divider selection
53
+ * 15 SD/SDIO clock running enable
54
+ * 14:12 SD/SDIO divider selection
55
+ * 11 Reserved
56
+ * 10:8 Video port output clock delay control bit
57
+ * 7 ARM CPU/AHB clock slow down enable
58
+ * 6:4 ARM CPU/AHB clock slow down setting
59
+ * 3:2 ECLK clock source selection
60
+ * 1 CPU/AHB clock slow down idle timer
61
+ * 0 CPU/AHB clock dynamic slow down enable (defined in bit[6:4])
62
+ */
63
+#define SCU_CLK_GET_PCLK_DIV(x) (((x) >> 23) & 0x7)
64
+
37
+
65
+/* SCU24 H-PLL Parameter Register (for Aspeed AST2400 SOC)
38
+DEF_HELPER_FLAGS_4(mve_vrshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
66
+ *
39
+DEF_HELPER_FLAGS_4(mve_vrshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
67
+ * 18 H-PLL parameter selection
40
+DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
68
+ * 0: Select H-PLL by strapping resistors
69
+ * 1: Select H-PLL by the programmed registers (SCU24[17:0])
70
+ * 17 Enable H-PLL bypass mode
71
+ * 16 Turn off H-PLL
72
+ * 10:5 H-PLL Numerator
73
+ * 4 H-PLL Output Divider
74
+ * 3:0 H-PLL Denumerator
75
+ *
76
+ * (Output frequency) = 24MHz * (2-OD) * [(Numerator+2) / (Denumerator+1)]
77
+ */
78
+
41
+
79
+#define SCU_AST2400_H_PLL_PROGRAMMED (0x1 << 18)
42
+DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
80
+#define SCU_AST2400_H_PLL_BYPASS_EN (0x1 << 17)
43
+DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
81
+#define SCU_AST2400_H_PLL_OFF (0x1 << 16)
44
+DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
82
+
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
83
+/* SCU24 H-PLL Parameter Register (for Aspeed AST2500 SOC)
84
+ *
85
+ * 21 Enable H-PLL reset
86
+ * 20 Enable H-PLL bypass mode
87
+ * 19 Turn off H-PLL
88
+ * 18:13 H-PLL Post Divider
89
+ * 12:5 H-PLL Numerator (M)
90
+ * 4:0 H-PLL Denumerator (N)
91
+ *
92
+ * (Output frequency) = CLKIN(24MHz) * [(M+1) / (N+1)] / (P+1)
93
+ *
94
+ * The default frequency is 792Mhz when CLKIN = 24MHz
95
+ */
96
+
97
+#define SCU_H_PLL_BYPASS_EN (0x1 << 20)
98
+#define SCU_H_PLL_OFF (0x1 << 19)
99
+
100
+/* SCU70 Hardware Strapping Register definition (for Aspeed AST2400 SOC)
101
*
102
* 31:29 Software defined strapping registers
103
* 28:27 DRAM size setting (for VGA driver use)
104
@@ -XXX,XX +XXX,XX @@ extern bool is_supported_silicon_rev(uint32_t silicon_rev);
105
#define SCU_AST2400_HW_STRAP_GET_CLK_SOURCE(x) (((((x) >> 23) & 0x1) << 1) \
106
| (((x) >> 18) & 0x1))
107
#define SCU_AST2400_HW_STRAP_CLK_SOURCE_MASK ((0x1 << 23) | (0x1 << 18))
108
-#define AST2400_CLK_25M_IN (0x1 << 23)
109
+#define SCU_HW_STRAP_CLK_25M_IN (0x1 << 23)
110
#define AST2400_CLK_24M_IN 0
111
#define AST2400_CLK_48M_IN 1
112
#define AST2400_CLK_25M_IN_24M_USB_CKI 2
113
#define AST2400_CLK_25M_IN_48M_USB_CKI 3
114
115
+#define SCU_HW_STRAP_CLK_48M_IN (0x1 << 18)
116
#define SCU_HW_STRAP_2ND_BOOT_WDT (0x1 << 17)
117
#define SCU_HW_STRAP_SUPER_IO_CONFIG (0x1 << 16)
118
#define SCU_HW_STRAP_VGA_CLASS_CODE (0x1 << 15)
119
@@ -XXX,XX +XXX,XX @@ extern bool is_supported_silicon_rev(uint32_t silicon_rev);
120
#define AST2400_DIS_BOOT 3
121
122
/*
123
- * Hardware strapping register definition (for Aspeed AST2500 SoC and
124
- * higher)
125
+ * SCU70 Hardware strapping register definition (for Aspeed AST2500
126
+ * SoC and higher)
127
*
128
* 31 Enable SPI Flash Strap Auto Fetch Mode
129
* 30 Enable GPIO Strap Mode
130
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
131
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
132
--- a/hw/misc/aspeed_scu.c
47
--- a/target/arm/translate.h
133
+++ b/hw/misc/aspeed_scu.c
48
+++ b/target/arm/translate.h
134
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_scu_get_random(void)
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
135
return num;
50
return x * 2 + 1;
136
}
51
}
137
52
138
+static void aspeed_scu_set_apb_freq(AspeedSCUState *s)
53
+static inline int rsub_64(DisasContext *s, int x)
139
+{
54
+{
140
+ uint32_t apb_divider;
55
+ return 64 - x;
141
+
142
+ switch (s->silicon_rev) {
143
+ case AST2400_A0_SILICON_REV:
144
+ case AST2400_A1_SILICON_REV:
145
+ apb_divider = 2;
146
+ break;
147
+ case AST2500_A0_SILICON_REV:
148
+ case AST2500_A1_SILICON_REV:
149
+ apb_divider = 4;
150
+ break;
151
+ default:
152
+ g_assert_not_reached();
153
+ }
154
+
155
+ s->apb_freq = s->hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[CLK_SEL]) + 1)
156
+ / apb_divider;
157
+}
56
+}
158
+
57
+
159
static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
58
+static inline int rsub_32(DisasContext *s, int x)
160
{
161
AspeedSCUState *s = ASPEED_SCU(opaque);
162
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
163
case PROT_KEY:
164
s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
165
return;
166
+ case CLK_SEL:
167
+ s->regs[reg] = data;
168
+ aspeed_scu_set_apb_freq(s);
169
+ break;
170
171
case FREQ_CNTR_EVAL:
172
case VGA_SCRATCH1 ... VGA_SCRATCH8:
173
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_scu_ops = {
174
.valid.unaligned = false,
175
};
176
177
+static uint32_t aspeed_scu_get_clkin(AspeedSCUState *s)
178
+{
59
+{
179
+ if (s->hw_strap1 & SCU_HW_STRAP_CLK_25M_IN) {
60
+ return 32 - x;
180
+ return 25000000;
181
+ } else if (s->hw_strap1 & SCU_HW_STRAP_CLK_48M_IN) {
182
+ return 48000000;
183
+ } else {
184
+ return 24000000;
185
+ }
186
+}
61
+}
187
+
62
+
188
+/*
63
+static inline int rsub_16(DisasContext *s, int x)
189
+ * Strapped frequencies for the AST2400 in MHz. They depend on the
190
+ * clkin frequency.
191
+ */
192
+static const uint32_t hpll_ast2400_freqs[][4] = {
193
+ { 384, 360, 336, 408 }, /* 24MHz or 48MHz */
194
+ { 400, 375, 350, 425 }, /* 25MHz */
195
+};
196
+
197
+static uint32_t aspeed_scu_calc_hpll_ast2400(AspeedSCUState *s)
198
+{
64
+{
199
+ uint32_t hpll_reg = s->regs[HPLL_PARAM];
65
+ return 16 - x;
200
+ uint8_t freq_select;
201
+ bool clk_25m_in;
202
+
203
+ if (hpll_reg & SCU_AST2400_H_PLL_OFF) {
204
+ return 0;
205
+ }
206
+
207
+ if (hpll_reg & SCU_AST2400_H_PLL_PROGRAMMED) {
208
+ uint32_t multiplier = 1;
209
+
210
+ if (!(hpll_reg & SCU_AST2400_H_PLL_BYPASS_EN)) {
211
+ uint32_t n = (hpll_reg >> 5) & 0x3f;
212
+ uint32_t od = (hpll_reg >> 4) & 0x1;
213
+ uint32_t d = hpll_reg & 0xf;
214
+
215
+ multiplier = (2 - od) * ((n + 2) / (d + 1));
216
+ }
217
+
218
+ return s->clkin * multiplier;
219
+ }
220
+
221
+ /* HW strapping */
222
+ clk_25m_in = !!(s->hw_strap1 & SCU_HW_STRAP_CLK_25M_IN);
223
+ freq_select = SCU_AST2400_HW_STRAP_GET_H_PLL_CLK(s->hw_strap1);
224
+
225
+ return hpll_ast2400_freqs[clk_25m_in][freq_select] * 1000000;
226
+}
66
+}
227
+
67
+
228
+static uint32_t aspeed_scu_calc_hpll_ast2500(AspeedSCUState *s)
68
+static inline int rsub_8(DisasContext *s, int x)
229
+{
69
+{
230
+ uint32_t hpll_reg = s->regs[HPLL_PARAM];
70
+ return 8 - x;
231
+ uint32_t multiplier = 1;
232
+
233
+ if (hpll_reg & SCU_H_PLL_OFF) {
234
+ return 0;
235
+ }
236
+
237
+ if (!(hpll_reg & SCU_H_PLL_BYPASS_EN)) {
238
+ uint32_t p = (hpll_reg >> 13) & 0x3f;
239
+ uint32_t m = (hpll_reg >> 5) & 0xff;
240
+ uint32_t n = hpll_reg & 0x1f;
241
+
242
+ multiplier = ((m + 1) / (n + 1)) / (p + 1);
243
+ }
244
+
245
+ return s->clkin * multiplier;
246
+}
71
+}
247
+
72
+
248
static void aspeed_scu_reset(DeviceState *dev)
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
249
{
74
{
250
AspeedSCUState *s = ASPEED_SCU(dev);
75
return (dc->features & (1ULL << feature)) != 0;
251
const uint32_t *reset;
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
252
+ uint32_t (*calc_hpll)(AspeedSCUState *s);
77
index XXXXXXX..XXXXXXX 100644
253
78
--- a/target/arm/mve.decode
254
switch (s->silicon_rev) {
79
+++ b/target/arm/mve.decode
255
case AST2400_A0_SILICON_REV:
80
@@ -XXX,XX +XXX,XX @@
256
case AST2400_A1_SILICON_REV:
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
257
reset = ast2400_a0_resets;
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
258
+ calc_hpll = aspeed_scu_calc_hpll_ast2400;
83
259
break;
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
260
case AST2500_A0_SILICON_REV:
85
+%rshift_i5 16:5 !function=rsub_32
261
case AST2500_A1_SILICON_REV:
86
+%rshift_i4 16:4 !function=rsub_16
262
reset = ast2500_a1_resets;
87
+%rshift_i3 16:3 !function=rsub_8
263
+ calc_hpll = aspeed_scu_calc_hpll_ast2500;
264
break;
265
default:
266
g_assert_not_reached();
267
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_reset(DeviceState *dev)
268
s->regs[HW_STRAP1] = s->hw_strap1;
269
s->regs[HW_STRAP2] = s->hw_strap2;
270
s->regs[PROT_KEY] = s->hw_prot_key;
271
+
88
+
272
+ /*
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
273
+ * All registers are set. Now compute the frequencies of the main clocks
90
+ size=0 shift=%rshift_i3
274
+ */
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
275
+ s->clkin = aspeed_scu_get_clkin(s);
92
+ size=1 shift=%rshift_i4
276
+ s->hpll = calc_hpll(s);
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
277
+ aspeed_scu_set_apb_freq(s);
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;
278
}
163
}
279
164
280
static uint32_t aspeed_silicon_revs[] = {
165
-static inline int rsub_64(DisasContext *s, int x)
166
-{
167
- return 64 - x;
168
-}
169
-
170
-static inline int rsub_32(DisasContext *s, int x)
171
-{
172
- return 32 - x;
173
-}
174
-static inline int rsub_16(DisasContext *s, int x)
175
-{
176
- return 16 - x;
177
-}
178
-static inline int rsub_8(DisasContext *s, int x)
179
-{
180
- return 8 - x;
181
-}
182
-
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
184
{
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
281
--
186
--
282
2.17.1
187
2.20.1
283
188
284
189
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
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
We emulate a TLB cache of size SMMU_IOTLB_MAX_SIZE=256.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
It is implemented as a hash table whose key is a combination
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
of the 16b asid and 48b IOVA (Jenkins hash).
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
Entries are invalidated on TLB invalidation commands, either
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
globally, or per asid, or per asid/iova.
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Message-id: 1529653501-15358-4-git-send-email-eric.auger@redhat.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/hw/arm/smmu-common.h | 13 +++++
16
hw/arm/smmu-common.c | 60 ++++++++++++++++++++++
17
hw/arm/smmuv3.c | 98 ++++++++++++++++++++++++++++++++++--
18
hw/arm/trace-events | 9 ++++
19
4 files changed, 176 insertions(+), 4 deletions(-)
20
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/smmu-common.h
18
--- a/target/arm/helper-mve.h
24
+++ b/include/hw/arm/smmu-common.h
19
+++ b/target/arm/helper-mve.h
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
uint8_t tbi; /* Top Byte Ignore */
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
uint16_t asid;
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
SMMUTransTableInfo tt[2];
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+ uint32_t iotlb_hits; /* counts IOTLB hits for this asid */
30
+ uint32_t iotlb_misses; /* counts IOTLB misses for this asid */
31
} SMMUTransCfg;
32
33
typedef struct SMMUDevice {
34
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUPciBus {
35
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
36
} SMMUPciBus;
37
38
+typedef struct SMMUIOTLBKey {
39
+ uint64_t iova;
40
+ uint16_t asid;
41
+} SMMUIOTLBKey;
42
+
24
+
43
typedef struct SMMUState {
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
/* <private> */
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
SysBusDevice dev;
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
@@ -XXX,XX +XXX,XX @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova);
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
/* Return the iommu mr associated to @sid, or NULL if none */
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid);
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
+#define SMMU_IOTLB_MAX_SIZE 256
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
40
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
43
+# VSHLL encoding T2 where shift == esize
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
45
+ qd=%qd qm=%qm size=0 shift=8
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
47
+ qd=%qd qm=%qm size=1 shift=16
51
+
48
+
52
+void smmu_iotlb_inv_all(SMMUState *s);
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
53
+void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid);
50
%rshift_i5 16:5 !function=rsub_32
54
+void smmu_iotlb_inv_iova(SMMUState *s, uint16_t asid, dma_addr_t iova);
51
%rshift_i4 16:4 !function=rsub_16
55
+
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
56
#endif /* HW_ARM_SMMU_COMMON */
53
VSUB 1111 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
57
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
54
VMUL 1110 1111 0 . .. ... 0 ... 0 1001 . 1 . 1 ... 0 @2op
58
index XXXXXXX..XXXXXXX 100644
55
59
--- a/hw/arm/smmu-common.c
56
-VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
60
+++ b/hw/arm/smmu-common.c
57
-VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
61
@@ -XXX,XX +XXX,XX @@
58
+# The VSHLL T2 encoding is not a @2op pattern, but is here because it
62
#include "qom/cpu.h"
59
+# overlaps what would be size=0b11 VMULH/VRMULH
63
#include "hw/qdev-properties.h"
64
#include "qapi/error.h"
65
+#include "qemu/jhash.h"
66
67
#include "qemu/error-report.h"
68
#include "hw/arm/smmu-common.h"
69
#include "smmu-internal.h"
70
71
+/* IOTLB Management */
72
+
73
+inline void smmu_iotlb_inv_all(SMMUState *s)
74
+{
60
+{
75
+ trace_smmu_iotlb_inv_all();
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
76
+ g_hash_table_remove_all(s->iotlb);
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
77
+}
67
+}
78
+
68
+
79
+static gboolean smmu_hash_remove_by_asid(gpointer key, gpointer value,
80
+ gpointer user_data)
81
+{
69
+{
82
+ uint16_t asid = *(uint16_t *)user_data;
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
83
+ SMMUIOTLBKey *iotlb_key = (SMMUIOTLBKey *)key;
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
84
+
72
+
85
+ return iotlb_key->asid == asid;
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
86
+}
74
+}
87
+
75
+
88
+inline void smmu_iotlb_inv_iova(SMMUState *s, uint16_t asid, dma_addr_t iova)
89
+{
76
+{
90
+ SMMUIOTLBKey key = {.asid = asid, .iova = iova};
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
91
+
79
+
92
+ trace_smmu_iotlb_inv_iova(asid, iova);
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
93
+ g_hash_table_remove(s->iotlb, &key);
94
+}
81
+}
95
+
82
+
96
+inline void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
97
+{
83
+{
98
+ trace_smmu_iotlb_inv_asid(asid);
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
99
+ g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_asid, &asid);
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
86
+
87
+ VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
100
+}
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
101
+
96
+
102
/* VMSAv8-64 Translation */
97
+# VSHLL T1 encoding; the T2 VSHLL encoding is elsewhere in this file
103
98
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
104
/**
99
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
105
@@ -XXX,XX +XXX,XX @@ IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid)
106
return NULL;
107
}
108
109
+static guint smmu_iotlb_key_hash(gconstpointer v)
110
+{
111
+ SMMUIOTLBKey *key = (SMMUIOTLBKey *)v;
112
+ uint32_t a, b, c;
113
+
100
+
114
+ /* Jenkins hash */
101
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
115
+ a = b = c = JHASH_INITVAL + sizeof(*key);
102
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
116
+ a += key->asid;
117
+ b += extract64(key->iova, 0, 32);
118
+ c += extract64(key->iova, 32, 32);
119
+
103
+
120
+ __jhash_mix(a, b, c);
104
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
121
+ __jhash_final(a, b, c);
105
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
122
+
106
+
123
+ return c;
107
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
124
+}
108
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
109
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/mve_helper.c
112
+++ b/target/arm/mve_helper.c
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
125
+
117
+
126
+static gboolean smmu_iotlb_key_equal(gconstpointer v1, gconstpointer v2)
118
+/*
127
+{
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
128
+ const SMMUIOTLBKey *k1 = v1;
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
129
+ const SMMUIOTLBKey *k2 = v2;
121
+ * the input, and LESIZE, LTYPE for the output.
130
+
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
131
+ return (k1->asid == k2->asid) && (k1->iova == k2->iova);
123
+ * because the long shift is strictly left-only.
132
+}
124
+ */
133
+
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
134
static void smmu_base_realize(DeviceState *dev, Error **errp)
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
135
{
127
+ void *vm, uint32_t shift) \
136
SMMUState *s = ARM_SMMU(dev);
128
+ { \
137
@@ -XXX,XX +XXX,XX @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
129
+ LTYPE *d = vd; \
138
return;
130
+ TYPE *m = vm; \
139
}
131
+ uint16_t mask = mve_element_mask(env); \
140
s->configs = g_hash_table_new_full(NULL, NULL, NULL, g_free);
132
+ unsigned le; \
141
+ s->iotlb = g_hash_table_new_full(smmu_iotlb_key_hash, smmu_iotlb_key_equal,
133
+ assert(shift <= 16); \
142
+ g_free, g_free);
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
143
s->smmu_pcibus_by_busptr = g_hash_table_new(NULL, NULL);
135
+ LTYPE r = (LTYPE)m[H##ESIZE(le * 2 + TOP)] << shift; \
144
136
+ mergemask(&d[H##LESIZE(le)], r, mask); \
145
if (s->primary_bus) {
137
+ } \
146
@@ -XXX,XX +XXX,XX @@ static void smmu_base_reset(DeviceState *dev)
138
+ mve_advance_vpt(env); \
147
SMMUState *s = ARM_SMMU(dev);
148
149
g_hash_table_remove_all(s->configs);
150
+ g_hash_table_remove_all(s->iotlb);
151
}
152
153
static Property smmu_dev_properties[] = {
154
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
155
index XXXXXXX..XXXXXXX 100644
156
--- a/hw/arm/smmuv3.c
157
+++ b/hw/arm/smmuv3.c
158
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
159
SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid};
160
SMMUPTWEventInfo ptw_info = {};
161
SMMUTranslationStatus status;
162
+ SMMUState *bs = ARM_SMMU(s);
163
+ uint64_t page_mask, aligned_addr;
164
+ IOMMUTLBEntry *cached_entry = NULL;
165
+ SMMUTransTableInfo *tt;
166
SMMUTransCfg *cfg = NULL;
167
IOMMUTLBEntry entry = {
168
.target_as = &address_space_memory,
169
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
170
.addr_mask = ~(hwaddr)0,
171
.perm = IOMMU_NONE,
172
};
173
+ SMMUIOTLBKey key, *new_key;
174
175
qemu_mutex_lock(&s->mutex);
176
177
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
178
goto epilogue;
179
}
180
181
- if (smmu_ptw(cfg, addr, flag, &entry, &ptw_info)) {
182
+ tt = select_tt(cfg, addr);
183
+ if (!tt) {
184
+ if (event.record_trans_faults) {
185
+ event.type = SMMU_EVT_F_TRANSLATION;
186
+ event.u.f_translation.addr = addr;
187
+ event.u.f_translation.rnw = flag & 0x1;
188
+ }
189
+ status = SMMU_TRANS_ERROR;
190
+ goto epilogue;
191
+ }
139
+ }
192
+
140
+
193
+ page_mask = (1ULL << (tt->granule_sz)) - 1;
141
+#define DO_VSHLL_ALL(OP, TOP) \
194
+ aligned_addr = addr & ~page_mask;
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) \
195
+
146
+
196
+ key.asid = cfg->asid;
147
+DO_VSHLL_ALL(vshllb, false)
197
+ key.iova = aligned_addr;
148
+DO_VSHLL_ALL(vshllt, true)
149
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-mve.c
152
+++ b/target/arm/translate-mve.c
153
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_S, vshli_s, true)
154
DO_2SHIFT(VSHRI_U, vshli_u, true)
155
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
198
+
157
+
199
+ cached_entry = g_hash_table_lookup(bs->iotlb, &key);
158
+#define DO_VSHLL(INSN, FN) \
200
+ if (cached_entry) {
159
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
201
+ cfg->iotlb_hits++;
160
+ { \
202
+ trace_smmu_iotlb_cache_hit(cfg->asid, aligned_addr,
161
+ static MVEGenTwoOpShiftFn * const fns[] = { \
203
+ cfg->iotlb_hits, cfg->iotlb_misses,
162
+ gen_helper_mve_##FN##b, \
204
+ 100 * cfg->iotlb_hits /
163
+ gen_helper_mve_##FN##h, \
205
+ (cfg->iotlb_hits + cfg->iotlb_misses));
164
+ }; \
206
+ if ((flag & IOMMU_WO) && !(cached_entry->perm & IOMMU_WO)) {
165
+ return do_2shift(s, a, fns[a->size], false); \
207
+ status = SMMU_TRANS_ERROR;
208
+ if (event.record_trans_faults) {
209
+ event.type = SMMU_EVT_F_PERMISSION;
210
+ event.u.f_permission.addr = addr;
211
+ event.u.f_permission.rnw = flag & 0x1;
212
+ }
213
+ } else {
214
+ status = SMMU_TRANS_SUCCESS;
215
+ }
216
+ goto epilogue;
217
+ }
166
+ }
218
+
167
+
219
+ cfg->iotlb_misses++;
168
+DO_VSHLL(VSHLL_BS, vshllbs)
220
+ trace_smmu_iotlb_cache_miss(cfg->asid, addr & ~page_mask,
169
+DO_VSHLL(VSHLL_BU, vshllbu)
221
+ cfg->iotlb_hits, cfg->iotlb_misses,
170
+DO_VSHLL(VSHLL_TS, vshllts)
222
+ 100 * cfg->iotlb_hits /
171
+DO_VSHLL(VSHLL_TU, vshlltu)
223
+ (cfg->iotlb_hits + cfg->iotlb_misses));
224
+
225
+ if (g_hash_table_size(bs->iotlb) >= SMMU_IOTLB_MAX_SIZE) {
226
+ smmu_iotlb_inv_all(bs);
227
+ }
228
+
229
+ cached_entry = g_new0(IOMMUTLBEntry, 1);
230
+
231
+ if (smmu_ptw(cfg, aligned_addr, flag, cached_entry, &ptw_info)) {
232
+ g_free(cached_entry);
233
switch (ptw_info.type) {
234
case SMMU_PTW_ERR_WALK_EABT:
235
event.type = SMMU_EVT_F_WALK_EABT;
236
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
237
}
238
status = SMMU_TRANS_ERROR;
239
} else {
240
+ new_key = g_new0(SMMUIOTLBKey, 1);
241
+ new_key->asid = cfg->asid;
242
+ new_key->iova = aligned_addr;
243
+ g_hash_table_insert(bs->iotlb, new_key, cached_entry);
244
status = SMMU_TRANS_SUCCESS;
245
}
246
247
@@ -XXX,XX +XXX,XX @@ epilogue:
248
switch (status) {
249
case SMMU_TRANS_SUCCESS:
250
entry.perm = flag;
251
+ entry.translated_addr = cached_entry->translated_addr +
252
+ (addr & page_mask);
253
+ entry.addr_mask = cached_entry->addr_mask;
254
trace_smmuv3_translate_success(mr->parent_obj.name, sid, addr,
255
entry.translated_addr, entry.perm);
256
break;
257
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
258
smmuv3_flush_config(sdev);
259
break;
260
}
261
- case SMMU_CMD_TLBI_NH_ALL:
262
case SMMU_CMD_TLBI_NH_ASID:
263
- case SMMU_CMD_TLBI_NH_VA:
264
+ {
265
+ uint16_t asid = CMD_ASID(&cmd);
266
+
267
+ trace_smmuv3_cmdq_tlbi_nh_asid(asid);
268
+ smmu_iotlb_inv_asid(bs, asid);
269
+ break;
270
+ }
271
+ case SMMU_CMD_TLBI_NH_ALL:
272
+ case SMMU_CMD_TLBI_NSNH_ALL:
273
+ trace_smmuv3_cmdq_tlbi_nh();
274
+ smmu_iotlb_inv_all(bs);
275
+ break;
276
case SMMU_CMD_TLBI_NH_VAA:
277
+ {
278
+ dma_addr_t addr = CMD_ADDR(&cmd);
279
+ uint16_t vmid = CMD_VMID(&cmd);
280
+
281
+ trace_smmuv3_cmdq_tlbi_nh_vaa(vmid, addr);
282
+ smmu_iotlb_inv_all(bs);
283
+ break;
284
+ }
285
+ case SMMU_CMD_TLBI_NH_VA:
286
+ {
287
+ uint16_t asid = CMD_ASID(&cmd);
288
+ uint16_t vmid = CMD_VMID(&cmd);
289
+ dma_addr_t addr = CMD_ADDR(&cmd);
290
+ bool leaf = CMD_LEAF(&cmd);
291
+
292
+ trace_smmuv3_cmdq_tlbi_nh_va(vmid, asid, addr, leaf);
293
+ smmu_iotlb_inv_iova(bs, asid, addr);
294
+ break;
295
+ }
296
case SMMU_CMD_TLBI_EL3_ALL:
297
case SMMU_CMD_TLBI_EL3_VA:
298
case SMMU_CMD_TLBI_EL2_ALL:
299
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
300
case SMMU_CMD_TLBI_EL2_VAA:
301
case SMMU_CMD_TLBI_S12_VMALL:
302
case SMMU_CMD_TLBI_S2_IPA:
303
- case SMMU_CMD_TLBI_NSNH_ALL:
304
case SMMU_CMD_ATC_INV:
305
case SMMU_CMD_PRI_RESP:
306
case SMMU_CMD_RESUME:
307
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
308
index XXXXXXX..XXXXXXX 100644
309
--- a/hw/arm/trace-events
310
+++ b/hw/arm/trace-events
311
@@ -XXX,XX +XXX,XX @@ smmu_ptw_invalid_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr,
312
smmu_ptw_page_pte(int stage, int level, uint64_t iova, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t address) "stage=%d level=%d iova=0x%"PRIx64" base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" page address = 0x%"PRIx64
313
smmu_ptw_block_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t iova, uint64_t gpa, int bsize_mb) "stage=%d level=%d base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" iova=0x%"PRIx64" block address = 0x%"PRIx64" block size = %d MiB"
314
smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte) "baseaddr=0x%"PRIx64" index=0x%x, pteaddr=0x%"PRIx64", pte=0x%"PRIx64
315
+smmu_iotlb_cache_hit(uint16_t asid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache HIT asid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
316
+smmu_iotlb_cache_miss(uint16_t asid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache MISS asid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
317
+smmu_iotlb_inv_all(void) "IOTLB invalidate all"
318
+smmu_iotlb_inv_asid(uint16_t asid) "IOTLB invalidate asid=%d"
319
+smmu_iotlb_inv_iova(uint16_t asid, uint64_t addr) "IOTLB invalidate asid=%d addr=0x%"PRIx64
320
321
#hw/arm/smmuv3.c
322
smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
323
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_cfgi_ste_range(int start, int end) "start=0x%d - end=0x%d"
324
smmuv3_cmdq_cfgi_cd(uint32_t sid) "streamid = %d"
325
smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid %d (hits=%d, misses=%d, hit rate=%d)"
326
smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid %d (hits=%d, misses=%d, hit rate=%d)"
327
+smmuv3_cmdq_tlbi_nh_va(int vmid, int asid, uint64_t addr, bool leaf) "vmid =%d asid =%d addr=0x%"PRIx64" leaf=%d"
328
+smmuv3_cmdq_tlbi_nh_vaa(int vmid, uint64_t addr) "vmid =%d addr=0x%"PRIx64
329
+smmuv3_cmdq_tlbi_nh(void) ""
330
+smmuv3_cmdq_tlbi_nh_asid(uint16_t asid) "asid=%d"
331
smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid %d"
332
--
172
--
333
2.17.1
173
2.20.1
334
174
335
175
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Implement the MVE VSRI and VSLI insns, which perform a
2
shift-and-insert operation.
2
3
3
When configured in dual I/O mode, address and data are sent in dual
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
mode, including the dummy byte cycles in between. Adapt the count to
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
the IO setting.
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(+)
6
13
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
9
Message-id: 20180612065716.10587-2-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/ssi/aspeed_smc.c | 9 ++++++++-
13
1 file changed, 8 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/aspeed_smc.c
16
--- a/target/arm/helper-mve.h
18
+++ b/hw/ssi/aspeed_smc.c
17
+++ b/target/arm/helper-mve.h
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
/* CEx Control Register */
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
#define R_CTRL0 (0x10 / 4)
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
+#define CTRL_IO_DUAL_DATA (1 << 29)
22
+
24
+#define CTRL_IO_DUAL_ADDR_DATA (1 << 28) /* Includes dummies */
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
#define CTRL_CMD_SHIFT 16
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
#define CTRL_CMD_MASK 0xff
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
#define CTRL_DUMMY_HIGH_SHIFT 14
26
+
28
@@ -XXX,XX +XXX,XX @@ static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->id];
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
32
+ uint32_t dummies = ((dummy_high << 2) | dummy_low) * 8;
31
index XXXXXXX..XXXXXXX 100644
33
32
--- a/target/arm/mve.decode
34
- return ((dummy_high << 2) | dummy_low) * 8;
33
+++ b/target/arm/mve.decode
35
+ if (r_ctrl0 & CTRL_IO_DUAL_ADDR_DATA) {
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
36
+ dummies /= 2;
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); \
37
+ }
83
+ }
38
+
84
+
39
+ return dummies;
85
+#define DO_SHL(N, SHIFT) ((N) << (SHIFT))
40
}
86
+#define DO_SHR(N, SHIFT) ((N) >> (SHIFT))
41
87
+#define SHL_MASK(EBITS, SHIFT) MAKE_64BIT_MASK((SHIFT), (EBITS) - (SHIFT))
42
static void aspeed_smc_flash_send_addr(AspeedSMCFlash *fl, uint32_t addr)
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
{ \
43
--
114
--
44
2.17.1
115
2.20.1
45
116
46
117
diff view generated by jsdifflib
1
Add support for MMU protection regions that are smaller than
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
2
TARGET_PAGE_SIZE. We do this by marking the TLB entry for those
3
pages with a flag TLB_RECHECK. This flag causes us to always
4
take the slow-path for accesses. In the slow path we can then
5
special case them to always call tlb_fill() again, so we have
6
the correct information for the exact address being accessed.
7
2
8
This change allows us to handle reading and writing from small
3
do_urshr() is borrowed from sve_helper.c.
9
regions; we cannot deal with execution from the small region.
10
4
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20180620130619.11362-2-peter.maydell@linaro.org
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
14
---
8
---
15
accel/tcg/softmmu_template.h | 24 ++++---
9
target/arm/helper-mve.h | 10 ++++++++++
16
include/exec/cpu-all.h | 5 +-
10
target/arm/mve.decode | 11 +++++++++++
17
accel/tcg/cputlb.c | 131 +++++++++++++++++++++++++++++------
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
18
3 files changed, 130 insertions(+), 30 deletions(-)
12
target/arm/translate-mve.c | 15 ++++++++++++++
13
4 files changed, 76 insertions(+)
19
14
20
diff --git a/accel/tcg/softmmu_template.h b/accel/tcg/softmmu_template.h
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/accel/tcg/softmmu_template.h
17
--- a/target/arm/helper-mve.h
23
+++ b/accel/tcg/softmmu_template.h
18
+++ b/target/arm/helper-mve.h
24
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
size_t mmu_idx, size_t index,
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
target_ulong addr,
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
- uintptr_t retaddr)
23
+
29
+ uintptr_t retaddr,
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+ bool recheck)
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
{
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
- return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, DATA_SIZE);
28
+
34
+ return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, recheck,
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+ DATA_SIZE);
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
}
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
#endif
32
+DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
39
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
40
41
/* ??? Note that the io helpers always read data in the target
42
byte ordering. We should push the LE/BE request down into io. */
43
- res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
44
+ res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr,
45
+ tlb_addr & TLB_RECHECK);
46
res = TGT_LE(res);
47
return res;
48
}
49
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
50
51
/* ??? Note that the io helpers always read data in the target
52
byte ordering. We should push the LE/BE request down into io. */
53
- res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
54
+ res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr,
55
+ tlb_addr & TLB_RECHECK);
56
res = TGT_BE(res);
57
return res;
58
}
59
@@ -XXX,XX +XXX,XX @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
60
size_t mmu_idx, size_t index,
61
DATA_TYPE val,
62
target_ulong addr,
63
- uintptr_t retaddr)
64
+ uintptr_t retaddr,
65
+ bool recheck)
66
{
67
CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
68
- return io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr, DATA_SIZE);
69
+ return io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr,
70
+ recheck, DATA_SIZE);
71
}
72
73
void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
74
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
75
/* ??? Note that the io helpers always read data in the target
76
byte ordering. We should push the LE/BE request down into io. */
77
val = TGT_LE(val);
78
- glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr);
79
+ glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr,
80
+ retaddr, tlb_addr & TLB_RECHECK);
81
return;
82
}
83
84
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
85
/* ??? Note that the io helpers always read data in the target
86
byte ordering. We should push the LE/BE request down into io. */
87
val = TGT_BE(val);
88
- glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr);
89
+ glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr,
90
+ tlb_addr & TLB_RECHECK);
91
return;
92
}
93
94
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
95
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
96
--- a/include/exec/cpu-all.h
35
--- a/target/arm/mve.decode
97
+++ b/include/exec/cpu-all.h
36
+++ b/target/arm/mve.decode
98
@@ -XXX,XX +XXX,XX @@ CPUArchState *cpu_copy(CPUArchState *env);
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
99
#define TLB_NOTDIRTY (1 << (TARGET_PAGE_BITS - 2))
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
100
/* Set if TLB entry is an IO callback. */
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
101
#define TLB_MMIO (1 << (TARGET_PAGE_BITS - 3))
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
102
+/* Set if TLB entry must have MMU lookup repeated for every access */
41
+
103
+#define TLB_RECHECK (1 << (TARGET_PAGE_BITS - 4))
42
+# Narrowing shifts (which only support b and h sizes)
104
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
105
/* Use this mask to check interception with an alignment mask
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
106
* in a TCG backend.
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
107
*/
46
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
108
-#define TLB_FLAGS_MASK (TLB_INVALID_MASK | TLB_NOTDIRTY | TLB_MMIO)
47
+
109
+#define TLB_FLAGS_MASK (TLB_INVALID_MASK | TLB_NOTDIRTY | TLB_MMIO \
48
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
110
+ | TLB_RECHECK)
49
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
111
50
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
112
void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
51
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
113
void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf);
52
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
114
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
115
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
116
--- a/accel/tcg/cputlb.c
54
--- a/target/arm/mve_helper.c
117
+++ b/accel/tcg/cputlb.c
55
+++ b/target/arm/mve_helper.c
118
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
119
target_ulong code_address;
57
120
uintptr_t addend;
58
DO_VSHLL_ALL(vshllb, false)
121
CPUTLBEntry *te, *tv, tn;
59
DO_VSHLL_ALL(vshllt, true)
122
- hwaddr iotlb, xlat, sz;
123
+ hwaddr iotlb, xlat, sz, paddr_page;
124
+ target_ulong vaddr_page;
125
unsigned vidx = env->vtlb_index++ % CPU_VTLB_SIZE;
126
int asidx = cpu_asidx_from_attrs(cpu, attrs);
127
128
assert_cpu_is_self(cpu);
129
- assert(size >= TARGET_PAGE_SIZE);
130
- if (size != TARGET_PAGE_SIZE) {
131
- tlb_add_large_page(env, vaddr, size);
132
- }
133
134
- sz = size;
135
- section = address_space_translate_for_iotlb(cpu, asidx, paddr, &xlat, &sz,
136
- attrs, &prot);
137
+ if (size < TARGET_PAGE_SIZE) {
138
+ sz = TARGET_PAGE_SIZE;
139
+ } else {
140
+ if (size > TARGET_PAGE_SIZE) {
141
+ tlb_add_large_page(env, vaddr, size);
142
+ }
143
+ sz = size;
144
+ }
145
+ vaddr_page = vaddr & TARGET_PAGE_MASK;
146
+ paddr_page = paddr & TARGET_PAGE_MASK;
147
+
60
+
148
+ section = address_space_translate_for_iotlb(cpu, asidx, paddr_page,
61
+/*
149
+ &xlat, &sz, attrs, &prot);
62
+ * Narrowing right shifts, taking a double sized input, shifting it
150
assert(sz >= TARGET_PAGE_SIZE);
63
+ * and putting the result in either the top or bottom half of the output.
151
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
152
tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
65
+ */
153
" prot=%x idx=%d\n",
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
154
vaddr, paddr, prot, mmu_idx);
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
155
68
+ void *vm, uint32_t shift) \
156
- address = vaddr;
69
+ { \
157
- if (!memory_region_is_ram(section->mr) && !memory_region_is_romd(section->mr)) {
70
+ LTYPE *m = vm; \
158
+ address = vaddr_page;
71
+ TYPE *d = vd; \
159
+ if (size < TARGET_PAGE_SIZE) {
72
+ uint16_t mask = mve_element_mask(env); \
160
+ /*
73
+ unsigned le; \
161
+ * Slow-path the TLB entries; we will repeat the MMU check and TLB
74
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
162
+ * fill on every access.
75
+ TYPE r = FN(m[H##LESIZE(le)], shift); \
163
+ */
76
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
164
+ address |= TLB_RECHECK;
77
+ } \
165
+ }
78
+ mve_advance_vpt(env); \
166
+ if (!memory_region_is_ram(section->mr) &&
167
+ !memory_region_is_romd(section->mr)) {
168
/* IO memory case */
169
address |= TLB_MMIO;
170
addend = 0;
171
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
172
}
173
174
code_address = address;
175
- iotlb = memory_region_section_get_iotlb(cpu, section, vaddr, paddr, xlat,
176
- prot, &address);
177
+ iotlb = memory_region_section_get_iotlb(cpu, section, vaddr_page,
178
+ paddr_page, xlat, prot, &address);
179
180
- index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
181
+ index = (vaddr_page >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
182
te = &env->tlb_table[mmu_idx][index];
183
/* do not discard the translation in te, evict it into a victim tlb */
184
tv = &env->tlb_v_table[mmu_idx][vidx];
185
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
186
* TARGET_PAGE_BITS, and either
187
* + the ram_addr_t of the page base of the target RAM (if NOTDIRTY or ROM)
188
* + the offset within section->mr of the page base (otherwise)
189
- * We subtract the vaddr (which is page aligned and thus won't
190
+ * We subtract the vaddr_page (which is page aligned and thus won't
191
* disturb the low bits) to give an offset which can be added to the
192
* (non-page-aligned) vaddr of the eventual memory access to get
193
* the MemoryRegion offset for the access. Note that the vaddr we
194
* subtract here is that of the page base, and not the same as the
195
* vaddr we add back in io_readx()/io_writex()/get_page_addr_code().
196
*/
197
- env->iotlb[mmu_idx][index].addr = iotlb - vaddr;
198
+ env->iotlb[mmu_idx][index].addr = iotlb - vaddr_page;
199
env->iotlb[mmu_idx][index].attrs = attrs;
200
201
/* Now calculate the new entry */
202
- tn.addend = addend - vaddr;
203
+ tn.addend = addend - vaddr_page;
204
if (prot & PAGE_READ) {
205
tn.addr_read = address;
206
} else {
207
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
208
tn.addr_write = address | TLB_MMIO;
209
} else if (memory_region_is_ram(section->mr)
210
&& cpu_physical_memory_is_clean(
211
- memory_region_get_ram_addr(section->mr) + xlat)) {
212
+ memory_region_get_ram_addr(section->mr) + xlat)) {
213
tn.addr_write = address | TLB_NOTDIRTY;
214
} else {
215
tn.addr_write = address;
216
@@ -XXX,XX +XXX,XX @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
217
218
static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
219
int mmu_idx,
220
- target_ulong addr, uintptr_t retaddr, int size)
221
+ target_ulong addr, uintptr_t retaddr,
222
+ bool recheck, int size)
223
{
224
CPUState *cpu = ENV_GET_CPU(env);
225
hwaddr mr_offset;
226
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
227
bool locked = false;
228
MemTxResult r;
229
230
+ if (recheck) {
231
+ /*
232
+ * This is a TLB_RECHECK access, where the MMU protection
233
+ * covers a smaller range than a target page, and we must
234
+ * repeat the MMU check here. This tlb_fill() call might
235
+ * longjump out if this access should cause a guest exception.
236
+ */
237
+ int index;
238
+ target_ulong tlb_addr;
239
+
240
+ tlb_fill(cpu, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
241
+
242
+ index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
243
+ tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
244
+ if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
245
+ /* RAM access */
246
+ uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;
247
+
248
+ return ldn_p((void *)haddr, size);
249
+ }
250
+ /* Fall through for handling IO accesses */
251
+ }
79
+ }
252
+
80
+
253
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
81
+#define DO_VSHRN_ALL(OP, FN) \
254
mr = section->mr;
82
+ DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
255
mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
83
+ DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
256
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
84
+ DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
257
static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
85
+ DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
258
int mmu_idx,
259
uint64_t val, target_ulong addr,
260
- uintptr_t retaddr, int size)
261
+ uintptr_t retaddr, bool recheck, int size)
262
{
263
CPUState *cpu = ENV_GET_CPU(env);
264
hwaddr mr_offset;
265
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
266
bool locked = false;
267
MemTxResult r;
268
269
+ if (recheck) {
270
+ /*
271
+ * This is a TLB_RECHECK access, where the MMU protection
272
+ * covers a smaller range than a target page, and we must
273
+ * repeat the MMU check here. This tlb_fill() call might
274
+ * longjump out if this access should cause a guest exception.
275
+ */
276
+ int index;
277
+ target_ulong tlb_addr;
278
+
86
+
279
+ tlb_fill(cpu, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
88
+{
89
+ if (likely(sh < 64)) {
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
91
+ } else if (sh == 64) {
92
+ return x >> 63;
93
+ } else {
94
+ return 0;
95
+ }
96
+}
280
+
97
+
281
+ index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
282
+ tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
283
+ if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
284
+ /* RAM access */
101
index XXXXXXX..XXXXXXX 100644
285
+ uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_VSHLL(VSHLL_BS, vshllbs)
105
DO_VSHLL(VSHLL_BU, vshllbu)
106
DO_VSHLL(VSHLL_TS, vshllts)
107
DO_VSHLL(VSHLL_TU, vshlltu)
286
+
108
+
287
+ stn_p((void *)haddr, size, val);
109
+#define DO_2SHIFT_N(INSN, FN) \
288
+ return;
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
289
+ }
111
+ { \
290
+ /* Fall through for handling IO accesses */
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); \
291
+ }
117
+ }
292
+
118
+
293
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
294
mr = section->mr;
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
295
mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
296
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
297
tlb_fill(ENV_GET_CPU(env), addr, 0, MMU_INST_FETCH, mmu_idx, 0);
298
}
299
}
300
+
301
+ if (unlikely(env->tlb_table[mmu_idx][index].addr_code & TLB_RECHECK)) {
302
+ /*
303
+ * This is a TLB_RECHECK access, where the MMU protection
304
+ * covers a smaller range than a target page, and we must
305
+ * repeat the MMU check here. This tlb_fill() call might
306
+ * longjump out if this access should cause a guest exception.
307
+ */
308
+ int index;
309
+ target_ulong tlb_addr;
310
+
311
+ tlb_fill(cpu, addr, 0, MMU_INST_FETCH, mmu_idx, 0);
312
+
313
+ index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
314
+ tlb_addr = env->tlb_table[mmu_idx][index].addr_code;
315
+ if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
316
+ /* RAM access. We can't handle this, so for now just stop */
317
+ cpu_abort(cpu, "Unable to handle guest executing from RAM within "
318
+ "a small MPU region at 0x" TARGET_FMT_lx, addr);
319
+ }
320
+ /*
321
+ * Fall through to handle IO accesses (which will almost certainly
322
+ * also result in failure)
323
+ */
324
+ }
325
+
326
iotlbentry = &env->iotlb[mmu_idx][index];
327
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
328
mr = section->mr;
329
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
330
tlb_addr = tlbe->addr_write & ~TLB_INVALID_MASK;
331
}
332
333
- /* Notice an IO access */
334
- if (unlikely(tlb_addr & TLB_MMIO)) {
335
+ /* Notice an IO access or a needs-MMU-lookup access */
336
+ if (unlikely(tlb_addr & (TLB_MMIO | TLB_RECHECK))) {
337
/* There's really nothing that can be done to
338
support this apart from stop-the-world. */
339
goto stop_the_world;
340
--
123
--
341
2.17.1
124
2.20.1
342
125
343
126
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Implement the MVE saturating shift-right-and-narrow insns
2
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
On TLB invalidation commands, let's call registered
3
4
IOMMU notifiers. Those can only be UNMAP notifiers.
4
do_srshr() is borrowed from sve_helper.c.
5
SMMUv3 does not support notification on MAP (VFIO).
5
6
7
This patch allows vhost use case where IOTLB API is notified
8
on each guest IOTLB invalidation.
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1529653501-15358-5-git-send-email-eric.auger@redhat.com
13
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
14
---
9
---
15
include/hw/arm/smmu-common.h | 6 +++
10
target/arm/helper-mve.h | 30 +++++++++++
16
hw/arm/smmu-common.c | 34 +++++++++++++
11
target/arm/mve.decode | 28 ++++++++++
17
hw/arm/smmuv3.c | 99 +++++++++++++++++++++++++++++++++++-
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
18
hw/arm/trace-events | 5 ++
13
target/arm/translate-mve.c | 12 +++++
19
4 files changed, 142 insertions(+), 2 deletions(-)
14
4 files changed, 174 insertions(+)
20
15
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/smmu-common.h
18
--- a/target/arm/helper-mve.h
24
+++ b/include/hw/arm/smmu-common.h
19
+++ b/target/arm/helper-mve.h
25
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_inv_all(SMMUState *s);
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid);
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
void smmu_iotlb_inv_iova(SMMUState *s, uint16_t asid, dma_addr_t iova);
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+/* Unmap the range of all the notifiers registered to any IOMMU mr */
24
+
30
+void smmu_inv_notifiers_all(SMMUState *s);
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+/* Unmap the range of all the notifiers registered to @mr */
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr);
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+
29
+
35
#endif /* HW_ARM_SMMU_COMMON */
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
index XXXXXXX..XXXXXXX 100644
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
--- a/hw/arm/smmu-common.c
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+++ b/hw/arm/smmu-common.c
34
+
40
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_iotlb_key_equal(gconstpointer v1, gconstpointer v2)
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
return (k1->asid == k2->asid) && (k1->iova == k2->iova);
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/mve.decode
57
+++ b/target/arm/mve.decode
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
62
+
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
68
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
69
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
70
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
71
+
72
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
73
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
74
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
75
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
76
+
77
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
78
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
79
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
80
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
81
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
82
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
83
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
84
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
85
+
86
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
87
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
88
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
89
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
90
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/mve_helper.c
93
+++ b/target/arm/mve_helper.c
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
95
}
42
}
96
}
43
97
44
+/* Unmap the whole notifier's range */
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
45
+static void smmu_unmap_notifier_range(IOMMUNotifier *n)
46
+{
99
+{
47
+ IOMMUTLBEntry entry;
100
+ if (likely(sh < 64)) {
48
+
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
49
+ entry.target_as = &address_space_memory;
102
+ } else {
50
+ entry.iova = n->start;
103
+ /* Rounding the sign bit always produces 0. */
51
+ entry.perm = IOMMU_NONE;
104
+ return 0;
52
+ entry.addr_mask = n->end - n->start;
53
+
54
+ memory_region_notify_one(n, &entry);
55
+}
56
+
57
+/* Unmap all notifiers attached to @mr */
58
+inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
59
+{
60
+ IOMMUNotifier *n;
61
+
62
+ trace_smmu_inv_notifiers_mr(mr->parent_obj.name);
63
+ IOMMU_NOTIFIER_FOREACH(n, mr) {
64
+ smmu_unmap_notifier_range(n);
65
+ }
105
+ }
66
+}
106
+}
67
+
107
+
68
+/* Unmap all notifiers of all mr's */
108
DO_VSHRN_ALL(vshrn, DO_SHR)
69
+void smmu_inv_notifiers_all(SMMUState *s)
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)
70
+{
113
+{
71
+ SMMUNotifierNode *node;
114
+ if (val > max) {
72
+
115
+ *satp = true;
73
+ QLIST_FOREACH(node, &s->notifiers_list, next) {
116
+ return max;
74
+ smmu_inv_notifiers_mr(&node->sdev->iommu);
117
+ } else if (val < min) {
118
+ *satp = true;
119
+ return min;
120
+ } else {
121
+ return val;
75
+ }
122
+ }
76
+}
123
+}
77
+
124
+
78
static void smmu_base_realize(DeviceState *dev, Error **errp)
125
+/* Saturating narrowing right shifts */
79
{
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
80
SMMUState *s = ARM_SMMU(dev);
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
81
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
128
+ void *vm, uint32_t shift) \
82
index XXXXXXX..XXXXXXX 100644
129
+ { \
83
--- a/hw/arm/smmuv3.c
130
+ LTYPE *m = vm; \
84
+++ b/hw/arm/smmuv3.c
131
+ TYPE *d = vd; \
85
@@ -XXX,XX +XXX,XX @@ epilogue:
132
+ uint16_t mask = mve_element_mask(env); \
86
return entry;
133
+ bool qc = false; \
87
}
134
+ unsigned le; \
88
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
89
+/**
136
+ bool sat = false; \
90
+ * smmuv3_notify_iova - call the notifier @n for a given
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
91
+ * @asid and @iova tuple.
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
92
+ *
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
93
+ * @mr: IOMMU mr region handle
140
+ } \
94
+ * @n: notifier to be called
141
+ if (qc) { \
95
+ * @asid: address space ID or negative value if we don't care
142
+ env->vfp.qc[0] = qc; \
96
+ * @iova: iova
143
+ } \
97
+ */
144
+ mve_advance_vpt(env); \
98
+static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
99
+ IOMMUNotifier *n,
100
+ int asid,
101
+ dma_addr_t iova)
102
+{
103
+ SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
104
+ SMMUEventInfo event = {};
105
+ SMMUTransTableInfo *tt;
106
+ SMMUTransCfg *cfg;
107
+ IOMMUTLBEntry entry;
108
+
109
+ cfg = smmuv3_get_config(sdev, &event);
110
+ if (!cfg) {
111
+ qemu_log_mask(LOG_GUEST_ERROR,
112
+ "%s error decoding the configuration for iommu mr=%s\n",
113
+ __func__, mr->parent_obj.name);
114
+ return;
115
+ }
145
+ }
116
+
146
+
117
+ if (asid >= 0 && cfg->asid != asid) {
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
118
+ return;
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
119
+ }
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
120
+
150
+
121
+ tt = select_tt(cfg, iova);
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
122
+ if (!tt) {
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
123
+ return;
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
124
+ }
154
+
125
+
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
126
+ entry.target_as = &address_space_memory;
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
127
+ entry.iova = iova;
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
128
+ entry.addr_mask = (1 << tt->granule_sz) - 1;
158
+
129
+ entry.perm = IOMMU_NONE;
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
130
+
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
131
+ memory_region_notify_one(n, &entry);
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
132
+}
162
+
133
+
163
+#define DO_SHRN_SB(N, M, SATP) \
134
+/* invalidate an asid/iova tuple in all mr's */
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
135
+static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
165
+#define DO_SHRN_UB(N, M, SATP) \
136
+{
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
137
+ SMMUNotifierNode *node;
167
+#define DO_SHRUN_B(N, M, SATP) \
138
+
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
139
+ QLIST_FOREACH(node, &s->notifiers_list, next) {
169
+
140
+ IOMMUMemoryRegion *mr = &node->sdev->iommu;
170
+#define DO_SHRN_SH(N, M, SATP) \
141
+ IOMMUNotifier *n;
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
142
+
172
+#define DO_SHRN_UH(N, M, SATP) \
143
+ trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
144
+
174
+#define DO_SHRUN_H(N, M, SATP) \
145
+ IOMMU_NOTIFIER_FOREACH(n, mr) {
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
146
+ smmuv3_notify_iova(mr, n, asid, iova);
176
+
147
+ }
177
+#define DO_RSHRN_SB(N, M, SATP) \
148
+ }
178
+ do_sat_bhs(do_srshr(N, M), INT8_MIN, INT8_MAX, SATP)
149
+}
179
+#define DO_RSHRN_UB(N, M, SATP) \
150
+
180
+ do_sat_bhs(do_urshr(N, M), 0, UINT8_MAX, SATP)
151
static int smmuv3_cmdq_consume(SMMUv3State *s)
181
+#define DO_RSHRUN_B(N, M, SATP) \
152
{
182
+ do_sat_bhs(do_srshr(N, M), 0, UINT8_MAX, SATP)
153
SMMUState *bs = ARM_SMMU(s);
183
+
154
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
184
+#define DO_RSHRN_SH(N, M, SATP) \
155
uint16_t asid = CMD_ASID(&cmd);
185
+ do_sat_bhs(do_srshr(N, M), INT16_MIN, INT16_MAX, SATP)
156
186
+#define DO_RSHRN_UH(N, M, SATP) \
157
trace_smmuv3_cmdq_tlbi_nh_asid(asid);
187
+ do_sat_bhs(do_urshr(N, M), 0, UINT16_MAX, SATP)
158
+ smmu_inv_notifiers_all(&s->smmu_state);
188
+#define DO_RSHRUN_H(N, M, SATP) \
159
smmu_iotlb_inv_asid(bs, asid);
189
+ do_sat_bhs(do_srshr(N, M), 0, UINT16_MAX, SATP)
160
break;
190
+
161
}
191
+DO_VSHRN_SAT_SB(vqshrnb_sb, vqshrnt_sb, DO_SHRN_SB)
162
case SMMU_CMD_TLBI_NH_ALL:
192
+DO_VSHRN_SAT_SH(vqshrnb_sh, vqshrnt_sh, DO_SHRN_SH)
163
case SMMU_CMD_TLBI_NSNH_ALL:
193
+DO_VSHRN_SAT_UB(vqshrnb_ub, vqshrnt_ub, DO_SHRN_UB)
164
trace_smmuv3_cmdq_tlbi_nh();
194
+DO_VSHRN_SAT_UH(vqshrnb_uh, vqshrnt_uh, DO_SHRN_UH)
165
+ smmu_inv_notifiers_all(&s->smmu_state);
195
+DO_VSHRN_SAT_SB(vqshrunbb, vqshruntb, DO_SHRUN_B)
166
smmu_iotlb_inv_all(bs);
196
+DO_VSHRN_SAT_SH(vqshrunbh, vqshrunth, DO_SHRUN_H)
167
break;
197
+
168
case SMMU_CMD_TLBI_NH_VAA:
198
+DO_VSHRN_SAT_SB(vqrshrnb_sb, vqrshrnt_sb, DO_RSHRN_SB)
169
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
199
+DO_VSHRN_SAT_SH(vqrshrnb_sh, vqrshrnt_sh, DO_RSHRN_SH)
170
uint16_t vmid = CMD_VMID(&cmd);
200
+DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
171
201
+DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
172
trace_smmuv3_cmdq_tlbi_nh_vaa(vmid, addr);
202
+DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
173
+ smmuv3_inv_notifiers_iova(bs, -1, addr);
203
+DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
174
smmu_iotlb_inv_all(bs);
204
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
175
break;
205
index XXXXXXX..XXXXXXX 100644
176
}
206
--- a/target/arm/translate-mve.c
177
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
207
+++ b/target/arm/translate-mve.c
178
bool leaf = CMD_LEAF(&cmd);
208
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VSHRNB, vshrnb)
179
209
DO_2SHIFT_N(VSHRNT, vshrnt)
180
trace_smmuv3_cmdq_tlbi_nh_va(vmid, asid, addr, leaf);
210
DO_2SHIFT_N(VRSHRNB, vrshrnb)
181
+ smmuv3_inv_notifiers_iova(bs, asid, addr);
211
DO_2SHIFT_N(VRSHRNT, vrshrnt)
182
smmu_iotlb_inv_iova(bs, asid, addr);
212
+DO_2SHIFT_N(VQSHRNB_S, vqshrnb_s)
183
break;
213
+DO_2SHIFT_N(VQSHRNT_S, vqshrnt_s)
184
}
214
+DO_2SHIFT_N(VQSHRNB_U, vqshrnb_u)
185
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
215
+DO_2SHIFT_N(VQSHRNT_U, vqshrnt_u)
186
IOMMUNotifierFlag old,
216
+DO_2SHIFT_N(VQSHRUNB, vqshrunb)
187
IOMMUNotifierFlag new)
217
+DO_2SHIFT_N(VQSHRUNT, vqshrunt)
188
{
218
+DO_2SHIFT_N(VQRSHRNB_S, vqrshrnb_s)
189
+ SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
219
+DO_2SHIFT_N(VQRSHRNT_S, vqrshrnt_s)
190
+ SMMUv3State *s3 = sdev->smmu;
220
+DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
191
+ SMMUState *s = &(s3->smmu_state);
221
+DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
192
+ SMMUNotifierNode *node = NULL;
222
+DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
193
+ SMMUNotifierNode *next_node = NULL;
223
+DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
194
+
195
+ if (new & IOMMU_NOTIFIER_MAP) {
196
+ int bus_num = pci_bus_num(sdev->bus);
197
+ PCIDevice *pcidev = pci_find_device(sdev->bus, bus_num, sdev->devfn);
198
+
199
+ warn_report("SMMUv3 does not support notification on MAP: "
200
+ "device %s will not function properly", pcidev->name);
201
+ }
202
+
203
if (old == IOMMU_NOTIFIER_NONE) {
204
- warn_report("SMMUV3 does not support vhost/vfio integration yet: "
205
- "devices of those types will not function properly");
206
+ trace_smmuv3_notify_flag_add(iommu->parent_obj.name);
207
+ node = g_malloc0(sizeof(*node));
208
+ node->sdev = sdev;
209
+ QLIST_INSERT_HEAD(&s->notifiers_list, node, next);
210
+ return;
211
+ }
212
+
213
+ /* update notifier node with new flags */
214
+ QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
215
+ if (node->sdev == sdev) {
216
+ if (new == IOMMU_NOTIFIER_NONE) {
217
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
218
+ QLIST_REMOVE(node, next);
219
+ g_free(node);
220
+ }
221
+ return;
222
+ }
223
}
224
}
225
226
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
227
index XXXXXXX..XXXXXXX 100644
228
--- a/hw/arm/trace-events
229
+++ b/hw/arm/trace-events
230
@@ -XXX,XX +XXX,XX @@ smmu_iotlb_cache_miss(uint16_t asid, uint64_t addr, uint32_t hit, uint32_t miss,
231
smmu_iotlb_inv_all(void) "IOTLB invalidate all"
232
smmu_iotlb_inv_asid(uint16_t asid) "IOTLB invalidate asid=%d"
233
smmu_iotlb_inv_iova(uint16_t asid, uint64_t addr) "IOTLB invalidate asid=%d addr=0x%"PRIx64
234
+smmu_inv_notifiers_mr(const char *name) "iommu mr=%s"
235
236
#hw/arm/smmuv3.c
237
smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
238
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_tlbi_nh_vaa(int vmid, uint64_t addr) "vmid =%d addr=0x%"PRIx64
239
smmuv3_cmdq_tlbi_nh(void) ""
240
smmuv3_cmdq_tlbi_nh_asid(uint16_t asid) "asid=%d"
241
smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid %d"
242
+smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s"
243
+smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
244
+smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint64_t iova) "iommu mr=%s asid=%d iova=0x%"PRIx64
245
+
246
--
224
--
247
2.17.1
225
2.20.1
248
226
249
227
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.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
Also handle the fake transfers for dummy bytes in this setup
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
routine. It will be useful when we activate MMIO execution.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
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(+)
5
14
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
7
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
8
Message-id: 20180612065716.10587-4-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/ssi/aspeed_smc.c | 31 ++++++++++++++++---------------
12
1 file changed, 16 insertions(+), 15 deletions(-)
13
14
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ssi/aspeed_smc.c
17
--- a/target/arm/helper-mve.h
17
+++ b/hw/ssi/aspeed_smc.c
18
+++ b/target/arm/helper-mve.h
18
@@ -XXX,XX +XXX,XX @@ static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
return dummies;
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
}
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
-static void aspeed_smc_flash_send_addr(AspeedSMCFlash *fl, uint32_t addr)
23
+
23
+static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr)
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
24
{
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
25
const AspeedSMCState *s = fl->controller;
26
index XXXXXXX..XXXXXXX 100644
26
uint8_t cmd = aspeed_smc_flash_cmd(fl);
27
--- a/target/arm/mve.decode
27
+ int i;
28
+++ b/target/arm/mve.decode
28
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
29
/* Flash access can not exceed CS segment */
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
30
addr = aspeed_smc_check_segment_addr(fl, addr);
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
31
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_send_addr(AspeedSMCFlash *fl, uint32_t addr)
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
32
ssi_transfer(s->spi, (addr >> 16) & 0xff);
33
+
33
ssi_transfer(s->spi, (addr >> 8) & 0xff);
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
34
ssi_transfer(s->spi, (addr & 0xff));
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;
35
+
51
+
36
+ /*
52
+ /*
37
+ * Use fake transfers to model dummy bytes. The value should
53
+ * For each 32-bit element, we shift it left, bringing in the
38
+ * be configured to some non-zero value in fast read mode and
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
39
+ * zero in read mode. But, as the HW allows inconsistent
55
+ * the top become the new rdm, if the predicate mask permits.
40
+ * settings, let's check for fast read mode.
56
+ * The final rdm value is returned to update the register.
57
+ * shift == 0 here means "shift by 32 bits".
41
+ */
58
+ */
42
+ if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) {
59
+ if (shift == 0) {
43
+ for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
44
+ ssi_transfer(fl->controller->spi, 0xFF);
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);
45
+ }
76
+ }
46
+ }
77
+ }
47
}
78
+ mve_advance_vpt(env);
48
79
+ return rdm;
49
static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
80
+}
50
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
51
case CTRL_READMODE:
82
index XXXXXXX..XXXXXXX 100644
52
case CTRL_FREADMODE:
83
--- a/target/arm/translate-mve.c
53
aspeed_smc_flash_select(fl);
84
+++ b/target/arm/translate-mve.c
54
- aspeed_smc_flash_send_addr(fl, addr);
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
55
-
86
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
56
- /*
87
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
57
- * Use fake transfers to model dummy bytes. The value should
88
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
58
- * be configured to some non-zero value in fast read mode and
89
+
59
- * zero in read mode. But, as the HW allows inconsistent
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
60
- * settings, let's check for fast read mode.
91
+{
61
- */
92
+ /*
62
- if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) {
93
+ * Whole Vector Left Shift with Carry. The carry is taken
63
- for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
94
+ * from a general purpose register and written back there.
64
- ssi_transfer(fl->controller->spi, 0xFF);
95
+ * An imm of 0 means "shift by 32".
65
- }
96
+ */
66
- }
97
+ TCGv_ptr qd;
67
+ aspeed_smc_flash_setup(fl, addr);
98
+ TCGv_i32 rdm;
68
99
+
69
for (i = 0; i < size; i++) {
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
70
ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
101
+ return false;
71
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
102
+ }
72
break;
103
+ if (a->rdm == 13 || a->rdm == 15) {
73
case CTRL_WRITEMODE:
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
74
aspeed_smc_flash_select(fl);
105
+ return false;
75
- aspeed_smc_flash_send_addr(fl, addr);
106
+ }
76
+ aspeed_smc_flash_setup(fl, addr);
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
77
108
+ return true;
78
for (i = 0; i < size; i++) {
109
+ }
79
ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
110
+
111
+ qd = mve_qreg_ptr(a->qd);
112
+ rdm = load_reg(s, a->rdm);
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
114
+ store_reg(s, a->rdm, rdm);
115
+ tcg_temp_free_ptr(qd);
116
+ mve_update_eci(s);
117
+ return true;
118
+}
80
--
119
--
81
2.17.1
120
2.20.1
82
121
83
122
diff view generated by jsdifflib
1
From: Jia He <hejianet@gmail.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
In case the STE's config is "Bypass" we currently don't set the
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
IOMMUTLBEntry perm flags and the access does not succeed. Also
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
if the config is 0b0xx (Aborted/Reserved), decode_ste and
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
6
smmuv3_decode_config currently returns -EINVAL and we don't enter
8
---
7
the expected code path: we record an event whereas we should not.
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(-)
8
14
9
This patch fixes those bugs and simplifies the error handling.
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
10
decode_ste and smmuv3_decode_config now return 0 if aborted or
11
bypassed config was found. Only bad config info produces negative
12
error values. In smmuv3_translate we more clearly differentiate
13
errors, bypass/smmu disabled, aborted and success cases. Also
14
trace points are differentiated.
15
16
Fixes: 9bde7f0674fe ("hw/arm/smmuv3: Implement translate callback")
17
Reported-by: jia.he@hxt-semitech.com
18
Signed-off-by: jia.he@hxt-semitech.com
19
Signed-off-by: Eric Auger <eric.auger@redhat.com>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Message-id: 1529653501-15358-2-git-send-email-eric.auger@redhat.com
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
24
hw/arm/smmuv3-internal.h | 12 ++++-
25
hw/arm/smmuv3.c | 96 +++++++++++++++++++++++++++-------------
26
hw/arm/trace-events | 7 +--
27
3 files changed, 80 insertions(+), 35 deletions(-)
28
29
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
30
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/smmuv3-internal.h
17
--- a/target/arm/helper-mve.h
32
+++ b/hw/arm/smmuv3-internal.h
18
+++ b/target/arm/helper-mve.h
33
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
34
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
35
#include "hw/arm/smmu-common.h"
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
36
22
37
+typedef enum SMMUTranslationStatus {
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
38
+ SMMU_TRANS_DISABLE,
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
39
+ SMMU_TRANS_ABORT,
40
+ SMMU_TRANS_BYPASS,
41
+ SMMU_TRANS_ERROR,
42
+ SMMU_TRANS_SUCCESS,
43
+} SMMUTranslationStatus;
44
+
25
+
45
/* MMIO Registers */
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
46
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
47
REG32(IDR0, 0x0)
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
48
@@ -XXX,XX +XXX,XX @@ enum { /* Command completion notification */
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
49
/* Events */
50
51
typedef enum SMMUEventType {
52
- SMMU_EVT_OK = 0x00,
53
+ SMMU_EVT_NONE = 0x00,
54
SMMU_EVT_F_UUT ,
55
SMMU_EVT_C_BAD_STREAMID ,
56
SMMU_EVT_F_STE_FETCH ,
57
@@ -XXX,XX +XXX,XX @@ typedef enum SMMUEventType {
58
} SMMUEventType;
59
60
static const char *event_stringify[] = {
61
- [SMMU_EVT_OK] = "SMMU_EVT_OK",
62
+ [SMMU_EVT_NONE] = "no recorded event",
63
[SMMU_EVT_F_UUT] = "SMMU_EVT_F_UUT",
64
[SMMU_EVT_C_BAD_STREAMID] = "SMMU_EVT_C_BAD_STREAMID",
65
[SMMU_EVT_F_STE_FETCH] = "SMMU_EVT_F_STE_FETCH",
66
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
67
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/smmuv3.c
31
--- a/target/arm/mve.decode
69
+++ b/hw/arm/smmuv3.c
32
+++ b/target/arm/mve.decode
70
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
71
#include "hw/qdev-core.h"
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
72
#include "hw/pci/pci.h"
35
73
#include "exec/address-spaces.h"
36
# Vector add across vector
74
+#include "cpu.h"
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
75
#include "trace.h"
38
+{
76
#include "qemu/log.h"
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
77
#include "qemu/error-report.h"
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
78
@@ -XXX,XX +XXX,XX @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
41
+ rdahi=%rdahi rdalo=%rdalo
79
EVT_SET_SID(&evt, info->sid);
42
+}
80
43
81
switch (info->type) {
44
# Predicate operations
82
- case SMMU_EVT_OK:
45
%mask_22_13 22:1 13:3
83
+ case SMMU_EVT_NONE:
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
84
return;
47
index XXXXXXX..XXXXXXX 100644
85
case SMMU_EVT_F_UUT:
48
--- a/target/arm/mve_helper.c
86
EVT_SET_SSID(&evt, info->u.f_uut.ssid);
49
+++ b/target/arm/mve_helper.c
87
@@ -XXX,XX +XXX,XX @@ static int smmu_get_cd(SMMUv3State *s, STE *ste, uint32_t ssid,
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
88
return 0;
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;
89
}
82
}
90
83
91
-/* Returns <0 if the caller has no need to continue the translation */
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
92
+/* Returns < 0 in case of invalid STE, 0 otherwise */
85
+{
93
static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
86
+ /*
94
STE *ste, SMMUEventInfo *event)
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
95
{
88
+ * elements of the vector into a 64-bit result stored in
96
uint32_t config;
89
+ * a pair of general-purpose registers.
97
- int ret = -EINVAL;
90
+ * No need to check Qm's bank: it is only 3 bits in decode.
98
91
+ */
99
if (!STE_VALID(ste)) {
92
+ TCGv_ptr qm;
100
goto bad_ste;
93
+ TCGv_i64 rda;
101
@@ -XXX,XX +XXX,XX @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
94
+ TCGv_i32 rdalo, rdahi;
102
config = STE_CONFIG(ste);
95
+
103
96
+ if (!dc_isar_feature(aa32_mve, s)) {
104
if (STE_CFG_ABORT(config)) {
97
+ return false;
105
- cfg->aborted = true; /* abort but don't record any event */
98
+ }
106
- return ret;
99
+ /*
107
+ cfg->aborted = true;
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
108
+ return 0;
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
109
}
102
+ */
110
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
111
if (STE_CFG_BYPASS(config)) {
104
+ return false;
112
cfg->bypassed = true;
105
+ }
113
- return ret;
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
114
+ return 0;
107
+ return true;
115
}
116
117
if (STE_CFG_S2_ENABLED(config)) {
118
@@ -XXX,XX +XXX,XX @@ bad_cd:
119
* the different configuration decoding steps
120
* @event: must be zero'ed by the caller
121
*
122
- * return < 0 if the translation needs to be aborted (@event is filled
123
+ * return < 0 in case of config decoding error (@event is filled
124
* accordingly). Return 0 otherwise.
125
*/
126
static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
127
@@ -XXX,XX +XXX,XX @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
128
SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
129
uint32_t sid = smmu_get_sid(sdev);
130
SMMUv3State *s = sdev->smmu;
131
- int ret = -EINVAL;
132
+ int ret;
133
STE ste;
134
CD cd;
135
136
- if (smmu_find_ste(s, sid, &ste, event)) {
137
+ ret = smmu_find_ste(s, sid, &ste, event);
138
+ if (ret) {
139
return ret;
140
}
141
142
- if (decode_ste(s, cfg, &ste, event)) {
143
+ ret = decode_ste(s, cfg, &ste, event);
144
+ if (ret) {
145
return ret;
146
}
147
148
- if (smmu_get_cd(s, &ste, 0 /* ssid */, &cd, event)) {
149
+ if (cfg->aborted || cfg->bypassed) {
150
+ return 0;
151
+ }
108
+ }
152
+
109
+
153
+ ret = smmu_get_cd(s, &ste, 0 /* ssid */, &cd, event);
110
+ /*
154
+ if (ret) {
111
+ * This insn is subject to beat-wise execution. Partial execution
155
return ret;
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
156
}
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
157
114
+ */
158
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
115
+ if (a->a || mve_skip_first_beat(s)) {
159
SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
116
+ /* Accumulate input from RdaHi:RdaLo */
160
SMMUv3State *s = sdev->smmu;
117
+ rda = tcg_temp_new_i64();
161
uint32_t sid = smmu_get_sid(sdev);
118
+ rdalo = load_reg(s, a->rdalo);
162
- SMMUEventInfo event = {.type = SMMU_EVT_OK, .sid = sid};
119
+ rdahi = load_reg(s, a->rdahi);
163
+ SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid};
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
164
SMMUPTWEventInfo ptw_info = {};
121
+ tcg_temp_free_i32(rdalo);
165
+ SMMUTranslationStatus status;
122
+ tcg_temp_free_i32(rdahi);
166
SMMUTransCfg cfg = {};
123
+ } else {
167
IOMMUTLBEntry entry = {
124
+ /* Accumulate starting at zero */
168
.target_as = &address_space_memory,
125
+ rda = tcg_const_i64(0);
169
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
170
.addr_mask = ~(hwaddr)0,
171
.perm = IOMMU_NONE,
172
};
173
- int ret = 0;
174
175
if (!smmu_enabled(s)) {
176
- goto out;
177
+ status = SMMU_TRANS_DISABLE;
178
+ goto epilogue;
179
}
180
181
- ret = smmuv3_decode_config(mr, &cfg, &event);
182
- if (ret) {
183
- goto out;
184
+ if (smmuv3_decode_config(mr, &cfg, &event)) {
185
+ status = SMMU_TRANS_ERROR;
186
+ goto epilogue;
187
}
188
189
if (cfg.aborted) {
190
- goto out;
191
+ status = SMMU_TRANS_ABORT;
192
+ goto epilogue;
193
}
194
195
- ret = smmu_ptw(&cfg, addr, flag, &entry, &ptw_info);
196
- if (ret) {
197
+ if (cfg.bypassed) {
198
+ status = SMMU_TRANS_BYPASS;
199
+ goto epilogue;
200
+ }
126
+ }
201
+
127
+
202
+ if (smmu_ptw(&cfg, addr, flag, &entry, &ptw_info)) {
128
+ qm = mve_qreg_ptr(a->qm);
203
switch (ptw_info.type) {
129
+ if (a->u) {
204
case SMMU_PTW_ERR_WALK_EABT:
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
205
event.type = SMMU_EVT_F_WALK_EABT;
206
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
207
default:
208
g_assert_not_reached();
209
}
210
+ status = SMMU_TRANS_ERROR;
211
+ } else {
131
+ } else {
212
+ status = SMMU_TRANS_SUCCESS;
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
213
}
133
+ }
214
-out:
134
+ tcg_temp_free_ptr(qm);
215
- if (ret) {
216
- qemu_log_mask(LOG_GUEST_ERROR,
217
- "%s translation failed for iova=0x%"PRIx64"(%d)\n",
218
- mr->parent_obj.name, addr, ret);
219
- entry.perm = IOMMU_NONE;
220
- smmuv3_record_event(s, &event);
221
- } else if (!cfg.aborted) {
222
+
135
+
223
+epilogue:
136
+ rdalo = tcg_temp_new_i32();
224
+ switch (status) {
137
+ rdahi = tcg_temp_new_i32();
225
+ case SMMU_TRANS_SUCCESS:
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
226
entry.perm = flag;
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
227
- trace_smmuv3_translate(mr->parent_obj.name, sid, addr,
140
+ store_reg(s, a->rdalo, rdalo);
228
- entry.translated_addr, entry.perm);
141
+ store_reg(s, a->rdahi, rdahi);
229
+ trace_smmuv3_translate_success(mr->parent_obj.name, sid, addr,
142
+ tcg_temp_free_i64(rda);
230
+ entry.translated_addr, entry.perm);
143
+ mve_update_eci(s);
231
+ break;
144
+ return true;
232
+ case SMMU_TRANS_DISABLE:
145
+}
233
+ entry.perm = flag;
146
+
234
+ entry.addr_mask = ~TARGET_PAGE_MASK;
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
235
+ trace_smmuv3_translate_disable(mr->parent_obj.name, sid, addr,
148
{
236
+ entry.perm);
149
TCGv_ptr qd;
237
+ break;
238
+ case SMMU_TRANS_BYPASS:
239
+ entry.perm = flag;
240
+ entry.addr_mask = ~TARGET_PAGE_MASK;
241
+ trace_smmuv3_translate_bypass(mr->parent_obj.name, sid, addr,
242
+ entry.perm);
243
+ break;
244
+ case SMMU_TRANS_ABORT:
245
+ /* no event is recorded on abort */
246
+ trace_smmuv3_translate_abort(mr->parent_obj.name, sid, addr,
247
+ entry.perm);
248
+ break;
249
+ case SMMU_TRANS_ERROR:
250
+ qemu_log_mask(LOG_GUEST_ERROR,
251
+ "%s translation failed for iova=0x%"PRIx64"(%s)\n",
252
+ mr->parent_obj.name, addr, smmu_event_string(event.type));
253
+ smmuv3_record_event(s, &event);
254
+ break;
255
}
256
257
return entry;
258
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
259
index XXXXXXX..XXXXXXX 100644
260
--- a/hw/arm/trace-events
261
+++ b/hw/arm/trace-events
262
@@ -XXX,XX +XXX,XX @@ smmuv3_record_event(const char *type, uint32_t sid) "%s sid=%d"
263
smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "SID:0x%x features:0x%x, sid_split:0x%x"
264
smmuv3_find_ste_2lvl(uint64_t strtab_base, uint64_t l1ptr, int l1_ste_offset, uint64_t l2ptr, int l2_ste_offset, int max_l2_ste) "strtab_base:0x%"PRIx64" l1ptr:0x%"PRIx64" l1_off:0x%x, l2ptr:0x%"PRIx64" l2_off:0x%x max_l2_ste:%d"
265
smmuv3_get_ste(uint64_t addr) "STE addr: 0x%"PRIx64
266
-smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d bypass iova:0x%"PRIx64" is_write=%d"
267
-smmuv3_translate_in(uint16_t sid, int pci_bus_num, uint64_t strtab_base) "SID:0x%x bus:%d strtab_base:0x%"PRIx64
268
+smmuv3_translate_disable(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d bypass (smmu disabled) iova:0x%"PRIx64" is_write=%d"
269
+smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d STE bypass iova:0x%"PRIx64" is_write=%d"
270
+smmuv3_translate_abort(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d abort on iova:0x%"PRIx64" is_write=%d"
271
+smmuv3_translate_success(const char *n, uint16_t sid, uint64_t iova, uint64_t translated, int perm) "%s sid=%d iova=0x%"PRIx64" translated=0x%"PRIx64" perm=0x%x"
272
smmuv3_get_cd(uint64_t addr) "CD addr: 0x%"PRIx64
273
-smmuv3_translate(const char *n, uint16_t sid, uint64_t iova, uint64_t translated, int perm) "%s sid=%d iova=0x%"PRIx64" translated=0x%"PRIx64" perm=0x%x"
274
smmuv3_decode_cd(uint32_t oas) "oas=%d"
275
smmuv3_decode_cd_tt(int i, uint32_t tsz, uint64_t ttb, uint32_t granule_sz) "TT[%d]:tsz:%d ttb:0x%"PRIx64" granule_sz:%d"
276
--
150
--
277
2.17.1
151
2.20.1
278
152
279
153
diff view generated by jsdifflib
1
We want to handle small MPU region sizes for ARMv7M. To do this,
1
The MVE extension to v8.1M includes some new shift instructions which
2
make get_phys_addr_pmsav7() set the page size to the region
2
sit entirely within the non-coprocessor part of the encoding space
3
size if it is less that TARGET_PAGE_SIZE, rather than working
3
and which operate only on general-purpose registers. They take up
4
only in TARGET_PAGE_SIZE chunks.
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
5
with Rm == 13 or 15.
6
Since the core TCG code con't handle execution from small
6
7
MPU regions, we strip the exec permission from them so that
7
Implement the long shifts by immediate, which perform shifts on a
8
any execution attempts will cause an MPU exception, rather
8
pair of general-purpose registers treated as a 64-bit quantity, with
9
than allowing it to end up with a cpu_abort() in
9
an immediate shift count between 1 and 32.
10
get_page_addr_code().
10
11
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
12
(The previous code's intention was to make any small page be
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
13
treated as having no permissions, but unfortunately errors
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
14
in the implementation meant that it didn't behave that way.
14
is too difficult, because the functions that generate the code are
15
It's possible that some binaries using small regions were
15
shared between a dozen different kinds of arithmetic or logical
16
accidentally working with our old behaviour and won't now.)
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.
17
23
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20180620130619.11362-3-peter.maydell@linaro.org
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
21
---
27
---
22
target/arm/helper.c | 37 ++++++++++++++++++++++++++-----------
28
target/arm/helper-mve.h | 3 ++
23
1 file changed, 26 insertions(+), 11 deletions(-)
29
target/arm/translate.h | 1 +
24
30
target/arm/t32.decode | 28 +++++++++++++
25
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
target/arm/mve_helper.c | 10 +++++
26
index XXXXXXX..XXXXXXX 100644
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
27
--- a/target/arm/helper.c
33
5 files changed, 132 insertions(+)
28
+++ b/target/arm/helper.c
34
29
@@ -XXX,XX +XXX,XX @@ static inline bool m_is_system_region(CPUARMState *env, uint32_t address)
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
30
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
36
index XXXXXXX..XXXXXXX 100644
31
MMUAccessType access_type, ARMMMUIdx mmu_idx,
37
--- a/target/arm/helper-mve.h
32
hwaddr *phys_ptr, int *prot,
38
+++ b/target/arm/helper-mve.h
33
+ target_ulong *page_size,
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
ARMMMUFaultInfo *fi)
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
43
+
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.h
49
+++ b/target/arm/translate.h
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
55
56
/**
57
* arm_tbflags_from_tb:
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/t32.decode
61
+++ b/target/arm/t32.decode
62
@@ -XXX,XX +XXX,XX @@
63
&mcr !extern cp opc1 crn crm opc2 rt
64
&mcrr !extern cp opc1 crm rt rt2
65
66
+&mve_shl_ri rdalo rdahi shim
67
+
68
+# rdahi: bits [3:1] from insn, bit 0 is 1
69
+# rdalo: bits [3:1] from insn, bit 0 is 0
70
+%rdahi_9 9:3 !function=times_2_plus_1
71
+%rdalo_17 17:3 !function=times_2
72
+
73
# Data-processing (register)
74
75
%imm5_12_6 12:3 6:2
76
@@ -XXX,XX +XXX,XX @@
77
@S_xrr_shi ....... .... . rn:4 .... .... .. shty:2 rm:4 \
78
&s_rrr_shi shim=%imm5_12_6 s=1 rd=0
79
80
+@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
81
+ &mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
82
+
35
{
83
{
36
ARMCPU *cpu = arm_env_get_cpu(env);
84
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
37
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
85
AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi
38
bool is_user = regime_is_user(env, mmu_idx);
86
}
39
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
40
*phys_ptr = address;
88
{
41
+ *page_size = TARGET_PAGE_SIZE;
89
+ # The v8.1M MVE shift insns overlap in encoding with MOVS/ORRS
42
*prot = 0;
90
+ # and are distinguished by having Rm==13 or 15. Those are UNPREDICTABLE
43
91
+ # cases for MOVS/ORRS. We decode the MVE cases first, ensuring that
44
if (regime_translation_disabled(env, mmu_idx) ||
92
+ # they explicitly call unallocated_encoding() for cases that must UNDEF
45
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
93
+ # (eg "using a new shift insn on a v8.1M CPU without MVE"), and letting
46
rsize++;
94
+ # the rest fall through (where ORR_rrri and MOV_rxri will end up
47
}
95
+ # handling them as r13 and r15 accesses with the same semantics as A32).
48
}
96
+ [
49
- if (rsize < TARGET_PAGE_BITS) {
97
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
50
- qemu_log_mask(LOG_UNIMP,
98
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
51
- "DRSR[%d]: No support for MPU (sub)region size of"
99
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
52
- " %" PRIu32 " bytes. Minimum is %d.\n",
100
+
53
- n, (1 << rsize), TARGET_PAGE_SIZE);
101
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
54
- continue;
102
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
55
- }
103
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
56
if (srdis) {
104
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
57
continue;
105
+ ]
58
}
106
+
59
+ if (rsize < TARGET_PAGE_BITS) {
107
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
60
+ *page_size = 1 << rsize;
108
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
61
+ }
109
}
62
break;
110
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
63
}
111
index XXXXXXX..XXXXXXX 100644
64
112
--- a/target/arm/mve_helper.c
65
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
113
+++ b/target/arm/mve_helper.c
66
114
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
67
fi->type = ARMFault_Permission;
115
mve_advance_vpt(env);
68
fi->level = 1;
116
return rdm;
69
+ /*
117
}
70
+ * Core QEMU code can't handle execution from small pages yet, so
118
+
71
+ * don't try it. This way we'll get an MPU exception, rather than
119
+uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
72
+ * eventually causing QEMU to exit in get_page_addr_code().
120
+{
73
+ */
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
74
+ if (*page_size < TARGET_PAGE_SIZE && (*prot & PAGE_EXEC)) {
122
+}
75
+ qemu_log_mask(LOG_UNIMP,
123
+
76
+ "MPU: No support for execution from regions "
124
+uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
77
+ "smaller than 1K\n");
125
+{
78
+ *prot &= ~PAGE_EXEC;
126
+ return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
79
+ }
127
+}
80
return !(*prot & (1 << access_type));
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
}
129
index XXXXXXX..XXXXXXX 100644
82
130
--- a/target/arm/translate.c
83
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
131
+++ b/target/arm/translate.c
84
} else if (arm_feature(env, ARM_FEATURE_V7)) {
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
85
/* PMSAv7 */
133
return true;
86
ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
134
}
87
- phys_ptr, prot, fi);
135
88
+ phys_ptr, prot, page_size, fi);
136
+/*
89
} else {
137
+ * v8.1M MVE wide-shifts
90
/* Pre-v7 MPU */
138
+ */
91
ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
92
@@ -XXX,XX +XXX,XX @@ bool arm_tlb_fill(CPUState *cs, vaddr address,
140
+ WideShiftImmFn *fn)
93
core_to_arm_mmu_idx(env, mmu_idx), &phys_addr,
141
+{
94
&attrs, &prot, &page_size, fi, NULL);
142
+ TCGv_i64 rda;
95
if (!ret) {
143
+ TCGv_i32 rdalo, rdahi;
96
- /* Map a single [sub]page. */
144
+
97
- phys_addr &= TARGET_PAGE_MASK;
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
98
- address &= TARGET_PAGE_MASK;
146
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
99
+ /*
147
+ return false;
100
+ * Map a single [sub]page. Regions smaller than our declared
148
+ }
101
+ * target page size are handled specially, so for those we
149
+ if (a->rdahi == 15) {
102
+ * pass in the exact addresses.
150
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
103
+ */
151
+ return false;
104
+ if (page_size >= TARGET_PAGE_SIZE) {
152
+ }
105
+ phys_addr &= TARGET_PAGE_MASK;
153
+ if (!dc_isar_feature(aa32_mve, s) ||
106
+ address &= TARGET_PAGE_MASK;
154
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
107
+ }
155
+ a->rdahi == 13) {
108
tlb_set_page_with_attrs(cs, address, phys_addr, attrs,
156
+ /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
109
prot, mmu_idx, page_size);
157
+ unallocated_encoding(s);
110
return 0;
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
+}
225
+
226
/*
227
* Multiply and multiply accumulate
228
*/
111
--
229
--
112
2.17.1
230
2.20.1
113
231
114
232
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Implement the MVE long shifts by register, which perform shifts on a
2
2
pair of general-purpose registers treated as a 64-bit quantity, with
3
These COMs are hard to find, and the companie dropped the support
3
the shift count in another general-purpose register, which might be
4
few years ago.
4
either positive or negative.
5
5
6
Per the "Gumstix Product Changes, Known Issues, and EOL" pdf:
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
- Phasing out: PXA270-based Verdex product line
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
September 2012
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
10
we have to move the CSEL pattern into the same decodetree group.
11
- Phasing out: PXA255-based Basix & Connex
11
12
September 2009
13
14
However there are still booting SD card image availables, very
15
convenient to stress test the QEMU SD card implementation.
16
Therefore I volunteer to keep an eye on this file, while it
17
is useful for testing.
18
19
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Reviewed-by: Thomas Huth <thuth@redhat.com>
21
Message-id: 20180606144706.29732-1-f4bug@amsat.org
22
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
23
---
15
---
24
MAINTAINERS | 3 ++-
16
target/arm/helper-mve.h | 6 +++
25
1 file changed, 2 insertions(+), 1 deletion(-)
17
target/arm/translate.h | 1 +
26
18
target/arm/t32.decode | 16 +++++--
27
diff --git a/MAINTAINERS b/MAINTAINERS
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
28
index XXXXXXX..XXXXXXX 100644
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
29
--- a/MAINTAINERS
21
5 files changed, 182 insertions(+), 3 deletions(-)
30
+++ b/MAINTAINERS
22
31
@@ -XXX,XX +XXX,XX @@ F: include/hw/arm/digic.h
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
32
F: hw/*/digic*
24
index XXXXXXX..XXXXXXX 100644
33
25
--- a/target/arm/helper-mve.h
34
Gumstix
26
+++ b/target/arm/helper-mve.h
35
+M: Philippe Mathieu-Daudé <f4bug@amsat.org>
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
L: qemu-devel@nongnu.org
28
37
L: qemu-arm@nongnu.org
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
38
-S: Orphan
30
39
+S: Odd Fixes
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
40
F: hw/arm/gumstix.c
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
41
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
42
i.MX31
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
55
@@ -XXX,XX +XXX,XX @@
56
&mcrr !extern cp opc1 crm rt rt2
57
58
&mve_shl_ri rdalo rdahi shim
59
+&mve_shl_rr rdalo rdahi rm
60
61
# rdahi: bits [3:1] from insn, bit 0 is 1
62
# rdalo: bits [3:1] from insn, bit 0 is 0
63
@@ -XXX,XX +XXX,XX @@
64
65
@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
66
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
67
+@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
68
+ &mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
69
70
{
71
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
72
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
73
URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
74
SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
75
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
76
+
77
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
78
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
79
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
80
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
81
+ UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
82
+ SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
83
]
84
85
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
86
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
87
+
88
+ # v8.1M CSEL and friends
89
+ CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
90
}
91
{
92
MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi
93
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
94
}
95
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
96
97
-# v8.1M CSEL and friends
98
-CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
99
-
100
# Data-processing (register-shifted register)
101
102
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
103
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/mve_helper.c
106
+++ b/target/arm/mve_helper.c
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
108
return rdm;
109
}
110
111
+uint64_t HELPER(mve_sshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
112
+{
113
+ return do_sqrshl_d(n, -(int8_t)shift, false, NULL);
114
+}
115
+
116
+uint64_t HELPER(mve_ushll)(CPUARMState *env, uint64_t n, uint32_t shift)
117
+{
118
+ return do_uqrshl_d(n, (int8_t)shift, false, NULL);
119
+}
120
+
121
uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
122
{
123
return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
124
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
{
126
return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
}
128
+
129
+uint64_t HELPER(mve_sqrshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
130
+{
131
+ return do_sqrshl_d(n, -(int8_t)shift, true, &env->QF);
132
+}
133
+
134
+uint64_t HELPER(mve_uqrshll)(CPUARMState *env, uint64_t n, uint32_t shift)
135
+{
136
+ return do_uqrshl_d(n, (int8_t)shift, true, &env->QF);
137
+}
138
+
139
+/* Operate on 64-bit values, but saturate at 48 bits */
140
+static inline int64_t do_sqrshl48_d(int64_t src, int64_t shift,
141
+ bool round, uint32_t *sat)
142
+{
143
+ if (shift <= -48) {
144
+ /* Rounding the sign bit always produces 0. */
145
+ if (round) {
146
+ return 0;
147
+ }
148
+ return src >> 63;
149
+ } else if (shift < 0) {
150
+ if (round) {
151
+ src >>= -shift - 1;
152
+ return (src >> 1) + (src & 1);
153
+ }
154
+ return src >> -shift;
155
+ } else if (shift < 48) {
156
+ int64_t val = src << shift;
157
+ int64_t extval = sextract64(val, 0, 48);
158
+ if (!sat || val == extval) {
159
+ return extval;
160
+ }
161
+ } else if (!sat || src == 0) {
162
+ return 0;
163
+ }
164
+
165
+ *sat = 1;
166
+ return (1ULL << 47) - (src >= 0);
167
+}
168
+
169
+/* Operate on 64-bit values, but saturate at 48 bits */
170
+static inline uint64_t do_uqrshl48_d(uint64_t src, int64_t shift,
171
+ bool round, uint32_t *sat)
172
+{
173
+ uint64_t val, extval;
174
+
175
+ if (shift <= -(48 + round)) {
176
+ return 0;
177
+ } else if (shift < 0) {
178
+ if (round) {
179
+ val = src >> (-shift - 1);
180
+ val = (val >> 1) + (val & 1);
181
+ } else {
182
+ val = src >> -shift;
183
+ }
184
+ extval = extract64(val, 0, 48);
185
+ if (!sat || val == extval) {
186
+ return extval;
187
+ }
188
+ } else if (shift < 48) {
189
+ uint64_t val = src << shift;
190
+ uint64_t extval = extract64(val, 0, 48);
191
+ if (!sat || val == extval) {
192
+ return extval;
193
+ }
194
+ } else if (!sat || src == 0) {
195
+ return 0;
196
+ }
197
+
198
+ *sat = 1;
199
+ return MAKE_64BIT_MASK(0, 48);
200
+}
201
+
202
+uint64_t HELPER(mve_sqrshrl48)(CPUARMState *env, uint64_t n, uint32_t shift)
203
+{
204
+ return do_sqrshl48_d(n, -(int8_t)shift, true, &env->QF);
205
+}
206
+
207
+uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
208
+{
209
+ return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
210
+}
211
diff --git a/target/arm/translate.c b/target/arm/translate.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/arm/translate.c
214
+++ b/target/arm/translate.c
215
@@ -XXX,XX +XXX,XX @@ static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
216
return do_mve_shl_ri(s, a, gen_urshr64_i64);
217
}
218
219
+static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
220
+{
221
+ TCGv_i64 rda;
222
+ TCGv_i32 rdalo, rdahi;
223
+
224
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
225
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
226
+ return false;
227
+ }
228
+ if (a->rdahi == 15) {
229
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
230
+ return false;
231
+ }
232
+ if (!dc_isar_feature(aa32_mve, s) ||
233
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
234
+ a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
235
+ a->rm == a->rdahi || a->rm == a->rdalo) {
236
+ /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
237
+ unallocated_encoding(s);
238
+ return true;
239
+ }
240
+
241
+ rda = tcg_temp_new_i64();
242
+ rdalo = load_reg(s, a->rdalo);
243
+ rdahi = load_reg(s, a->rdahi);
244
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
245
+
246
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
247
+ fn(rda, cpu_env, rda, cpu_R[a->rm]);
248
+
249
+ tcg_gen_extrl_i64_i32(rdalo, rda);
250
+ tcg_gen_extrh_i64_i32(rdahi, rda);
251
+ store_reg(s, a->rdalo, rdalo);
252
+ store_reg(s, a->rdahi, rdahi);
253
+ tcg_temp_free_i64(rda);
254
+
255
+ return true;
256
+}
257
+
258
+static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
259
+{
260
+ return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
261
+}
262
+
263
+static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
264
+{
265
+ return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
266
+}
267
+
268
+static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
269
+{
270
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
271
+}
272
+
273
+static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
274
+{
275
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
276
+}
277
+
278
+static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
279
+{
280
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
281
+}
282
+
283
+static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
284
+{
285
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
286
+}
287
+
288
/*
289
* Multiply and multiply accumulate
290
*/
43
--
291
--
44
2.17.1
292
2.20.1
45
293
46
294
diff view generated by jsdifflib
Deleted patch
1
From: Joel Stanley <joel@jms.id.au>
2
1
3
This adds Cedric as the maintainer, with Andrew and I as reviewers, for
4
the ASPEED boards and the peripherals we have developed.
5
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
8
Acked-by: Cédric Le Goater <clg@kaod.org>
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
10
Message-id: 20180625140055.32223-1-joel@jms.id.au
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
MAINTAINERS | 11 +++++++++++
14
1 file changed, 11 insertions(+)
15
16
diff --git a/MAINTAINERS b/MAINTAINERS
17
index XXXXXXX..XXXXXXX 100644
18
--- a/MAINTAINERS
19
+++ b/MAINTAINERS
20
@@ -XXX,XX +XXX,XX @@ M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
21
S: Maintained
22
F: hw/arm/msf2-som.c
23
24
+ASPEED BMCs
25
+M: Cédric Le Goater <clg@kaod.org>
26
+R: Andrew Jeffery <andrew@aj.id.au>
27
+R: Joel Stanley <joel@jms.id.au>
28
+L: qemu-arm@nongnu.org
29
+S: Maintained
30
+F: hw/*/*aspeed*
31
+F: include/hw/*/*aspeed*
32
+F: hw/net/ftgmac100.c
33
+F: include/hw/net/ftgmac100.h
34
+
35
CRIS Machines
36
-------------
37
Axis Dev88
38
--
39
2.17.1
40
41
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-2-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
hw/input/pckbd.c | 4 +++-
9
1 file changed, 3 insertions(+), 1 deletion(-)
10
11
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/input/pckbd.c
14
+++ b/hw/input/pckbd.c
15
@@ -XXX,XX +XXX,XX @@
16
* THE SOFTWARE.
17
*/
18
#include "qemu/osdep.h"
19
+#include "qemu/log.h"
20
#include "hw/hw.h"
21
#include "hw/isa/isa.h"
22
#include "hw/i386/pc.h"
23
@@ -XXX,XX +XXX,XX @@ static void kbd_write_command(void *opaque, hwaddr addr,
24
/* ignore that */
25
break;
26
default:
27
- fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", (int)val);
28
+ qemu_log_mask(LOG_GUEST_ERROR,
29
+ "unsupported keyboard cmd=0x%02" PRIx64 "\n", val);
30
break;
31
}
32
}
33
--
34
2.17.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-4-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
hw/dma/omap_dma.c | 6 ++++--
9
1 file changed, 4 insertions(+), 2 deletions(-)
10
11
diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/dma/omap_dma.c
14
+++ b/hw/dma/omap_dma.c
15
@@ -XXX,XX +XXX,XX @@
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
17
*/
18
#include "qemu/osdep.h"
19
+#include "qemu/log.h"
20
#include "qemu-common.h"
21
#include "qemu/timer.h"
22
#include "hw/arm/omap.h"
23
@@ -XXX,XX +XXX,XX @@ static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
24
case 0x480:    /* DMA_PCh0_SR */
25
case 0x482:    /* DMA_PCh1_SR */
26
case 0x4c0:    /* DMA_PChD_SR_0 */
27
- printf("%s: Physical Channel Status Registers not implemented.\n",
28
- __func__);
29
+ qemu_log_mask(LOG_UNIMP,
30
+ "%s: Physical Channel Status Registers not implemented\n",
31
+ __func__);
32
*ret = 0xff;
33
break;
34
35
--
36
2.17.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-5-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
hw/dma/omap_dma.c | 64 +++++++++++++++++++++++++++++------------------
9
1 file changed, 40 insertions(+), 24 deletions(-)
10
11
diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/dma/omap_dma.c
14
+++ b/hw/dma/omap_dma.c
15
@@ -XXX,XX +XXX,XX @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
16
ch->burst[0] = (value & 0x0180) >> 7;
17
ch->pack[0] = (value & 0x0040) >> 6;
18
ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
19
- if (ch->port[0] >= __omap_dma_port_last)
20
- printf("%s: invalid DMA port %i\n", __func__,
21
- ch->port[0]);
22
- if (ch->port[1] >= __omap_dma_port_last)
23
- printf("%s: invalid DMA port %i\n", __func__,
24
- ch->port[1]);
25
+ if (ch->port[0] >= __omap_dma_port_last) {
26
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid DMA port %i\n",
27
+ __func__, ch->port[0]);
28
+ }
29
+ if (ch->port[1] >= __omap_dma_port_last) {
30
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid DMA port %i\n",
31
+ __func__, ch->port[1]);
32
+ }
33
ch->data_type = 1 << (value & 3);
34
if ((value & 3) == 3) {
35
- printf("%s: bad data_type for DMA channel\n", __func__);
36
+ qemu_log_mask(LOG_GUEST_ERROR,
37
+ "%s: bad data_type for DMA channel\n", __func__);
38
ch->data_type >>= 1;
39
}
40
break;
41
@@ -XXX,XX +XXX,XX @@ static void omap_dma4_write(void *opaque, hwaddr addr,
42
if (value & 2)                        /* SOFTRESET */
43
omap_dma_reset(s->dma);
44
s->ocp = value & 0x3321;
45
- if (((s->ocp >> 12) & 3) == 3)                /* MIDLEMODE */
46
- fprintf(stderr, "%s: invalid DMA power mode\n", __func__);
47
+ if (((s->ocp >> 12) & 3) == 3) { /* MIDLEMODE */
48
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid DMA power mode\n",
49
+ __func__);
50
+ }
51
return;
52
53
case 0x78:    /* DMA4_GCR */
54
s->gcr = value & 0x00ff00ff;
55
-    if ((value & 0xff) == 0x00)        /* MAX_CHANNEL_FIFO_DEPTH */
56
- fprintf(stderr, "%s: wrong FIFO depth in GCR\n", __func__);
57
+ if ((value & 0xff) == 0x00) { /* MAX_CHANNEL_FIFO_DEPTH */
58
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: wrong FIFO depth in GCR\n",
59
+ __func__);
60
+ }
61
return;
62
63
case 0x80 ... 0xfff:
64
@@ -XXX,XX +XXX,XX @@ static void omap_dma4_write(void *opaque, hwaddr addr,
65
case 0x00:    /* DMA4_CCR */
66
ch->buf_disable = (value >> 25) & 1;
67
ch->src_sync = (value >> 24) & 1;    /* XXX For CamDMA must be 1 */
68
- if (ch->buf_disable && !ch->src_sync)
69
- fprintf(stderr, "%s: Buffering disable is not allowed in "
70
- "destination synchronised mode\n", __func__);
71
+ if (ch->buf_disable && !ch->src_sync) {
72
+ qemu_log_mask(LOG_GUEST_ERROR,
73
+ "%s: Buffering disable is not allowed in "
74
+ "destination synchronised mode\n", __func__);
75
+ }
76
ch->prefetch = (value >> 23) & 1;
77
ch->bs = (value >> 18) & 1;
78
ch->transparent_copy = (value >> 17) & 1;
79
@@ -XXX,XX +XXX,XX @@ static void omap_dma4_write(void *opaque, hwaddr addr,
80
ch->suspend = (value & 0x0100) >> 8;
81
ch->priority = (value & 0x0040) >> 6;
82
ch->fs = (value & 0x0020) >> 5;
83
- if (ch->fs && ch->bs && ch->mode[0] && ch->mode[1])
84
- fprintf(stderr, "%s: For a packet transfer at least one port "
85
- "must be constant-addressed\n", __func__);
86
+ if (ch->fs && ch->bs && ch->mode[0] && ch->mode[1]) {
87
+ qemu_log_mask(LOG_GUEST_ERROR,
88
+ "%s: For a packet transfer at least one port "
89
+ "must be constant-addressed\n", __func__);
90
+ }
91
ch->sync = (value & 0x001f) | ((value >> 14) & 0x0060);
92
/* XXX must be 0x01 for CamDMA */
93
94
@@ -XXX,XX +XXX,XX @@ static void omap_dma4_write(void *opaque, hwaddr addr,
95
ch->endian_lock[0] =(value >> 20) & 1;
96
ch->endian[1] =(value >> 19) & 1;
97
ch->endian_lock[1] =(value >> 18) & 1;
98
- if (ch->endian[0] != ch->endian[1])
99
- fprintf(stderr, "%s: DMA endianness conversion enable attempt\n",
100
- __func__);
101
+ if (ch->endian[0] != ch->endian[1]) {
102
+ qemu_log_mask(LOG_GUEST_ERROR,
103
+ "%s: DMA endianness conversion enable attempt\n",
104
+ __func__);
105
+ }
106
ch->write_mode = (value >> 16) & 3;
107
ch->burst[1] = (value & 0xc000) >> 14;
108
ch->pack[1] = (value & 0x2000) >> 13;
109
@@ -XXX,XX +XXX,XX @@ static void omap_dma4_write(void *opaque, hwaddr addr,
110
ch->burst[0] = (value & 0x0180) >> 7;
111
ch->pack[0] = (value & 0x0040) >> 6;
112
ch->translate[0] = (value & 0x003c) >> 2;
113
- if (ch->translate[0] | ch->translate[1])
114
- fprintf(stderr, "%s: bad MReqAddressTranslate sideband signal\n",
115
- __func__);
116
+ if (ch->translate[0] | ch->translate[1]) {
117
+ qemu_log_mask(LOG_GUEST_ERROR,
118
+ "%s: bad MReqAddressTranslate sideband signal\n",
119
+ __func__);
120
+ }
121
ch->data_type = 1 << (value & 3);
122
if ((value & 3) == 3) {
123
- printf("%s: bad data_type for DMA channel\n", __func__);
124
+ qemu_log_mask(LOG_GUEST_ERROR,
125
+ "%s: bad data_type for DMA channel\n", __func__);
126
ch->data_type >>= 1;
127
}
128
break;
129
--
130
2.17.1
131
132
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-7-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
hw/sd/omap_mmc.c | 13 +++++++++----
9
1 file changed, 9 insertions(+), 4 deletions(-)
10
11
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/omap_mmc.c
14
+++ b/hw/sd/omap_mmc.c
15
@@ -XXX,XX +XXX,XX @@
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
17
*/
18
#include "qemu/osdep.h"
19
+#include "qemu/log.h"
20
#include "hw/hw.h"
21
#include "hw/arm/omap.h"
22
#include "hw/sd/sd.h"
23
@@ -XXX,XX +XXX,XX @@ static void omap_mmc_write(void *opaque, hwaddr offset,
24
s->enable = (value >> 11) & 1;
25
s->be = (value >> 10) & 1;
26
s->clkdiv = (value >> 0) & (s->rev >= 2 ? 0x3ff : 0xff);
27
- if (s->mode != 0)
28
- printf("SD mode %i unimplemented!\n", s->mode);
29
- if (s->be != 0)
30
- printf("SD FIFO byte sex unimplemented!\n");
31
+ if (s->mode != 0) {
32
+ qemu_log_mask(LOG_UNIMP,
33
+ "omap_mmc_wr: mode #%i unimplemented\n", s->mode);
34
+ }
35
+ if (s->be != 0) {
36
+ qemu_log_mask(LOG_UNIMP,
37
+ "omap_mmc_wr: Big Endian not implemented\n");
38
+ }
39
if (s->dw != 0 && s->lines < 4)
40
printf("4-bit SD bus enabled\n");
41
if (!s->enable)
42
--
43
2.17.1
44
45
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-8-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
hw/i2c/omap_i2c.c | 20 ++++++++++++--------
9
1 file changed, 12 insertions(+), 8 deletions(-)
10
11
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/i2c/omap_i2c.c
14
+++ b/hw/i2c/omap_i2c.c
15
@@ -XXX,XX +XXX,XX @@
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
17
*/
18
#include "qemu/osdep.h"
19
+#include "qemu/log.h"
20
#include "hw/hw.h"
21
#include "hw/i2c/i2c.h"
22
#include "hw/arm/omap.h"
23
@@ -XXX,XX +XXX,XX @@ static void omap_i2c_write(void *opaque, hwaddr addr,
24
}
25
break;
26
}
27
- if ((value & (1 << 15)) && !(value & (1 << 10))) {    /* MST */
28
- fprintf(stderr, "%s: I^2C slave mode not supported\n",
29
- __func__);
30
+ if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */
31
+ qemu_log_mask(LOG_UNIMP, "%s: I^2C slave mode not supported\n",
32
+ __func__);
33
break;
34
}
35
- if ((value & (1 << 15)) && value & (1 << 8)) {        /* XA */
36
- fprintf(stderr, "%s: 10-bit addressing mode not supported\n",
37
- __func__);
38
+ if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */
39
+ qemu_log_mask(LOG_UNIMP,
40
+ "%s: 10-bit addressing mode not supported\n",
41
+ __func__);
42
break;
43
}
44
if ((value & (1 << 15)) && value & (1 << 0)) {        /* STT */
45
@@ -XXX,XX +XXX,XX @@ static void omap_i2c_write(void *opaque, hwaddr addr,
46
s->stat |= 0x3f;
47
omap_i2c_interrupts_update(s);
48
}
49
- if (value & (1 << 15))                    /* ST_EN */
50
- fprintf(stderr, "%s: System Test not supported\n", __func__);
51
+ if (value & (1 << 15)) { /* ST_EN */
52
+ qemu_log_mask(LOG_UNIMP,
53
+ "%s: System Test not supported\n", __func__);
54
+ }
55
break;
56
57
default:
58
--
59
2.17.1
60
61
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-10-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
include/hw/arm/omap.h | 12 ++++++------
9
1 file changed, 6 insertions(+), 6 deletions(-)
10
11
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/hw/arm/omap.h
14
+++ b/include/hw/arm/omap.h
15
@@ -XXX,XX +XXX,XX @@
16
# define hw_omap_h        "omap.h"
17
#include "hw/irq.h"
18
#include "target/arm/cpu-qom.h"
19
+#include "qemu/log.h"
20
21
# define OMAP_EMIFS_BASE    0x00000000
22
# define OMAP2_Q0_BASE        0x00000000
23
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
24
unsigned long sdram_size,
25
const char *core);
26
27
-#define OMAP_FMT_plx "%#08" HWADDR_PRIx
28
-
29
uint32_t omap_badwidth_read8(void *opaque, hwaddr addr);
30
void omap_badwidth_write8(void *opaque, hwaddr addr,
31
uint32_t value);
32
@@ -XXX,XX +XXX,XX @@ void omap_badwidth_write32(void *opaque, hwaddr addr,
33
void omap_mpu_wakeup(void *opaque, int irq, int req);
34
35
# define OMAP_BAD_REG(paddr)        \
36
- fprintf(stderr, "%s: Bad register " OMAP_FMT_plx "\n",    \
37
- __func__, paddr)
38
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad register %#08"HWADDR_PRIx"\n", \
39
+ __func__, paddr)
40
# define OMAP_RO_REG(paddr)        \
41
- fprintf(stderr, "%s: Read-only register " OMAP_FMT_plx "\n",    \
42
- __func__, paddr)
43
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Read-only register %#08" \
44
+ HWADDR_PRIx "\n", \
45
+ __func__, paddr)
46
47
/* OMAP-specific Linux bootloader tags for the ATAG_BOARD area
48
(Board-specifc tags are not here) */
49
--
50
2.17.1
51
52
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-11-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
hw/arm/stellaris.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/stellaris.c
14
+++ b/hw/arm/stellaris.c
15
@@ -XXX,XX +XXX,XX @@ static void ssys_write(void *opaque, hwaddr offset,
16
case 0x040: /* SRCR0 */
17
case 0x044: /* SRCR1 */
18
case 0x048: /* SRCR2 */
19
- fprintf(stderr, "Peripheral reset not implemented\n");
20
+ qemu_log_mask(LOG_UNIMP, "Peripheral reset not implemented\n");
21
break;
22
case 0x054: /* IMC */
23
s->int_mask = value & 0x7f;
24
--
25
2.17.1
26
27
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Implement the MVE shifts by immediate, which perform shifts
2
2
on a single general-purpose register.
3
hw_error() finally calls abort(), but there is no need to abort here.
3
4
4
These patterns overlap with the long-shift-by-immediates,
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
so we have to rearrange the grouping a little here.
6
Message-id: 20180624040609.17572-13-f4bug@amsat.org
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
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
9
---
10
---
10
hw/net/stellaris_enet.c | 9 +++++++--
11
target/arm/helper-mve.h | 3 ++
11
1 file changed, 7 insertions(+), 2 deletions(-)
12
target/arm/translate.h | 1 +
12
13
target/arm/t32.decode | 31 ++++++++++++++-----
13
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
14
target/arm/mve_helper.c | 10 ++++++
14
index XXXXXXX..XXXXXXX 100644
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
15
--- a/hw/net/stellaris_enet.c
16
5 files changed, 104 insertions(+), 9 deletions(-)
16
+++ b/hw/net/stellaris_enet.c
17
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-mve.h
21
+++ b/target/arm/helper-mve.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
26
+
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate.h
32
+++ b/target/arm/translate.h
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
37
+typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
38
39
/**
40
* arm_tbflags_from_tb:
41
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/t32.decode
44
+++ b/target/arm/t32.decode
17
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@
18
#include "qemu/osdep.h"
46
19
#include "hw/sysbus.h"
47
&mve_shl_ri rdalo rdahi shim
20
#include "net/net.h"
48
&mve_shl_rr rdalo rdahi rm
21
+#include "qemu/log.h"
49
+&mve_sh_ri rda shim
22
#include <zlib.h>
50
23
51
# rdahi: bits [3:1] from insn, bit 0 is 1
24
//#define DEBUG_STELLARIS_ENET 1
52
# rdalo: bits [3:1] from insn, bit 0 is 0
25
@@ -XXX,XX +XXX,XX @@ static uint64_t stellaris_enet_read(void *opaque, hwaddr offset,
53
@@ -XXX,XX +XXX,XX @@
26
case 0x3c: /* Undocumented: Timestamp? */
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
27
return 0;
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
28
default:
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
29
- hw_error("stellaris_enet_read: Bad offset %x\n", (int)offset);
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
30
+ qemu_log_mask(LOG_GUEST_ERROR, "stellaris_enet_rd%d: Illegal register"
58
+ &mve_sh_ri shim=%imm5_12_6
31
+ " 0x02%" HWADDR_PRIx "\n",
59
32
+ size * 8, offset);
60
{
33
return 0;
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
34
}
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);
35
}
105
}
36
@@ -XXX,XX +XXX,XX @@ static void stellaris_enet_write(void *opaque, hwaddr offset,
106
+
37
/* Ignored. */
107
+uint32_t HELPER(mve_uqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
38
break;
108
+{
39
default:
109
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
40
- hw_error("stellaris_enet_write: Bad offset %x\n", (int)offset);
110
+}
41
+ qemu_log_mask(LOG_GUEST_ERROR, "stellaris_enet_wr%d: Illegal register "
111
+
42
+ "0x02%" HWADDR_PRIx " = 0x%" PRIx64 "\n",
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
43
+ size * 8, offset, value);
113
+{
44
}
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
115
+}
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/translate.c
119
+++ b/target/arm/translate.c
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
121
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
123
{
124
- TCGv_i32 t = tcg_temp_new_i32();
125
+ TCGv_i32 t;
126
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
128
+ if (sh == 32) {
129
+ tcg_gen_movi_i32(d, 0);
130
+ return;
131
+ }
132
+ t = tcg_temp_new_i32();
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
134
tcg_gen_sari_i32(d, a, sh);
135
tcg_gen_add_i32(d, d, t);
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
137
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
139
{
140
- TCGv_i32 t = tcg_temp_new_i32();
141
+ TCGv_i32 t;
142
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
144
+ if (sh == 32) {
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
146
+ return;
147
+ }
148
+ t = tcg_temp_new_i32();
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
150
tcg_gen_shri_i32(d, a, sh);
151
tcg_gen_add_i32(d, d, t);
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
45
}
154
}
46
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
*/
47
--
211
--
48
2.17.1
212
2.20.1
49
213
50
214
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Implement the MVE shifts by register, which perform
2
shifts on a single general-purpose register.
2
3
3
Let's cache config data to avoid fetching and parsing STE/CD
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
structures on each translation. We invalidate them on data structure
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
invalidation commands.
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
7
---
8
target/arm/helper-mve.h | 2 ++
9
target/arm/translate.h | 1 +
10
target/arm/t32.decode | 18 ++++++++++++++----
11
target/arm/mve_helper.c | 10 ++++++++++
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
5 files changed, 57 insertions(+), 4 deletions(-)
6
14
7
We put in place a per-smmu mutex to protect the config cache. This
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
will be useful too to protect the IOTLB cache. The caches can be
9
accessed without BQL, ie. in IO dataplane. The same kind of mutex was
10
put in place in the intel viommu.
11
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 1529653501-15358-3-git-send-email-eric.auger@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
include/hw/arm/smmu-common.h | 5 ++
18
include/hw/arm/smmuv3.h | 1 +
19
hw/arm/smmu-common.c | 24 ++++++-
20
hw/arm/smmuv3.c | 135 +++++++++++++++++++++++++++++++++--
21
hw/arm/trace-events | 6 ++
22
5 files changed, 164 insertions(+), 7 deletions(-)
23
24
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/arm/smmu-common.h
17
--- a/target/arm/helper-mve.h
27
+++ b/include/hw/arm/smmu-common.h
18
+++ b/target/arm/helper-mve.h
28
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
29
int devfn;
20
30
IOMMUMemoryRegion iommu;
21
DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
31
AddressSpace as;
22
DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
32
+ uint32_t cfg_cache_hits;
23
+DEF_HELPER_FLAGS_3(mve_uqrshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
33
+ uint32_t cfg_cache_misses;
24
+DEF_HELPER_FLAGS_3(mve_sqrshr, TCG_CALL_NO_RWG, i32, env, i32, i32)
34
} SMMUDevice;
25
diff --git a/target/arm/translate.h b/target/arm/translate.h
35
26
index XXXXXXX..XXXXXXX 100644
36
typedef struct SMMUNotifierNode {
27
--- a/target/arm/translate.h
37
@@ -XXX,XX +XXX,XX @@ int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
28
+++ b/target/arm/translate.h
38
*/
29
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
39
SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova);
30
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
40
31
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
41
+/* Return the iommu mr associated to @sid, or NULL if none */
32
typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
42
+IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid);
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
41
@@ -XXX,XX +XXX,XX @@
42
&mve_shl_ri rdalo rdahi shim
43
&mve_shl_rr rdalo rdahi rm
44
&mve_sh_ri rda shim
45
+&mve_sh_rr rda rm
46
47
# rdahi: bits [3:1] from insn, bit 0 is 1
48
# rdalo: bits [3:1] from insn, bit 0 is 0
49
@@ -XXX,XX +XXX,XX @@
50
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
51
@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
52
&mve_sh_ri shim=%imm5_12_6
53
+@mve_sh_rr ....... .... . rda:4 rm:4 .... .... .... &mve_sh_rr
54
55
{
56
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
57
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
58
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
59
}
60
61
- LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
62
- ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
63
- UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
64
- SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
65
+ {
66
+ UQRSHL_rr 1110101 0010 1 .... .... 1111 0000 1101 @mve_sh_rr
67
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
68
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
69
+ }
43
+
70
+
44
#endif /* HW_ARM_SMMU_COMMON */
71
+ {
45
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
72
+ SQRSHR_rr 1110101 0010 1 .... .... 1111 0010 1101 @mve_sh_rr
73
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
74
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
75
+ }
76
+
77
UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
78
SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
79
]
80
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
46
index XXXXXXX..XXXXXXX 100644
81
index XXXXXXX..XXXXXXX 100644
47
--- a/include/hw/arm/smmuv3.h
82
--- a/target/arm/mve_helper.c
48
+++ b/include/hw/arm/smmuv3.h
83
+++ b/target/arm/mve_helper.c
49
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUv3State {
84
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
50
SMMUQueue eventq, cmdq;
85
{
51
86
return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
52
qemu_irq irq[4];
53
+ QemuMutex mutex;
54
} SMMUv3State;
55
56
typedef enum {
57
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/smmu-common.c
60
+++ b/hw/arm/smmu-common.c
61
@@ -XXX,XX +XXX,XX @@ static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
62
return &sdev->as;
63
}
87
}
64
88
+
65
+IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid)
89
+uint32_t HELPER(mve_uqrshl)(CPUARMState *env, uint32_t n, uint32_t shift)
66
+{
90
+{
67
+ uint8_t bus_n, devfn;
91
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, true, &env->QF);
68
+ SMMUPciBus *smmu_bus;
69
+ SMMUDevice *smmu;
70
+
71
+ bus_n = PCI_BUS_NUM(sid);
72
+ smmu_bus = smmu_find_smmu_pcibus(s, bus_n);
73
+ if (smmu_bus) {
74
+ devfn = sid & 0x7;
75
+ smmu = smmu_bus->pbdev[devfn];
76
+ if (smmu) {
77
+ return &smmu->iommu;
78
+ }
79
+ }
80
+ return NULL;
81
+}
92
+}
82
+
93
+
83
static void smmu_base_realize(DeviceState *dev, Error **errp)
94
+uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
84
{
95
+{
85
SMMUState *s = ARM_SMMU(dev);
96
+ return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
86
@@ -XXX,XX +XXX,XX @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
97
+}
87
error_propagate(errp, local_err);
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
88
return;
99
index XXXXXXX..XXXXXXX 100644
89
}
100
--- a/target/arm/translate.c
90
-
101
+++ b/target/arm/translate.c
91
+ s->configs = g_hash_table_new_full(NULL, NULL, NULL, g_free);
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
92
s->smmu_pcibus_by_busptr = g_hash_table_new(NULL, NULL);
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
93
104
}
94
if (s->primary_bus) {
105
95
@@ -XXX,XX +XXX,XX @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
96
107
+{
97
static void smmu_base_reset(DeviceState *dev)
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
98
{
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
99
- /* will be filled later on */
110
+ return false;
100
+ SMMUState *s = ARM_SMMU(dev);
111
+ }
112
+ if (!dc_isar_feature(aa32_mve, s) ||
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
115
+ a->rm == a->rda) {
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
117
+ unallocated_encoding(s);
118
+ return true;
119
+ }
101
+
120
+
102
+ g_hash_table_remove_all(s->configs);
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
103
}
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
104
123
+ return true;
105
static Property smmu_dev_properties[] = {
106
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/smmuv3.c
109
+++ b/hw/arm/smmuv3.c
110
@@ -XXX,XX +XXX,XX @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
111
return decode_cd(cfg, &cd, event);
112
}
113
114
+/**
115
+ * smmuv3_get_config - Look up for a cached copy of configuration data for
116
+ * @sdev and on cache miss performs a configuration structure decoding from
117
+ * guest RAM.
118
+ *
119
+ * @sdev: SMMUDevice handle
120
+ * @event: output event info
121
+ *
122
+ * The configuration cache contains data resulting from both STE and CD
123
+ * decoding under the form of an SMMUTransCfg struct. The hash table is indexed
124
+ * by the SMMUDevice handle.
125
+ */
126
+static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev, SMMUEventInfo *event)
127
+{
128
+ SMMUv3State *s = sdev->smmu;
129
+ SMMUState *bc = &s->smmu_state;
130
+ SMMUTransCfg *cfg;
131
+
132
+ cfg = g_hash_table_lookup(bc->configs, sdev);
133
+ if (cfg) {
134
+ sdev->cfg_cache_hits++;
135
+ trace_smmuv3_config_cache_hit(smmu_get_sid(sdev),
136
+ sdev->cfg_cache_hits, sdev->cfg_cache_misses,
137
+ 100 * sdev->cfg_cache_hits /
138
+ (sdev->cfg_cache_hits + sdev->cfg_cache_misses));
139
+ } else {
140
+ sdev->cfg_cache_misses++;
141
+ trace_smmuv3_config_cache_miss(smmu_get_sid(sdev),
142
+ sdev->cfg_cache_hits, sdev->cfg_cache_misses,
143
+ 100 * sdev->cfg_cache_hits /
144
+ (sdev->cfg_cache_hits + sdev->cfg_cache_misses));
145
+ cfg = g_new0(SMMUTransCfg, 1);
146
+
147
+ if (!smmuv3_decode_config(&sdev->iommu, cfg, event)) {
148
+ g_hash_table_insert(bc->configs, sdev, cfg);
149
+ } else {
150
+ g_free(cfg);
151
+ cfg = NULL;
152
+ }
153
+ }
154
+ return cfg;
155
+}
124
+}
156
+
125
+
157
+static void smmuv3_flush_config(SMMUDevice *sdev)
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
158
+{
127
+{
159
+ SMMUv3State *s = sdev->smmu;
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
160
+ SMMUState *bc = &s->smmu_state;
161
+
162
+ trace_smmuv3_config_cache_inv(smmu_get_sid(sdev));
163
+ g_hash_table_remove(bc->configs, sdev);
164
+}
129
+}
165
+
130
+
166
static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
167
IOMMUAccessFlags flag, int iommu_idx)
132
+{
168
{
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
169
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
134
+}
170
SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid};
171
SMMUPTWEventInfo ptw_info = {};
172
SMMUTranslationStatus status;
173
- SMMUTransCfg cfg = {};
174
+ SMMUTransCfg *cfg = NULL;
175
IOMMUTLBEntry entry = {
176
.target_as = &address_space_memory,
177
.iova = addr,
178
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
179
.perm = IOMMU_NONE,
180
};
181
182
+ qemu_mutex_lock(&s->mutex);
183
+
135
+
184
if (!smmu_enabled(s)) {
136
/*
185
status = SMMU_TRANS_DISABLE;
137
* Multiply and multiply accumulate
186
goto epilogue;
138
*/
187
}
188
189
- if (smmuv3_decode_config(mr, &cfg, &event)) {
190
+ cfg = smmuv3_get_config(sdev, &event);
191
+ if (!cfg) {
192
status = SMMU_TRANS_ERROR;
193
goto epilogue;
194
}
195
196
- if (cfg.aborted) {
197
+ if (cfg->aborted) {
198
status = SMMU_TRANS_ABORT;
199
goto epilogue;
200
}
201
202
- if (cfg.bypassed) {
203
+ if (cfg->bypassed) {
204
status = SMMU_TRANS_BYPASS;
205
goto epilogue;
206
}
207
208
- if (smmu_ptw(&cfg, addr, flag, &entry, &ptw_info)) {
209
+ if (smmu_ptw(cfg, addr, flag, &entry, &ptw_info)) {
210
switch (ptw_info.type) {
211
case SMMU_PTW_ERR_WALK_EABT:
212
event.type = SMMU_EVT_F_WALK_EABT;
213
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
214
}
215
216
epilogue:
217
+ qemu_mutex_unlock(&s->mutex);
218
switch (status) {
219
case SMMU_TRANS_SUCCESS:
220
entry.perm = flag;
221
@@ -XXX,XX +XXX,XX @@ epilogue:
222
223
static int smmuv3_cmdq_consume(SMMUv3State *s)
224
{
225
+ SMMUState *bs = ARM_SMMU(s);
226
SMMUCmdError cmd_error = SMMU_CERROR_NONE;
227
SMMUQueue *q = &s->cmdq;
228
SMMUCommandType type = 0;
229
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
230
231
trace_smmuv3_cmdq_opcode(smmu_cmd_string(type));
232
233
+ qemu_mutex_lock(&s->mutex);
234
switch (type) {
235
case SMMU_CMD_SYNC:
236
if (CMD_SYNC_CS(&cmd) & CMD_SYNC_SIG_IRQ) {
237
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
238
break;
239
case SMMU_CMD_PREFETCH_CONFIG:
240
case SMMU_CMD_PREFETCH_ADDR:
241
+ break;
242
case SMMU_CMD_CFGI_STE:
243
+ {
244
+ uint32_t sid = CMD_SID(&cmd);
245
+ IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
246
+ SMMUDevice *sdev;
247
+
248
+ if (CMD_SSEC(&cmd)) {
249
+ cmd_error = SMMU_CERROR_ILL;
250
+ break;
251
+ }
252
+
253
+ if (!mr) {
254
+ break;
255
+ }
256
+
257
+ trace_smmuv3_cmdq_cfgi_ste(sid);
258
+ sdev = container_of(mr, SMMUDevice, iommu);
259
+ smmuv3_flush_config(sdev);
260
+
261
+ break;
262
+ }
263
case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */
264
+ {
265
+ uint32_t start = CMD_SID(&cmd), end, i;
266
+ uint8_t range = CMD_STE_RANGE(&cmd);
267
+
268
+ if (CMD_SSEC(&cmd)) {
269
+ cmd_error = SMMU_CERROR_ILL;
270
+ break;
271
+ }
272
+
273
+ end = start + (1 << (range + 1)) - 1;
274
+ trace_smmuv3_cmdq_cfgi_ste_range(start, end);
275
+
276
+ for (i = start; i <= end; i++) {
277
+ IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, i);
278
+ SMMUDevice *sdev;
279
+
280
+ if (!mr) {
281
+ continue;
282
+ }
283
+ sdev = container_of(mr, SMMUDevice, iommu);
284
+ smmuv3_flush_config(sdev);
285
+ }
286
+ break;
287
+ }
288
case SMMU_CMD_CFGI_CD:
289
case SMMU_CMD_CFGI_CD_ALL:
290
+ {
291
+ uint32_t sid = CMD_SID(&cmd);
292
+ IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
293
+ SMMUDevice *sdev;
294
+
295
+ if (CMD_SSEC(&cmd)) {
296
+ cmd_error = SMMU_CERROR_ILL;
297
+ break;
298
+ }
299
+
300
+ if (!mr) {
301
+ break;
302
+ }
303
+
304
+ trace_smmuv3_cmdq_cfgi_cd(sid);
305
+ sdev = container_of(mr, SMMUDevice, iommu);
306
+ smmuv3_flush_config(sdev);
307
+ break;
308
+ }
309
case SMMU_CMD_TLBI_NH_ALL:
310
case SMMU_CMD_TLBI_NH_ASID:
311
case SMMU_CMD_TLBI_NH_VA:
312
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
313
"Illegal command type: %d\n", CMD_TYPE(&cmd));
314
break;
315
}
316
+ qemu_mutex_unlock(&s->mutex);
317
if (cmd_error) {
318
break;
319
}
320
@@ -XXX,XX +XXX,XX @@ static void smmu_realize(DeviceState *d, Error **errp)
321
return;
322
}
323
324
+ qemu_mutex_init(&s->mutex);
325
+
326
memory_region_init_io(&sys->iomem, OBJECT(s),
327
&smmu_mem_ops, sys, TYPE_ARM_SMMUV3, 0x20000);
328
329
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
330
index XXXXXXX..XXXXXXX 100644
331
--- a/hw/arm/trace-events
332
+++ b/hw/arm/trace-events
333
@@ -XXX,XX +XXX,XX @@ smmuv3_translate_success(const char *n, uint16_t sid, uint64_t iova, uint64_t tr
334
smmuv3_get_cd(uint64_t addr) "CD addr: 0x%"PRIx64
335
smmuv3_decode_cd(uint32_t oas) "oas=%d"
336
smmuv3_decode_cd_tt(int i, uint32_t tsz, uint64_t ttb, uint32_t granule_sz) "TT[%d]:tsz:%d ttb:0x%"PRIx64" granule_sz:%d"
337
+smmuv3_cmdq_cfgi_ste(int streamid) "streamid =%d"
338
+smmuv3_cmdq_cfgi_ste_range(int start, int end) "start=0x%d - end=0x%d"
339
+smmuv3_cmdq_cfgi_cd(uint32_t sid) "streamid = %d"
340
+smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid %d (hits=%d, misses=%d, hit rate=%d)"
341
+smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid %d (hits=%d, misses=%d, hit rate=%d)"
342
+smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid %d"
343
--
139
--
344
2.17.1
140
2.20.1
345
141
346
142
diff view generated by jsdifflib