1
Small pile of bug fixes for rc1. I've included my patches to get
1
Hi; here's the latest batch of arm changes. The big thing
2
our docs building with Sphinx 3, just for convenience...
2
in here is the SMMUv3 changes to add stage-2 translation support.
3
3
4
thanks
4
-- PMM
5
-- PMM
5
6
6
The following changes since commit b149dea55cce97cb226683d06af61984a1c11e96:
7
The following changes since commit aa9bbd865502ed517624ab6fe7d4b5d89ca95e43:
7
8
8
Merge remote-tracking branch 'remotes/cschoenebeck/tags/pull-9p-20201102' into staging (2020-11-02 10:57:48 +0000)
9
Merge tag 'pull-ppc-20230528' of https://gitlab.com/danielhb/qemu into staging (2023-05-29 14:31:52 -0700)
9
10
10
are available in the Git repository at:
11
are available in the Git repository at:
11
12
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201102
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230530
13
14
14
for you to fetch changes up to ffb4fbf90a2f63c9cb33e4bb9f854c79bf04ca4a:
15
for you to fetch changes up to b03d0d4f531a8b867e0aac1fab0b876903015680:
15
16
16
tests/qtest/npcm7xx_rng-test: Disable randomness tests (2020-11-02 16:52:18 +0000)
17
docs: sbsa: correct graphics card name (2023-05-30 13:32:46 +0100)
17
18
18
----------------------------------------------------------------
19
----------------------------------------------------------------
19
target-arm queue:
20
target-arm queue:
20
* target/arm: Fix Neon emulation bugs on big-endian hosts
21
* fsl-imx6: Add SNVS support for i.MX6 boards
21
* target/arm: fix handling of HCR.FB
22
* smmuv3: Add support for stage 2 translations
22
* target/arm: fix LORID_EL1 access check
23
* hw/dma/xilinx_axidma: Check DMASR.HALTED to prevent infinite loop
23
* disas/capstone: Fix monitor disassembly of >32 bytes
24
* hw/arm/xlnx-zynqmp: fix unsigned error when checking the RPUs number
24
* hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
25
* cleanups for recent Kconfig changes
25
* hw/arm/boot: fix SVE for EL3 direct kernel boot
26
* target/arm: Explicitly select short-format FSR for M-profile
26
* hw/display/omap_lcdc: Fix potential NULL pointer dereference
27
* tests/qtest: Run arm-specific tests only if the required machine is available
27
* hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
28
* hw/arm/sbsa-ref: add GIC node into DT
28
* target/arm: Get correct MMU index for other-security-state
29
* docs: sbsa: correct graphics card name
29
* configure: Test that gio libs from pkg-config work
30
* Update copyright dates to 2023
30
* hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
31
* docs: Fix building with Sphinx 3
32
* tests/qtest/npcm7xx_rng-test: Disable randomness tests
33
31
34
----------------------------------------------------------------
32
----------------------------------------------------------------
35
AlexChen (2):
33
Clément Chigot (1):
36
hw/display/omap_lcdc: Fix potential NULL pointer dereference
34
hw/arm/xlnx-zynqmp: fix unsigned error when checking the RPUs number
37
hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
38
35
39
Peter Maydell (9):
36
Enze Li (1):
40
target/arm: Fix float16 pairwise Neon ops on big-endian hosts
37
Update copyright dates to 2023
41
target/arm: Fix VUDOT/VSDOT (scalar) on big-endian hosts
42
disas/capstone: Fix monitor disassembly of >32 bytes
43
target/arm: Get correct MMU index for other-security-state
44
configure: Test that gio libs from pkg-config work
45
hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
46
scripts/kerneldoc: For Sphinx 3 use c:macro for macros with arguments
47
qemu-option-trace.rst.inc: Don't use option:: markup
48
tests/qtest/npcm7xx_rng-test: Disable randomness tests
49
38
50
Philippe Mathieu-Daudé (1):
39
Fabiano Rosas (3):
51
hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
40
target/arm: Explain why we need to select ARM_V7M
41
arm/Kconfig: Keep Kconfig default entries in default.mak as documentation
42
arm/Kconfig: Make TCG dependence explicit
52
43
53
Richard Henderson (11):
44
Marcin Juszkiewicz (2):
54
target/arm: Introduce neon_full_reg_offset
45
hw/arm/sbsa-ref: add GIC node into DT
55
target/arm: Move neon_element_offset to translate.c
46
docs: sbsa: correct graphics card name
56
target/arm: Use neon_element_offset in neon_load/store_reg
57
target/arm: Use neon_element_offset in vfp_reg_offset
58
target/arm: Add read/write_neon_element32
59
target/arm: Expand read/write_neon_element32 to all MemOp
60
target/arm: Rename neon_load_reg32 to vfp_load_reg32
61
target/arm: Add read/write_neon_element64
62
target/arm: Rename neon_load_reg64 to vfp_load_reg64
63
target/arm: Simplify do_long_3d and do_2scalar_long
64
target/arm: Improve do_prewiden_3d
65
47
66
Rémi Denis-Courmont (3):
48
Mostafa Saleh (10):
67
target/arm: fix handling of HCR.FB
49
hw/arm/smmuv3: Add missing fields for IDR0
68
target/arm: fix LORID_EL1 access check
50
hw/arm/smmuv3: Update translation config to hold stage-2
69
hw/arm/boot: fix SVE for EL3 direct kernel boot
51
hw/arm/smmuv3: Refactor stage-1 PTW
52
hw/arm/smmuv3: Add page table walk for stage-2
53
hw/arm/smmuv3: Parse STE config for stage-2
54
hw/arm/smmuv3: Make TLB lookup work for stage-2
55
hw/arm/smmuv3: Add VMID to TLB tagging
56
hw/arm/smmuv3: Add CMDs related to stage-2
57
hw/arm/smmuv3: Add stage-2 support in iova notifier
58
hw/arm/smmuv3: Add knob to choose translation stage and enable stage-2
70
59
71
docs/qemu-option-trace.rst.inc | 6 +-
60
Peter Maydell (1):
72
configure | 10 +-
61
target/arm: Explicitly select short-format FSR for M-profile
73
include/hw/intc/arm_gicv3_common.h | 1 -
74
disas/capstone.c | 2 +-
75
hw/arm/boot.c | 3 +
76
hw/arm/smmuv3.c | 3 +-
77
hw/display/exynos4210_fimd.c | 4 +-
78
hw/display/omap_lcdc.c | 10 +-
79
hw/intc/arm_gicv3_cpuif.c | 5 +-
80
target/arm/helper.c | 24 +-
81
target/arm/m_helper.c | 3 +-
82
target/arm/translate.c | 153 +++++++++---
83
target/arm/vec_helper.c | 12 +-
84
tests/qtest/npcm7xx_rng-test.c | 14 +-
85
scripts/kernel-doc | 18 +-
86
target/arm/translate-neon.c.inc | 472 ++++++++++++++++++++-----------------
87
target/arm/translate-vfp.c.inc | 341 +++++++++++----------------
88
17 files changed, 588 insertions(+), 493 deletions(-)
89
62
63
Thomas Huth (1):
64
tests/qtest: Run arm-specific tests only if the required machine is available
65
66
Tommy Wu (1):
67
hw/dma/xilinx_axidma: Check DMASR.HALTED to prevent infinite loop.
68
69
Vitaly Cheptsov (1):
70
fsl-imx6: Add SNVS support for i.MX6 boards
71
72
docs/conf.py | 2 +-
73
docs/system/arm/sbsa.rst | 2 +-
74
configs/devices/aarch64-softmmu/default.mak | 6 +
75
configs/devices/arm-softmmu/default.mak | 40 ++++
76
hw/arm/smmu-internal.h | 37 +++
77
hw/arm/smmuv3-internal.h | 12 +-
78
include/hw/arm/fsl-imx6.h | 2 +
79
include/hw/arm/smmu-common.h | 45 +++-
80
include/hw/arm/smmuv3.h | 4 +
81
include/qemu/help-texts.h | 2 +-
82
hw/arm/fsl-imx6.c | 8 +
83
hw/arm/sbsa-ref.c | 19 +-
84
hw/arm/smmu-common.c | 209 ++++++++++++++--
85
hw/arm/smmuv3.c | 357 ++++++++++++++++++++++++----
86
hw/arm/xlnx-zynqmp.c | 2 +-
87
hw/dma/xilinx_axidma.c | 11 +-
88
target/arm/tcg/tlb_helper.c | 13 +-
89
hw/arm/Kconfig | 123 ++++++----
90
hw/arm/trace-events | 14 +-
91
target/arm/Kconfig | 3 +
92
tests/qtest/meson.build | 7 +-
93
21 files changed, 773 insertions(+), 145 deletions(-)
94
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
From: Vitaly Cheptsov <cheptsov@ispras.ru>
2
2
3
Secure mode is not exempted from checking SCR_EL3.TLOR, and in the
3
SNVS is supported on both i.MX6 and i.MX6UL and is needed
4
future HCR_EL2.TLOR when S-EL2 is enabled.
4
to support shutdown on the board.
5
5
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
6
Cc: Peter Maydell <peter.maydell@linaro.org> (odd fixer:SABRELITE / i.MX6)
7
Cc: Jean-Christophe Dubois <jcd@tribudubois.net> (reviewer:SABRELITE / i.MX6)
8
Cc: qemu-arm@nongnu.org (open list:SABRELITE / i.MX6)
9
Cc: qemu-devel@nongnu.org (open list:All patches CC here)
10
Signed-off-by: Vitaly Cheptsov <cheptsov@ispras.ru>
11
Message-id: 20230515095015.66860-1-cheptsov@ispras.ru
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
14
---
10
target/arm/helper.c | 19 +++++--------------
15
include/hw/arm/fsl-imx6.h | 2 ++
11
1 file changed, 5 insertions(+), 14 deletions(-)
16
hw/arm/fsl-imx6.c | 8 ++++++++
17
2 files changed, 10 insertions(+)
12
18
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
21
--- a/include/hw/arm/fsl-imx6.h
16
+++ b/target/arm/helper.c
22
+++ b/include/hw/arm/fsl-imx6.h
17
@@ -XXX,XX +XXX,XX @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
23
@@ -XXX,XX +XXX,XX @@
18
#endif
24
#include "hw/cpu/a9mpcore.h"
19
25
#include "hw/misc/imx6_ccm.h"
20
/* Shared logic between LORID and the rest of the LOR* registers.
26
#include "hw/misc/imx6_src.h"
21
- * Secure state has already been delt with.
27
+#include "hw/misc/imx7_snvs.h"
22
+ * Secure state exclusion has already been dealt with.
28
#include "hw/watchdog/wdt_imx2.h"
23
*/
29
#include "hw/char/imx_serial.h"
24
-static CPAccessResult access_lor_ns(CPUARMState *env)
30
#include "hw/timer/imx_gpt.h"
25
+static CPAccessResult access_lor_ns(CPUARMState *env,
31
@@ -XXX,XX +XXX,XX @@ struct FslIMX6State {
26
+ const ARMCPRegInfo *ri, bool isread)
32
A9MPPrivState a9mpcore;
27
{
33
IMX6CCMState ccm;
28
int el = arm_current_el(env);
34
IMX6SRCState src;
29
35
+ IMX7SNVSState snvs;
30
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_ns(CPUARMState *env)
36
IMXSerialState uart[FSL_IMX6_NUM_UARTS];
31
return CP_ACCESS_OK;
37
IMXGPTState gpt;
32
}
38
IMXEPITState epit[FSL_IMX6_NUM_EPITS];
33
39
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
34
-static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri,
40
index XXXXXXX..XXXXXXX 100644
35
- bool isread)
41
--- a/hw/arm/fsl-imx6.c
36
-{
42
+++ b/hw/arm/fsl-imx6.c
37
- if (arm_is_secure_below_el3(env)) {
43
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_init(Object *obj)
38
- /* Access ok in secure mode. */
44
39
- return CP_ACCESS_OK;
45
object_initialize_child(obj, "src", &s->src, TYPE_IMX6_SRC);
40
- }
46
41
- return access_lor_ns(env);
47
+ object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
42
-}
48
+
43
-
49
for (i = 0; i < FSL_IMX6_NUM_UARTS; i++) {
44
static CPAccessResult access_lor_other(CPUARMState *env,
50
snprintf(name, NAME_SIZE, "uart%d", i + 1);
45
const ARMCPRegInfo *ri, bool isread)
51
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
46
{
52
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
47
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_other(CPUARMState *env,
53
qdev_get_gpio_in(DEVICE(&s->a9mpcore),
48
/* Access denied in secure mode. */
54
FSL_IMX6_ENET_MAC_1588_IRQ));
49
return CP_ACCESS_TRAP;
55
50
}
56
+ /*
51
- return access_lor_ns(env);
57
+ * SNVS
52
+ return access_lor_ns(env, ri, isread);
58
+ */
53
}
59
+ sysbus_realize(SYS_BUS_DEVICE(&s->snvs), &error_abort);
54
60
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6_SNVSHP_ADDR);
55
/*
61
+
56
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lor_reginfo[] = {
62
/*
57
.type = ARM_CP_CONST, .resetvalue = 0 },
63
* Watchdog
58
{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
64
*/
59
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
60
- .access = PL1_R, .accessfn = access_lorid,
61
+ .access = PL1_R, .accessfn = access_lor_ns,
62
.type = ARM_CP_CONST, .resetvalue = 0 },
63
REGINFO_SENTINEL
64
};
65
--
65
--
66
2.20.1
66
2.34.1
67
68
diff view generated by jsdifflib
1
The randomness tests in the NPCM7xx RNG test fail intermittently
1
From: Mostafa Saleh <smostafa@google.com>
2
but fairly frequently. On my machine running the test in a loop:
3
while QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/npcm7xx_rng-test; do true; done
4
2
5
will fail in less than a minute with an error like:
3
In preparation for adding stage-2 support.
6
ERROR:../../tests/qtest/npcm7xx_rng-test.c:256:test_first_byte_runs:
4
Add IDR0 fields related to stage-2.
7
assertion failed (calc_runs_p(buf.l, sizeof(buf) * BITS_PER_BYTE) > 0.01): (0.00286205989 > 0.01)
8
5
9
(Failures have been observed on all 4 of the randomness tests,
6
VMID16: 16-bit VMID supported.
10
not just first_byte_runs.)
7
S2P: Stage-2 translation supported.
11
8
12
It's not clear why these tests are failing like this, but intermittent
9
They are described in 6.3.1 SMMU_IDR0.
13
failures make CI and merge testing awkward, so disable running them
14
unless a developer specifically sets QEMU_TEST_FLAKY_RNG_TESTS when
15
running the test suite, until we work out the cause.
16
10
11
No functional change intended.
12
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Eric Auger <eric.auger@redhat.com>
15
Signed-off-by: Mostafa Saleh <smostafa@google.com>
16
Tested-by: Eric Auger <eric.auger@redhat.com>
17
Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
18
Message-id: 20230516203327.2051088-2-smostafa@google.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Message-id: 20201102152454.8287-1-peter.maydell@linaro.org
20
Reviewed-by: Havard Skinnemoen <hskinnemoen@google.com>
21
---
20
---
22
tests/qtest/npcm7xx_rng-test.c | 14 ++++++++++----
21
hw/arm/smmuv3-internal.h | 2 ++
23
1 file changed, 10 insertions(+), 4 deletions(-)
22
1 file changed, 2 insertions(+)
24
23
25
diff --git a/tests/qtest/npcm7xx_rng-test.c b/tests/qtest/npcm7xx_rng-test.c
24
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
26
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/qtest/npcm7xx_rng-test.c
26
--- a/hw/arm/smmuv3-internal.h
28
+++ b/tests/qtest/npcm7xx_rng-test.c
27
+++ b/hw/arm/smmuv3-internal.h
29
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
28
@@ -XXX,XX +XXX,XX @@ typedef enum SMMUTranslationStatus {
30
29
/* MMIO Registers */
31
qtest_add_func("npcm7xx_rng/enable_disable", test_enable_disable);
30
32
qtest_add_func("npcm7xx_rng/rosel", test_rosel);
31
REG32(IDR0, 0x0)
33
- qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
32
+ FIELD(IDR0, S2P, 0 , 1)
34
- qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
33
FIELD(IDR0, S1P, 1 , 1)
35
- qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
34
FIELD(IDR0, TTF, 2 , 2)
36
- qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
35
FIELD(IDR0, COHACC, 4 , 1)
37
+ /*
36
FIELD(IDR0, ASID16, 12, 1)
38
+ * These tests fail intermittently; only run them on explicit
37
+ FIELD(IDR0, VMID16, 18, 1)
39
+ * request until we figure out why.
38
FIELD(IDR0, TTENDIAN, 21, 2)
40
+ */
39
FIELD(IDR0, STALL_MODEL, 24, 2)
41
+ if (getenv("QEMU_TEST_FLAKY_RNG_TESTS")) {
40
FIELD(IDR0, TERM_MODEL, 26, 1)
42
+ qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
43
+ qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
44
+ qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
45
+ qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
46
+ }
47
48
qtest_start("-machine npcm750-evb");
49
ret = g_test_run();
50
--
41
--
51
2.20.1
42
2.34.1
52
53
diff view generated by jsdifflib
1
From: AlexChen <alex.chen@huawei.com>
1
From: Mostafa Saleh <smostafa@google.com>
2
2
3
In exynos4210_fimd_update(), the pointer s is dereferinced before
3
In preparation for adding stage-2 support, add a S2 config
4
being check if it is valid, which may lead to NULL pointer dereference.
4
struct(SMMUS2Cfg), composed of the following fields and embedded in
5
So move the assignment to global_width after checking that the s is valid.
5
the main SMMUTransCfg:
6
-tsz: Size of IPA input region (S2T0SZ)
7
-sl0: Start level of translation (S2SL0)
8
-affd: AF Fault Disable (S2AFFD)
9
-record_faults: Record fault events (S2R)
10
-granule_sz: Granule page shift (based on S2TG)
11
-vmid: Virtual Machine ID (S2VMID)
12
-vttb: Address of translation table base (S2TTB)
13
-eff_ps: Effective PA output range (based on S2PS)
6
14
7
Reported-by: Euler Robot <euler.robot@huawei.com>
15
They will be used in the next patches in stage-2 address translation.
8
Signed-off-by: Alex Chen <alex.chen@huawei.com>
16
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
The fields in SMMUS2Cfg, are reordered to make the shared and stage-1
10
Message-id: 5F9F8D88.9030102@huawei.com
18
fields next to each other, this reordering didn't change the struct
19
size (104 bytes before and after).
20
21
Stage-1 only fields: aa64, asid, tt, ttb, tbi, record_faults, oas.
22
oas is stage-1 output address size. However, it is used to check
23
input address in case stage-1 is unimplemented or bypassed according
24
to SMMUv3 manual IHI0070.E "3.4. Address sizes"
25
26
Shared fields: stage, disabled, bypassed, aborted, iotlb_*.
27
28
No functional change intended.
29
30
Reviewed-by: Eric Auger <eric.auger@redhat.com>
31
Signed-off-by: Mostafa Saleh <smostafa@google.com>
32
Tested-by: Eric Auger <eric.auger@redhat.com>
33
Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
34
Message-id: 20230516203327.2051088-3-smostafa@google.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
36
---
13
hw/display/exynos4210_fimd.c | 4 +++-
37
include/hw/arm/smmu-common.h | 22 +++++++++++++++++++---
14
1 file changed, 3 insertions(+), 1 deletion(-)
38
1 file changed, 19 insertions(+), 3 deletions(-)
15
39
16
diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c
40
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
17
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/display/exynos4210_fimd.c
42
--- a/include/hw/arm/smmu-common.h
19
+++ b/hw/display/exynos4210_fimd.c
43
+++ b/include/hw/arm/smmu-common.h
20
@@ -XXX,XX +XXX,XX @@ static void exynos4210_fimd_update(void *opaque)
44
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTLBEntry {
21
bool blend = false;
45
uint8_t granule;
22
uint8_t *host_fb_addr;
46
} SMMUTLBEntry;
23
bool is_dirty = false;
47
24
- const int global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
48
+/* Stage-2 configuration. */
25
+ int global_width;
49
+typedef struct SMMUS2Cfg {
26
50
+ uint8_t tsz; /* Size of IPA input region (S2T0SZ) */
27
if (!s || !s->console || !s->enabled ||
51
+ uint8_t sl0; /* Start level of translation (S2SL0) */
28
surface_bits_per_pixel(qemu_console_surface(s->console)) == 0) {
52
+ bool affd; /* AF Fault Disable (S2AFFD) */
29
return;
53
+ bool record_faults; /* Record fault events (S2R) */
30
}
54
+ uint8_t granule_sz; /* Granule page shift (based on S2TG) */
55
+ uint8_t eff_ps; /* Effective PA output range (based on S2PS) */
56
+ uint16_t vmid; /* Virtual Machine ID (S2VMID) */
57
+ uint64_t vttb; /* Address of translation table base (S2TTB) */
58
+} SMMUS2Cfg;
31
+
59
+
32
+ global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
60
/*
33
exynos4210_update_resolution(s);
61
* Generic structure populated by derived SMMU devices
34
surface = qemu_console_surface(s->console);
62
* after decoding the configuration information and used as
35
63
* input to the page table walk
64
*/
65
typedef struct SMMUTransCfg {
66
+ /* Shared fields between stage-1 and stage-2. */
67
int stage; /* translation stage */
68
- bool aa64; /* arch64 or aarch32 translation table */
69
bool disabled; /* smmu is disabled */
70
bool bypassed; /* translation is bypassed */
71
bool aborted; /* translation is aborted */
72
+ uint32_t iotlb_hits; /* counts IOTLB hits */
73
+ uint32_t iotlb_misses; /* counts IOTLB misses*/
74
+ /* Used by stage-1 only. */
75
+ bool aa64; /* arch64 or aarch32 translation table */
76
bool record_faults; /* record fault events */
77
uint64_t ttb; /* TT base address */
78
uint8_t oas; /* output address width */
79
uint8_t tbi; /* Top Byte Ignore */
80
uint16_t asid;
81
SMMUTransTableInfo tt[2];
82
- uint32_t iotlb_hits; /* counts IOTLB hits for this asid */
83
- uint32_t iotlb_misses; /* counts IOTLB misses for this asid */
84
+ /* Used by stage-2 only. */
85
+ struct SMMUS2Cfg s2cfg;
86
} SMMUTransCfg;
87
88
typedef struct SMMUDevice {
36
--
89
--
37
2.20.1
90
2.34.1
38
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Mostafa Saleh <smostafa@google.com>
2
2
3
In both cases, we can sink the write-back and perform
3
In preparation for adding stage-2 support, rename smmu_ptw_64 to
4
the accumulate into the normal destination temps.
4
smmu_ptw_64_s1 and refactor some of the code so it can be reused in
5
stage-2 page table walk.
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Remove AA64 check from PTW as decode_cd already ensures that AA64 is
7
Message-id: 20201030022618.785675-11-richard.henderson@linaro.org
8
used, otherwise it faults with C_BAD_CD.
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
10
A stage member is added to SMMUPTWEventInfo to differentiate
11
between stage-1 and stage-2 ptw faults.
12
13
Add stage argument to trace_smmu_ptw_level be consistent with other
14
trace events.
15
16
Signed-off-by: Mostafa Saleh <smostafa@google.com>
17
Reviewed-by: Eric Auger <eric.auger@redhat.com>
18
Tested-by: Eric Auger <eric.auger@redhat.com>
19
Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
20
Message-id: 20230516203327.2051088-4-smostafa@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
22
---
11
target/arm/translate-neon.c.inc | 23 +++++++++--------------
23
include/hw/arm/smmu-common.h | 16 +++++++++++++---
12
1 file changed, 9 insertions(+), 14 deletions(-)
24
hw/arm/smmu-common.c | 27 ++++++++++-----------------
25
hw/arm/smmuv3.c | 2 ++
26
hw/arm/trace-events | 2 +-
27
4 files changed, 26 insertions(+), 21 deletions(-)
13
28
14
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
29
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
15
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-neon.c.inc
31
--- a/include/hw/arm/smmu-common.h
17
+++ b/target/arm/translate-neon.c.inc
32
+++ b/include/hw/arm/smmu-common.h
18
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
33
@@ -XXX,XX +XXX,XX @@
19
if (accfn) {
34
#include "hw/pci/pci.h"
20
tmp = tcg_temp_new_i64();
35
#include "qom/object.h"
21
read_neon_element64(tmp, a->vd, 0, MO_64);
36
22
- accfn(tmp, tmp, rd0);
37
-#define SMMU_PCI_BUS_MAX 256
23
- write_neon_element64(tmp, a->vd, 0, MO_64);
38
-#define SMMU_PCI_DEVFN_MAX 256
24
+ accfn(rd0, tmp, rd0);
39
-#define SMMU_PCI_DEVFN(sid) (sid & 0xFF)
25
read_neon_element64(tmp, a->vd, 1, MO_64);
40
+#define SMMU_PCI_BUS_MAX 256
26
- accfn(tmp, tmp, rd1);
41
+#define SMMU_PCI_DEVFN_MAX 256
27
- write_neon_element64(tmp, a->vd, 1, MO_64);
42
+#define SMMU_PCI_DEVFN(sid) (sid & 0xFF)
28
+ accfn(rd1, tmp, rd1);
43
+
29
tcg_temp_free_i64(tmp);
44
+/* VMSAv8-64 Translation constants and functions */
30
- } else {
45
+#define VMSA_LEVELS 4
31
- write_neon_element64(rd0, a->vd, 0, MO_64);
46
+
32
- write_neon_element64(rd1, a->vd, 1, MO_64);
47
+#define VMSA_STRIDE(gran) ((gran) - VMSA_LEVELS + 1)
48
+#define VMSA_BIT_LVL(isz, strd, lvl) ((isz) - (strd) * \
49
+ (VMSA_LEVELS - (lvl)))
50
+#define VMSA_IDXMSK(isz, strd, lvl) ((1ULL << \
51
+ VMSA_BIT_LVL(isz, strd, lvl)) - 1)
52
53
/*
54
* Page table walk error types
55
@@ -XXX,XX +XXX,XX @@ typedef enum {
56
} SMMUPTWEventType;
57
58
typedef struct SMMUPTWEventInfo {
59
+ int stage;
60
SMMUPTWEventType type;
61
dma_addr_t addr; /* fetched address that induced an abort, if any */
62
} SMMUPTWEventInfo;
63
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/smmu-common.c
66
+++ b/hw/arm/smmu-common.c
67
@@ -XXX,XX +XXX,XX @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova)
68
}
69
70
/**
71
- * smmu_ptw_64 - VMSAv8-64 Walk of the page tables for a given IOVA
72
+ * smmu_ptw_64_s1 - VMSAv8-64 Walk of the page tables for a given IOVA
73
* @cfg: translation config
74
* @iova: iova to translate
75
* @perm: access type
76
@@ -XXX,XX +XXX,XX @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova)
77
* Upon success, @tlbe is filled with translated_addr and entry
78
* permission rights.
79
*/
80
-static int smmu_ptw_64(SMMUTransCfg *cfg,
81
- dma_addr_t iova, IOMMUAccessFlags perm,
82
- SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
83
+static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
84
+ dma_addr_t iova, IOMMUAccessFlags perm,
85
+ SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
86
{
87
dma_addr_t baseaddr, indexmask;
88
int stage = cfg->stage;
89
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
33
}
90
}
34
91
35
+ write_neon_element64(rd0, a->vd, 0, MO_64);
92
granule_sz = tt->granule_sz;
36
+ write_neon_element64(rd1, a->vd, 1, MO_64);
93
- stride = granule_sz - 3;
37
tcg_temp_free_i64(rd0);
94
+ stride = VMSA_STRIDE(granule_sz);
38
tcg_temp_free_i64(rd1);
95
inputsize = 64 - tt->tsz;
39
96
level = 4 - (inputsize - 4) / stride;
40
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
97
- indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
41
if (accfn) {
98
+ indexmask = VMSA_IDXMSK(inputsize, stride, level);
42
TCGv_i64 t64 = tcg_temp_new_i64();
99
baseaddr = extract64(tt->ttb, 0, 48);
43
read_neon_element64(t64, a->vd, 0, MO_64);
100
baseaddr &= ~indexmask;
44
- accfn(t64, t64, rn0_64);
101
45
- write_neon_element64(t64, a->vd, 0, MO_64);
102
- while (level <= 3) {
46
+ accfn(rn0_64, t64, rn0_64);
103
+ while (level < VMSA_LEVELS) {
47
read_neon_element64(t64, a->vd, 1, MO_64);
104
uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
48
- accfn(t64, t64, rn1_64);
105
uint64_t mask = subpage_size - 1;
49
- write_neon_element64(t64, a->vd, 1, MO_64);
106
uint32_t offset = iova_level_offset(iova, inputsize, level, granule_sz);
50
+ accfn(rn1_64, t64, rn1_64);
107
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
51
tcg_temp_free_i64(t64);
108
if (get_pte(baseaddr, offset, &pte, info)) {
52
- } else {
109
goto error;
53
- write_neon_element64(rn0_64, a->vd, 0, MO_64);
110
}
54
- write_neon_element64(rn1_64, a->vd, 1, MO_64);
111
- trace_smmu_ptw_level(level, iova, subpage_size,
55
}
112
+ trace_smmu_ptw_level(stage, level, iova, subpage_size,
56
+
113
baseaddr, offset, pte);
57
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
114
58
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
115
if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) {
59
tcg_temp_free_i64(rn0_64);
116
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
60
tcg_temp_free_i64(rn1_64);
117
info->type = SMMU_PTW_ERR_TRANSLATION;
61
return true;
118
119
error:
120
+ info->stage = 1;
121
tlbe->entry.perm = IOMMU_NONE;
122
return -EINVAL;
123
}
124
@@ -XXX,XX +XXX,XX @@ error:
125
int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
126
SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
127
{
128
- if (!cfg->aa64) {
129
- /*
130
- * This code path is not entered as we check this while decoding
131
- * the configuration data in the derived SMMU model.
132
- */
133
- g_assert_not_reached();
134
- }
135
-
136
- return smmu_ptw_64(cfg, iova, perm, tlbe, info);
137
+ return smmu_ptw_64_s1(cfg, iova, perm, tlbe, info);
138
}
139
140
/**
141
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/hw/arm/smmuv3.c
144
+++ b/hw/arm/smmuv3.c
145
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
146
cached_entry = g_new0(SMMUTLBEntry, 1);
147
148
if (smmu_ptw(cfg, aligned_addr, flag, cached_entry, &ptw_info)) {
149
+ /* All faults from PTW has S2 field. */
150
+ event.u.f_walk_eabt.s2 = (ptw_info.stage == 2);
151
g_free(cached_entry);
152
switch (ptw_info.type) {
153
case SMMU_PTW_ERR_WALK_EABT:
154
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
155
index XXXXXXX..XXXXXXX 100644
156
--- a/hw/arm/trace-events
157
+++ b/hw/arm/trace-events
158
@@ -XXX,XX +XXX,XX @@ virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
159
160
# smmu-common.c
161
smmu_add_mr(const char *name) "%s"
162
-smmu_ptw_level(int level, uint64_t iova, size_t subpage_size, uint64_t baseaddr, uint32_t offset, uint64_t pte) "level=%d iova=0x%"PRIx64" subpage_sz=0x%zx baseaddr=0x%"PRIx64" offset=%d => pte=0x%"PRIx64
163
+smmu_ptw_level(int stage, int level, uint64_t iova, size_t subpage_size, uint64_t baseaddr, uint32_t offset, uint64_t pte) "stage=%d level=%d iova=0x%"PRIx64" subpage_sz=0x%zx baseaddr=0x%"PRIx64" offset=%d => pte=0x%"PRIx64
164
smmu_ptw_invalid_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, uint32_t offset, uint64_t pte) "stage=%d level=%d base@=0x%"PRIx64" pte@=0x%"PRIx64" offset=%d pte=0x%"PRIx64
165
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
166
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"
62
--
167
--
63
2.20.1
168
2.34.1
64
65
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Mostafa Saleh <smostafa@google.com>
2
2
3
Model these off the aa64 read/write_vec_element functions.
3
In preparation for adding stage-2 support, add Stage-2 PTW code.
4
Use it within translate-neon.c.inc. The new functions do
4
Only Aarch64 format is supported as stage-1.
5
not allocate or free temps, so this rearranges the calling
5
6
code a bit.
6
Nesting stage-1 and stage-2 is not supported right now.
7
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
HTTU is not supported, SW is expected to maintain the Access flag.
9
Message-id: 20201030022618.785675-6-richard.henderson@linaro.org
9
This is described in the SMMUv3 manual(IHI 0070.E.a)
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
"5.2. Stream Table Entry" in "[181] S2AFFD".
11
This flag determines the behavior on access of a stage-2 page whose
12
descriptor has AF == 0:
13
- 0b0: An Access flag fault occurs (stall not supported).
14
- 0b1: An Access flag fault never occurs.
15
An Access fault takes priority over a Permission fault.
16
17
There are 3 address size checks for stage-2 according to
18
(IHI 0070.E.a) in "3.4. Address sizes".
19
- As nesting is not supported, input address is passed directly to
20
stage-2, and is checked against IAS.
21
We use cfg->oas to hold the OAS when stage-1 is not used, this is set
22
in the next patch.
23
This check is done outside of smmu_ptw_64_s2 as it is not part of
24
stage-2(it throws stage-1 fault), and the stage-2 function shouldn't
25
change it's behavior when nesting is supported.
26
When nesting is supported and we figure out how to combine TLB for
27
stage-1 and stage-2 we can move this check into the stage-1 function
28
as described in ARM DDI0487I.a in pseudocode
29
aarch64/translation/vmsa_translation/AArch64.S1Translate
30
aarch64/translation/vmsa_translation/AArch64.S1DisabledOutput
31
32
- Input to stage-2 is checked against s2t0sz, and throws stage-2
33
transaltion fault if exceeds it.
34
35
- Output of stage-2 is checked against effective PA output range.
36
37
Reviewed-by: Eric Auger <eric.auger@redhat.com>
38
Signed-off-by: Mostafa Saleh <smostafa@google.com>
39
Tested-by: Eric Auger <eric.auger@redhat.com>
40
Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
41
Message-id: 20230516203327.2051088-5-smostafa@google.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
43
---
13
target/arm/translate.c | 26 ++++
44
hw/arm/smmu-internal.h | 35 ++++++++++
14
target/arm/translate-neon.c.inc | 256 ++++++++++++++++++++------------
45
hw/arm/smmu-common.c | 142 ++++++++++++++++++++++++++++++++++++++++-
15
2 files changed, 183 insertions(+), 99 deletions(-)
46
2 files changed, 176 insertions(+), 1 deletion(-)
16
47
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
48
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
18
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate.c
50
--- a/hw/arm/smmu-internal.h
20
+++ b/target/arm/translate.c
51
+++ b/hw/arm/smmu-internal.h
21
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
52
@@ -XXX,XX +XXX,XX @@
22
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
53
#define PTE_APTABLE(pte) \
54
(extract64(pte, 61, 2))
55
56
+#define PTE_AF(pte) \
57
+ (extract64(pte, 10, 1))
58
/*
59
* TODO: At the moment all transactions are considered as privileged (EL1)
60
* as IOMMU translation callback does not pass user/priv attributes.
61
@@ -XXX,XX +XXX,XX @@
62
#define is_permission_fault(ap, perm) \
63
(((perm) & IOMMU_WO) && ((ap) & 0x2))
64
65
+#define is_permission_fault_s2(s2ap, perm) \
66
+ (!(((s2ap) & (perm)) == (perm)))
67
+
68
#define PTE_AP_TO_PERM(ap) \
69
(IOMMU_ACCESS_FLAG(true, !((ap) & 0x2)))
70
71
@@ -XXX,XX +XXX,XX @@ uint64_t iova_level_offset(uint64_t iova, int inputsize,
72
MAKE_64BIT_MASK(0, gsz - 3);
23
}
73
}
24
74
25
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
75
+/* FEAT_LPA2 and FEAT_TTST are not implemented. */
76
+static inline int get_start_level(int sl0 , int granule_sz)
26
+{
77
+{
27
+ long off = neon_element_offset(reg, ele, size);
78
+ /* ARM DDI0487I.a: Table D8-12. */
28
+
79
+ if (granule_sz == 12) {
29
+ switch (size) {
80
+ return 2 - sl0;
30
+ case MO_32:
81
+ }
31
+ tcg_gen_ld_i32(dest, cpu_env, off);
82
+ /* ARM DDI0487I.a: Table D8-22 and Table D8-31. */
32
+ break;
83
+ return 3 - sl0;
33
+ default:
34
+ g_assert_not_reached();
35
+ }
36
+}
84
+}
37
+
85
+
38
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
86
+/*
87
+ * Index in a concatenated first level stage-2 page table.
88
+ * ARM DDI0487I.a: D8.2.2 Concatenated translation tables.
89
+ */
90
+static inline int pgd_concat_idx(int start_level, int granule_sz,
91
+ dma_addr_t ipa)
39
+{
92
+{
40
+ long off = neon_element_offset(reg, ele, size);
93
+ uint64_t ret;
41
+
94
+ /*
42
+ switch (size) {
95
+ * Get the number of bits handled by next levels, then any extra bits in
43
+ case MO_32:
96
+ * the address should index the concatenated tables. This relation can be
44
+ tcg_gen_st_i32(src, cpu_env, off);
97
+ * deduced from tables in ARM DDI0487I.a: D8.2.7-9
45
+ break;
98
+ */
46
+ default:
99
+ int shift = level_shift(start_level - 1, granule_sz);
47
+ g_assert_not_reached();
100
+
48
+ }
101
+ ret = ipa >> shift;
102
+ return ret;
49
+}
103
+}
50
+
104
+
51
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
105
#define SMMU_IOTLB_ASID(key) ((key).asid)
106
107
typedef struct SMMUIOTLBPageInvInfo {
108
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/arm/smmu-common.c
111
+++ b/hw/arm/smmu-common.c
112
@@ -XXX,XX +XXX,XX @@ error:
113
return -EINVAL;
114
}
115
116
+/**
117
+ * smmu_ptw_64_s2 - VMSAv8-64 Walk of the page tables for a given ipa
118
+ * for stage-2.
119
+ * @cfg: translation config
120
+ * @ipa: ipa to translate
121
+ * @perm: access type
122
+ * @tlbe: SMMUTLBEntry (out)
123
+ * @info: handle to an error info
124
+ *
125
+ * Return 0 on success, < 0 on error. In case of error, @info is filled
126
+ * and tlbe->perm is set to IOMMU_NONE.
127
+ * Upon success, @tlbe is filled with translated_addr and entry
128
+ * permission rights.
129
+ */
130
+static int smmu_ptw_64_s2(SMMUTransCfg *cfg,
131
+ dma_addr_t ipa, IOMMUAccessFlags perm,
132
+ SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
133
+{
134
+ const int stage = 2;
135
+ int granule_sz = cfg->s2cfg.granule_sz;
136
+ /* ARM DDI0487I.a: Table D8-7. */
137
+ int inputsize = 64 - cfg->s2cfg.tsz;
138
+ int level = get_start_level(cfg->s2cfg.sl0, granule_sz);
139
+ int stride = VMSA_STRIDE(granule_sz);
140
+ int idx = pgd_concat_idx(level, granule_sz, ipa);
141
+ /*
142
+ * Get the ttb from concatenated structure.
143
+ * The offset is the idx * size of each ttb(number of ptes * (sizeof(pte))
144
+ */
145
+ uint64_t baseaddr = extract64(cfg->s2cfg.vttb, 0, 48) + (1 << stride) *
146
+ idx * sizeof(uint64_t);
147
+ dma_addr_t indexmask = VMSA_IDXMSK(inputsize, stride, level);
148
+
149
+ baseaddr &= ~indexmask;
150
+
151
+ /*
152
+ * On input, a stage 2 Translation fault occurs if the IPA is outside the
153
+ * range configured by the relevant S2T0SZ field of the STE.
154
+ */
155
+ if (ipa >= (1ULL << inputsize)) {
156
+ info->type = SMMU_PTW_ERR_TRANSLATION;
157
+ goto error;
158
+ }
159
+
160
+ while (level < VMSA_LEVELS) {
161
+ uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
162
+ uint64_t mask = subpage_size - 1;
163
+ uint32_t offset = iova_level_offset(ipa, inputsize, level, granule_sz);
164
+ uint64_t pte, gpa;
165
+ dma_addr_t pte_addr = baseaddr + offset * sizeof(pte);
166
+ uint8_t s2ap;
167
+
168
+ if (get_pte(baseaddr, offset, &pte, info)) {
169
+ goto error;
170
+ }
171
+ trace_smmu_ptw_level(stage, level, ipa, subpage_size,
172
+ baseaddr, offset, pte);
173
+ if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) {
174
+ trace_smmu_ptw_invalid_pte(stage, level, baseaddr,
175
+ pte_addr, offset, pte);
176
+ break;
177
+ }
178
+
179
+ if (is_table_pte(pte, level)) {
180
+ baseaddr = get_table_pte_address(pte, granule_sz);
181
+ level++;
182
+ continue;
183
+ } else if (is_page_pte(pte, level)) {
184
+ gpa = get_page_pte_address(pte, granule_sz);
185
+ trace_smmu_ptw_page_pte(stage, level, ipa,
186
+ baseaddr, pte_addr, pte, gpa);
187
+ } else {
188
+ uint64_t block_size;
189
+
190
+ gpa = get_block_pte_address(pte, level, granule_sz,
191
+ &block_size);
192
+ trace_smmu_ptw_block_pte(stage, level, baseaddr,
193
+ pte_addr, pte, ipa, gpa,
194
+ block_size >> 20);
195
+ }
196
+
197
+ /*
198
+ * If S2AFFD and PTE.AF are 0 => fault. (5.2. Stream Table Entry)
199
+ * An Access fault takes priority over a Permission fault.
200
+ */
201
+ if (!PTE_AF(pte) && !cfg->s2cfg.affd) {
202
+ info->type = SMMU_PTW_ERR_ACCESS;
203
+ goto error;
204
+ }
205
+
206
+ s2ap = PTE_AP(pte);
207
+ if (is_permission_fault_s2(s2ap, perm)) {
208
+ info->type = SMMU_PTW_ERR_PERMISSION;
209
+ goto error;
210
+ }
211
+
212
+ /*
213
+ * The address output from the translation causes a stage 2 Address
214
+ * Size fault if it exceeds the effective PA output range.
215
+ */
216
+ if (gpa >= (1ULL << cfg->s2cfg.eff_ps)) {
217
+ info->type = SMMU_PTW_ERR_ADDR_SIZE;
218
+ goto error;
219
+ }
220
+
221
+ tlbe->entry.translated_addr = gpa;
222
+ tlbe->entry.iova = ipa & ~mask;
223
+ tlbe->entry.addr_mask = mask;
224
+ tlbe->entry.perm = s2ap;
225
+ tlbe->level = level;
226
+ tlbe->granule = granule_sz;
227
+ return 0;
228
+ }
229
+ info->type = SMMU_PTW_ERR_TRANSLATION;
230
+
231
+error:
232
+ info->stage = 2;
233
+ tlbe->entry.perm = IOMMU_NONE;
234
+ return -EINVAL;
235
+}
236
+
237
/**
238
* smmu_ptw - Walk the page tables for an IOVA, according to @cfg
239
*
240
@@ -XXX,XX +XXX,XX @@ error:
241
int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
242
SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
52
{
243
{
53
TCGv_ptr ret = tcg_temp_new_ptr();
244
- return smmu_ptw_64_s1(cfg, iova, perm, tlbe, info);
54
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
245
+ if (cfg->stage == 1) {
55
index XXXXXXX..XXXXXXX 100644
246
+ return smmu_ptw_64_s1(cfg, iova, perm, tlbe, info);
56
--- a/target/arm/translate-neon.c.inc
247
+ } else if (cfg->stage == 2) {
57
+++ b/target/arm/translate-neon.c.inc
248
+ /*
58
@@ -XXX,XX +XXX,XX @@ static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
249
+ * If bypassing stage 1(or unimplemented), the input address is passed
59
* early. Since Q is 0 there are always just two passes, so instead
250
+ * directly to stage 2 as IPA. If the input address of a transaction
60
* of a complicated loop over each pass we just unroll.
251
+ * exceeds the size of the IAS, a stage 1 Address Size fault occurs.
61
*/
252
+ * For AA64, IAS = OAS according to (IHI 0070.E.a) "3.4 Address sizes"
62
- tmp = neon_load_reg(a->vn, 0);
253
+ */
63
- tmp2 = neon_load_reg(a->vn, 1);
254
+ if (iova >= (1ULL << cfg->oas)) {
64
+ tmp = tcg_temp_new_i32();
255
+ info->type = SMMU_PTW_ERR_ADDR_SIZE;
65
+ tmp2 = tcg_temp_new_i32();
256
+ info->stage = 1;
66
+ tmp3 = tcg_temp_new_i32();
257
+ tlbe->entry.perm = IOMMU_NONE;
67
+
258
+ return -EINVAL;
68
+ read_neon_element32(tmp, a->vn, 0, MO_32);
259
+ }
69
+ read_neon_element32(tmp2, a->vn, 1, MO_32);
260
+
70
fn(tmp, tmp, tmp2);
261
+ return smmu_ptw_64_s2(cfg, iova, perm, tlbe, info);
71
- tcg_temp_free_i32(tmp2);
262
+ }
72
263
+
73
- tmp3 = neon_load_reg(a->vm, 0);
264
+ g_assert_not_reached();
74
- tmp2 = neon_load_reg(a->vm, 1);
75
+ read_neon_element32(tmp3, a->vm, 0, MO_32);
76
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
77
fn(tmp3, tmp3, tmp2);
78
- tcg_temp_free_i32(tmp2);
79
80
- neon_store_reg(a->vd, 0, tmp);
81
- neon_store_reg(a->vd, 1, tmp3);
82
+ write_neon_element32(tmp, a->vd, 0, MO_32);
83
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
84
+
85
+ tcg_temp_free_i32(tmp);
86
+ tcg_temp_free_i32(tmp2);
87
+ tcg_temp_free_i32(tmp3);
88
return true;
89
}
265
}
90
266
91
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
267
/**
92
* 2-reg-and-shift operations, size < 3 case, where the
93
* helper needs to be passed cpu_env.
94
*/
95
- TCGv_i32 constimm;
96
+ TCGv_i32 constimm, tmp;
97
int pass;
98
99
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
100
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
101
* by immediate using the variable shift operations.
102
*/
103
constimm = tcg_const_i32(dup_const(a->size, a->shift));
104
+ tmp = tcg_temp_new_i32();
105
106
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
107
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
108
+ read_neon_element32(tmp, a->vm, pass, MO_32);
109
fn(tmp, cpu_env, tmp, constimm);
110
- neon_store_reg(a->vd, pass, tmp);
111
+ write_neon_element32(tmp, a->vd, pass, MO_32);
112
}
113
+ tcg_temp_free_i32(tmp);
114
tcg_temp_free_i32(constimm);
115
return true;
116
}
117
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
118
constimm = tcg_const_i64(-a->shift);
119
rm1 = tcg_temp_new_i64();
120
rm2 = tcg_temp_new_i64();
121
+ rd = tcg_temp_new_i32();
122
123
/* Load both inputs first to avoid potential overwrite if rm == rd */
124
neon_load_reg64(rm1, a->vm);
125
neon_load_reg64(rm2, a->vm + 1);
126
127
shiftfn(rm1, rm1, constimm);
128
- rd = tcg_temp_new_i32();
129
narrowfn(rd, cpu_env, rm1);
130
- neon_store_reg(a->vd, 0, rd);
131
+ write_neon_element32(rd, a->vd, 0, MO_32);
132
133
shiftfn(rm2, rm2, constimm);
134
- rd = tcg_temp_new_i32();
135
narrowfn(rd, cpu_env, rm2);
136
- neon_store_reg(a->vd, 1, rd);
137
+ write_neon_element32(rd, a->vd, 1, MO_32);
138
139
+ tcg_temp_free_i32(rd);
140
tcg_temp_free_i64(rm1);
141
tcg_temp_free_i64(rm2);
142
tcg_temp_free_i64(constimm);
143
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
144
constimm = tcg_const_i32(imm);
145
146
/* Load all inputs first to avoid potential overwrite */
147
- rm1 = neon_load_reg(a->vm, 0);
148
- rm2 = neon_load_reg(a->vm, 1);
149
- rm3 = neon_load_reg(a->vm + 1, 0);
150
- rm4 = neon_load_reg(a->vm + 1, 1);
151
+ rm1 = tcg_temp_new_i32();
152
+ rm2 = tcg_temp_new_i32();
153
+ rm3 = tcg_temp_new_i32();
154
+ rm4 = tcg_temp_new_i32();
155
+ read_neon_element32(rm1, a->vm, 0, MO_32);
156
+ read_neon_element32(rm2, a->vm, 1, MO_32);
157
+ read_neon_element32(rm3, a->vm, 2, MO_32);
158
+ read_neon_element32(rm4, a->vm, 3, MO_32);
159
rtmp = tcg_temp_new_i64();
160
161
shiftfn(rm1, rm1, constimm);
162
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
163
tcg_temp_free_i32(rm2);
164
165
narrowfn(rm1, cpu_env, rtmp);
166
- neon_store_reg(a->vd, 0, rm1);
167
+ write_neon_element32(rm1, a->vd, 0, MO_32);
168
+ tcg_temp_free_i32(rm1);
169
170
shiftfn(rm3, rm3, constimm);
171
shiftfn(rm4, rm4, constimm);
172
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
173
174
narrowfn(rm3, cpu_env, rtmp);
175
tcg_temp_free_i64(rtmp);
176
- neon_store_reg(a->vd, 1, rm3);
177
+ write_neon_element32(rm3, a->vd, 1, MO_32);
178
+ tcg_temp_free_i32(rm3);
179
return true;
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
183
widen_mask = dup_const(a->size + 1, widen_mask);
184
}
185
186
- rm0 = neon_load_reg(a->vm, 0);
187
- rm1 = neon_load_reg(a->vm, 1);
188
+ rm0 = tcg_temp_new_i32();
189
+ rm1 = tcg_temp_new_i32();
190
+ read_neon_element32(rm0, a->vm, 0, MO_32);
191
+ read_neon_element32(rm1, a->vm, 1, MO_32);
192
tmp = tcg_temp_new_i64();
193
194
widenfn(tmp, rm0);
195
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
196
if (src1_wide) {
197
neon_load_reg64(rn0_64, a->vn);
198
} else {
199
- TCGv_i32 tmp = neon_load_reg(a->vn, 0);
200
+ TCGv_i32 tmp = tcg_temp_new_i32();
201
+ read_neon_element32(tmp, a->vn, 0, MO_32);
202
widenfn(rn0_64, tmp);
203
tcg_temp_free_i32(tmp);
204
}
205
- rm = neon_load_reg(a->vm, 0);
206
+ rm = tcg_temp_new_i32();
207
+ read_neon_element32(rm, a->vm, 0, MO_32);
208
209
widenfn(rm_64, rm);
210
tcg_temp_free_i32(rm);
211
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
212
if (src1_wide) {
213
neon_load_reg64(rn1_64, a->vn + 1);
214
} else {
215
- TCGv_i32 tmp = neon_load_reg(a->vn, 1);
216
+ TCGv_i32 tmp = tcg_temp_new_i32();
217
+ read_neon_element32(tmp, a->vn, 1, MO_32);
218
widenfn(rn1_64, tmp);
219
tcg_temp_free_i32(tmp);
220
}
221
- rm = neon_load_reg(a->vm, 1);
222
+ rm = tcg_temp_new_i32();
223
+ read_neon_element32(rm, a->vm, 1, MO_32);
224
225
neon_store_reg64(rn0_64, a->vd);
226
227
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
228
229
narrowfn(rd1, rn_64);
230
231
- neon_store_reg(a->vd, 0, rd0);
232
- neon_store_reg(a->vd, 1, rd1);
233
+ write_neon_element32(rd0, a->vd, 0, MO_32);
234
+ write_neon_element32(rd1, a->vd, 1, MO_32);
235
236
+ tcg_temp_free_i32(rd0);
237
+ tcg_temp_free_i32(rd1);
238
tcg_temp_free_i64(rn_64);
239
tcg_temp_free_i64(rm_64);
240
241
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
242
rd0 = tcg_temp_new_i64();
243
rd1 = tcg_temp_new_i64();
244
245
- rn = neon_load_reg(a->vn, 0);
246
- rm = neon_load_reg(a->vm, 0);
247
+ rn = tcg_temp_new_i32();
248
+ rm = tcg_temp_new_i32();
249
+ read_neon_element32(rn, a->vn, 0, MO_32);
250
+ read_neon_element32(rm, a->vm, 0, MO_32);
251
opfn(rd0, rn, rm);
252
- tcg_temp_free_i32(rn);
253
- tcg_temp_free_i32(rm);
254
255
- rn = neon_load_reg(a->vn, 1);
256
- rm = neon_load_reg(a->vm, 1);
257
+ read_neon_element32(rn, a->vn, 1, MO_32);
258
+ read_neon_element32(rm, a->vm, 1, MO_32);
259
opfn(rd1, rn, rm);
260
tcg_temp_free_i32(rn);
261
tcg_temp_free_i32(rm);
262
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
263
264
static inline TCGv_i32 neon_get_scalar(int size, int reg)
265
{
266
- TCGv_i32 tmp;
267
- if (size == 1) {
268
- tmp = neon_load_reg(reg & 7, reg >> 4);
269
+ TCGv_i32 tmp = tcg_temp_new_i32();
270
+ if (size == MO_16) {
271
+ read_neon_element32(tmp, reg & 7, reg >> 4, MO_32);
272
if (reg & 8) {
273
gen_neon_dup_high16(tmp);
274
} else {
275
gen_neon_dup_low16(tmp);
276
}
277
} else {
278
- tmp = neon_load_reg(reg & 15, reg >> 4);
279
+ read_neon_element32(tmp, reg & 15, reg >> 4, MO_32);
280
}
281
return tmp;
282
}
283
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
284
* perform an accumulation operation of that result into the
285
* destination.
286
*/
287
- TCGv_i32 scalar;
288
+ TCGv_i32 scalar, tmp;
289
int pass;
290
291
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
292
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
293
}
294
295
scalar = neon_get_scalar(a->size, a->vm);
296
+ tmp = tcg_temp_new_i32();
297
298
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
299
- TCGv_i32 tmp = neon_load_reg(a->vn, pass);
300
+ read_neon_element32(tmp, a->vn, pass, MO_32);
301
opfn(tmp, tmp, scalar);
302
if (accfn) {
303
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
304
+ TCGv_i32 rd = tcg_temp_new_i32();
305
+ read_neon_element32(rd, a->vd, pass, MO_32);
306
accfn(tmp, rd, tmp);
307
tcg_temp_free_i32(rd);
308
}
309
- neon_store_reg(a->vd, pass, tmp);
310
+ write_neon_element32(tmp, a->vd, pass, MO_32);
311
}
312
+ tcg_temp_free_i32(tmp);
313
tcg_temp_free_i32(scalar);
314
return true;
315
}
316
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
317
* performs a kind of fused op-then-accumulate using a helper
318
* function that takes all of rd, rn and the scalar at once.
319
*/
320
- TCGv_i32 scalar;
321
+ TCGv_i32 scalar, rn, rd;
322
int pass;
323
324
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
325
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
326
}
327
328
scalar = neon_get_scalar(a->size, a->vm);
329
+ rn = tcg_temp_new_i32();
330
+ rd = tcg_temp_new_i32();
331
332
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
333
- TCGv_i32 rn = neon_load_reg(a->vn, pass);
334
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
335
+ read_neon_element32(rn, a->vn, pass, MO_32);
336
+ read_neon_element32(rd, a->vd, pass, MO_32);
337
opfn(rd, cpu_env, rn, scalar, rd);
338
- tcg_temp_free_i32(rn);
339
- neon_store_reg(a->vd, pass, rd);
340
+ write_neon_element32(rd, a->vd, pass, MO_32);
341
}
342
+ tcg_temp_free_i32(rn);
343
+ tcg_temp_free_i32(rd);
344
tcg_temp_free_i32(scalar);
345
346
return true;
347
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
348
scalar = neon_get_scalar(a->size, a->vm);
349
350
/* Load all inputs before writing any outputs, in case of overlap */
351
- rn = neon_load_reg(a->vn, 0);
352
+ rn = tcg_temp_new_i32();
353
+ read_neon_element32(rn, a->vn, 0, MO_32);
354
rn0_64 = tcg_temp_new_i64();
355
opfn(rn0_64, rn, scalar);
356
- tcg_temp_free_i32(rn);
357
358
- rn = neon_load_reg(a->vn, 1);
359
+ read_neon_element32(rn, a->vn, 1, MO_32);
360
rn1_64 = tcg_temp_new_i64();
361
opfn(rn1_64, rn, scalar);
362
tcg_temp_free_i32(rn);
363
@@ -XXX,XX +XXX,XX @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
364
return false;
365
}
366
n <<= 3;
367
+ tmp = tcg_temp_new_i32();
368
if (a->op) {
369
- tmp = neon_load_reg(a->vd, 0);
370
+ read_neon_element32(tmp, a->vd, 0, MO_32);
371
} else {
372
- tmp = tcg_temp_new_i32();
373
tcg_gen_movi_i32(tmp, 0);
374
}
375
- tmp2 = neon_load_reg(a->vm, 0);
376
+ tmp2 = tcg_temp_new_i32();
377
+ read_neon_element32(tmp2, a->vm, 0, MO_32);
378
ptr1 = vfp_reg_ptr(true, a->vn);
379
tmp4 = tcg_const_i32(n);
380
gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp4);
381
- tcg_temp_free_i32(tmp);
382
+
383
if (a->op) {
384
- tmp = neon_load_reg(a->vd, 1);
385
+ read_neon_element32(tmp, a->vd, 1, MO_32);
386
} else {
387
- tmp = tcg_temp_new_i32();
388
tcg_gen_movi_i32(tmp, 0);
389
}
390
- tmp3 = neon_load_reg(a->vm, 1);
391
+ tmp3 = tcg_temp_new_i32();
392
+ read_neon_element32(tmp3, a->vm, 1, MO_32);
393
gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp4);
394
+ tcg_temp_free_i32(tmp);
395
tcg_temp_free_i32(tmp4);
396
tcg_temp_free_ptr(ptr1);
397
- neon_store_reg(a->vd, 0, tmp2);
398
- neon_store_reg(a->vd, 1, tmp3);
399
- tcg_temp_free_i32(tmp);
400
+
401
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
402
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
403
+ tcg_temp_free_i32(tmp2);
404
+ tcg_temp_free_i32(tmp3);
405
return true;
406
}
407
408
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
409
static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
410
{
411
int pass, half;
412
+ TCGv_i32 tmp[2];
413
414
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
415
return false;
416
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
417
return true;
418
}
419
420
- for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
421
- TCGv_i32 tmp[2];
422
+ tmp[0] = tcg_temp_new_i32();
423
+ tmp[1] = tcg_temp_new_i32();
424
425
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
426
for (half = 0; half < 2; half++) {
427
- tmp[half] = neon_load_reg(a->vm, pass * 2 + half);
428
+ read_neon_element32(tmp[half], a->vm, pass * 2 + half, MO_32);
429
switch (a->size) {
430
case 0:
431
tcg_gen_bswap32_i32(tmp[half], tmp[half]);
432
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
433
g_assert_not_reached();
434
}
435
}
436
- neon_store_reg(a->vd, pass * 2, tmp[1]);
437
- neon_store_reg(a->vd, pass * 2 + 1, tmp[0]);
438
+ write_neon_element32(tmp[1], a->vd, pass * 2, MO_32);
439
+ write_neon_element32(tmp[0], a->vd, pass * 2 + 1, MO_32);
440
}
441
+
442
+ tcg_temp_free_i32(tmp[0]);
443
+ tcg_temp_free_i32(tmp[1]);
444
return true;
445
}
446
447
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
448
rm0_64 = tcg_temp_new_i64();
449
rm1_64 = tcg_temp_new_i64();
450
rd_64 = tcg_temp_new_i64();
451
- tmp = neon_load_reg(a->vm, pass * 2);
452
+
453
+ tmp = tcg_temp_new_i32();
454
+ read_neon_element32(tmp, a->vm, pass * 2, MO_32);
455
widenfn(rm0_64, tmp);
456
- tcg_temp_free_i32(tmp);
457
- tmp = neon_load_reg(a->vm, pass * 2 + 1);
458
+ read_neon_element32(tmp, a->vm, pass * 2 + 1, MO_32);
459
widenfn(rm1_64, tmp);
460
tcg_temp_free_i32(tmp);
461
+
462
opfn(rd_64, rm0_64, rm1_64);
463
tcg_temp_free_i64(rm0_64);
464
tcg_temp_free_i64(rm1_64);
465
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
466
narrowfn(rd0, cpu_env, rm);
467
neon_load_reg64(rm, a->vm + 1);
468
narrowfn(rd1, cpu_env, rm);
469
- neon_store_reg(a->vd, 0, rd0);
470
- neon_store_reg(a->vd, 1, rd1);
471
+ write_neon_element32(rd0, a->vd, 0, MO_32);
472
+ write_neon_element32(rd1, a->vd, 1, MO_32);
473
+ tcg_temp_free_i32(rd0);
474
+ tcg_temp_free_i32(rd1);
475
tcg_temp_free_i64(rm);
476
return true;
477
}
478
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
479
}
480
481
rd = tcg_temp_new_i64();
482
+ rm0 = tcg_temp_new_i32();
483
+ rm1 = tcg_temp_new_i32();
484
485
- rm0 = neon_load_reg(a->vm, 0);
486
- rm1 = neon_load_reg(a->vm, 1);
487
+ read_neon_element32(rm0, a->vm, 0, MO_32);
488
+ read_neon_element32(rm1, a->vm, 1, MO_32);
489
490
widenfn(rd, rm0);
491
tcg_gen_shli_i64(rd, rd, 8 << a->size);
492
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
493
494
fpst = fpstatus_ptr(FPST_STD);
495
ahp = get_ahp_flag();
496
- tmp = neon_load_reg(a->vm, 0);
497
+ tmp = tcg_temp_new_i32();
498
+ read_neon_element32(tmp, a->vm, 0, MO_32);
499
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
500
- tmp2 = neon_load_reg(a->vm, 1);
501
+ tmp2 = tcg_temp_new_i32();
502
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
503
gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
504
tcg_gen_shli_i32(tmp2, tmp2, 16);
505
tcg_gen_or_i32(tmp2, tmp2, tmp);
506
- tcg_temp_free_i32(tmp);
507
- tmp = neon_load_reg(a->vm, 2);
508
+ read_neon_element32(tmp, a->vm, 2, MO_32);
509
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
510
- tmp3 = neon_load_reg(a->vm, 3);
511
- neon_store_reg(a->vd, 0, tmp2);
512
+ tmp3 = tcg_temp_new_i32();
513
+ read_neon_element32(tmp3, a->vm, 3, MO_32);
514
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
515
+ tcg_temp_free_i32(tmp2);
516
gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
517
tcg_gen_shli_i32(tmp3, tmp3, 16);
518
tcg_gen_or_i32(tmp3, tmp3, tmp);
519
- neon_store_reg(a->vd, 1, tmp3);
520
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
521
+ tcg_temp_free_i32(tmp3);
522
tcg_temp_free_i32(tmp);
523
tcg_temp_free_i32(ahp);
524
tcg_temp_free_ptr(fpst);
525
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
526
fpst = fpstatus_ptr(FPST_STD);
527
ahp = get_ahp_flag();
528
tmp3 = tcg_temp_new_i32();
529
- tmp = neon_load_reg(a->vm, 0);
530
- tmp2 = neon_load_reg(a->vm, 1);
531
+ tmp2 = tcg_temp_new_i32();
532
+ tmp = tcg_temp_new_i32();
533
+ read_neon_element32(tmp, a->vm, 0, MO_32);
534
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
535
tcg_gen_ext16u_i32(tmp3, tmp);
536
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
537
- neon_store_reg(a->vd, 0, tmp3);
538
+ write_neon_element32(tmp3, a->vd, 0, MO_32);
539
tcg_gen_shri_i32(tmp, tmp, 16);
540
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
541
- neon_store_reg(a->vd, 1, tmp);
542
- tmp3 = tcg_temp_new_i32();
543
+ write_neon_element32(tmp, a->vd, 1, MO_32);
544
+ tcg_temp_free_i32(tmp);
545
tcg_gen_ext16u_i32(tmp3, tmp2);
546
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
547
- neon_store_reg(a->vd, 2, tmp3);
548
+ write_neon_element32(tmp3, a->vd, 2, MO_32);
549
+ tcg_temp_free_i32(tmp3);
550
tcg_gen_shri_i32(tmp2, tmp2, 16);
551
gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
552
- neon_store_reg(a->vd, 3, tmp2);
553
+ write_neon_element32(tmp2, a->vd, 3, MO_32);
554
+ tcg_temp_free_i32(tmp2);
555
tcg_temp_free_i32(ahp);
556
tcg_temp_free_ptr(fpst);
557
558
@@ -XXX,XX +XXX,XX @@ DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
559
560
static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
561
{
562
+ TCGv_i32 tmp;
563
int pass;
564
565
/* Handle a 2-reg-misc operation by iterating 32 bits at a time */
566
@@ -XXX,XX +XXX,XX @@ static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
567
return true;
568
}
569
570
+ tmp = tcg_temp_new_i32();
571
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
572
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
573
+ read_neon_element32(tmp, a->vm, pass, MO_32);
574
fn(tmp, tmp);
575
- neon_store_reg(a->vd, pass, tmp);
576
+ write_neon_element32(tmp, a->vd, pass, MO_32);
577
}
578
+ tcg_temp_free_i32(tmp);
579
580
return true;
581
}
582
@@ -XXX,XX +XXX,XX @@ static bool trans_VTRN(DisasContext *s, arg_2misc *a)
583
return true;
584
}
585
586
- if (a->size == 2) {
587
+ tmp = tcg_temp_new_i32();
588
+ tmp2 = tcg_temp_new_i32();
589
+ if (a->size == MO_32) {
590
for (pass = 0; pass < (a->q ? 4 : 2); pass += 2) {
591
- tmp = neon_load_reg(a->vm, pass);
592
- tmp2 = neon_load_reg(a->vd, pass + 1);
593
- neon_store_reg(a->vm, pass, tmp2);
594
- neon_store_reg(a->vd, pass + 1, tmp);
595
+ read_neon_element32(tmp, a->vm, pass, MO_32);
596
+ read_neon_element32(tmp2, a->vd, pass + 1, MO_32);
597
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
598
+ write_neon_element32(tmp, a->vd, pass + 1, MO_32);
599
}
600
} else {
601
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
602
- tmp = neon_load_reg(a->vm, pass);
603
- tmp2 = neon_load_reg(a->vd, pass);
604
- if (a->size == 0) {
605
+ read_neon_element32(tmp, a->vm, pass, MO_32);
606
+ read_neon_element32(tmp2, a->vd, pass, MO_32);
607
+ if (a->size == MO_8) {
608
gen_neon_trn_u8(tmp, tmp2);
609
} else {
610
gen_neon_trn_u16(tmp, tmp2);
611
}
612
- neon_store_reg(a->vm, pass, tmp2);
613
- neon_store_reg(a->vd, pass, tmp);
614
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
615
+ write_neon_element32(tmp, a->vd, pass, MO_32);
616
}
617
}
618
+ tcg_temp_free_i32(tmp);
619
+ tcg_temp_free_i32(tmp2);
620
return true;
621
}
622
--
268
--
623
2.20.1
269
2.34.1
624
625
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Mostafa Saleh <smostafa@google.com>
2
2
3
This will shortly have users outside of translate-neon.c.inc.
3
Parse stage-2 configuration from STE and populate it in SMMUS2Cfg.
4
4
Validity of field values are checked when possible.
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
6
Message-id: 20201030022618.785675-3-richard.henderson@linaro.org
6
Only AA64 tables are supported and Small Translation Tables (STT) are
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
not supported.
8
9
According to SMMUv3 UM(IHI0070E) "5.2 Stream Table Entry": All fields
10
with an S2 prefix (with the exception of S2VMID) are IGNORED when
11
stage-2 bypasses translation (Config[1] == 0).
12
13
Which means that VMID can be used(for TLB tagging) even if stage-2 is
14
bypassed, so we parse it unconditionally when S2P exists. Otherwise
15
it is set to -1.(only S1P)
16
17
As stall is not supported, if S2S is set the translation would abort.
18
For S2R, we reuse the same code used for stage-1 with flag
19
record_faults. However when nested translation is supported we would
20
need to separate stage-1 and stage-2 faults.
21
22
Fix wrong shift in STE_S2HD, STE_S2HA, STE_S2S.
23
24
Signed-off-by: Mostafa Saleh <smostafa@google.com>
25
Tested-by: Eric Auger <eric.auger@redhat.com>
26
Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
27
Reviewed-by: Eric Auger <eric.auger@redhat.com>
28
Message-id: 20230516203327.2051088-6-smostafa@google.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
30
---
10
target/arm/translate.c | 20 ++++++++++++++++++++
31
hw/arm/smmuv3-internal.h | 10 +-
11
target/arm/translate-neon.c.inc | 19 -------------------
32
include/hw/arm/smmu-common.h | 1 +
12
2 files changed, 20 insertions(+), 19 deletions(-)
33
include/hw/arm/smmuv3.h | 3 +
13
34
hw/arm/smmuv3.c | 181 +++++++++++++++++++++++++++++++++--
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
35
4 files changed, 185 insertions(+), 10 deletions(-)
36
37
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
15
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
39
--- a/hw/arm/smmuv3-internal.h
17
+++ b/target/arm/translate.c
40
+++ b/hw/arm/smmuv3-internal.h
18
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
41
@@ -XXX,XX +XXX,XX @@ typedef struct CD {
19
return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
42
#define STE_S2TG(x) extract32((x)->word[5], 14, 2)
43
#define STE_S2PS(x) extract32((x)->word[5], 16, 3)
44
#define STE_S2AA64(x) extract32((x)->word[5], 19, 1)
45
-#define STE_S2HD(x) extract32((x)->word[5], 24, 1)
46
-#define STE_S2HA(x) extract32((x)->word[5], 25, 1)
47
-#define STE_S2S(x) extract32((x)->word[5], 26, 1)
48
+#define STE_S2ENDI(x) extract32((x)->word[5], 20, 1)
49
+#define STE_S2AFFD(x) extract32((x)->word[5], 21, 1)
50
+#define STE_S2HD(x) extract32((x)->word[5], 23, 1)
51
+#define STE_S2HA(x) extract32((x)->word[5], 24, 1)
52
+#define STE_S2S(x) extract32((x)->word[5], 25, 1)
53
+#define STE_S2R(x) extract32((x)->word[5], 26, 1)
54
+
55
#define STE_CTXPTR(x) \
56
({ \
57
unsigned long addr; \
58
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
59
index XXXXXXX..XXXXXXX 100644
60
--- a/include/hw/arm/smmu-common.h
61
+++ b/include/hw/arm/smmu-common.h
62
@@ -XXX,XX +XXX,XX @@
63
64
/* VMSAv8-64 Translation constants and functions */
65
#define VMSA_LEVELS 4
66
+#define VMSA_MAX_S2_CONCAT 16
67
68
#define VMSA_STRIDE(gran) ((gran) - VMSA_LEVELS + 1)
69
#define VMSA_BIT_LVL(isz, strd, lvl) ((isz) - (strd) * \
70
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/include/hw/arm/smmuv3.h
73
+++ b/include/hw/arm/smmuv3.h
74
@@ -XXX,XX +XXX,XX @@ struct SMMUv3Class {
75
#define TYPE_ARM_SMMUV3 "arm-smmuv3"
76
OBJECT_DECLARE_TYPE(SMMUv3State, SMMUv3Class, ARM_SMMUV3)
77
78
+#define STAGE1_SUPPORTED(s) FIELD_EX32(s->idr[0], IDR0, S1P)
79
+#define STAGE2_SUPPORTED(s) FIELD_EX32(s->idr[0], IDR0, S2P)
80
+
81
#endif
82
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/arm/smmuv3.c
85
+++ b/hw/arm/smmuv3.c
86
@@ -XXX,XX +XXX,XX @@
87
#include "smmuv3-internal.h"
88
#include "smmu-internal.h"
89
90
+#define PTW_RECORD_FAULT(cfg) (((cfg)->stage == 1) ? (cfg)->record_faults : \
91
+ (cfg)->s2cfg.record_faults)
92
+
93
/**
94
* smmuv3_trigger_irq - pulse @irq if enabled and update
95
* GERROR register in case of GERROR interrupt
96
@@ -XXX,XX +XXX,XX @@ static int smmu_get_cd(SMMUv3State *s, STE *ste, uint32_t ssid,
97
return 0;
20
}
98
}
21
99
22
+/*
100
+/*
23
+ * Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
101
+ * Max valid value is 39 when SMMU_IDR3.STT == 0.
24
+ * where 0 is the least significant end of the register.
102
+ * In architectures after SMMUv3.0:
103
+ * - If STE.S2TG selects a 4KB or 16KB granule, the minimum valid value for this
104
+ * field is MAX(16, 64-IAS)
105
+ * - If STE.S2TG selects a 64KB granule, the minimum valid value for this field
106
+ * is (64-IAS).
107
+ * As we only support AA64, IAS = OAS.
25
+ */
108
+ */
26
+static long neon_element_offset(int reg, int element, MemOp size)
109
+static bool s2t0sz_valid(SMMUTransCfg *cfg)
27
+{
110
+{
28
+ int element_size = 1 << size;
111
+ if (cfg->s2cfg.tsz > 39) {
29
+ int ofs = element * element_size;
112
+ return false;
30
+#ifdef HOST_WORDS_BIGENDIAN
113
+ }
114
+
115
+ if (cfg->s2cfg.granule_sz == 16) {
116
+ return (cfg->s2cfg.tsz >= 64 - oas2bits(SMMU_IDR5_OAS));
117
+ }
118
+
119
+ return (cfg->s2cfg.tsz >= MAX(64 - oas2bits(SMMU_IDR5_OAS), 16));
120
+}
121
+
122
+/*
123
+ * Return true if s2 page table config is valid.
124
+ * This checks with the configured start level, ias_bits and granularity we can
125
+ * have a valid page table as described in ARM ARM D8.2 Translation process.
126
+ * The idea here is to see for the highest possible number of IPA bits, how
127
+ * many concatenated tables we would need, if it is more than 16, then this is
128
+ * not possible.
129
+ */
130
+static bool s2_pgtable_config_valid(uint8_t sl0, uint8_t t0sz, uint8_t gran)
131
+{
132
+ int level = get_start_level(sl0, gran);
133
+ uint64_t ipa_bits = 64 - t0sz;
134
+ uint64_t max_ipa = (1ULL << ipa_bits) - 1;
135
+ int nr_concat = pgd_concat_idx(level, gran, max_ipa) + 1;
136
+
137
+ return nr_concat <= VMSA_MAX_S2_CONCAT;
138
+}
139
+
140
+static int decode_ste_s2_cfg(SMMUTransCfg *cfg, STE *ste)
141
+{
142
+ cfg->stage = 2;
143
+
144
+ if (STE_S2AA64(ste) == 0x0) {
145
+ qemu_log_mask(LOG_UNIMP,
146
+ "SMMUv3 AArch32 tables not supported\n");
147
+ g_assert_not_reached();
148
+ }
149
+
150
+ switch (STE_S2TG(ste)) {
151
+ case 0x0: /* 4KB */
152
+ cfg->s2cfg.granule_sz = 12;
153
+ break;
154
+ case 0x1: /* 64KB */
155
+ cfg->s2cfg.granule_sz = 16;
156
+ break;
157
+ case 0x2: /* 16KB */
158
+ cfg->s2cfg.granule_sz = 14;
159
+ break;
160
+ default:
161
+ qemu_log_mask(LOG_GUEST_ERROR,
162
+ "SMMUv3 bad STE S2TG: %x\n", STE_S2TG(ste));
163
+ goto bad_ste;
164
+ }
165
+
166
+ cfg->s2cfg.vttb = STE_S2TTB(ste);
167
+
168
+ cfg->s2cfg.sl0 = STE_S2SL0(ste);
169
+ /* FEAT_TTST not supported. */
170
+ if (cfg->s2cfg.sl0 == 0x3) {
171
+ qemu_log_mask(LOG_UNIMP, "SMMUv3 S2SL0 = 0x3 has no meaning!\n");
172
+ goto bad_ste;
173
+ }
174
+
175
+ /* For AA64, The effective S2PS size is capped to the OAS. */
176
+ cfg->s2cfg.eff_ps = oas2bits(MIN(STE_S2PS(ste), SMMU_IDR5_OAS));
31
+ /*
177
+ /*
32
+ * Calculate the offset assuming fully little-endian,
178
+ * It is ILLEGAL for the address in S2TTB to be outside the range
33
+ * then XOR to account for the order of the 8-byte units.
179
+ * described by the effective S2PS value.
34
+ */
180
+ */
35
+ if (element_size < 8) {
181
+ if (cfg->s2cfg.vttb & ~(MAKE_64BIT_MASK(0, cfg->s2cfg.eff_ps))) {
36
+ ofs ^= 8 - element_size;
182
+ qemu_log_mask(LOG_GUEST_ERROR,
37
+ }
183
+ "SMMUv3 S2TTB too large 0x%lx, effective PS %d bits\n",
38
+#endif
184
+ cfg->s2cfg.vttb, cfg->s2cfg.eff_ps);
39
+ return neon_full_reg_offset(reg) + ofs;
185
+ goto bad_ste;
186
+ }
187
+
188
+ cfg->s2cfg.tsz = STE_S2T0SZ(ste);
189
+
190
+ if (!s2t0sz_valid(cfg)) {
191
+ qemu_log_mask(LOG_GUEST_ERROR, "SMMUv3 bad STE S2T0SZ = %d\n",
192
+ cfg->s2cfg.tsz);
193
+ goto bad_ste;
194
+ }
195
+
196
+ if (!s2_pgtable_config_valid(cfg->s2cfg.sl0, cfg->s2cfg.tsz,
197
+ cfg->s2cfg.granule_sz)) {
198
+ qemu_log_mask(LOG_GUEST_ERROR,
199
+ "SMMUv3 STE stage 2 config not valid!\n");
200
+ goto bad_ste;
201
+ }
202
+
203
+ /* Only LE supported(IDR0.TTENDIAN). */
204
+ if (STE_S2ENDI(ste)) {
205
+ qemu_log_mask(LOG_GUEST_ERROR,
206
+ "SMMUv3 STE_S2ENDI only supports LE!\n");
207
+ goto bad_ste;
208
+ }
209
+
210
+ cfg->s2cfg.affd = STE_S2AFFD(ste);
211
+
212
+ cfg->s2cfg.record_faults = STE_S2R(ste);
213
+ /* As stall is not supported. */
214
+ if (STE_S2S(ste)) {
215
+ qemu_log_mask(LOG_UNIMP, "SMMUv3 Stall not implemented!\n");
216
+ goto bad_ste;
217
+ }
218
+
219
+ /* This is still here as stage 2 has not been fully enabled yet. */
220
+ qemu_log_mask(LOG_UNIMP, "SMMUv3 does not support stage 2 yet\n");
221
+ goto bad_ste;
222
+
223
+ return 0;
224
+
225
+bad_ste:
226
+ return -EINVAL;
40
+}
227
+}
41
+
228
+
42
static inline long vfp_reg_offset(bool dp, unsigned reg)
229
/* Returns < 0 in case of invalid STE, 0 otherwise */
230
static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
231
STE *ste, SMMUEventInfo *event)
43
{
232
{
44
if (dp) {
233
uint32_t config;
45
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
234
+ int ret;
46
index XXXXXXX..XXXXXXX 100644
235
47
--- a/target/arm/translate-neon.c.inc
236
if (!STE_VALID(ste)) {
48
+++ b/target/arm/translate-neon.c.inc
237
if (!event->inval_ste_allowed) {
49
@@ -XXX,XX +XXX,XX @@ static inline int neon_3same_fp_size(DisasContext *s, int x)
238
@@ -XXX,XX +XXX,XX @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
50
#include "decode-neon-ls.c.inc"
239
return 0;
51
#include "decode-neon-shared.c.inc"
240
}
52
241
53
-/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
242
- if (STE_CFG_S2_ENABLED(config)) {
54
- * where 0 is the least significant end of the register.
243
- qemu_log_mask(LOG_UNIMP, "SMMUv3 does not support stage 2 yet\n");
55
- */
244
+ /*
56
-static inline long
245
+ * If a stage is enabled in SW while not advertised, throw bad ste
57
-neon_element_offset(int reg, int element, MemOp size)
246
+ * according to user manual(IHI0070E) "5.2 Stream Table Entry".
58
-{
247
+ */
59
- int element_size = 1 << size;
248
+ if (!STAGE1_SUPPORTED(s) && STE_CFG_S1_ENABLED(config)) {
60
- int ofs = element * element_size;
249
+ qemu_log_mask(LOG_GUEST_ERROR, "SMMUv3 S1 used but not supported.\n");
61
-#ifdef HOST_WORDS_BIGENDIAN
250
goto bad_ste;
62
- /* Calculate the offset assuming fully little-endian,
251
}
63
- * then XOR to account for the order of the 8-byte units.
252
+ if (!STAGE2_SUPPORTED(s) && STE_CFG_S2_ENABLED(config)) {
64
- */
253
+ qemu_log_mask(LOG_GUEST_ERROR, "SMMUv3 S2 used but not supported.\n");
65
- if (element_size < 8) {
254
+ goto bad_ste;
66
- ofs ^= 8 - element_size;
255
+ }
67
- }
256
+
68
-#endif
257
+ if (STAGE2_SUPPORTED(s)) {
69
- return neon_full_reg_offset(reg) + ofs;
258
+ /* VMID is considered even if s2 is disabled. */
70
-}
259
+ cfg->s2cfg.vmid = STE_S2VMID(ste);
71
-
260
+ } else {
72
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
261
+ /* Default to -1 */
73
{
262
+ cfg->s2cfg.vmid = -1;
74
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
263
+ }
264
+
265
+ if (STE_CFG_S2_ENABLED(config)) {
266
+ /*
267
+ * Stage-1 OAS defaults to OAS even if not enabled as it would be used
268
+ * in input address check for stage-2.
269
+ */
270
+ cfg->oas = oas2bits(SMMU_IDR5_OAS);
271
+ ret = decode_ste_s2_cfg(cfg, ste);
272
+ if (ret) {
273
+ goto bad_ste;
274
+ }
275
+ }
276
277
if (STE_S1CDMAX(ste) != 0) {
278
qemu_log_mask(LOG_UNIMP,
279
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
280
if (cached_entry) {
281
if ((flag & IOMMU_WO) && !(cached_entry->entry.perm & IOMMU_WO)) {
282
status = SMMU_TRANS_ERROR;
283
- if (cfg->record_faults) {
284
+ /*
285
+ * We know that the TLB only contains either stage-1 or stage-2 as
286
+ * nesting is not supported. So it is sufficient to check the
287
+ * translation stage to know the TLB stage for now.
288
+ */
289
+ event.u.f_walk_eabt.s2 = (cfg->stage == 2);
290
+ if (PTW_RECORD_FAULT(cfg)) {
291
event.type = SMMU_EVT_F_PERMISSION;
292
event.u.f_permission.addr = addr;
293
event.u.f_permission.rnw = flag & 0x1;
294
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
295
event.u.f_walk_eabt.addr2 = ptw_info.addr;
296
break;
297
case SMMU_PTW_ERR_TRANSLATION:
298
- if (cfg->record_faults) {
299
+ if (PTW_RECORD_FAULT(cfg)) {
300
event.type = SMMU_EVT_F_TRANSLATION;
301
event.u.f_translation.addr = addr;
302
event.u.f_translation.rnw = flag & 0x1;
303
}
304
break;
305
case SMMU_PTW_ERR_ADDR_SIZE:
306
- if (cfg->record_faults) {
307
+ if (PTW_RECORD_FAULT(cfg)) {
308
event.type = SMMU_EVT_F_ADDR_SIZE;
309
event.u.f_addr_size.addr = addr;
310
event.u.f_addr_size.rnw = flag & 0x1;
311
}
312
break;
313
case SMMU_PTW_ERR_ACCESS:
314
- if (cfg->record_faults) {
315
+ if (PTW_RECORD_FAULT(cfg)) {
316
event.type = SMMU_EVT_F_ACCESS;
317
event.u.f_access.addr = addr;
318
event.u.f_access.rnw = flag & 0x1;
319
}
320
break;
321
case SMMU_PTW_ERR_PERMISSION:
322
- if (cfg->record_faults) {
323
+ if (PTW_RECORD_FAULT(cfg)) {
324
event.type = SMMU_EVT_F_PERMISSION;
325
event.u.f_permission.addr = addr;
326
event.u.f_permission.rnw = flag & 0x1;
75
--
327
--
76
2.20.1
328
2.34.1
77
78
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Mostafa Saleh <smostafa@google.com>
2
2
3
Use the BIT_ULL() macro to ensure we use 64-bit arithmetic.
3
Right now, either stage-1 or stage-2 are supported, this simplifies
4
This fixes the following Coverity issue (OVERFLOW_BEFORE_WIDEN):
4
how we can deal with TLBs.
5
This patch makes TLB lookup work if stage-2 is enabled instead of
6
stage-1.
7
TLB lookup is done before a PTW, if a valid entry is found we won't
8
do the PTW.
9
To be able to do TLB lookup, we need the correct tagging info, as
10
granularity and input size, so we get this based on the supported
11
translation stage. The TLB entries are added correctly from each
12
stage PTW.
5
13
6
CID 1432363 (#1 of 1): Unintentional integer overflow:
14
When nested translation is supported, this would need to change, for
15
example if we go with a combined TLB implementation, we would need to
16
use the min of the granularities in TLB.
7
17
8
overflow_before_widen:
18
As stage-2 shouldn't be tagged by ASID, it will be set to -1 if S1P
9
Potentially overflowing expression 1 << scale with type int
19
is not enabled.
10
(32 bits, signed) is evaluated using 32-bit arithmetic, and
11
then used in a context that expects an expression of type
12
hwaddr (64 bits, unsigned).
13
20
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Signed-off-by: Mostafa Saleh <smostafa@google.com>
15
Acked-by: Eric Auger <eric.auger@redhat.com>
22
Reviewed-by: Eric Auger <eric.auger@redhat.com>
16
Message-id: 20201030144617.1535064-1-philmd@redhat.com
23
Tested-by: Eric Auger <eric.auger@redhat.com>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
25
Message-id: 20230516203327.2051088-7-smostafa@google.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
27
---
20
hw/arm/smmuv3.c | 3 ++-
28
hw/arm/smmuv3.c | 44 +++++++++++++++++++++++++++++++++-----------
21
1 file changed, 2 insertions(+), 1 deletion(-)
29
1 file changed, 33 insertions(+), 11 deletions(-)
22
30
23
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
31
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
24
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/smmuv3.c
33
--- a/hw/arm/smmuv3.c
26
+++ b/hw/arm/smmuv3.c
34
+++ b/hw/arm/smmuv3.c
27
@@ -XXX,XX +XXX,XX @@
35
@@ -XXX,XX +XXX,XX @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
28
*/
36
STE ste;
29
37
CD cd;
30
#include "qemu/osdep.h"
38
31
+#include "qemu/bitops.h"
39
+ /* ASID defaults to -1 (if s1 is not supported). */
32
#include "hw/irq.h"
40
+ cfg->asid = -1;
33
#include "hw/sysbus.h"
41
+
34
#include "migration/vmstate.h"
42
ret = smmu_find_ste(s, sid, &ste, event);
35
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
43
if (ret) {
36
scale = CMD_SCALE(cmd);
44
return ret;
37
num = CMD_NUM(cmd);
45
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
38
ttl = CMD_TTL(cmd);
46
.addr_mask = ~(hwaddr)0,
39
- num_pages = (num + 1) * (1 << (scale));
47
.perm = IOMMU_NONE,
40
+ num_pages = (num + 1) * BIT_ULL(scale);
48
};
49
+ /*
50
+ * Combined attributes used for TLB lookup, as only one stage is supported,
51
+ * it will hold attributes based on the enabled stage.
52
+ */
53
+ SMMUTransTableInfo tt_combined;
54
55
qemu_mutex_lock(&s->mutex);
56
57
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
58
goto epilogue;
41
}
59
}
42
60
43
if (type == SMMU_CMD_TLBI_NH_VA) {
61
- tt = select_tt(cfg, addr);
62
- if (!tt) {
63
- if (cfg->record_faults) {
64
- event.type = SMMU_EVT_F_TRANSLATION;
65
- event.u.f_translation.addr = addr;
66
- event.u.f_translation.rnw = flag & 0x1;
67
+ if (cfg->stage == 1) {
68
+ /* Select stage1 translation table. */
69
+ tt = select_tt(cfg, addr);
70
+ if (!tt) {
71
+ if (cfg->record_faults) {
72
+ event.type = SMMU_EVT_F_TRANSLATION;
73
+ event.u.f_translation.addr = addr;
74
+ event.u.f_translation.rnw = flag & 0x1;
75
+ }
76
+ status = SMMU_TRANS_ERROR;
77
+ goto epilogue;
78
}
79
- status = SMMU_TRANS_ERROR;
80
- goto epilogue;
81
- }
82
+ tt_combined.granule_sz = tt->granule_sz;
83
+ tt_combined.tsz = tt->tsz;
84
85
- page_mask = (1ULL << (tt->granule_sz)) - 1;
86
+ } else {
87
+ /* Stage2. */
88
+ tt_combined.granule_sz = cfg->s2cfg.granule_sz;
89
+ tt_combined.tsz = cfg->s2cfg.tsz;
90
+ }
91
+ /*
92
+ * TLB lookup looks for granule and input size for a translation stage,
93
+ * as only one stage is supported right now, choose the right values
94
+ * from the configuration.
95
+ */
96
+ page_mask = (1ULL << tt_combined.granule_sz) - 1;
97
aligned_addr = addr & ~page_mask;
98
99
- cached_entry = smmu_iotlb_lookup(bs, cfg, tt, aligned_addr);
100
+ cached_entry = smmu_iotlb_lookup(bs, cfg, &tt_combined, aligned_addr);
101
if (cached_entry) {
102
if ((flag & IOMMU_WO) && !(cached_entry->entry.perm & IOMMU_WO)) {
103
status = SMMU_TRANS_ERROR;
44
--
104
--
45
2.20.1
105
2.34.1
46
47
diff view generated by jsdifflib
1
From: AlexChen <alex.chen@huawei.com>
1
From: Mostafa Saleh <smostafa@google.com>
2
2
3
In omap_lcd_interrupts(), the pointer omap_lcd is dereferinced before
3
Allow TLB to be tagged with VMID.
4
being check if it is valid, which may lead to NULL pointer dereference.
4
5
So move the assignment to surface after checking that the omap_lcd is valid
5
If stage-1 is only supported, VMID is set to -1 and ignored from STE
6
and move surface_bits_per_pixel(surface) to after the surface assignment.
6
and CMD_TLBI_NH* cmds.
7
7
8
Reported-by: Euler Robot <euler.robot@huawei.com>
8
Update smmu_iotlb_insert trace event to have vmid.
9
Signed-off-by: AlexChen <alex.chen@huawei.com>
9
10
Message-id: 5F9CDB8A.9000001@huawei.com
10
Signed-off-by: Mostafa Saleh <smostafa@google.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
Tested-by: Eric Auger <eric.auger@redhat.com>
13
Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
14
Message-id: 20230516203327.2051088-8-smostafa@google.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
16
---
14
hw/display/omap_lcdc.c | 10 +++++++---
17
hw/arm/smmu-internal.h | 2 ++
15
1 file changed, 7 insertions(+), 3 deletions(-)
18
include/hw/arm/smmu-common.h | 5 +++--
16
19
hw/arm/smmu-common.c | 36 ++++++++++++++++++++++--------------
17
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
20
hw/arm/smmuv3.c | 12 +++++++++---
18
index XXXXXXX..XXXXXXX 100644
21
hw/arm/trace-events | 6 +++---
19
--- a/hw/display/omap_lcdc.c
22
5 files changed, 39 insertions(+), 22 deletions(-)
20
+++ b/hw/display/omap_lcdc.c
23
21
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
24
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
22
static void omap_update_display(void *opaque)
25
index XXXXXXX..XXXXXXX 100644
23
{
26
--- a/hw/arm/smmu-internal.h
24
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
27
+++ b/hw/arm/smmu-internal.h
25
- DisplaySurface *surface = qemu_console_surface(omap_lcd->con);
28
@@ -XXX,XX +XXX,XX @@ static inline int pgd_concat_idx(int start_level, int granule_sz,
26
+ DisplaySurface *surface;
29
}
27
draw_line_func draw_line;
30
28
int size, height, first, last;
31
#define SMMU_IOTLB_ASID(key) ((key).asid)
29
int width, linesize, step, bpp, frame_offset;
32
+#define SMMU_IOTLB_VMID(key) ((key).vmid)
30
hwaddr frame_base;
33
31
34
typedef struct SMMUIOTLBPageInvInfo {
32
- if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable ||
35
int asid;
33
- !surface_bits_per_pixel(surface)) {
36
+ int vmid;
34
+ if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable) {
37
uint64_t iova;
35
+ return;
38
uint64_t mask;
39
} SMMUIOTLBPageInvInfo;
40
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/hw/arm/smmu-common.h
43
+++ b/include/hw/arm/smmu-common.h
44
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUPciBus {
45
typedef struct SMMUIOTLBKey {
46
uint64_t iova;
47
uint16_t asid;
48
+ uint16_t vmid;
49
uint8_t tg;
50
uint8_t level;
51
} SMMUIOTLBKey;
52
@@ -XXX,XX +XXX,XX @@ IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid);
53
SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg,
54
SMMUTransTableInfo *tt, hwaddr iova);
55
void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *entry);
56
-SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint64_t iova,
57
+SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint16_t vmid, uint64_t iova,
58
uint8_t tg, uint8_t level);
59
void smmu_iotlb_inv_all(SMMUState *s);
60
void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid);
61
-void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
62
+void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova,
63
uint8_t tg, uint64_t num_pages, uint8_t ttl);
64
65
/* Unmap the range of all the notifiers registered to any IOMMU mr */
66
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/smmu-common.c
69
+++ b/hw/arm/smmu-common.c
70
@@ -XXX,XX +XXX,XX @@ static guint smmu_iotlb_key_hash(gconstpointer v)
71
72
/* Jenkins hash */
73
a = b = c = JHASH_INITVAL + sizeof(*key);
74
- a += key->asid + key->level + key->tg;
75
+ a += key->asid + key->vmid + key->level + key->tg;
76
b += extract64(key->iova, 0, 32);
77
c += extract64(key->iova, 32, 32);
78
79
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_iotlb_key_equal(gconstpointer v1, gconstpointer v2)
80
SMMUIOTLBKey *k1 = (SMMUIOTLBKey *)v1, *k2 = (SMMUIOTLBKey *)v2;
81
82
return (k1->asid == k2->asid) && (k1->iova == k2->iova) &&
83
- (k1->level == k2->level) && (k1->tg == k2->tg);
84
+ (k1->level == k2->level) && (k1->tg == k2->tg) &&
85
+ (k1->vmid == k2->vmid);
86
}
87
88
-SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint64_t iova,
89
+SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint16_t vmid, uint64_t iova,
90
uint8_t tg, uint8_t level)
91
{
92
- SMMUIOTLBKey key = {.asid = asid, .iova = iova, .tg = tg, .level = level};
93
+ SMMUIOTLBKey key = {.asid = asid, .vmid = vmid, .iova = iova,
94
+ .tg = tg, .level = level};
95
96
return key;
97
}
98
@@ -XXX,XX +XXX,XX @@ SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg,
99
uint64_t mask = subpage_size - 1;
100
SMMUIOTLBKey key;
101
102
- key = smmu_get_iotlb_key(cfg->asid, iova & ~mask, tg, level);
103
+ key = smmu_get_iotlb_key(cfg->asid, cfg->s2cfg.vmid,
104
+ iova & ~mask, tg, level);
105
entry = g_hash_table_lookup(bs->iotlb, &key);
106
if (entry) {
107
break;
108
@@ -XXX,XX +XXX,XX @@ SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg,
109
110
if (entry) {
111
cfg->iotlb_hits++;
112
- trace_smmu_iotlb_lookup_hit(cfg->asid, iova,
113
+ trace_smmu_iotlb_lookup_hit(cfg->asid, cfg->s2cfg.vmid, iova,
114
cfg->iotlb_hits, cfg->iotlb_misses,
115
100 * cfg->iotlb_hits /
116
(cfg->iotlb_hits + cfg->iotlb_misses));
117
} else {
118
cfg->iotlb_misses++;
119
- trace_smmu_iotlb_lookup_miss(cfg->asid, iova,
120
+ trace_smmu_iotlb_lookup_miss(cfg->asid, cfg->s2cfg.vmid, iova,
121
cfg->iotlb_hits, cfg->iotlb_misses,
122
100 * cfg->iotlb_hits /
123
(cfg->iotlb_hits + cfg->iotlb_misses));
124
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *new)
125
smmu_iotlb_inv_all(bs);
126
}
127
128
- *key = smmu_get_iotlb_key(cfg->asid, new->entry.iova, tg, new->level);
129
- trace_smmu_iotlb_insert(cfg->asid, new->entry.iova, tg, new->level);
130
+ *key = smmu_get_iotlb_key(cfg->asid, cfg->s2cfg.vmid, new->entry.iova,
131
+ tg, new->level);
132
+ trace_smmu_iotlb_insert(cfg->asid, cfg->s2cfg.vmid, new->entry.iova,
133
+ tg, new->level);
134
g_hash_table_insert(bs->iotlb, key, new);
135
}
136
137
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_hash_remove_by_asid(gpointer key, gpointer value,
138
139
return SMMU_IOTLB_ASID(*iotlb_key) == asid;
140
}
141
-
142
-static gboolean smmu_hash_remove_by_asid_iova(gpointer key, gpointer value,
143
+static gboolean smmu_hash_remove_by_asid_vmid_iova(gpointer key, gpointer value,
144
gpointer user_data)
145
{
146
SMMUTLBEntry *iter = (SMMUTLBEntry *)value;
147
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_hash_remove_by_asid_iova(gpointer key, gpointer value,
148
if (info->asid >= 0 && info->asid != SMMU_IOTLB_ASID(iotlb_key)) {
149
return false;
150
}
151
+ if (info->vmid >= 0 && info->vmid != SMMU_IOTLB_VMID(iotlb_key)) {
152
+ return false;
36
+ }
153
+ }
154
return ((info->iova & ~entry->addr_mask) == entry->iova) ||
155
((entry->iova & ~info->mask) == info->iova);
156
}
157
158
-void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
159
+void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova,
160
uint8_t tg, uint64_t num_pages, uint8_t ttl)
161
{
162
/* if tg is not set we use 4KB range invalidation */
163
uint8_t granule = tg ? tg * 2 + 10 : 12;
164
165
if (ttl && (num_pages == 1) && (asid >= 0)) {
166
- SMMUIOTLBKey key = smmu_get_iotlb_key(asid, iova, tg, ttl);
167
+ SMMUIOTLBKey key = smmu_get_iotlb_key(asid, vmid, iova, tg, ttl);
168
169
if (g_hash_table_remove(s->iotlb, &key)) {
170
return;
171
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
172
173
SMMUIOTLBPageInvInfo info = {
174
.asid = asid, .iova = iova,
175
+ .vmid = vmid,
176
.mask = (num_pages * 1 << granule) - 1};
177
178
g_hash_table_foreach_remove(s->iotlb,
179
- smmu_hash_remove_by_asid_iova,
180
+ smmu_hash_remove_by_asid_vmid_iova,
181
&info);
182
}
183
184
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
185
index XXXXXXX..XXXXXXX 100644
186
--- a/hw/arm/smmuv3.c
187
+++ b/hw/arm/smmuv3.c
188
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
189
{
190
dma_addr_t end, addr = CMD_ADDR(cmd);
191
uint8_t type = CMD_TYPE(cmd);
192
- uint16_t vmid = CMD_VMID(cmd);
193
+ int vmid = -1;
194
uint8_t scale = CMD_SCALE(cmd);
195
uint8_t num = CMD_NUM(cmd);
196
uint8_t ttl = CMD_TTL(cmd);
197
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
198
uint64_t num_pages;
199
uint8_t granule;
200
int asid = -1;
201
+ SMMUv3State *smmuv3 = ARM_SMMUV3(s);
37
+
202
+
38
+ surface = qemu_console_surface(omap_lcd->con);
203
+ /* Only consider VMID if stage-2 is supported. */
39
+ if (!surface_bits_per_pixel(surface)) {
204
+ if (STAGE2_SUPPORTED(smmuv3)) {
205
+ vmid = CMD_VMID(cmd);
206
+ }
207
208
if (type == SMMU_CMD_TLBI_NH_VA) {
209
asid = CMD_ASID(cmd);
210
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
211
if (!tg) {
212
trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, 1, ttl, leaf);
213
smmuv3_inv_notifiers_iova(s, asid, addr, tg, 1);
214
- smmu_iotlb_inv_iova(s, asid, addr, tg, 1, ttl);
215
+ smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, 1, ttl);
40
return;
216
return;
41
}
217
}
42
218
219
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
220
num_pages = (mask + 1) >> granule;
221
trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf);
222
smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages);
223
- smmu_iotlb_inv_iova(s, asid, addr, tg, num_pages, ttl);
224
+ smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, num_pages, ttl);
225
addr += mask + 1;
226
}
227
}
228
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
229
index XXXXXXX..XXXXXXX 100644
230
--- a/hw/arm/trace-events
231
+++ b/hw/arm/trace-events
232
@@ -XXX,XX +XXX,XX @@ smmu_iotlb_inv_all(void) "IOTLB invalidate all"
233
smmu_iotlb_inv_asid(uint16_t asid) "IOTLB invalidate asid=%d"
234
smmu_iotlb_inv_iova(uint16_t asid, uint64_t addr) "IOTLB invalidate asid=%d addr=0x%"PRIx64
235
smmu_inv_notifiers_mr(const char *name) "iommu mr=%s"
236
-smmu_iotlb_lookup_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"
237
-smmu_iotlb_lookup_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"
238
-smmu_iotlb_insert(uint16_t asid, uint64_t addr, uint8_t tg, uint8_t level) "IOTLB ++ asid=%d addr=0x%"PRIx64" tg=%d level=%d"
239
+smmu_iotlb_lookup_hit(uint16_t asid, uint16_t vmid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache HIT asid=%d vmid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
240
+smmu_iotlb_lookup_miss(uint16_t asid, uint16_t vmid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache MISS asid=%d vmid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
241
+smmu_iotlb_insert(uint16_t asid, uint16_t vmid, uint64_t addr, uint8_t tg, uint8_t level) "IOTLB ++ asid=%d vmid=%d addr=0x%"PRIx64" tg=%d level=%d"
242
243
# smmuv3.c
244
smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
43
--
245
--
44
2.20.1
246
2.34.1
45
46
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Mostafa Saleh <smostafa@google.com>
2
2
3
The only uses of this function are for loading VFP
3
CMD_TLBI_S2_IPA: As S1+S2 is not enabled, for now this can be the
4
double-precision values, and nothing to do with NEON.
4
same as CMD_TLBI_NH_VAA.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
CMD_TLBI_S12_VMALL: Added new function to invalidate TLB by VMID.
7
Message-id: 20201030022618.785675-10-richard.henderson@linaro.org
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
For stage-1 only commands, add a check to throw CERROR_ILL if used
9
when stage-1 is not supported.
10
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
Signed-off-by: Mostafa Saleh <smostafa@google.com>
13
Tested-by: Eric Auger <eric.auger@redhat.com>
14
Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
15
Message-id: 20230516203327.2051088-9-smostafa@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
17
---
11
target/arm/translate.c | 8 ++--
18
include/hw/arm/smmu-common.h | 1 +
12
target/arm/translate-vfp.c.inc | 84 +++++++++++++++++-----------------
19
hw/arm/smmu-common.c | 16 +++++++++++
13
2 files changed, 46 insertions(+), 46 deletions(-)
20
hw/arm/smmuv3.c | 55 ++++++++++++++++++++++++++++++------
14
21
hw/arm/trace-events | 4 ++-
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
22
4 files changed, 67 insertions(+), 9 deletions(-)
16
index XXXXXXX..XXXXXXX 100644
23
17
--- a/target/arm/translate.c
24
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
18
+++ b/target/arm/translate.c
25
index XXXXXXX..XXXXXXX 100644
19
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
26
--- a/include/hw/arm/smmu-common.h
27
+++ b/include/hw/arm/smmu-common.h
28
@@ -XXX,XX +XXX,XX @@ SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint16_t vmid, uint64_t iova,
29
uint8_t tg, uint8_t level);
30
void smmu_iotlb_inv_all(SMMUState *s);
31
void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid);
32
+void smmu_iotlb_inv_vmid(SMMUState *s, uint16_t vmid);
33
void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova,
34
uint8_t tg, uint64_t num_pages, uint8_t ttl);
35
36
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/smmu-common.c
39
+++ b/hw/arm/smmu-common.c
40
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_hash_remove_by_asid(gpointer key, gpointer value,
41
42
return SMMU_IOTLB_ASID(*iotlb_key) == asid;
43
}
44
+
45
+static gboolean smmu_hash_remove_by_vmid(gpointer key, gpointer value,
46
+ gpointer user_data)
47
+{
48
+ uint16_t vmid = *(uint16_t *)user_data;
49
+ SMMUIOTLBKey *iotlb_key = (SMMUIOTLBKey *)key;
50
+
51
+ return SMMU_IOTLB_VMID(*iotlb_key) == vmid;
52
+}
53
+
54
static gboolean smmu_hash_remove_by_asid_vmid_iova(gpointer key, gpointer value,
55
gpointer user_data)
56
{
57
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
58
g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_asid, &asid);
59
}
60
61
+inline void smmu_iotlb_inv_vmid(SMMUState *s, uint16_t vmid)
62
+{
63
+ trace_smmu_iotlb_inv_vmid(vmid);
64
+ g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_vmid, &vmid);
65
+}
66
+
67
/* VMSAv8-64 Translation */
68
69
/**
70
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/arm/smmuv3.c
73
+++ b/hw/arm/smmuv3.c
74
@@ -XXX,XX +XXX,XX @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova,
20
}
75
}
21
}
76
}
22
77
23
-static inline void neon_load_reg64(TCGv_i64 var, int reg)
78
-static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
24
+static inline void vfp_load_reg64(TCGv_i64 var, int reg)
79
+static void smmuv3_range_inval(SMMUState *s, Cmd *cmd)
25
{
80
{
26
- tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
81
dma_addr_t end, addr = CMD_ADDR(cmd);
27
+ tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
82
uint8_t type = CMD_TYPE(cmd);
28
}
83
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
29
84
}
30
-static inline void neon_store_reg64(TCGv_i64 var, int reg)
85
31
+static inline void vfp_store_reg64(TCGv_i64 var, int reg)
86
if (!tg) {
32
{
87
- trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, 1, ttl, leaf);
33
- tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
88
+ trace_smmuv3_range_inval(vmid, asid, addr, tg, 1, ttl, leaf);
34
+ tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
89
smmuv3_inv_notifiers_iova(s, asid, addr, tg, 1);
35
}
90
smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, 1, ttl);
36
91
return;
37
static inline void vfp_load_reg32(TCGv_i32 var, int reg)
92
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
38
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
93
uint64_t mask = dma_aligned_pow2_mask(addr, end, 64);
39
index XXXXXXX..XXXXXXX 100644
94
40
--- a/target/arm/translate-vfp.c.inc
95
num_pages = (mask + 1) >> granule;
41
+++ b/target/arm/translate-vfp.c.inc
96
- trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf);
42
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
97
+ trace_smmuv3_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf);
43
tcg_gen_ext_i32_i64(nf, cpu_NF);
98
smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages);
44
tcg_gen_ext_i32_i64(vf, cpu_VF);
99
smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, num_pages, ttl);
45
100
addr += mask + 1;
46
- neon_load_reg64(frn, rn);
101
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
47
- neon_load_reg64(frm, rm);
102
{
48
+ vfp_load_reg64(frn, rn);
103
uint16_t asid = CMD_ASID(&cmd);
49
+ vfp_load_reg64(frm, rm);
104
50
switch (a->cc) {
105
+ if (!STAGE1_SUPPORTED(s)) {
51
case 0: /* eq: Z */
106
+ cmd_error = SMMU_CERROR_ILL;
52
tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
107
+ break;
53
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
108
+ }
54
tcg_temp_free_i64(tmp);
109
+
110
trace_smmuv3_cmdq_tlbi_nh_asid(asid);
111
smmu_inv_notifiers_all(&s->smmu_state);
112
smmu_iotlb_inv_asid(bs, asid);
55
break;
113
break;
56
}
114
}
57
- neon_store_reg64(dest, rd);
115
case SMMU_CMD_TLBI_NH_ALL:
58
+ vfp_store_reg64(dest, rd);
116
+ if (!STAGE1_SUPPORTED(s)) {
59
tcg_temp_free_i64(frn);
117
+ cmd_error = SMMU_CERROR_ILL;
60
tcg_temp_free_i64(frm);
118
+ break;
61
tcg_temp_free_i64(dest);
119
+ }
62
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
120
+ QEMU_FALLTHROUGH;
63
TCGv_i64 tcg_res;
121
case SMMU_CMD_TLBI_NSNH_ALL:
64
tcg_op = tcg_temp_new_i64();
122
trace_smmuv3_cmdq_tlbi_nh();
65
tcg_res = tcg_temp_new_i64();
123
smmu_inv_notifiers_all(&s->smmu_state);
66
- neon_load_reg64(tcg_op, rm);
124
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
67
+ vfp_load_reg64(tcg_op, rm);
125
break;
68
gen_helper_rintd(tcg_res, tcg_op, fpst);
126
case SMMU_CMD_TLBI_NH_VAA:
69
- neon_store_reg64(tcg_res, rd);
127
case SMMU_CMD_TLBI_NH_VA:
70
+ vfp_store_reg64(tcg_res, rd);
128
- smmuv3_s1_range_inval(bs, &cmd);
71
tcg_temp_free_i64(tcg_op);
129
+ if (!STAGE1_SUPPORTED(s)) {
72
tcg_temp_free_i64(tcg_res);
130
+ cmd_error = SMMU_CERROR_ILL;
73
} else {
131
+ break;
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
132
+ }
75
tcg_double = tcg_temp_new_i64();
133
+ smmuv3_range_inval(bs, &cmd);
76
tcg_res = tcg_temp_new_i64();
134
+ break;
77
tcg_tmp = tcg_temp_new_i32();
135
+ case SMMU_CMD_TLBI_S12_VMALL:
78
- neon_load_reg64(tcg_double, rm);
136
+ {
79
+ vfp_load_reg64(tcg_double, rm);
137
+ uint16_t vmid = CMD_VMID(&cmd);
80
if (is_signed) {
138
+
81
gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
139
+ if (!STAGE2_SUPPORTED(s)) {
82
} else {
140
+ cmd_error = SMMU_CERROR_ILL;
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
141
+ break;
84
tmp = tcg_temp_new_i64();
142
+ }
85
if (a->l) {
143
+
86
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
144
+ trace_smmuv3_cmdq_tlbi_s12_vmid(vmid);
87
- neon_store_reg64(tmp, a->vd);
145
+ smmu_inv_notifiers_all(&s->smmu_state);
88
+ vfp_store_reg64(tmp, a->vd);
146
+ smmu_iotlb_inv_vmid(bs, vmid);
89
} else {
147
+ break;
90
- neon_load_reg64(tmp, a->vd);
148
+ }
91
+ vfp_load_reg64(tmp, a->vd);
149
+ case SMMU_CMD_TLBI_S2_IPA:
92
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
150
+ if (!STAGE2_SUPPORTED(s)) {
93
}
151
+ cmd_error = SMMU_CERROR_ILL;
94
tcg_temp_free_i64(tmp);
152
+ break;
95
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
153
+ }
96
if (a->l) {
154
+ /*
97
/* load */
155
+ * As currently only either s1 or s2 are supported
98
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
156
+ * we can reuse same function for s2.
99
- neon_store_reg64(tmp, a->vd + i);
157
+ */
100
+ vfp_store_reg64(tmp, a->vd + i);
158
+ smmuv3_range_inval(bs, &cmd);
101
} else {
159
break;
102
/* store */
160
case SMMU_CMD_TLBI_EL3_ALL:
103
- neon_load_reg64(tmp, a->vd + i);
161
case SMMU_CMD_TLBI_EL3_VA:
104
+ vfp_load_reg64(tmp, a->vd + i);
162
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
105
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
163
case SMMU_CMD_TLBI_EL2_ASID:
164
case SMMU_CMD_TLBI_EL2_VA:
165
case SMMU_CMD_TLBI_EL2_VAA:
166
- case SMMU_CMD_TLBI_S12_VMALL:
167
- case SMMU_CMD_TLBI_S2_IPA:
168
case SMMU_CMD_ATC_INV:
169
case SMMU_CMD_PRI_RESP:
170
case SMMU_CMD_RESUME:
171
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
172
break;
173
default:
174
cmd_error = SMMU_CERROR_ILL;
175
- qemu_log_mask(LOG_GUEST_ERROR,
176
- "Illegal command type: %d\n", CMD_TYPE(&cmd));
177
break;
106
}
178
}
107
tcg_gen_addi_i32(addr, addr, offset);
179
qemu_mutex_unlock(&s->mutex);
108
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
180
if (cmd_error) {
109
fd = tcg_temp_new_i64();
181
+ if (cmd_error == SMMU_CERROR_ILL) {
110
fpst = fpstatus_ptr(FPST_FPCR);
182
+ qemu_log_mask(LOG_GUEST_ERROR,
111
183
+ "Illegal command type: %d\n", CMD_TYPE(&cmd));
112
- neon_load_reg64(f0, vn);
184
+ }
113
- neon_load_reg64(f1, vm);
185
break;
114
+ vfp_load_reg64(f0, vn);
115
+ vfp_load_reg64(f1, vm);
116
117
for (;;) {
118
if (reads_vd) {
119
- neon_load_reg64(fd, vd);
120
+ vfp_load_reg64(fd, vd);
121
}
186
}
122
fn(fd, f0, f1, fpst);
187
/*
123
- neon_store_reg64(fd, vd);
188
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
124
+ vfp_store_reg64(fd, vd);
189
index XXXXXXX..XXXXXXX 100644
125
190
--- a/hw/arm/trace-events
126
if (veclen == 0) {
191
+++ b/hw/arm/trace-events
127
break;
192
@@ -XXX,XX +XXX,XX @@ smmu_ptw_block_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, ui
128
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
193
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
129
veclen--;
194
smmu_iotlb_inv_all(void) "IOTLB invalidate all"
130
vd = vfp_advance_dreg(vd, delta_d);
195
smmu_iotlb_inv_asid(uint16_t asid) "IOTLB invalidate asid=%d"
131
vn = vfp_advance_dreg(vn, delta_d);
196
+smmu_iotlb_inv_vmid(uint16_t vmid) "IOTLB invalidate vmid=%d"
132
- neon_load_reg64(f0, vn);
197
smmu_iotlb_inv_iova(uint16_t asid, uint64_t addr) "IOTLB invalidate asid=%d addr=0x%"PRIx64
133
+ vfp_load_reg64(f0, vn);
198
smmu_inv_notifiers_mr(const char *name) "iommu mr=%s"
134
if (delta_m) {
199
smmu_iotlb_lookup_hit(uint16_t asid, uint16_t vmid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache HIT asid=%d vmid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
135
vm = vfp_advance_dreg(vm, delta_m);
200
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_cfgi_ste_range(int start, int end) "start=0x%x - end=0x%x"
136
- neon_load_reg64(f1, vm);
201
smmuv3_cmdq_cfgi_cd(uint32_t sid) "sid=0x%x"
137
+ vfp_load_reg64(f1, vm);
202
smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid=0x%x (hits=%d, misses=%d, hit rate=%d)"
138
}
203
smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid=0x%x (hits=%d, misses=%d, hit rate=%d)"
139
}
204
-smmuv3_s1_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t num_pages, uint8_t ttl, bool leaf) "vmid=%d asid=%d addr=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" ttl=%d leaf=%d"
140
205
+smmuv3_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t num_pages, uint8_t ttl, bool leaf) "vmid=%d asid=%d addr=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" ttl=%d leaf=%d"
141
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
206
smmuv3_cmdq_tlbi_nh(void) ""
142
f0 = tcg_temp_new_i64();
207
smmuv3_cmdq_tlbi_nh_asid(uint16_t asid) "asid=%d"
143
fd = tcg_temp_new_i64();
208
+smmuv3_cmdq_tlbi_s12_vmid(uint16_t vmid) "vmid=%d"
144
209
smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
145
- neon_load_reg64(f0, vm);
210
smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s"
146
+ vfp_load_reg64(f0, vm);
211
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
147
148
for (;;) {
149
fn(fd, f0);
150
- neon_store_reg64(fd, vd);
151
+ vfp_store_reg64(fd, vd);
152
153
if (veclen == 0) {
154
break;
155
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
156
/* single source one-many */
157
while (veclen--) {
158
vd = vfp_advance_dreg(vd, delta_d);
159
- neon_store_reg64(fd, vd);
160
+ vfp_store_reg64(fd, vd);
161
}
162
break;
163
}
164
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
165
veclen--;
166
vd = vfp_advance_dreg(vd, delta_d);
167
vd = vfp_advance_dreg(vm, delta_m);
168
- neon_load_reg64(f0, vm);
169
+ vfp_load_reg64(f0, vm);
170
}
171
172
tcg_temp_free_i64(f0);
173
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
174
vm = tcg_temp_new_i64();
175
vd = tcg_temp_new_i64();
176
177
- neon_load_reg64(vn, a->vn);
178
- neon_load_reg64(vm, a->vm);
179
+ vfp_load_reg64(vn, a->vn);
180
+ vfp_load_reg64(vm, a->vm);
181
if (neg_n) {
182
/* VFNMS, VFMS */
183
gen_helper_vfp_negd(vn, vn);
184
}
185
- neon_load_reg64(vd, a->vd);
186
+ vfp_load_reg64(vd, a->vd);
187
if (neg_d) {
188
/* VFNMA, VFNMS */
189
gen_helper_vfp_negd(vd, vd);
190
}
191
fpst = fpstatus_ptr(FPST_FPCR);
192
gen_helper_vfp_muladdd(vd, vn, vm, vd, fpst);
193
- neon_store_reg64(vd, a->vd);
194
+ vfp_store_reg64(vd, a->vd);
195
196
tcg_temp_free_ptr(fpst);
197
tcg_temp_free_i64(vn);
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
199
fd = tcg_const_i64(vfp_expand_imm(MO_64, a->imm));
200
201
for (;;) {
202
- neon_store_reg64(fd, vd);
203
+ vfp_store_reg64(fd, vd);
204
205
if (veclen == 0) {
206
break;
207
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
208
vd = tcg_temp_new_i64();
209
vm = tcg_temp_new_i64();
210
211
- neon_load_reg64(vd, a->vd);
212
+ vfp_load_reg64(vd, a->vd);
213
if (a->z) {
214
tcg_gen_movi_i64(vm, 0);
215
} else {
216
- neon_load_reg64(vm, a->vm);
217
+ vfp_load_reg64(vm, a->vm);
218
}
219
220
if (a->e) {
221
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
222
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
223
vd = tcg_temp_new_i64();
224
gen_helper_vfp_fcvt_f16_to_f64(vd, tmp, fpst, ahp_mode);
225
- neon_store_reg64(vd, a->vd);
226
+ vfp_store_reg64(vd, a->vd);
227
tcg_temp_free_i32(ahp_mode);
228
tcg_temp_free_ptr(fpst);
229
tcg_temp_free_i32(tmp);
230
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
231
tmp = tcg_temp_new_i32();
232
vm = tcg_temp_new_i64();
233
234
- neon_load_reg64(vm, a->vm);
235
+ vfp_load_reg64(vm, a->vm);
236
gen_helper_vfp_fcvt_f64_to_f16(tmp, vm, fpst, ahp_mode);
237
tcg_temp_free_i64(vm);
238
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
239
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
240
}
241
242
tmp = tcg_temp_new_i64();
243
- neon_load_reg64(tmp, a->vm);
244
+ vfp_load_reg64(tmp, a->vm);
245
fpst = fpstatus_ptr(FPST_FPCR);
246
gen_helper_rintd(tmp, tmp, fpst);
247
- neon_store_reg64(tmp, a->vd);
248
+ vfp_store_reg64(tmp, a->vd);
249
tcg_temp_free_ptr(fpst);
250
tcg_temp_free_i64(tmp);
251
return true;
252
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
253
}
254
255
tmp = tcg_temp_new_i64();
256
- neon_load_reg64(tmp, a->vm);
257
+ vfp_load_reg64(tmp, a->vm);
258
fpst = fpstatus_ptr(FPST_FPCR);
259
tcg_rmode = tcg_const_i32(float_round_to_zero);
260
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
261
gen_helper_rintd(tmp, tmp, fpst);
262
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
263
- neon_store_reg64(tmp, a->vd);
264
+ vfp_store_reg64(tmp, a->vd);
265
tcg_temp_free_ptr(fpst);
266
tcg_temp_free_i64(tmp);
267
tcg_temp_free_i32(tcg_rmode);
268
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
269
}
270
271
tmp = tcg_temp_new_i64();
272
- neon_load_reg64(tmp, a->vm);
273
+ vfp_load_reg64(tmp, a->vm);
274
fpst = fpstatus_ptr(FPST_FPCR);
275
gen_helper_rintd_exact(tmp, tmp, fpst);
276
- neon_store_reg64(tmp, a->vd);
277
+ vfp_store_reg64(tmp, a->vd);
278
tcg_temp_free_ptr(fpst);
279
tcg_temp_free_i64(tmp);
280
return true;
281
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
282
vd = tcg_temp_new_i64();
283
vfp_load_reg32(vm, a->vm);
284
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
285
- neon_store_reg64(vd, a->vd);
286
+ vfp_store_reg64(vd, a->vd);
287
tcg_temp_free_i32(vm);
288
tcg_temp_free_i64(vd);
289
return true;
290
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
291
292
vd = tcg_temp_new_i32();
293
vm = tcg_temp_new_i64();
294
- neon_load_reg64(vm, a->vm);
295
+ vfp_load_reg64(vm, a->vm);
296
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
297
vfp_store_reg32(vd, a->vd);
298
tcg_temp_free_i32(vd);
299
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
300
/* u32 -> f64 */
301
gen_helper_vfp_uitod(vd, vm, fpst);
302
}
303
- neon_store_reg64(vd, a->vd);
304
+ vfp_store_reg64(vd, a->vd);
305
tcg_temp_free_i32(vm);
306
tcg_temp_free_i64(vd);
307
tcg_temp_free_ptr(fpst);
308
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
309
310
vm = tcg_temp_new_i64();
311
vd = tcg_temp_new_i32();
312
- neon_load_reg64(vm, a->vm);
313
+ vfp_load_reg64(vm, a->vm);
314
gen_helper_vjcvt(vd, vm, cpu_env);
315
vfp_store_reg32(vd, a->vd);
316
tcg_temp_free_i64(vm);
317
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
318
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
319
320
vd = tcg_temp_new_i64();
321
- neon_load_reg64(vd, a->vd);
322
+ vfp_load_reg64(vd, a->vd);
323
324
fpst = fpstatus_ptr(FPST_FPCR);
325
shift = tcg_const_i32(frac_bits);
326
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
327
g_assert_not_reached();
328
}
329
330
- neon_store_reg64(vd, a->vd);
331
+ vfp_store_reg64(vd, a->vd);
332
tcg_temp_free_i64(vd);
333
tcg_temp_free_i32(shift);
334
tcg_temp_free_ptr(fpst);
335
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
336
fpst = fpstatus_ptr(FPST_FPCR);
337
vm = tcg_temp_new_i64();
338
vd = tcg_temp_new_i32();
339
- neon_load_reg64(vm, a->vm);
340
+ vfp_load_reg64(vm, a->vm);
341
342
if (a->s) {
343
if (a->rz) {
344
--
212
--
345
2.20.1
213
2.34.1
346
347
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Mostafa Saleh <smostafa@google.com>
2
2
3
This seems a bit more readable than using offsetof CPU_DoubleU.
3
In smmuv3_notify_iova, read the granule based on translation stage
4
and use VMID if valid value is sent.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Mostafa Saleh <smostafa@google.com>
6
Message-id: 20201030022618.785675-5-richard.henderson@linaro.org
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Eric Auger <eric.auger@redhat.com>
9
Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Message-id: 20230516203327.2051088-10-smostafa@google.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
12
---
10
target/arm/translate.c | 13 ++++---------
13
hw/arm/smmuv3.c | 39 ++++++++++++++++++++++++++-------------
11
1 file changed, 4 insertions(+), 9 deletions(-)
14
hw/arm/trace-events | 2 +-
15
2 files changed, 27 insertions(+), 14 deletions(-)
12
16
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
19
--- a/hw/arm/smmuv3.c
16
+++ b/target/arm/translate.c
20
+++ b/hw/arm/smmuv3.c
17
@@ -XXX,XX +XXX,XX @@ static long neon_element_offset(int reg, int element, MemOp size)
21
@@ -XXX,XX +XXX,XX @@ epilogue:
18
return neon_full_reg_offset(reg) + ofs;
22
* @mr: IOMMU mr region handle
23
* @n: notifier to be called
24
* @asid: address space ID or negative value if we don't care
25
+ * @vmid: virtual machine ID or negative value if we don't care
26
* @iova: iova
27
* @tg: translation granule (if communicated through range invalidation)
28
* @num_pages: number of @granule sized pages (if tg != 0), otherwise 1
29
*/
30
static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
31
IOMMUNotifier *n,
32
- int asid, dma_addr_t iova,
33
- uint8_t tg, uint64_t num_pages)
34
+ int asid, int vmid,
35
+ dma_addr_t iova, uint8_t tg,
36
+ uint64_t num_pages)
37
{
38
SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
39
IOMMUTLBEvent event;
40
uint8_t granule;
41
+ SMMUv3State *s = sdev->smmu;
42
43
if (!tg) {
44
SMMUEventInfo event = {.inval_ste_allowed = true};
45
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
46
return;
47
}
48
49
- tt = select_tt(cfg, iova);
50
- if (!tt) {
51
+ if (vmid >= 0 && cfg->s2cfg.vmid != vmid) {
52
return;
53
}
54
- granule = tt->granule_sz;
55
+
56
+ if (STAGE1_SUPPORTED(s)) {
57
+ tt = select_tt(cfg, iova);
58
+ if (!tt) {
59
+ return;
60
+ }
61
+ granule = tt->granule_sz;
62
+ } else {
63
+ granule = cfg->s2cfg.granule_sz;
64
+ }
65
+
66
} else {
67
granule = tg * 2 + 10;
68
}
69
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
70
memory_region_notify_iommu_one(n, &event);
19
}
71
}
20
72
21
-static inline long vfp_reg_offset(bool dp, unsigned reg)
73
-/* invalidate an asid/iova range tuple in all mr's */
22
+/* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
74
-static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova,
23
+static long vfp_reg_offset(bool dp, unsigned reg)
75
- uint8_t tg, uint64_t num_pages)
76
+/* invalidate an asid/vmid/iova range tuple in all mr's */
77
+static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, int vmid,
78
+ dma_addr_t iova, uint8_t tg,
79
+ uint64_t num_pages)
24
{
80
{
25
if (dp) {
81
SMMUDevice *sdev;
26
- return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
82
27
+ return neon_element_offset(reg, 0, MO_64);
83
@@ -XXX,XX +XXX,XX @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova,
28
} else {
84
IOMMUMemoryRegion *mr = &sdev->iommu;
29
- long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
85
IOMMUNotifier *n;
30
- if (reg & 1) {
86
31
- ofs += offsetof(CPU_DoubleU, l.upper);
87
- trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova,
32
- } else {
88
- tg, num_pages);
33
- ofs += offsetof(CPU_DoubleU, l.lower);
89
+ trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, vmid,
34
- }
90
+ iova, tg, num_pages);
35
- return ofs;
91
36
+ return neon_element_offset(reg >> 1, reg & 1, MO_32);
92
IOMMU_NOTIFIER_FOREACH(n, mr) {
93
- smmuv3_notify_iova(mr, n, asid, iova, tg, num_pages);
94
+ smmuv3_notify_iova(mr, n, asid, vmid, iova, tg, num_pages);
95
}
37
}
96
}
38
}
97
}
98
@@ -XXX,XX +XXX,XX @@ static void smmuv3_range_inval(SMMUState *s, Cmd *cmd)
99
100
if (!tg) {
101
trace_smmuv3_range_inval(vmid, asid, addr, tg, 1, ttl, leaf);
102
- smmuv3_inv_notifiers_iova(s, asid, addr, tg, 1);
103
+ smmuv3_inv_notifiers_iova(s, asid, vmid, addr, tg, 1);
104
smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, 1, ttl);
105
return;
106
}
107
@@ -XXX,XX +XXX,XX @@ static void smmuv3_range_inval(SMMUState *s, Cmd *cmd)
108
109
num_pages = (mask + 1) >> granule;
110
trace_smmuv3_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf);
111
- smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages);
112
+ smmuv3_inv_notifiers_iova(s, asid, vmid, addr, tg, num_pages);
113
smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, num_pages, ttl);
114
addr += mask + 1;
115
}
116
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/arm/trace-events
119
+++ b/hw/arm/trace-events
120
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_tlbi_s12_vmid(uint16_t vmid) "vmid=%d"
121
smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
122
smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s"
123
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
124
-smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint64_t iova, uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64
125
+smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint16_t vmid, uint64_t iova, uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d vmid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64
39
126
40
--
127
--
41
2.20.1
128
2.34.1
42
43
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Mostafa Saleh <smostafa@google.com>
2
2
3
We can use proper widening loads to extend 32-bit inputs,
3
As everything is in place, we can use a new system property to
4
and skip the "widenfn" step.
4
advertise which stage is supported and remove bad_ste from STE
5
stage2 config.
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
The property added arm-smmuv3.stage can have 3 values:
7
Message-id: 20201030022618.785675-12-richard.henderson@linaro.org
8
- "1": Stage-1 only is advertised.
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
- "2": Stage-2 only is advertised.
10
11
If not passed or an unsupported value is passed, it will default to
12
stage-1.
13
14
Advertise VMID16.
15
16
Don't try to decode CD, if stage-2 is configured.
17
18
Reviewed-by: Eric Auger <eric.auger@redhat.com>
19
Signed-off-by: Mostafa Saleh <smostafa@google.com>
20
Tested-by: Eric Auger <eric.auger@redhat.com>
21
Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
22
Message-id: 20230516203327.2051088-11-smostafa@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
24
---
11
target/arm/translate.c | 6 +++
25
include/hw/arm/smmuv3.h | 1 +
12
target/arm/translate-neon.c.inc | 66 ++++++++++++++++++---------------
26
hw/arm/smmuv3.c | 32 ++++++++++++++++++++++----------
13
2 files changed, 43 insertions(+), 29 deletions(-)
27
2 files changed, 23 insertions(+), 10 deletions(-)
14
28
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
29
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
16
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
31
--- a/include/hw/arm/smmuv3.h
18
+++ b/target/arm/translate.c
32
+++ b/include/hw/arm/smmuv3.h
19
@@ -XXX,XX +XXX,XX @@ static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
33
@@ -XXX,XX +XXX,XX @@ struct SMMUv3State {
20
long off = neon_element_offset(reg, ele, memop);
34
21
35
qemu_irq irq[4];
22
switch (memop) {
36
QemuMutex mutex;
23
+ case MO_SL:
37
+ char *stage;
24
+ tcg_gen_ld32s_i64(dest, cpu_env, off);
38
};
25
+ break;
39
26
+ case MO_UL:
40
typedef enum {
27
+ tcg_gen_ld32u_i64(dest, cpu_env, off);
41
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
28
+ break;
29
case MO_Q:
30
tcg_gen_ld_i64(dest, cpu_env, off);
31
break;
32
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
33
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.c.inc
43
--- a/hw/arm/smmuv3.c
35
+++ b/target/arm/translate-neon.c.inc
44
+++ b/hw/arm/smmuv3.c
36
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1reg_imm *a)
45
@@ -XXX,XX +XXX,XX @@
37
static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
46
#include "hw/irq.h"
38
NeonGenWidenFn *widenfn,
47
#include "hw/sysbus.h"
39
NeonGenTwo64OpFn *opfn,
48
#include "migration/vmstate.h"
40
- bool src1_wide)
49
+#include "hw/qdev-properties.h"
41
+ int src1_mop, int src2_mop)
50
#include "hw/qdev-core.h"
51
#include "hw/pci/pci.h"
52
#include "cpu.h"
53
@@ -XXX,XX +XXX,XX @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
54
55
static void smmuv3_init_regs(SMMUv3State *s)
42
{
56
{
43
/* 3-regs different lengths, prewidening case (VADDL/VSUBL/VAADW/VSUBW) */
57
- /**
44
TCGv_i64 rn0_64, rn1_64, rm_64;
58
- * IDR0: stage1 only, AArch64 only, coherent access, 16b ASID,
45
- TCGv_i32 rm;
59
- * multi-level stream table
46
60
- */
47
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
61
- s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1); /* stage 1 supported */
48
return false;
62
+ /* Based on sys property, the stages supported in smmu will be advertised.*/
49
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
63
+ if (s->stage && !strcmp("2", s->stage)) {
50
return false;
64
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S2P, 1);
65
+ } else {
66
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1);
67
+ }
68
+
69
s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTF, 2); /* AArch64 PTW only */
70
s->idr[0] = FIELD_DP32(s->idr[0], IDR0, COHACC, 1); /* IO coherent */
71
s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ASID16, 1); /* 16-bit ASID */
72
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, VMID16, 1); /* 16-bit VMID */
73
s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTENDIAN, 2); /* little endian */
74
s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STALL_MODEL, 1); /* No stall */
75
/* terminated transaction will always be aborted/error returned */
76
@@ -XXX,XX +XXX,XX @@ static int decode_ste_s2_cfg(SMMUTransCfg *cfg, STE *ste)
77
goto bad_ste;
51
}
78
}
52
79
53
- if (!widenfn || !opfn) {
80
- /* This is still here as stage 2 has not been fully enabled yet. */
54
+ if (!opfn) {
81
- qemu_log_mask(LOG_UNIMP, "SMMUv3 does not support stage 2 yet\n");
55
/* size == 3 case, which is an entirely different insn group */
82
- goto bad_ste;
56
return false;
83
-
84
return 0;
85
86
bad_ste:
87
@@ -XXX,XX +XXX,XX @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
88
return ret;
57
}
89
}
58
90
59
- if ((a->vd & 1) || (src1_wide && (a->vn & 1))) {
91
- if (cfg->aborted || cfg->bypassed) {
60
+ if ((a->vd & 1) || (src1_mop == MO_Q && (a->vn & 1))) {
92
+ if (cfg->aborted || cfg->bypassed || (cfg->stage == 2)) {
61
return false;
93
return 0;
62
}
94
}
63
95
64
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
96
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_smmuv3 = {
65
rn1_64 = tcg_temp_new_i64();
66
rm_64 = tcg_temp_new_i64();
67
68
- if (src1_wide) {
69
- read_neon_element64(rn0_64, a->vn, 0, MO_64);
70
+ if (src1_mop >= 0) {
71
+ read_neon_element64(rn0_64, a->vn, 0, src1_mop);
72
} else {
73
TCGv_i32 tmp = tcg_temp_new_i32();
74
read_neon_element32(tmp, a->vn, 0, MO_32);
75
widenfn(rn0_64, tmp);
76
tcg_temp_free_i32(tmp);
77
}
97
}
78
- rm = tcg_temp_new_i32();
98
};
79
- read_neon_element32(rm, a->vm, 0, MO_32);
99
80
+ if (src2_mop >= 0) {
100
+static Property smmuv3_properties[] = {
81
+ read_neon_element64(rm_64, a->vm, 0, src2_mop);
101
+ /*
82
+ } else {
102
+ * Stages of translation advertised.
83
+ TCGv_i32 tmp = tcg_temp_new_i32();
103
+ * "1": Stage 1
84
+ read_neon_element32(tmp, a->vm, 0, MO_32);
104
+ * "2": Stage 2
85
+ widenfn(rm_64, tmp);
105
+ * Defaults to stage 1
86
+ tcg_temp_free_i32(tmp);
106
+ */
87
+ }
107
+ DEFINE_PROP_STRING("stage", SMMUv3State, stage),
88
108
+ DEFINE_PROP_END_OF_LIST()
89
- widenfn(rm_64, rm);
109
+};
90
- tcg_temp_free_i32(rm);
110
+
91
opfn(rn0_64, rn0_64, rm_64);
111
static void smmuv3_instance_init(Object *obj)
92
112
{
93
/*
113
/* Nothing much to do here as of now */
94
* Load second pass inputs before storing the first pass result, to
114
@@ -XXX,XX +XXX,XX @@ static void smmuv3_class_init(ObjectClass *klass, void *data)
95
* avoid incorrect results if a narrow input overlaps with the result.
115
&c->parent_phases);
96
*/
116
c->parent_realize = dc->realize;
97
- if (src1_wide) {
117
dc->realize = smmu_realize;
98
- read_neon_element64(rn1_64, a->vn, 1, MO_64);
118
+ device_class_set_props(dc, smmuv3_properties);
99
+ if (src1_mop >= 0) {
100
+ read_neon_element64(rn1_64, a->vn, 1, src1_mop);
101
} else {
102
TCGv_i32 tmp = tcg_temp_new_i32();
103
read_neon_element32(tmp, a->vn, 1, MO_32);
104
widenfn(rn1_64, tmp);
105
tcg_temp_free_i32(tmp);
106
}
107
- rm = tcg_temp_new_i32();
108
- read_neon_element32(rm, a->vm, 1, MO_32);
109
+ if (src2_mop >= 0) {
110
+ read_neon_element64(rm_64, a->vm, 1, src2_mop);
111
+ } else {
112
+ TCGv_i32 tmp = tcg_temp_new_i32();
113
+ read_neon_element32(tmp, a->vm, 1, MO_32);
114
+ widenfn(rm_64, tmp);
115
+ tcg_temp_free_i32(tmp);
116
+ }
117
118
write_neon_element64(rn0_64, a->vd, 0, MO_64);
119
120
- widenfn(rm_64, rm);
121
- tcg_temp_free_i32(rm);
122
opfn(rn1_64, rn1_64, rm_64);
123
write_neon_element64(rn1_64, a->vd, 1, MO_64);
124
125
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
126
return true;
127
}
119
}
128
120
129
-#define DO_PREWIDEN(INSN, S, EXT, OP, SRC1WIDE) \
121
static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
130
+#define DO_PREWIDEN(INSN, S, OP, SRC1WIDE, SIGN) \
131
static bool trans_##INSN##_3d(DisasContext *s, arg_3diff *a) \
132
{ \
133
static NeonGenWidenFn * const widenfn[] = { \
134
gen_helper_neon_widen_##S##8, \
135
gen_helper_neon_widen_##S##16, \
136
- tcg_gen_##EXT##_i32_i64, \
137
- NULL, \
138
+ NULL, NULL, \
139
}; \
140
static NeonGenTwo64OpFn * const addfn[] = { \
141
gen_helper_neon_##OP##l_u16, \
142
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
143
tcg_gen_##OP##_i64, \
144
NULL, \
145
}; \
146
- return do_prewiden_3d(s, a, widenfn[a->size], \
147
- addfn[a->size], SRC1WIDE); \
148
+ int narrow_mop = a->size == MO_32 ? MO_32 | SIGN : -1; \
149
+ return do_prewiden_3d(s, a, widenfn[a->size], addfn[a->size], \
150
+ SRC1WIDE ? MO_Q : narrow_mop, \
151
+ narrow_mop); \
152
}
153
154
-DO_PREWIDEN(VADDL_S, s, ext, add, false)
155
-DO_PREWIDEN(VADDL_U, u, extu, add, false)
156
-DO_PREWIDEN(VSUBL_S, s, ext, sub, false)
157
-DO_PREWIDEN(VSUBL_U, u, extu, sub, false)
158
-DO_PREWIDEN(VADDW_S, s, ext, add, true)
159
-DO_PREWIDEN(VADDW_U, u, extu, add, true)
160
-DO_PREWIDEN(VSUBW_S, s, ext, sub, true)
161
-DO_PREWIDEN(VSUBW_U, u, extu, sub, true)
162
+DO_PREWIDEN(VADDL_S, s, add, false, MO_SIGN)
163
+DO_PREWIDEN(VADDL_U, u, add, false, 0)
164
+DO_PREWIDEN(VSUBL_S, s, sub, false, MO_SIGN)
165
+DO_PREWIDEN(VSUBL_U, u, sub, false, 0)
166
+DO_PREWIDEN(VADDW_S, s, add, true, MO_SIGN)
167
+DO_PREWIDEN(VADDW_U, u, add, true, 0)
168
+DO_PREWIDEN(VSUBW_S, s, sub, true, MO_SIGN)
169
+DO_PREWIDEN(VSUBW_U, u, sub, true, 0)
170
171
static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
172
NeonGenTwo64OpFn *opfn, NeonGenNarrowFn *narrowfn)
173
--
122
--
174
2.20.1
123
2.34.1
175
176
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Tommy Wu <tommy.wu@sifive.com>
2
2
3
Replace all uses of neon_load/store_reg64 within translate-neon.c.inc.
3
When we receive a packet from the xilinx_axienet and then try to s2mem
4
through the xilinx_axidma, if the descriptor ring buffer is full in the
5
xilinx axidma driver, we’ll assert the DMASR.HALTED in the
6
function : stream_process_s2mem and return 0. In the end, we’ll be stuck in
7
an infinite loop in axienet_eth_rx_notify.
4
8
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
This patch checks the DMASR.HALTED state when we try to push data
6
Message-id: 20201030022618.785675-9-richard.henderson@linaro.org
10
from xilinx axi-enet to xilinx axi-dma. When the DMASR.HALTED is asserted,
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
we will not keep pushing the data and then prevent the infinte loop.
12
13
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
14
Reviewed-by: Edgar E. Iglesias <edgar@zeroasic.com>
15
Reviewed-by: Frank Chang <frank.chang@sifive.com>
16
Message-id: 20230519062137.1251741-1-tommy.wu@sifive.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
18
---
10
target/arm/translate.c | 26 +++++++++
19
hw/dma/xilinx_axidma.c | 11 ++++++++---
11
target/arm/translate-neon.c.inc | 94 ++++++++++++++++-----------------
20
1 file changed, 8 insertions(+), 3 deletions(-)
12
2 files changed, 73 insertions(+), 47 deletions(-)
13
21
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
22
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
24
--- a/hw/dma/xilinx_axidma.c
17
+++ b/target/arm/translate.c
25
+++ b/hw/dma/xilinx_axidma.c
18
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
26
@@ -XXX,XX +XXX,XX @@ static inline int stream_idle(struct Stream *s)
19
}
27
return !!(s->regs[R_DMASR] & DMASR_IDLE);
20
}
28
}
21
29
22
+static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
30
+static inline int stream_halted(struct Stream *s)
23
+{
31
+{
24
+ long off = neon_element_offset(reg, ele, memop);
32
+ return !!(s->regs[R_DMASR] & DMASR_HALTED);
25
+
26
+ switch (memop) {
27
+ case MO_Q:
28
+ tcg_gen_ld_i64(dest, cpu_env, off);
29
+ break;
30
+ default:
31
+ g_assert_not_reached();
32
+ }
33
+}
33
+}
34
+
34
+
35
static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
35
static void stream_reset(struct Stream *s)
36
{
36
{
37
long off = neon_element_offset(reg, ele, memop);
37
s->regs[R_DMASR] = DMASR_HALTED; /* starts up halted. */
38
@@ -XXX,XX +XXX,XX @@ static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
38
@@ -XXX,XX +XXX,XX @@ static void stream_process_mem2s(struct Stream *s, StreamSink *tx_data_dev,
39
uint64_t addr;
40
bool eop;
41
42
- if (!stream_running(s) || stream_idle(s)) {
43
+ if (!stream_running(s) || stream_idle(s) || stream_halted(s)) {
44
return;
39
}
45
}
40
}
46
41
47
@@ -XXX,XX +XXX,XX @@ static size_t stream_process_s2mem(struct Stream *s, unsigned char *buf,
42
+static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
48
unsigned int rxlen;
43
+{
49
size_t pos = 0;
44
+ long off = neon_element_offset(reg, ele, memop);
50
45
+
51
- if (!stream_running(s) || stream_idle(s)) {
46
+ switch (memop) {
52
+ if (!stream_running(s) || stream_idle(s) || stream_halted(s)) {
47
+ case MO_64:
53
return 0;
48
+ tcg_gen_st_i64(src, cpu_env, off);
49
+ break;
50
+ default:
51
+ g_assert_not_reached();
52
+ }
53
+}
54
+
55
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
56
{
57
TCGv_ptr ret = tcg_temp_new_ptr();
58
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-neon.c.inc
61
+++ b/target/arm/translate-neon.c.inc
62
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_64(DisasContext *s, arg_2reg_shift *a,
63
for (pass = 0; pass < a->q + 1; pass++) {
64
TCGv_i64 tmp = tcg_temp_new_i64();
65
66
- neon_load_reg64(tmp, a->vm + pass);
67
+ read_neon_element64(tmp, a->vm, pass, MO_64);
68
fn(tmp, cpu_env, tmp, constimm);
69
- neon_store_reg64(tmp, a->vd + pass);
70
+ write_neon_element64(tmp, a->vd, pass, MO_64);
71
tcg_temp_free_i64(tmp);
72
}
54
}
73
tcg_temp_free_i64(constimm);
55
74
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
56
@@ -XXX,XX +XXX,XX @@ xilinx_axidma_data_stream_can_push(StreamSink *obj,
75
rd = tcg_temp_new_i32();
57
XilinxAXIDMAStreamSink *ds = XILINX_AXI_DMA_DATA_STREAM(obj);
76
58
struct Stream *s = &ds->dma->streams[1];
77
/* Load both inputs first to avoid potential overwrite if rm == rd */
59
78
- neon_load_reg64(rm1, a->vm);
60
- if (!stream_running(s) || stream_idle(s)) {
79
- neon_load_reg64(rm2, a->vm + 1);
61
+ if (!stream_running(s) || stream_idle(s) || stream_halted(s)) {
80
+ read_neon_element64(rm1, a->vm, 0, MO_64);
62
ds->dma->notify = notify;
81
+ read_neon_element64(rm2, a->vm, 1, MO_64);
63
ds->dma->notify_opaque = notify_opaque;
82
64
return false;
83
shiftfn(rm1, rm1, constimm);
84
narrowfn(rd, cpu_env, rm1);
85
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
86
tcg_gen_shli_i64(tmp, tmp, a->shift);
87
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
88
}
89
- neon_store_reg64(tmp, a->vd);
90
+ write_neon_element64(tmp, a->vd, 0, MO_64);
91
92
widenfn(tmp, rm1);
93
tcg_temp_free_i32(rm1);
94
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
95
tcg_gen_shli_i64(tmp, tmp, a->shift);
96
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
97
}
98
- neon_store_reg64(tmp, a->vd + 1);
99
+ write_neon_element64(tmp, a->vd, 1, MO_64);
100
tcg_temp_free_i64(tmp);
101
return true;
102
}
103
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
104
rm_64 = tcg_temp_new_i64();
105
106
if (src1_wide) {
107
- neon_load_reg64(rn0_64, a->vn);
108
+ read_neon_element64(rn0_64, a->vn, 0, MO_64);
109
} else {
110
TCGv_i32 tmp = tcg_temp_new_i32();
111
read_neon_element32(tmp, a->vn, 0, MO_32);
112
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
113
* avoid incorrect results if a narrow input overlaps with the result.
114
*/
115
if (src1_wide) {
116
- neon_load_reg64(rn1_64, a->vn + 1);
117
+ read_neon_element64(rn1_64, a->vn, 1, MO_64);
118
} else {
119
TCGv_i32 tmp = tcg_temp_new_i32();
120
read_neon_element32(tmp, a->vn, 1, MO_32);
121
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
122
rm = tcg_temp_new_i32();
123
read_neon_element32(rm, a->vm, 1, MO_32);
124
125
- neon_store_reg64(rn0_64, a->vd);
126
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
127
128
widenfn(rm_64, rm);
129
tcg_temp_free_i32(rm);
130
opfn(rn1_64, rn1_64, rm_64);
131
- neon_store_reg64(rn1_64, a->vd + 1);
132
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
133
134
tcg_temp_free_i64(rn0_64);
135
tcg_temp_free_i64(rn1_64);
136
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
137
rd0 = tcg_temp_new_i32();
138
rd1 = tcg_temp_new_i32();
139
140
- neon_load_reg64(rn_64, a->vn);
141
- neon_load_reg64(rm_64, a->vm);
142
+ read_neon_element64(rn_64, a->vn, 0, MO_64);
143
+ read_neon_element64(rm_64, a->vm, 0, MO_64);
144
145
opfn(rn_64, rn_64, rm_64);
146
147
narrowfn(rd0, rn_64);
148
149
- neon_load_reg64(rn_64, a->vn + 1);
150
- neon_load_reg64(rm_64, a->vm + 1);
151
+ read_neon_element64(rn_64, a->vn, 1, MO_64);
152
+ read_neon_element64(rm_64, a->vm, 1, MO_64);
153
154
opfn(rn_64, rn_64, rm_64);
155
156
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
157
/* Don't store results until after all loads: they might overlap */
158
if (accfn) {
159
tmp = tcg_temp_new_i64();
160
- neon_load_reg64(tmp, a->vd);
161
+ read_neon_element64(tmp, a->vd, 0, MO_64);
162
accfn(tmp, tmp, rd0);
163
- neon_store_reg64(tmp, a->vd);
164
- neon_load_reg64(tmp, a->vd + 1);
165
+ write_neon_element64(tmp, a->vd, 0, MO_64);
166
+ read_neon_element64(tmp, a->vd, 1, MO_64);
167
accfn(tmp, tmp, rd1);
168
- neon_store_reg64(tmp, a->vd + 1);
169
+ write_neon_element64(tmp, a->vd, 1, MO_64);
170
tcg_temp_free_i64(tmp);
171
} else {
172
- neon_store_reg64(rd0, a->vd);
173
- neon_store_reg64(rd1, a->vd + 1);
174
+ write_neon_element64(rd0, a->vd, 0, MO_64);
175
+ write_neon_element64(rd1, a->vd, 1, MO_64);
176
}
177
178
tcg_temp_free_i64(rd0);
179
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
180
181
if (accfn) {
182
TCGv_i64 t64 = tcg_temp_new_i64();
183
- neon_load_reg64(t64, a->vd);
184
+ read_neon_element64(t64, a->vd, 0, MO_64);
185
accfn(t64, t64, rn0_64);
186
- neon_store_reg64(t64, a->vd);
187
- neon_load_reg64(t64, a->vd + 1);
188
+ write_neon_element64(t64, a->vd, 0, MO_64);
189
+ read_neon_element64(t64, a->vd, 1, MO_64);
190
accfn(t64, t64, rn1_64);
191
- neon_store_reg64(t64, a->vd + 1);
192
+ write_neon_element64(t64, a->vd, 1, MO_64);
193
tcg_temp_free_i64(t64);
194
} else {
195
- neon_store_reg64(rn0_64, a->vd);
196
- neon_store_reg64(rn1_64, a->vd + 1);
197
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
198
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
199
}
200
tcg_temp_free_i64(rn0_64);
201
tcg_temp_free_i64(rn1_64);
202
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
203
right = tcg_temp_new_i64();
204
dest = tcg_temp_new_i64();
205
206
- neon_load_reg64(right, a->vn);
207
- neon_load_reg64(left, a->vm);
208
+ read_neon_element64(right, a->vn, 0, MO_64);
209
+ read_neon_element64(left, a->vm, 0, MO_64);
210
tcg_gen_extract2_i64(dest, right, left, a->imm * 8);
211
- neon_store_reg64(dest, a->vd);
212
+ write_neon_element64(dest, a->vd, 0, MO_64);
213
214
tcg_temp_free_i64(left);
215
tcg_temp_free_i64(right);
216
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
217
destright = tcg_temp_new_i64();
218
219
if (a->imm < 8) {
220
- neon_load_reg64(right, a->vn);
221
- neon_load_reg64(middle, a->vn + 1);
222
+ read_neon_element64(right, a->vn, 0, MO_64);
223
+ read_neon_element64(middle, a->vn, 1, MO_64);
224
tcg_gen_extract2_i64(destright, right, middle, a->imm * 8);
225
- neon_load_reg64(left, a->vm);
226
+ read_neon_element64(left, a->vm, 0, MO_64);
227
tcg_gen_extract2_i64(destleft, middle, left, a->imm * 8);
228
} else {
229
- neon_load_reg64(right, a->vn + 1);
230
- neon_load_reg64(middle, a->vm);
231
+ read_neon_element64(right, a->vn, 1, MO_64);
232
+ read_neon_element64(middle, a->vm, 0, MO_64);
233
tcg_gen_extract2_i64(destright, right, middle, (a->imm - 8) * 8);
234
- neon_load_reg64(left, a->vm + 1);
235
+ read_neon_element64(left, a->vm, 1, MO_64);
236
tcg_gen_extract2_i64(destleft, middle, left, (a->imm - 8) * 8);
237
}
238
239
- neon_store_reg64(destright, a->vd);
240
- neon_store_reg64(destleft, a->vd + 1);
241
+ write_neon_element64(destright, a->vd, 0, MO_64);
242
+ write_neon_element64(destleft, a->vd, 1, MO_64);
243
244
tcg_temp_free_i64(destright);
245
tcg_temp_free_i64(destleft);
246
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
247
248
if (accfn) {
249
TCGv_i64 tmp64 = tcg_temp_new_i64();
250
- neon_load_reg64(tmp64, a->vd + pass);
251
+ read_neon_element64(tmp64, a->vd, pass, MO_64);
252
accfn(rd_64, tmp64, rd_64);
253
tcg_temp_free_i64(tmp64);
254
}
255
- neon_store_reg64(rd_64, a->vd + pass);
256
+ write_neon_element64(rd_64, a->vd, pass, MO_64);
257
tcg_temp_free_i64(rd_64);
258
}
259
return true;
260
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
261
rd0 = tcg_temp_new_i32();
262
rd1 = tcg_temp_new_i32();
263
264
- neon_load_reg64(rm, a->vm);
265
+ read_neon_element64(rm, a->vm, 0, MO_64);
266
narrowfn(rd0, cpu_env, rm);
267
- neon_load_reg64(rm, a->vm + 1);
268
+ read_neon_element64(rm, a->vm, 1, MO_64);
269
narrowfn(rd1, cpu_env, rm);
270
write_neon_element32(rd0, a->vd, 0, MO_32);
271
write_neon_element32(rd1, a->vd, 1, MO_32);
272
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
273
274
widenfn(rd, rm0);
275
tcg_gen_shli_i64(rd, rd, 8 << a->size);
276
- neon_store_reg64(rd, a->vd);
277
+ write_neon_element64(rd, a->vd, 0, MO_64);
278
widenfn(rd, rm1);
279
tcg_gen_shli_i64(rd, rd, 8 << a->size);
280
- neon_store_reg64(rd, a->vd + 1);
281
+ write_neon_element64(rd, a->vd, 1, MO_64);
282
283
tcg_temp_free_i64(rd);
284
tcg_temp_free_i32(rm0);
285
@@ -XXX,XX +XXX,XX @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a)
286
rm = tcg_temp_new_i64();
287
rd = tcg_temp_new_i64();
288
for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
289
- neon_load_reg64(rm, a->vm + pass);
290
- neon_load_reg64(rd, a->vd + pass);
291
- neon_store_reg64(rm, a->vd + pass);
292
- neon_store_reg64(rd, a->vm + pass);
293
+ read_neon_element64(rm, a->vm, pass, MO_64);
294
+ read_neon_element64(rd, a->vd, pass, MO_64);
295
+ write_neon_element64(rm, a->vd, pass, MO_64);
296
+ write_neon_element64(rd, a->vm, pass, MO_64);
297
}
298
tcg_temp_free_i64(rm);
299
tcg_temp_free_i64(rd);
300
--
65
--
301
2.20.1
66
2.34.1
302
67
303
68
diff view generated by jsdifflib
1
If we're using the capstone disassembler, disassembly of a run of
1
From: Clément Chigot <chigot@adacore.com>
2
instructions more than 32 bytes long disassembles the wrong data for
3
instructions beyond the 32 byte mark:
4
2
5
(qemu) xp /16x 0x100
3
When passing --smp with a number lower than XLNX_ZYNQMP_NUM_APU_CPUS,
6
0000000000000100: 0x00000005 0x54410001 0x00000001 0x00001000
4
the expression (ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS) will result
7
0000000000000110: 0x00000000 0x00000004 0x54410002 0x3c000000
5
in a positive number as ms->smp.cpus is a unsigned int.
8
0000000000000120: 0x00000000 0x00000004 0x54410009 0x74736574
6
This will raise the following error afterwards, as Qemu will try to
9
0000000000000130: 0x00000000 0x00000000 0x00000000 0x00000000
7
instantiate some additional RPUs.
10
(qemu) xp /16i 0x100
8
| $ qemu-system-aarch64 --smp 1 -M xlnx-zcu102
11
0x00000100: 00000005 andeq r0, r0, r5
9
| **
12
0x00000104: 54410001 strbpl r0, [r1], #-1
10
| ERROR:../src/tcg/tcg.c:777:tcg_register_thread:
13
0x00000108: 00000001 andeq r0, r0, r1
11
| assertion failed: (n < tcg_max_ctxs)
14
0x0000010c: 00001000 andeq r1, r0, r0
15
0x00000110: 00000000 andeq r0, r0, r0
16
0x00000114: 00000004 andeq r0, r0, r4
17
0x00000118: 54410002 strbpl r0, [r1], #-2
18
0x0000011c: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
19
0x00000120: 54410001 strbpl r0, [r1], #-1
20
0x00000124: 00000001 andeq r0, r0, r1
21
0x00000128: 00001000 andeq r1, r0, r0
22
0x0000012c: 00000000 andeq r0, r0, r0
23
0x00000130: 00000004 andeq r0, r0, r4
24
0x00000134: 54410002 strbpl r0, [r1], #-2
25
0x00000138: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
26
0x0000013c: 00000000 andeq r0, r0, r0
27
12
28
Here the disassembly of 0x120..0x13f is using the data that is in
13
Signed-off-by: Clément Chigot <chigot@adacore.com>
29
0x104..0x123.
14
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
30
15
Tested-by: Francisco Iglesias <frasse.iglesias@gmail.com>
31
This is caused by passing the wrong value to the read_memory_func().
16
Message-id: 20230524143714.565792-1-chigot@adacore.com
32
The intention is that at this point in the loop the 'cap_buf' buffer
33
already contains 'csize' bytes of data for the instruction at guest
34
addr 'pc', and we want to read in an extra 'tsize' bytes. Those
35
extra bytes are therefore at 'pc + csize', not 'pc'. On the first
36
time through the loop 'csize' happens to be zero, so the initial read
37
of 32 bytes into cap_buf is correct and as long as the disassembly
38
never needs to read more data we return the correct information.
39
40
Use the correct guest address in the call to read_memory_func().
41
42
Cc: qemu-stable@nongnu.org
43
Fixes: https://bugs.launchpad.net/qemu/+bug/1900779
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
45
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
46
Message-id: 20201022132445.25039-1-peter.maydell@linaro.org
47
---
18
---
48
disas/capstone.c | 2 +-
19
hw/arm/xlnx-zynqmp.c | 2 +-
49
1 file changed, 1 insertion(+), 1 deletion(-)
20
1 file changed, 1 insertion(+), 1 deletion(-)
50
21
51
diff --git a/disas/capstone.c b/disas/capstone.c
22
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
52
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
53
--- a/disas/capstone.c
24
--- a/hw/arm/xlnx-zynqmp.c
54
+++ b/disas/capstone.c
25
+++ b/hw/arm/xlnx-zynqmp.c
55
@@ -XXX,XX +XXX,XX @@ bool cap_disas_monitor(disassemble_info *info, uint64_t pc, int count)
26
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s,
56
27
const char *boot_cpu, Error **errp)
57
/* Make certain that we can make progress. */
28
{
58
assert(tsize != 0);
29
int i;
59
- info->read_memory_func(pc, cap_buf + csize, tsize, info);
30
- int num_rpus = MIN(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS,
60
+ info->read_memory_func(pc + csize, cap_buf + csize, tsize, info);
31
+ int num_rpus = MIN((int)(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS),
61
csize += tsize;
32
XLNX_ZYNQMP_NUM_RPU_CPUS);
62
33
63
if (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) {
34
if (num_rpus <= 0) {
64
--
35
--
65
2.20.1
36
2.34.1
66
37
67
38
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
HCR should be applied when NS is set, not when it is cleared.
3
pflash-cfi02-test.c always uses the "musicpal" machine for testing,
4
test-arm-mptimer.c always uses the "vexpress-a9" machine, and
5
microbit-test.c requires the "microbit" machine, so we should only
6
run these tests if the machines have been enabled in the configuration.
4
7
5
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Fabiano Rosas <farosas@suse.de>
10
Message-id: 20230524080600.1618137-1-thuth@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
12
---
9
target/arm/helper.c | 5 ++---
13
tests/qtest/meson.build | 7 ++++---
10
1 file changed, 2 insertions(+), 3 deletions(-)
14
1 file changed, 4 insertions(+), 3 deletions(-)
11
15
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
18
--- a/tests/qtest/meson.build
15
+++ b/target/arm/helper.c
19
+++ b/tests/qtest/meson.build
16
@@ -XXX,XX +XXX,XX @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
20
@@ -XXX,XX +XXX,XX @@ qtests_arm = \
17
21
(config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
18
/*
22
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
19
* Non-IS variants of TLB operations are upgraded to
23
(config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
20
- * IS versions if we are at NS EL1 and HCR_EL2.FB is set to
24
- (config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) + \
21
+ * IS versions if we are at EL1 and HCR_EL2.FB is effectively set to
25
+ (config_all_devices.has_key('CONFIG_PFLASH_CFI02') and
22
* force broadcast of these operations.
26
+ config_all_devices.has_key('CONFIG_MUSICPAL') ? ['pflash-cfi02-test'] : []) + \
23
*/
27
(config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : []) + \
24
static bool tlb_force_broadcast(CPUARMState *env)
28
(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
25
{
29
(config_all_devices.has_key('CONFIG_GENERIC_LOADER') ? ['hexloader-test'] : []) + \
26
- return (env->cp15.hcr_el2 & HCR_FB) &&
30
(config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
27
- arm_current_el(env) == 1 && arm_is_secure_below_el3(env);
31
+ (config_all_devices.has_key('CONFIG_VEXPRESS') ? ['test-arm-mptimer'] : []) + \
28
+ return arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_FB);
32
+ (config_all_devices.has_key('CONFIG_MICROBIT') ? ['microbit-test'] : []) + \
29
}
33
['arm-cpu-features',
30
34
- 'microbit-test',
31
static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
35
- 'test-arm-mptimer',
36
'boot-serial-test']
37
38
# TODO: once aarch64 TCG is fixed on ARM 32 bit host, make bios-tables-test unconditional
32
--
39
--
33
2.20.1
40
2.34.1
34
35
diff view generated by jsdifflib
1
In arm_v7m_mmu_idx_for_secstate() we get the 'priv' level to pass to
1
For M-profile, there is no guest-facing A-profile format FSR, but we
2
armv7m_mmu_idx_for_secstate_and_priv() by calling arm_current_el().
2
still use the env->exception.fsr field to pass fault information from
3
This is incorrect when the security state being queried is not the
3
the point where a fault is raised to the code in
4
current one, because arm_current_el() uses the current security state
4
arm_v7m_cpu_do_interrupt() which interprets it and sets the M-profile
5
to determine which of the banked CONTROL.nPRIV bits to look at.
5
specific fault status registers. So it doesn't matter whether we
6
The effect was that if (for instance) Secure state was in privileged
6
fill in env->exception.fsr in the short format or the LPAE format, as
7
mode but Non-Secure was not then we would return the wrong MMU index.
7
long as both sides agree. As it happens arm_v7m_cpu_do_interrupt()
8
assumes short-form.
8
9
9
The only places where we are using this function in a way that could
10
In compute_fsr_fsc() we weren't explicitly choosing short-form for
10
trigger this bug are for the stack loads during a v8M function-return
11
M-profile, but instead relied on it falling out in the wash because
11
and for the instruction fetch of a v8M SG insn.
12
arm_s1_regime_using_lpae_format() would be false. This was broken in
13
commit 452c67a4 when we added v8R support, because we said "PMSAv8 is
14
always LPAE format" (as it is for v8R), forgetting that we were
15
implicitly using this code path on M-profile. At that point we would
16
hit a g_assert_not_reached():
17
ERROR:../../target/arm/internals.h:549:arm_fi_to_lfsc: code should not be reached
12
18
13
Fix the bug by expanding out the M-profile version of the
19
#7 0x0000555555e055f7 in arm_fi_to_lfsc (fi=0x7fffecff9a90) at ../../target/arm/internals.h:549
14
arm_current_el() logic inline so it can use the passed in secstate
20
#8 0x0000555555e05a27 in compute_fsr_fsc (env=0x555557356670, fi=0x7fffecff9a90, target_el=1, mmu_idx=1, ret_fsc=0x7fffecff9a1c)
15
rather than env->v7m.secure.
21
at ../../target/arm/tlb_helper.c:95
22
#9 0x0000555555e05b62 in arm_deliver_fault (cpu=0x555557354800, addr=268961344, access_type=MMU_INST_FETCH, mmu_idx=1, fi=0x7fffecff9a90)
23
at ../../target/arm/tlb_helper.c:132
24
#10 0x0000555555e06095 in arm_cpu_tlb_fill (cs=0x555557354800, address=268961344, size=1, access_type=MMU_INST_FETCH, mmu_idx=1, probe=false, retaddr=0)
25
at ../../target/arm/tlb_helper.c:260
16
26
27
The specific assertion changed when commit fcc7404eff24b4c added
28
"assert not M-profile" to arm_is_secure_below_el3(), because the
29
conditions being checked in compute_fsr_fsc() include
30
arm_el_is_aa64(), which will end up calling arm_is_secure_below_el3()
31
and asserting before we try to call arm_fi_to_lfsc():
32
33
#7 0x0000555555efaf43 in arm_is_secure_below_el3 (env=0x5555574665a0) at ../../target/arm/cpu.h:2396
34
#8 0x0000555555efb103 in arm_is_el2_enabled (env=0x5555574665a0) at ../../target/arm/cpu.h:2448
35
#9 0x0000555555efb204 in arm_el_is_aa64 (env=0x5555574665a0, el=1) at ../../target/arm/cpu.h:2509
36
#10 0x0000555555efbdfd in compute_fsr_fsc (env=0x5555574665a0, fi=0x7fffecff99e0, target_el=1, mmu_idx=1, ret_fsc=0x7fffecff996c)
37
38
Avoid the assertion and the incorrect FSR format selection by
39
explicitly making M-profile use the short-format in this function.
40
41
Fixes: 452c67a42704 ("target/arm: Enable TTBCR_EAE for ARMv8-R AArch32")a
42
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1658
43
Cc: qemu-stable@nongnu.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
45
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20201022164408.13214-1-peter.maydell@linaro.org
46
Message-id: 20230523131726.866635-1-peter.maydell@linaro.org
20
---
47
---
21
target/arm/m_helper.c | 3 ++-
48
target/arm/tcg/tlb_helper.c | 13 +++++++++++--
22
1 file changed, 2 insertions(+), 1 deletion(-)
49
1 file changed, 11 insertions(+), 2 deletions(-)
23
50
24
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
51
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
25
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/m_helper.c
53
--- a/target/arm/tcg/tlb_helper.c
27
+++ b/target/arm/m_helper.c
54
+++ b/target/arm/tcg/tlb_helper.c
28
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
55
@@ -XXX,XX +XXX,XX @@ static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
29
/* Return the MMU index for a v7M CPU in the specified security state */
56
ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
30
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
57
uint32_t fsr, fsc;
31
{
58
32
- bool priv = arm_current_el(env) != 0;
59
- if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
33
+ bool priv = arm_v7m_is_handler_mode(env) ||
60
- arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
34
+ !(env->v7m.control[secstate] & 1);
61
+ /*
35
62
+ * For M-profile there is no guest-facing FSR. We compute a
36
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
63
+ * short-form value for env->exception.fsr which we will then
37
}
64
+ * examine in arm_v7m_cpu_do_interrupt(). In theory we could
65
+ * use the LPAE format instead as long as both bits of code agree
66
+ * (and arm_fi_to_lfsc() handled the M-profile specific
67
+ * ARMFault_QEMU_NSCExec and ARMFault_QEMU_SFault cases).
68
+ */
69
+ if (!arm_feature(env, ARM_FEATURE_M) &&
70
+ (target_el == 2 || arm_el_is_aa64(env, target_el) ||
71
+ arm_s1_regime_using_lpae_format(env, arm_mmu_idx))) {
72
/*
73
* LPAE format fault status register : bottom 6 bits are
74
* status code in the same form as needed for syndrome
38
--
75
--
39
2.20.1
76
2.34.1
40
41
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
When booting a CPU with EL3 using the -kernel flag, set up CPTR_EL3 so
3
We currently need to select ARM_V7M unconditionally when TCG is
4
that SVE will not trap to EL3.
4
present in the build because some translate.c helpers and the whole of
5
m_helpers.c are not yet under CONFIG_ARM_V7M.
5
6
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
7
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Fabiano Rosas <farosas@suse.de>
8
Message-id: 20201030151541.11976-1-remi@remlab.net
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20230523180525.29994-2-farosas@suse.de
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
hw/arm/boot.c | 3 +++
13
target/arm/Kconfig | 3 +++
12
1 file changed, 3 insertions(+)
14
1 file changed, 3 insertions(+)
13
15
14
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
16
diff --git a/target/arm/Kconfig b/target/arm/Kconfig
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/boot.c
18
--- a/target/arm/Kconfig
17
+++ b/hw/arm/boot.c
19
+++ b/target/arm/Kconfig
18
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
20
@@ -XXX,XX +XXX,XX @@
19
if (cpu_isar_feature(aa64_mte, cpu)) {
21
config ARM
20
env->cp15.scr_el3 |= SCR_ATA;
22
bool
21
}
23
select ARM_COMPATIBLE_SEMIHOSTING if TCG
22
+ if (cpu_isar_feature(aa64_sve, cpu)) {
24
+
23
+ env->cp15.cptr_el[3] |= CPTR_EZ;
25
+ # We need to select this until we move m_helper.c and the
24
+ }
26
+ # translate.c v7m helpers under ARM_V7M.
25
/* AArch64 kernels never boot in secure mode */
27
select ARM_V7M if TCG
26
assert(!info->secure_boot);
28
27
/* This hook is only supported for AArch32 currently:
29
config AARCH64
28
--
30
--
29
2.20.1
31
2.34.1
30
32
31
33
diff view generated by jsdifflib
1
Sphinx 3.2 is pickier than earlier versions about the option:: markup,
1
From: Fabiano Rosas <farosas@suse.de>
2
and complains about our usage in qemu-option-trace.rst:
3
2
4
../../docs/qemu-option-trace.rst.inc:4:Malformed option description
3
When we moved the arm default CONFIGs into Kconfig and removed them
5
'[enable=]PATTERN', should look like "opt", "-opt args", "--opt args",
4
from default.mak, we made it harder to identify which CONFIGs are
6
"/opt args" or "+opt args"
5
selected by default in case users want to disable them.
7
6
8
In this file, we're really trying to document the different parts of
7
Bring back the default entries into default.mak, but keep them
9
the top-level --trace option, which qemu-nbd.rst and qemu-img.rst
8
commented out. This way users can keep their workflows of editing
10
have already introduced with an option:: markup. So it's not right
9
default.mak to remove build options without needing to search through
11
to use option:: here anyway. Switch to a different markup
10
Kconfig.
12
(definition lists) which gives about the same formatted output.
13
11
14
(Unlike option::, this markup doesn't produce index entries; but
12
Reported-by: Thomas Huth <thuth@redhat.com>
15
at the moment we don't do anything much with indexes anyway, and
13
Signed-off-by: Fabiano Rosas <farosas@suse.de>
16
in any case I think it doesn't make much sense to have individual
14
Reviewed-by: Thomas Huth <thuth@redhat.com>
17
index entries for the sub-parts of the --trace option.)
15
Message-id: 20230523180525.29994-3-farosas@suse.de
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
configs/devices/aarch64-softmmu/default.mak | 6 ++++
19
configs/devices/arm-softmmu/default.mak | 40 +++++++++++++++++++++
20
2 files changed, 46 insertions(+)
18
21
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
diff --git a/configs/devices/aarch64-softmmu/default.mak b/configs/devices/aarch64-softmmu/default.mak
20
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
21
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Message-id: 20201030174700.7204-3-peter.maydell@linaro.org
23
---
24
docs/qemu-option-trace.rst.inc | 6 +++---
25
1 file changed, 3 insertions(+), 3 deletions(-)
26
27
diff --git a/docs/qemu-option-trace.rst.inc b/docs/qemu-option-trace.rst.inc
28
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
29
--- a/docs/qemu-option-trace.rst.inc
24
--- a/configs/devices/aarch64-softmmu/default.mak
30
+++ b/docs/qemu-option-trace.rst.inc
25
+++ b/configs/devices/aarch64-softmmu/default.mak
31
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@
32
27
33
Specify tracing options.
28
# We support all the 32 bit boards so need all their config
34
29
include ../arm-softmmu/default.mak
35
-.. option:: [enable=]PATTERN
30
+
36
+``[enable=]PATTERN``
31
+# These are selected by default when TCG is enabled, uncomment them to
37
32
+# keep out of the build.
38
Immediately enable events matching *PATTERN*
33
+# CONFIG_XLNX_ZYNQMP_ARM=n
39
(either event name or a globbing pattern). This option is only
34
+# CONFIG_XLNX_VERSAL=n
40
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
35
+# CONFIG_SBSA_REF=n
41
36
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
42
Use :option:`-trace help` to print a list of names of trace points.
37
index XXXXXXX..XXXXXXX 100644
43
38
--- a/configs/devices/arm-softmmu/default.mak
44
-.. option:: events=FILE
39
+++ b/configs/devices/arm-softmmu/default.mak
45
+``events=FILE``
40
@@ -XXX,XX +XXX,XX @@
46
41
# CONFIG_TEST_DEVICES=n
47
Immediately enable events listed in *FILE*.
42
48
The file must contain one event name (as listed in the ``trace-events-all``
43
CONFIG_ARM_VIRT=y
49
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
44
+
50
available if QEMU has been compiled with the ``simple``, ``log`` or
45
+# These are selected by default when TCG is enabled, uncomment them to
51
``ftrace`` tracing backend.
46
+# keep out of the build.
52
47
+# CONFIG_CUBIEBOARD=n
53
-.. option:: file=FILE
48
+# CONFIG_EXYNOS4=n
54
+``file=FILE``
49
+# CONFIG_HIGHBANK=n
55
50
+# CONFIG_INTEGRATOR=n
56
Log output traces to *FILE*.
51
+# CONFIG_FSL_IMX31=n
57
This option is only available if QEMU has been compiled with
52
+# CONFIG_MUSICPAL=n
53
+# CONFIG_MUSCA=n
54
+# CONFIG_CHEETAH=n
55
+# CONFIG_SX1=n
56
+# CONFIG_NSERIES=n
57
+# CONFIG_STELLARIS=n
58
+# CONFIG_STM32VLDISCOVERY=n
59
+# CONFIG_REALVIEW=n
60
+# CONFIG_VERSATILE=n
61
+# CONFIG_VEXPRESS=n
62
+# CONFIG_ZYNQ=n
63
+# CONFIG_MAINSTONE=n
64
+# CONFIG_GUMSTIX=n
65
+# CONFIG_SPITZ=n
66
+# CONFIG_TOSA=n
67
+# CONFIG_Z2=n
68
+# CONFIG_NPCM7XX=n
69
+# CONFIG_COLLIE=n
70
+# CONFIG_ASPEED_SOC=n
71
+# CONFIG_NETDUINO2=n
72
+# CONFIG_NETDUINOPLUS2=n
73
+# CONFIG_OLIMEX_STM32_H405=n
74
+# CONFIG_MPS2=n
75
+# CONFIG_RASPI=n
76
+# CONFIG_DIGIC=n
77
+# CONFIG_SABRELITE=n
78
+# CONFIG_EMCRAFT_SF2=n
79
+# CONFIG_MICROBIT=n
80
+# CONFIG_FSL_IMX25=n
81
+# CONFIG_FSL_IMX7=n
82
+# CONFIG_FSL_IMX6UL=n
83
+# CONFIG_ALLWINNER_H3=n
58
--
84
--
59
2.20.1
85
2.34.1
60
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
This function makes it clear that we're talking about the whole
3
Replace the 'default y if TCG' pattern with 'default y; depends on
4
register, and not the 32-bit piece at index 0. This fixes a bug
4
TCG'.
5
when running on a big-endian host.
5
6
6
That makes explict that there is a dependence on TCG and enabling
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
these CONFIGs via .mak files without TCG present will fail earlier.
8
Message-id: 20201030022618.785675-2-richard.henderson@linaro.org
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
10
Signed-off-by: Fabiano Rosas <farosas@suse.de>
11
Reviewed-by: Thomas Huth <thuth@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-id: 20230523180525.29994-4-farosas@suse.de
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
target/arm/translate.c | 8 ++++++
16
hw/arm/Kconfig | 123 ++++++++++++++++++++++++++++++++-----------------
13
target/arm/translate-neon.c.inc | 44 ++++++++++++++++-----------------
17
1 file changed, 82 insertions(+), 41 deletions(-)
14
target/arm/translate-vfp.c.inc | 2 +-
18
15
3 files changed, 31 insertions(+), 23 deletions(-)
19
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
16
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate.c
21
--- a/hw/arm/Kconfig
20
+++ b/target/arm/translate.c
22
+++ b/hw/arm/Kconfig
21
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
23
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
22
unallocated_encoding(s);
24
23
}
25
config CHEETAH
24
26
bool
25
+/*
27
- default y if TCG && ARM
26
+ * Return the offset of a "full" NEON Dreg.
28
+ default y
27
+ */
29
+ depends on TCG && ARM
28
+static long neon_full_reg_offset(unsigned reg)
30
select OMAP
29
+{
31
select TSC210X
30
+ return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
32
31
+}
33
config CUBIEBOARD
32
+
34
bool
33
static inline long vfp_reg_offset(bool dp, unsigned reg)
35
- default y if TCG && ARM
34
{
36
+ default y
35
if (dp) {
37
+ depends on TCG && ARM
36
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
38
select ALLWINNER_A10
37
index XXXXXXX..XXXXXXX 100644
39
38
--- a/target/arm/translate-neon.c.inc
40
config DIGIC
39
+++ b/target/arm/translate-neon.c.inc
41
bool
40
@@ -XXX,XX +XXX,XX @@ neon_element_offset(int reg, int element, MemOp size)
42
- default y if TCG && ARM
41
ofs ^= 8 - element_size;
43
+ default y
42
}
44
+ depends on TCG && ARM
43
#endif
45
select PTIMER
44
- return neon_reg_offset(reg, 0) + ofs;
46
select PFLASH_CFI02
45
+ return neon_full_reg_offset(reg) + ofs;
47
46
}
48
config EXYNOS4
47
49
bool
48
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
50
- default y if TCG && ARM
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
51
+ default y
50
* We cannot write 16 bytes at once because the
52
+ depends on TCG && ARM
51
* destination is unaligned.
53
imply I2C_DEVICES
52
*/
54
select A9MPCORE
53
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
55
select I2C
54
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
56
@@ -XXX,XX +XXX,XX @@ config EXYNOS4
55
8, 8, tmp);
57
56
- tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
58
config HIGHBANK
57
- neon_reg_offset(vd, 0), 8, 8);
59
bool
58
+ tcg_gen_gvec_mov(0, neon_full_reg_offset(vd + 1),
60
- default y if TCG && ARM
59
+ neon_full_reg_offset(vd), 8, 8);
61
+ default y
60
} else {
62
+ depends on TCG && ARM
61
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
63
select A9MPCORE
62
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
64
select A15MPCORE
63
vec_size, vec_size, tmp);
65
select AHCI
64
}
66
@@ -XXX,XX +XXX,XX @@ config HIGHBANK
65
tcg_gen_addi_i32(addr, addr, 1 << size);
67
66
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
68
config INTEGRATOR
67
static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
69
bool
68
{
70
- default y if TCG && ARM
69
int vec_size = a->q ? 16 : 8;
71
+ default y
70
- int rd_ofs = neon_reg_offset(a->vd, 0);
72
+ depends on TCG && ARM
71
- int rn_ofs = neon_reg_offset(a->vn, 0);
73
select ARM_TIMER
72
- int rm_ofs = neon_reg_offset(a->vm, 0);
74
select INTEGRATOR_DEBUG
73
+ int rd_ofs = neon_full_reg_offset(a->vd);
75
select PL011 # UART
74
+ int rn_ofs = neon_full_reg_offset(a->vn);
76
@@ -XXX,XX +XXX,XX @@ config INTEGRATOR
75
+ int rm_ofs = neon_full_reg_offset(a->vm);
77
76
78
config MAINSTONE
77
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
79
bool
78
return false;
80
- default y if TCG && ARM
79
@@ -XXX,XX +XXX,XX @@ static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)
81
+ default y
80
{
82
+ depends on TCG && ARM
81
/* Handle a 2-reg-shift insn which can be vectorized. */
83
select PXA2XX
82
int vec_size = a->q ? 16 : 8;
84
select PFLASH_CFI01
83
- int rd_ofs = neon_reg_offset(a->vd, 0);
85
select SMC91C111
84
- int rm_ofs = neon_reg_offset(a->vm, 0);
86
85
+ int rd_ofs = neon_full_reg_offset(a->vd);
87
config MUSCA
86
+ int rm_ofs = neon_full_reg_offset(a->vm);
88
bool
87
89
- default y if TCG && ARM
88
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
90
+ default y
89
return false;
91
+ depends on TCG && ARM
90
@@ -XXX,XX +XXX,XX @@ static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
92
select ARMSSE
91
{
93
select PL011
92
/* FP operations in 2-reg-and-shift group */
94
select PL031
93
int vec_size = a->q ? 16 : 8;
95
@@ -XXX,XX +XXX,XX @@ config MARVELL_88W8618
94
- int rd_ofs = neon_reg_offset(a->vd, 0);
96
95
- int rm_ofs = neon_reg_offset(a->vm, 0);
97
config MUSICPAL
96
+ int rd_ofs = neon_full_reg_offset(a->vd);
98
bool
97
+ int rm_ofs = neon_full_reg_offset(a->vm);
99
- default y if TCG && ARM
98
TCGv_ptr fpst;
100
+ default y
99
101
+ depends on TCG && ARM
100
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
102
select OR_IRQ
101
@@ -XXX,XX +XXX,XX @@ static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
103
select BITBANG_I2C
102
return true;
104
select MARVELL_88W8618
103
}
105
@@ -XXX,XX +XXX,XX @@ config MUSICPAL
104
106
105
- reg_ofs = neon_reg_offset(a->vd, 0);
107
config NETDUINO2
106
+ reg_ofs = neon_full_reg_offset(a->vd);
108
bool
107
vec_size = a->q ? 16 : 8;
109
- default y if TCG && ARM
108
imm = asimd_imm_const(a->imm, a->cmode, a->op);
110
+ default y
109
111
+ depends on TCG && ARM
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMULL_P_3d(DisasContext *s, arg_3diff *a)
112
select STM32F205_SOC
111
return true;
113
112
}
114
config NETDUINOPLUS2
113
115
bool
114
- tcg_gen_gvec_3_ool(neon_reg_offset(a->vd, 0),
116
- default y if TCG && ARM
115
- neon_reg_offset(a->vn, 0),
117
+ default y
116
- neon_reg_offset(a->vm, 0),
118
+ depends on TCG && ARM
117
+ tcg_gen_gvec_3_ool(neon_full_reg_offset(a->vd),
119
select STM32F405_SOC
118
+ neon_full_reg_offset(a->vn),
120
119
+ neon_full_reg_offset(a->vm),
121
config OLIMEX_STM32_H405
120
16, 16, 0, fn_gvec);
122
bool
121
return true;
123
- default y if TCG && ARM
122
}
124
+ default y
123
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
125
+ depends on TCG && ARM
124
{
126
select STM32F405_SOC
125
/* Two registers and a scalar, using gvec */
127
126
int vec_size = a->q ? 16 : 8;
128
config NSERIES
127
- int rd_ofs = neon_reg_offset(a->vd, 0);
129
bool
128
- int rn_ofs = neon_reg_offset(a->vn, 0);
130
- default y if TCG && ARM
129
+ int rd_ofs = neon_full_reg_offset(a->vd);
131
+ default y
130
+ int rn_ofs = neon_full_reg_offset(a->vn);
132
+ depends on TCG && ARM
131
int rm_ofs;
133
select OMAP
132
int idx;
134
select TMP105 # temperature sensor
133
TCGv_ptr fpstatus;
135
select BLIZZARD # LCD/TV controller
134
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
136
@@ -XXX,XX +XXX,XX @@ config PXA2XX
135
/* a->vm is M:Vm, which encodes both register and index */
137
136
idx = extract32(a->vm, a->size + 2, 2);
138
config GUMSTIX
137
a->vm = extract32(a->vm, 0, a->size + 2);
139
bool
138
- rm_ofs = neon_reg_offset(a->vm, 0);
140
- default y if TCG && ARM
139
+ rm_ofs = neon_full_reg_offset(a->vm);
141
+ default y
140
142
+ depends on TCG && ARM
141
fpstatus = fpstatus_ptr(a->size == 1 ? FPST_STD_F16 : FPST_STD);
143
select PFLASH_CFI01
142
tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, fpstatus,
144
select SMC91C111
143
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
145
select PXA2XX
144
return true;
146
145
}
147
config TOSA
146
148
bool
147
- tcg_gen_gvec_dup_mem(a->size, neon_reg_offset(a->vd, 0),
149
- default y if TCG && ARM
148
+ tcg_gen_gvec_dup_mem(a->size, neon_full_reg_offset(a->vd),
150
+ default y
149
neon_element_offset(a->vm, a->index, a->size),
151
+ depends on TCG && ARM
150
a->q ? 16 : 8, a->q ? 16 : 8);
152
select ZAURUS # scoop
151
return true;
153
select MICRODRIVE
152
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
154
select PXA2XX
153
static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn)
155
@@ -XXX,XX +XXX,XX @@ config TOSA
154
{
156
155
int vec_size = a->q ? 16 : 8;
157
config SPITZ
156
- int rd_ofs = neon_reg_offset(a->vd, 0);
158
bool
157
- int rm_ofs = neon_reg_offset(a->vm, 0);
159
- default y if TCG && ARM
158
+ int rd_ofs = neon_full_reg_offset(a->vd);
160
+ default y
159
+ int rm_ofs = neon_full_reg_offset(a->vm);
161
+ depends on TCG && ARM
160
162
select ADS7846 # touch-screen controller
161
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
163
select MAX111X # A/D converter
162
return false;
164
select WM8750 # audio codec
163
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
165
@@ -XXX,XX +XXX,XX @@ config SPITZ
164
index XXXXXXX..XXXXXXX 100644
166
165
--- a/target/arm/translate-vfp.c.inc
167
config Z2
166
+++ b/target/arm/translate-vfp.c.inc
168
bool
167
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
169
- default y if TCG && ARM
168
}
170
+ default y
169
171
+ depends on TCG && ARM
170
tmp = load_reg(s, a->rt);
172
select PFLASH_CFI01
171
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(a->vn, 0),
173
select WM8750
172
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(a->vn),
174
select PL011 # UART
173
vec_size, vec_size, tmp);
175
@@ -XXX,XX +XXX,XX @@ config Z2
174
tcg_temp_free_i32(tmp);
176
177
config REALVIEW
178
bool
179
- default y if TCG && ARM
180
+ default y
181
+ depends on TCG && ARM
182
imply PCI_DEVICES
183
imply PCI_TESTDEV
184
imply I2C_DEVICES
185
@@ -XXX,XX +XXX,XX @@ config REALVIEW
186
187
config SBSA_REF
188
bool
189
- default y if TCG && AARCH64
190
+ default y
191
+ depends on TCG && AARCH64
192
imply PCI_DEVICES
193
select AHCI
194
select ARM_SMMUV3
195
@@ -XXX,XX +XXX,XX @@ config SBSA_REF
196
197
config SABRELITE
198
bool
199
- default y if TCG && ARM
200
+ default y
201
+ depends on TCG && ARM
202
select FSL_IMX6
203
select SSI_M25P80
204
205
config STELLARIS
206
bool
207
- default y if TCG && ARM
208
+ default y
209
+ depends on TCG && ARM
210
imply I2C_DEVICES
211
select ARM_V7M
212
select CMSDK_APB_WATCHDOG
213
@@ -XXX,XX +XXX,XX @@ config STELLARIS
214
215
config STM32VLDISCOVERY
216
bool
217
- default y if TCG && ARM
218
+ default y
219
+ depends on TCG && ARM
220
select STM32F100_SOC
221
222
config STRONGARM
223
@@ -XXX,XX +XXX,XX @@ config STRONGARM
224
225
config COLLIE
226
bool
227
- default y if TCG && ARM
228
+ default y
229
+ depends on TCG && ARM
230
select PFLASH_CFI01
231
select ZAURUS # scoop
232
select STRONGARM
233
234
config SX1
235
bool
236
- default y if TCG && ARM
237
+ default y
238
+ depends on TCG && ARM
239
select OMAP
240
241
config VERSATILE
242
bool
243
- default y if TCG && ARM
244
+ default y
245
+ depends on TCG && ARM
246
select ARM_TIMER # sp804
247
select PFLASH_CFI01
248
select LSI_SCSI_PCI
249
@@ -XXX,XX +XXX,XX @@ config VERSATILE
250
251
config VEXPRESS
252
bool
253
- default y if TCG && ARM
254
+ default y
255
+ depends on TCG && ARM
256
select A9MPCORE
257
select A15MPCORE
258
select ARM_MPTIMER
259
@@ -XXX,XX +XXX,XX @@ config VEXPRESS
260
261
config ZYNQ
262
bool
263
- default y if TCG && ARM
264
+ default y
265
+ depends on TCG && ARM
266
select A9MPCORE
267
select CADENCE # UART
268
select PFLASH_CFI02
269
@@ -XXX,XX +XXX,XX @@ config ZYNQ
270
config ARM_V7M
271
bool
272
# currently v7M must be included in a TCG build due to translate.c
273
- default y if TCG && ARM
274
+ default y
275
+ depends on TCG && ARM
276
select PTIMER
277
278
config ALLWINNER_A10
279
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10
280
281
config ALLWINNER_H3
282
bool
283
- default y if TCG && ARM
284
+ default y
285
+ depends on TCG && ARM
286
select ALLWINNER_A10_PIT
287
select ALLWINNER_SUN8I_EMAC
288
select ALLWINNER_I2C
289
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_H3
290
291
config RASPI
292
bool
293
- default y if TCG && ARM
294
+ default y
295
+ depends on TCG && ARM
296
select FRAMEBUFFER
297
select PL011 # UART
298
select SDHCI
299
@@ -XXX,XX +XXX,XX @@ config STM32F405_SOC
300
301
config XLNX_ZYNQMP_ARM
302
bool
303
- default y if TCG && AARCH64
304
+ default y
305
+ depends on TCG && AARCH64
306
select AHCI
307
select ARM_GIC
308
select CADENCE
309
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP_ARM
310
311
config XLNX_VERSAL
312
bool
313
- default y if TCG && AARCH64
314
+ default y
315
+ depends on TCG && AARCH64
316
select ARM_GIC
317
select PL011
318
select CADENCE
319
@@ -XXX,XX +XXX,XX @@ config XLNX_VERSAL
320
321
config NPCM7XX
322
bool
323
- default y if TCG && ARM
324
+ default y
325
+ depends on TCG && ARM
326
select A9MPCORE
327
select ADM1272
328
select ARM_GIC
329
@@ -XXX,XX +XXX,XX @@ config NPCM7XX
330
331
config FSL_IMX25
332
bool
333
- default y if TCG && ARM
334
+ default y
335
+ depends on TCG && ARM
336
imply I2C_DEVICES
337
select IMX
338
select IMX_FEC
339
@@ -XXX,XX +XXX,XX @@ config FSL_IMX25
340
341
config FSL_IMX31
342
bool
343
- default y if TCG && ARM
344
+ default y
345
+ depends on TCG && ARM
346
imply I2C_DEVICES
347
select SERIAL
348
select IMX
349
@@ -XXX,XX +XXX,XX @@ config FSL_IMX6
350
351
config ASPEED_SOC
352
bool
353
- default y if TCG && ARM
354
+ default y
355
+ depends on TCG && ARM
356
select DS1338
357
select FTGMAC100
358
select I2C
359
@@ -XXX,XX +XXX,XX @@ config ASPEED_SOC
360
361
config MPS2
362
bool
363
- default y if TCG && ARM
364
+ default y
365
+ depends on TCG && ARM
366
imply I2C_DEVICES
367
select ARMSSE
368
select LAN9118
369
@@ -XXX,XX +XXX,XX @@ config MPS2
370
371
config FSL_IMX7
372
bool
373
- default y if TCG && ARM
374
+ default y
375
+ depends on TCG && ARM
376
imply PCI_DEVICES
377
imply TEST_DEVICES
378
imply I2C_DEVICES
379
@@ -XXX,XX +XXX,XX @@ config ARM_SMMUV3
380
381
config FSL_IMX6UL
382
bool
383
- default y if TCG && ARM
384
+ default y
385
+ depends on TCG && ARM
386
imply I2C_DEVICES
387
select A15MPCORE
388
select IMX
389
@@ -XXX,XX +XXX,XX @@ config FSL_IMX6UL
390
391
config MICROBIT
392
bool
393
- default y if TCG && ARM
394
+ default y
395
+ depends on TCG && ARM
396
select NRF51_SOC
397
398
config NRF51_SOC
399
@@ -XXX,XX +XXX,XX @@ config NRF51_SOC
400
401
config EMCRAFT_SF2
402
bool
403
- default y if TCG && ARM
404
+ default y
405
+ depends on TCG && ARM
406
select MSF2
407
select SSI_M25P80
175
408
176
--
409
--
177
2.20.1
410
2.34.1
178
411
179
412
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Enze Li <lienze@kylinos.cn>
2
2
3
We can then use this to improve VMOV (scalar to gp) and
3
I noticed that in the latest version, the copyright string is still
4
VMOV (gp to scalar) so that we simply perform the memory
4
2022, even though 2023 is halfway through. This patch fixes that and
5
operation that we wanted, rather than inserting or
5
fixes the documentation along with it.
6
extracting from a 32-bit quantity.
7
6
8
These were the last uses of neon_load/store_reg, so remove them.
7
Signed-off-by: Enze Li <lienze@kylinos.cn>
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20201030022618.785675-7-richard.henderson@linaro.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20230525064345.1152801-1-lienze@kylinos.cn
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
target/arm/translate.c | 50 +++++++++++++-----------
12
docs/conf.py | 2 +-
16
target/arm/translate-vfp.c.inc | 71 +++++-----------------------------
13
include/qemu/help-texts.h | 2 +-
17
2 files changed, 37 insertions(+), 84 deletions(-)
14
2 files changed, 2 insertions(+), 2 deletions(-)
18
15
19
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/docs/conf.py b/docs/conf.py
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate.c
18
--- a/docs/conf.py
22
+++ b/target/arm/translate.c
19
+++ b/docs/conf.py
23
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
20
@@ -XXX,XX +XXX,XX @@
24
* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
21
25
* where 0 is the least significant end of the register.
22
# General information about the project.
26
*/
23
project = u'QEMU'
27
-static long neon_element_offset(int reg, int element, MemOp size)
24
-copyright = u'2022, The QEMU Project Developers'
28
+static long neon_element_offset(int reg, int element, MemOp memop)
25
+copyright = u'2023, The QEMU Project Developers'
29
{
26
author = u'The QEMU Project Developers'
30
- int element_size = 1 << size;
27
31
+ int element_size = 1 << (memop & MO_SIZE);
28
# The version info for the project you're documenting, acts as replacement for
32
int ofs = element * element_size;
29
diff --git a/include/qemu/help-texts.h b/include/qemu/help-texts.h
33
#ifdef HOST_WORDS_BIGENDIAN
34
/*
35
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
36
}
37
}
38
39
-static TCGv_i32 neon_load_reg(int reg, int pass)
40
-{
41
- TCGv_i32 tmp = tcg_temp_new_i32();
42
- tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
43
- return tmp;
44
-}
45
-
46
-static void neon_store_reg(int reg, int pass, TCGv_i32 var)
47
-{
48
- tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
49
- tcg_temp_free_i32(var);
50
-}
51
-
52
static inline void neon_load_reg64(TCGv_i64 var, int reg)
53
{
54
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
55
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
56
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
57
}
58
59
-static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
60
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
61
{
62
- long off = neon_element_offset(reg, ele, size);
63
+ long off = neon_element_offset(reg, ele, memop);
64
65
- switch (size) {
66
- case MO_32:
67
+ switch (memop) {
68
+ case MO_SB:
69
+ tcg_gen_ld8s_i32(dest, cpu_env, off);
70
+ break;
71
+ case MO_UB:
72
+ tcg_gen_ld8u_i32(dest, cpu_env, off);
73
+ break;
74
+ case MO_SW:
75
+ tcg_gen_ld16s_i32(dest, cpu_env, off);
76
+ break;
77
+ case MO_UW:
78
+ tcg_gen_ld16u_i32(dest, cpu_env, off);
79
+ break;
80
+ case MO_UL:
81
+ case MO_SL:
82
tcg_gen_ld_i32(dest, cpu_env, off);
83
break;
84
default:
85
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
86
}
87
}
88
89
-static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
90
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
91
{
92
- long off = neon_element_offset(reg, ele, size);
93
+ long off = neon_element_offset(reg, ele, memop);
94
95
- switch (size) {
96
+ switch (memop) {
97
+ case MO_8:
98
+ tcg_gen_st8_i32(src, cpu_env, off);
99
+ break;
100
+ case MO_16:
101
+ tcg_gen_st16_i32(src, cpu_env, off);
102
+ break;
103
case MO_32:
104
tcg_gen_st_i32(src, cpu_env, off);
105
break;
106
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
107
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-vfp.c.inc
31
--- a/include/qemu/help-texts.h
109
+++ b/target/arm/translate-vfp.c.inc
32
+++ b/include/qemu/help-texts.h
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
33
@@ -XXX,XX +XXX,XX @@
111
{
34
#define QEMU_HELP_TEXTS_H
112
/* VMOV scalar to general purpose register */
35
113
TCGv_i32 tmp;
36
/* Copyright string for -version arguments, About dialogs, etc */
114
- int pass;
37
-#define QEMU_COPYRIGHT "Copyright (c) 2003-2022 " \
115
- uint32_t offset;
38
+#define QEMU_COPYRIGHT "Copyright (c) 2003-2023 " \
116
39
"Fabrice Bellard and the QEMU Project developers"
117
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
40
118
- if (a->size == 2
41
/* Bug reporting information for --help arguments, About dialogs, etc */
119
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
120
+ if (a->size == MO_32
121
? !dc_isar_feature(aa32_fpsp_v2, s)
122
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
123
return false;
124
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
125
return false;
126
}
127
128
- offset = a->index << a->size;
129
- pass = extract32(offset, 2, 1);
130
- offset = extract32(offset, 0, 2) * 8;
131
-
132
if (!vfp_access_check(s)) {
133
return true;
134
}
135
136
- tmp = neon_load_reg(a->vn, pass);
137
- switch (a->size) {
138
- case 0:
139
- if (offset) {
140
- tcg_gen_shri_i32(tmp, tmp, offset);
141
- }
142
- if (a->u) {
143
- gen_uxtb(tmp);
144
- } else {
145
- gen_sxtb(tmp);
146
- }
147
- break;
148
- case 1:
149
- if (a->u) {
150
- if (offset) {
151
- tcg_gen_shri_i32(tmp, tmp, 16);
152
- } else {
153
- gen_uxth(tmp);
154
- }
155
- } else {
156
- if (offset) {
157
- tcg_gen_sari_i32(tmp, tmp, 16);
158
- } else {
159
- gen_sxth(tmp);
160
- }
161
- }
162
- break;
163
- case 2:
164
- break;
165
- }
166
+ tmp = tcg_temp_new_i32();
167
+ read_neon_element32(tmp, a->vn, a->index, a->size | (a->u ? 0 : MO_SIGN));
168
store_reg(s, a->rt, tmp);
169
170
return true;
171
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
172
static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
173
{
174
/* VMOV general purpose register to scalar */
175
- TCGv_i32 tmp, tmp2;
176
- int pass;
177
- uint32_t offset;
178
+ TCGv_i32 tmp;
179
180
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
181
- if (a->size == 2
182
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
183
+ if (a->size == MO_32
184
? !dc_isar_feature(aa32_fpsp_v2, s)
185
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
186
return false;
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
188
return false;
189
}
190
191
- offset = a->index << a->size;
192
- pass = extract32(offset, 2, 1);
193
- offset = extract32(offset, 0, 2) * 8;
194
-
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
199
tmp = load_reg(s, a->rt);
200
- switch (a->size) {
201
- case 0:
202
- tmp2 = neon_load_reg(a->vn, pass);
203
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
204
- tcg_temp_free_i32(tmp2);
205
- break;
206
- case 1:
207
- tmp2 = neon_load_reg(a->vn, pass);
208
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
209
- tcg_temp_free_i32(tmp2);
210
- break;
211
- case 2:
212
- break;
213
- }
214
- neon_store_reg(a->vn, pass, tmp);
215
+ write_neon_element32(tmp, a->vn, a->index, a->size);
216
+ tcg_temp_free_i32(tmp);
217
218
return true;
219
}
220
--
42
--
221
2.20.1
43
2.34.1
222
223
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
The only uses of this function are for loading VFP
3
Let add GIC information into DeviceTree as part of SBSA-REF versioning.
4
single-precision values, and nothing to do with NEON.
5
4
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Trusted Firmware will read it and provide to next firmware level.
7
Message-id: 20201030022618.785675-8-richard.henderson@linaro.org
6
7
Bumps platform version to 0.1 one so we can check is node is present.
8
9
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/translate.c | 4 +-
13
hw/arm/sbsa-ref.c | 19 ++++++++++++++++++-
12
target/arm/translate-vfp.c.inc | 184 ++++++++++++++++-----------------
14
1 file changed, 18 insertions(+), 1 deletion(-)
13
2 files changed, 94 insertions(+), 94 deletions(-)
14
15
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
18
--- a/hw/arm/sbsa-ref.c
18
+++ b/target/arm/translate.c
19
+++ b/hw/arm/sbsa-ref.c
19
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg64(TCGv_i64 var, int reg)
20
@@ -XXX,XX +XXX,XX @@
20
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
21
#include "exec/hwaddr.h"
22
#include "kvm_arm.h"
23
#include "hw/arm/boot.h"
24
+#include "hw/arm/fdt.h"
25
#include "hw/arm/smmuv3.h"
26
#include "hw/block/flash.h"
27
#include "hw/boards.h"
28
@@ -XXX,XX +XXX,XX @@ static uint64_t sbsa_ref_cpu_mp_affinity(SBSAMachineState *sms, int idx)
29
return arm_cpu_mp_affinity(idx, clustersz);
21
}
30
}
22
31
23
-static inline void neon_load_reg32(TCGv_i32 var, int reg)
32
+static void sbsa_fdt_add_gic_node(SBSAMachineState *sms)
24
+static inline void vfp_load_reg32(TCGv_i32 var, int reg)
33
+{
25
{
34
+ char *nodename;
26
tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
35
+
36
+ nodename = g_strdup_printf("/intc");
37
+ qemu_fdt_add_subnode(sms->fdt, nodename);
38
+ qemu_fdt_setprop_sized_cells(sms->fdt, nodename, "reg",
39
+ 2, sbsa_ref_memmap[SBSA_GIC_DIST].base,
40
+ 2, sbsa_ref_memmap[SBSA_GIC_DIST].size,
41
+ 2, sbsa_ref_memmap[SBSA_GIC_REDIST].base,
42
+ 2, sbsa_ref_memmap[SBSA_GIC_REDIST].size);
43
+
44
+ g_free(nodename);
45
+}
46
/*
47
* Firmware on this machine only uses ACPI table to load OS, these limited
48
* device tree nodes are just to let firmware know the info which varies from
49
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
50
* fw compatibility.
51
*/
52
qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
53
- qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 0);
54
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 1);
55
56
if (ms->numa_state->have_numa_distance) {
57
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
58
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
59
60
g_free(nodename);
61
}
62
+
63
+ sbsa_fdt_add_gic_node(sms);
27
}
64
}
28
65
29
-static inline void neon_store_reg32(TCGv_i32 var, int reg)
66
#define SBSA_FLASH_SECTOR_SIZE (256 * KiB)
30
+static inline void vfp_store_reg32(TCGv_i32 var, int reg)
31
{
32
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
33
}
34
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-vfp.c.inc
37
+++ b/target/arm/translate-vfp.c.inc
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
39
frn = tcg_temp_new_i32();
40
frm = tcg_temp_new_i32();
41
dest = tcg_temp_new_i32();
42
- neon_load_reg32(frn, rn);
43
- neon_load_reg32(frm, rm);
44
+ vfp_load_reg32(frn, rn);
45
+ vfp_load_reg32(frm, rm);
46
switch (a->cc) {
47
case 0: /* eq: Z */
48
tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
50
if (sz == 1) {
51
tcg_gen_andi_i32(dest, dest, 0xffff);
52
}
53
- neon_store_reg32(dest, rd);
54
+ vfp_store_reg32(dest, rd);
55
tcg_temp_free_i32(frn);
56
tcg_temp_free_i32(frm);
57
tcg_temp_free_i32(dest);
58
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
59
TCGv_i32 tcg_res;
60
tcg_op = tcg_temp_new_i32();
61
tcg_res = tcg_temp_new_i32();
62
- neon_load_reg32(tcg_op, rm);
63
+ vfp_load_reg32(tcg_op, rm);
64
if (sz == 1) {
65
gen_helper_rinth(tcg_res, tcg_op, fpst);
66
} else {
67
gen_helper_rints(tcg_res, tcg_op, fpst);
68
}
69
- neon_store_reg32(tcg_res, rd);
70
+ vfp_store_reg32(tcg_res, rd);
71
tcg_temp_free_i32(tcg_op);
72
tcg_temp_free_i32(tcg_res);
73
}
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
75
gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
76
}
77
tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
78
- neon_store_reg32(tcg_tmp, rd);
79
+ vfp_store_reg32(tcg_tmp, rd);
80
tcg_temp_free_i32(tcg_tmp);
81
tcg_temp_free_i64(tcg_res);
82
tcg_temp_free_i64(tcg_double);
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
84
TCGv_i32 tcg_single, tcg_res;
85
tcg_single = tcg_temp_new_i32();
86
tcg_res = tcg_temp_new_i32();
87
- neon_load_reg32(tcg_single, rm);
88
+ vfp_load_reg32(tcg_single, rm);
89
if (sz == 1) {
90
if (is_signed) {
91
gen_helper_vfp_toslh(tcg_res, tcg_single, tcg_shift, fpst);
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
93
gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
94
}
95
}
96
- neon_store_reg32(tcg_res, rd);
97
+ vfp_store_reg32(tcg_res, rd);
98
tcg_temp_free_i32(tcg_res);
99
tcg_temp_free_i32(tcg_single);
100
}
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_half(DisasContext *s, arg_VMOV_single *a)
102
if (a->l) {
103
/* VFP to general purpose register */
104
tmp = tcg_temp_new_i32();
105
- neon_load_reg32(tmp, a->vn);
106
+ vfp_load_reg32(tmp, a->vn);
107
tcg_gen_andi_i32(tmp, tmp, 0xffff);
108
store_reg(s, a->rt, tmp);
109
} else {
110
/* general purpose register to VFP */
111
tmp = load_reg(s, a->rt);
112
tcg_gen_andi_i32(tmp, tmp, 0xffff);
113
- neon_store_reg32(tmp, a->vn);
114
+ vfp_store_reg32(tmp, a->vn);
115
tcg_temp_free_i32(tmp);
116
}
117
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
119
if (a->l) {
120
/* VFP to general purpose register */
121
tmp = tcg_temp_new_i32();
122
- neon_load_reg32(tmp, a->vn);
123
+ vfp_load_reg32(tmp, a->vn);
124
if (a->rt == 15) {
125
/* Set the 4 flag bits in the CPSR. */
126
gen_set_nzcv(tmp);
127
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
128
} else {
129
/* general purpose register to VFP */
130
tmp = load_reg(s, a->rt);
131
- neon_store_reg32(tmp, a->vn);
132
+ vfp_store_reg32(tmp, a->vn);
133
tcg_temp_free_i32(tmp);
134
}
135
136
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
137
if (a->op) {
138
/* fpreg to gpreg */
139
tmp = tcg_temp_new_i32();
140
- neon_load_reg32(tmp, a->vm);
141
+ vfp_load_reg32(tmp, a->vm);
142
store_reg(s, a->rt, tmp);
143
tmp = tcg_temp_new_i32();
144
- neon_load_reg32(tmp, a->vm + 1);
145
+ vfp_load_reg32(tmp, a->vm + 1);
146
store_reg(s, a->rt2, tmp);
147
} else {
148
/* gpreg to fpreg */
149
tmp = load_reg(s, a->rt);
150
- neon_store_reg32(tmp, a->vm);
151
+ vfp_store_reg32(tmp, a->vm);
152
tcg_temp_free_i32(tmp);
153
tmp = load_reg(s, a->rt2);
154
- neon_store_reg32(tmp, a->vm + 1);
155
+ vfp_store_reg32(tmp, a->vm + 1);
156
tcg_temp_free_i32(tmp);
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
160
if (a->op) {
161
/* fpreg to gpreg */
162
tmp = tcg_temp_new_i32();
163
- neon_load_reg32(tmp, a->vm * 2);
164
+ vfp_load_reg32(tmp, a->vm * 2);
165
store_reg(s, a->rt, tmp);
166
tmp = tcg_temp_new_i32();
167
- neon_load_reg32(tmp, a->vm * 2 + 1);
168
+ vfp_load_reg32(tmp, a->vm * 2 + 1);
169
store_reg(s, a->rt2, tmp);
170
} else {
171
/* gpreg to fpreg */
172
tmp = load_reg(s, a->rt);
173
- neon_store_reg32(tmp, a->vm * 2);
174
+ vfp_store_reg32(tmp, a->vm * 2);
175
tcg_temp_free_i32(tmp);
176
tmp = load_reg(s, a->rt2);
177
- neon_store_reg32(tmp, a->vm * 2 + 1);
178
+ vfp_store_reg32(tmp, a->vm * 2 + 1);
179
tcg_temp_free_i32(tmp);
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
183
tmp = tcg_temp_new_i32();
184
if (a->l) {
185
gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
186
- neon_store_reg32(tmp, a->vd);
187
+ vfp_store_reg32(tmp, a->vd);
188
} else {
189
- neon_load_reg32(tmp, a->vd);
190
+ vfp_load_reg32(tmp, a->vd);
191
gen_aa32_st16(s, tmp, addr, get_mem_index(s));
192
}
193
tcg_temp_free_i32(tmp);
194
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
195
tmp = tcg_temp_new_i32();
196
if (a->l) {
197
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
198
- neon_store_reg32(tmp, a->vd);
199
+ vfp_store_reg32(tmp, a->vd);
200
} else {
201
- neon_load_reg32(tmp, a->vd);
202
+ vfp_load_reg32(tmp, a->vd);
203
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
204
}
205
tcg_temp_free_i32(tmp);
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
207
if (a->l) {
208
/* load */
209
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
210
- neon_store_reg32(tmp, a->vd + i);
211
+ vfp_store_reg32(tmp, a->vd + i);
212
} else {
213
/* store */
214
- neon_load_reg32(tmp, a->vd + i);
215
+ vfp_load_reg32(tmp, a->vd + i);
216
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
217
}
218
tcg_gen_addi_i32(addr, addr, offset);
219
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
220
fd = tcg_temp_new_i32();
221
fpst = fpstatus_ptr(FPST_FPCR);
222
223
- neon_load_reg32(f0, vn);
224
- neon_load_reg32(f1, vm);
225
+ vfp_load_reg32(f0, vn);
226
+ vfp_load_reg32(f1, vm);
227
228
for (;;) {
229
if (reads_vd) {
230
- neon_load_reg32(fd, vd);
231
+ vfp_load_reg32(fd, vd);
232
}
233
fn(fd, f0, f1, fpst);
234
- neon_store_reg32(fd, vd);
235
+ vfp_store_reg32(fd, vd);
236
237
if (veclen == 0) {
238
break;
239
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
240
veclen--;
241
vd = vfp_advance_sreg(vd, delta_d);
242
vn = vfp_advance_sreg(vn, delta_d);
243
- neon_load_reg32(f0, vn);
244
+ vfp_load_reg32(f0, vn);
245
if (delta_m) {
246
vm = vfp_advance_sreg(vm, delta_m);
247
- neon_load_reg32(f1, vm);
248
+ vfp_load_reg32(f1, vm);
249
}
250
}
251
252
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_hp(DisasContext *s, VFPGen3OpSPFn *fn,
253
fd = tcg_temp_new_i32();
254
fpst = fpstatus_ptr(FPST_FPCR_F16);
255
256
- neon_load_reg32(f0, vn);
257
- neon_load_reg32(f1, vm);
258
+ vfp_load_reg32(f0, vn);
259
+ vfp_load_reg32(f1, vm);
260
261
if (reads_vd) {
262
- neon_load_reg32(fd, vd);
263
+ vfp_load_reg32(fd, vd);
264
}
265
fn(fd, f0, f1, fpst);
266
- neon_store_reg32(fd, vd);
267
+ vfp_store_reg32(fd, vd);
268
269
tcg_temp_free_i32(f0);
270
tcg_temp_free_i32(f1);
271
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
272
f0 = tcg_temp_new_i32();
273
fd = tcg_temp_new_i32();
274
275
- neon_load_reg32(f0, vm);
276
+ vfp_load_reg32(f0, vm);
277
278
for (;;) {
279
fn(fd, f0);
280
- neon_store_reg32(fd, vd);
281
+ vfp_store_reg32(fd, vd);
282
283
if (veclen == 0) {
284
break;
285
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
286
/* single source one-many */
287
while (veclen--) {
288
vd = vfp_advance_sreg(vd, delta_d);
289
- neon_store_reg32(fd, vd);
290
+ vfp_store_reg32(fd, vd);
291
}
292
break;
293
}
294
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
295
veclen--;
296
vd = vfp_advance_sreg(vd, delta_d);
297
vm = vfp_advance_sreg(vm, delta_m);
298
- neon_load_reg32(f0, vm);
299
+ vfp_load_reg32(f0, vm);
300
}
301
302
tcg_temp_free_i32(f0);
303
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_hp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
304
}
305
306
f0 = tcg_temp_new_i32();
307
- neon_load_reg32(f0, vm);
308
+ vfp_load_reg32(f0, vm);
309
fn(f0, f0);
310
- neon_store_reg32(f0, vd);
311
+ vfp_store_reg32(f0, vd);
312
tcg_temp_free_i32(f0);
313
314
return true;
315
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_hp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
316
vm = tcg_temp_new_i32();
317
vd = tcg_temp_new_i32();
318
319
- neon_load_reg32(vn, a->vn);
320
- neon_load_reg32(vm, a->vm);
321
+ vfp_load_reg32(vn, a->vn);
322
+ vfp_load_reg32(vm, a->vm);
323
if (neg_n) {
324
/* VFNMS, VFMS */
325
gen_helper_vfp_negh(vn, vn);
326
}
327
- neon_load_reg32(vd, a->vd);
328
+ vfp_load_reg32(vd, a->vd);
329
if (neg_d) {
330
/* VFNMA, VFNMS */
331
gen_helper_vfp_negh(vd, vd);
332
}
333
fpst = fpstatus_ptr(FPST_FPCR_F16);
334
gen_helper_vfp_muladdh(vd, vn, vm, vd, fpst);
335
- neon_store_reg32(vd, a->vd);
336
+ vfp_store_reg32(vd, a->vd);
337
338
tcg_temp_free_ptr(fpst);
339
tcg_temp_free_i32(vn);
340
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
341
vm = tcg_temp_new_i32();
342
vd = tcg_temp_new_i32();
343
344
- neon_load_reg32(vn, a->vn);
345
- neon_load_reg32(vm, a->vm);
346
+ vfp_load_reg32(vn, a->vn);
347
+ vfp_load_reg32(vm, a->vm);
348
if (neg_n) {
349
/* VFNMS, VFMS */
350
gen_helper_vfp_negs(vn, vn);
351
}
352
- neon_load_reg32(vd, a->vd);
353
+ vfp_load_reg32(vd, a->vd);
354
if (neg_d) {
355
/* VFNMA, VFNMS */
356
gen_helper_vfp_negs(vd, vd);
357
}
358
fpst = fpstatus_ptr(FPST_FPCR);
359
gen_helper_vfp_muladds(vd, vn, vm, vd, fpst);
360
- neon_store_reg32(vd, a->vd);
361
+ vfp_store_reg32(vd, a->vd);
362
363
tcg_temp_free_ptr(fpst);
364
tcg_temp_free_i32(vn);
365
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_hp(DisasContext *s, arg_VMOV_imm_sp *a)
366
}
367
368
fd = tcg_const_i32(vfp_expand_imm(MO_16, a->imm));
369
- neon_store_reg32(fd, a->vd);
370
+ vfp_store_reg32(fd, a->vd);
371
tcg_temp_free_i32(fd);
372
return true;
373
}
374
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
375
fd = tcg_const_i32(vfp_expand_imm(MO_32, a->imm));
376
377
for (;;) {
378
- neon_store_reg32(fd, vd);
379
+ vfp_store_reg32(fd, vd);
380
381
if (veclen == 0) {
382
break;
383
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a)
384
vd = tcg_temp_new_i32();
385
vm = tcg_temp_new_i32();
386
387
- neon_load_reg32(vd, a->vd);
388
+ vfp_load_reg32(vd, a->vd);
389
if (a->z) {
390
tcg_gen_movi_i32(vm, 0);
391
} else {
392
- neon_load_reg32(vm, a->vm);
393
+ vfp_load_reg32(vm, a->vm);
394
}
395
396
if (a->e) {
397
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
398
vd = tcg_temp_new_i32();
399
vm = tcg_temp_new_i32();
400
401
- neon_load_reg32(vd, a->vd);
402
+ vfp_load_reg32(vd, a->vd);
403
if (a->z) {
404
tcg_gen_movi_i32(vm, 0);
405
} else {
406
- neon_load_reg32(vm, a->vm);
407
+ vfp_load_reg32(vm, a->vm);
408
}
409
410
if (a->e) {
411
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f32_f16(DisasContext *s, arg_VCVT_f32_f16 *a)
412
/* The T bit tells us if we want the low or high 16 bits of Vm */
413
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
414
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp_mode);
415
- neon_store_reg32(tmp, a->vd);
416
+ vfp_store_reg32(tmp, a->vd);
417
tcg_temp_free_i32(ahp_mode);
418
tcg_temp_free_ptr(fpst);
419
tcg_temp_free_i32(tmp);
420
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f32(DisasContext *s, arg_VCVT_f16_f32 *a)
421
ahp_mode = get_ahp_flag();
422
tmp = tcg_temp_new_i32();
423
424
- neon_load_reg32(tmp, a->vm);
425
+ vfp_load_reg32(tmp, a->vm);
426
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp_mode);
427
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
428
tcg_temp_free_i32(ahp_mode);
429
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_hp(DisasContext *s, arg_VRINTR_sp *a)
430
}
431
432
tmp = tcg_temp_new_i32();
433
- neon_load_reg32(tmp, a->vm);
434
+ vfp_load_reg32(tmp, a->vm);
435
fpst = fpstatus_ptr(FPST_FPCR_F16);
436
gen_helper_rinth(tmp, tmp, fpst);
437
- neon_store_reg32(tmp, a->vd);
438
+ vfp_store_reg32(tmp, a->vd);
439
tcg_temp_free_ptr(fpst);
440
tcg_temp_free_i32(tmp);
441
return true;
442
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a)
443
}
444
445
tmp = tcg_temp_new_i32();
446
- neon_load_reg32(tmp, a->vm);
447
+ vfp_load_reg32(tmp, a->vm);
448
fpst = fpstatus_ptr(FPST_FPCR);
449
gen_helper_rints(tmp, tmp, fpst);
450
- neon_store_reg32(tmp, a->vd);
451
+ vfp_store_reg32(tmp, a->vd);
452
tcg_temp_free_ptr(fpst);
453
tcg_temp_free_i32(tmp);
454
return true;
455
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_hp(DisasContext *s, arg_VRINTZ_sp *a)
456
}
457
458
tmp = tcg_temp_new_i32();
459
- neon_load_reg32(tmp, a->vm);
460
+ vfp_load_reg32(tmp, a->vm);
461
fpst = fpstatus_ptr(FPST_FPCR_F16);
462
tcg_rmode = tcg_const_i32(float_round_to_zero);
463
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
464
gen_helper_rinth(tmp, tmp, fpst);
465
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
466
- neon_store_reg32(tmp, a->vd);
467
+ vfp_store_reg32(tmp, a->vd);
468
tcg_temp_free_ptr(fpst);
469
tcg_temp_free_i32(tcg_rmode);
470
tcg_temp_free_i32(tmp);
471
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
472
}
473
474
tmp = tcg_temp_new_i32();
475
- neon_load_reg32(tmp, a->vm);
476
+ vfp_load_reg32(tmp, a->vm);
477
fpst = fpstatus_ptr(FPST_FPCR);
478
tcg_rmode = tcg_const_i32(float_round_to_zero);
479
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
480
gen_helper_rints(tmp, tmp, fpst);
481
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
482
- neon_store_reg32(tmp, a->vd);
483
+ vfp_store_reg32(tmp, a->vd);
484
tcg_temp_free_ptr(fpst);
485
tcg_temp_free_i32(tcg_rmode);
486
tcg_temp_free_i32(tmp);
487
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_hp(DisasContext *s, arg_VRINTX_sp *a)
488
}
489
490
tmp = tcg_temp_new_i32();
491
- neon_load_reg32(tmp, a->vm);
492
+ vfp_load_reg32(tmp, a->vm);
493
fpst = fpstatus_ptr(FPST_FPCR_F16);
494
gen_helper_rinth_exact(tmp, tmp, fpst);
495
- neon_store_reg32(tmp, a->vd);
496
+ vfp_store_reg32(tmp, a->vd);
497
tcg_temp_free_ptr(fpst);
498
tcg_temp_free_i32(tmp);
499
return true;
500
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_sp(DisasContext *s, arg_VRINTX_sp *a)
501
}
502
503
tmp = tcg_temp_new_i32();
504
- neon_load_reg32(tmp, a->vm);
505
+ vfp_load_reg32(tmp, a->vm);
506
fpst = fpstatus_ptr(FPST_FPCR);
507
gen_helper_rints_exact(tmp, tmp, fpst);
508
- neon_store_reg32(tmp, a->vd);
509
+ vfp_store_reg32(tmp, a->vd);
510
tcg_temp_free_ptr(fpst);
511
tcg_temp_free_i32(tmp);
512
return true;
513
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
514
515
vm = tcg_temp_new_i32();
516
vd = tcg_temp_new_i64();
517
- neon_load_reg32(vm, a->vm);
518
+ vfp_load_reg32(vm, a->vm);
519
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
520
neon_store_reg64(vd, a->vd);
521
tcg_temp_free_i32(vm);
522
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
523
vm = tcg_temp_new_i64();
524
neon_load_reg64(vm, a->vm);
525
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
526
- neon_store_reg32(vd, a->vd);
527
+ vfp_store_reg32(vd, a->vd);
528
tcg_temp_free_i32(vd);
529
tcg_temp_free_i64(vm);
530
return true;
531
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
532
}
533
534
vm = tcg_temp_new_i32();
535
- neon_load_reg32(vm, a->vm);
536
+ vfp_load_reg32(vm, a->vm);
537
fpst = fpstatus_ptr(FPST_FPCR_F16);
538
if (a->s) {
539
/* i32 -> f16 */
540
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
541
/* u32 -> f16 */
542
gen_helper_vfp_uitoh(vm, vm, fpst);
543
}
544
- neon_store_reg32(vm, a->vd);
545
+ vfp_store_reg32(vm, a->vd);
546
tcg_temp_free_i32(vm);
547
tcg_temp_free_ptr(fpst);
548
return true;
549
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
550
}
551
552
vm = tcg_temp_new_i32();
553
- neon_load_reg32(vm, a->vm);
554
+ vfp_load_reg32(vm, a->vm);
555
fpst = fpstatus_ptr(FPST_FPCR);
556
if (a->s) {
557
/* i32 -> f32 */
558
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
559
/* u32 -> f32 */
560
gen_helper_vfp_uitos(vm, vm, fpst);
561
}
562
- neon_store_reg32(vm, a->vd);
563
+ vfp_store_reg32(vm, a->vd);
564
tcg_temp_free_i32(vm);
565
tcg_temp_free_ptr(fpst);
566
return true;
567
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
568
569
vm = tcg_temp_new_i32();
570
vd = tcg_temp_new_i64();
571
- neon_load_reg32(vm, a->vm);
572
+ vfp_load_reg32(vm, a->vm);
573
fpst = fpstatus_ptr(FPST_FPCR);
574
if (a->s) {
575
/* i32 -> f64 */
576
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
577
vd = tcg_temp_new_i32();
578
neon_load_reg64(vm, a->vm);
579
gen_helper_vjcvt(vd, vm, cpu_env);
580
- neon_store_reg32(vd, a->vd);
581
+ vfp_store_reg32(vd, a->vd);
582
tcg_temp_free_i64(vm);
583
tcg_temp_free_i32(vd);
584
return true;
585
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
586
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
587
588
vd = tcg_temp_new_i32();
589
- neon_load_reg32(vd, a->vd);
590
+ vfp_load_reg32(vd, a->vd);
591
592
fpst = fpstatus_ptr(FPST_FPCR_F16);
593
shift = tcg_const_i32(frac_bits);
594
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
595
g_assert_not_reached();
596
}
597
598
- neon_store_reg32(vd, a->vd);
599
+ vfp_store_reg32(vd, a->vd);
600
tcg_temp_free_i32(vd);
601
tcg_temp_free_i32(shift);
602
tcg_temp_free_ptr(fpst);
603
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
604
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
605
606
vd = tcg_temp_new_i32();
607
- neon_load_reg32(vd, a->vd);
608
+ vfp_load_reg32(vd, a->vd);
609
610
fpst = fpstatus_ptr(FPST_FPCR);
611
shift = tcg_const_i32(frac_bits);
612
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
613
g_assert_not_reached();
614
}
615
616
- neon_store_reg32(vd, a->vd);
617
+ vfp_store_reg32(vd, a->vd);
618
tcg_temp_free_i32(vd);
619
tcg_temp_free_i32(shift);
620
tcg_temp_free_ptr(fpst);
621
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
622
623
fpst = fpstatus_ptr(FPST_FPCR_F16);
624
vm = tcg_temp_new_i32();
625
- neon_load_reg32(vm, a->vm);
626
+ vfp_load_reg32(vm, a->vm);
627
628
if (a->s) {
629
if (a->rz) {
630
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
631
gen_helper_vfp_touih(vm, vm, fpst);
632
}
633
}
634
- neon_store_reg32(vm, a->vd);
635
+ vfp_store_reg32(vm, a->vd);
636
tcg_temp_free_i32(vm);
637
tcg_temp_free_ptr(fpst);
638
return true;
639
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
640
641
fpst = fpstatus_ptr(FPST_FPCR);
642
vm = tcg_temp_new_i32();
643
- neon_load_reg32(vm, a->vm);
644
+ vfp_load_reg32(vm, a->vm);
645
646
if (a->s) {
647
if (a->rz) {
648
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
649
gen_helper_vfp_touis(vm, vm, fpst);
650
}
651
}
652
- neon_store_reg32(vm, a->vd);
653
+ vfp_store_reg32(vm, a->vd);
654
tcg_temp_free_i32(vm);
655
tcg_temp_free_ptr(fpst);
656
return true;
657
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
658
gen_helper_vfp_touid(vd, vm, fpst);
659
}
660
}
661
- neon_store_reg32(vd, a->vd);
662
+ vfp_store_reg32(vd, a->vd);
663
tcg_temp_free_i32(vd);
664
tcg_temp_free_i64(vm);
665
tcg_temp_free_ptr(fpst);
666
@@ -XXX,XX +XXX,XX @@ static bool trans_VINS(DisasContext *s, arg_VINS *a)
667
/* Insert low half of Vm into high half of Vd */
668
rm = tcg_temp_new_i32();
669
rd = tcg_temp_new_i32();
670
- neon_load_reg32(rm, a->vm);
671
- neon_load_reg32(rd, a->vd);
672
+ vfp_load_reg32(rm, a->vm);
673
+ vfp_load_reg32(rd, a->vd);
674
tcg_gen_deposit_i32(rd, rd, rm, 16, 16);
675
- neon_store_reg32(rd, a->vd);
676
+ vfp_store_reg32(rd, a->vd);
677
tcg_temp_free_i32(rm);
678
tcg_temp_free_i32(rd);
679
return true;
680
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOVX(DisasContext *s, arg_VINS *a)
681
682
/* Set Vd to high half of Vm */
683
rm = tcg_temp_new_i32();
684
- neon_load_reg32(rm, a->vm);
685
+ vfp_load_reg32(rm, a->vm);
686
tcg_gen_shri_i32(rm, rm, 16);
687
- neon_store_reg32(rm, a->vd);
688
+ vfp_store_reg32(rm, a->vd);
689
tcg_temp_free_i32(rm);
690
return true;
691
}
692
--
67
--
693
2.20.1
68
2.34.1
694
695
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
These are the only users of neon_reg_offset, so remove that.
3
We moved from VGA to Bochs to have PCIe card.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
6
Message-id: 20201030022618.785675-4-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
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>
9
---
8
---
10
target/arm/translate.c | 14 ++------------
9
docs/system/arm/sbsa.rst | 2 +-
11
1 file changed, 2 insertions(+), 12 deletions(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
12
11
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
14
--- a/docs/system/arm/sbsa.rst
16
+++ b/target/arm/translate.c
15
+++ b/docs/system/arm/sbsa.rst
17
@@ -XXX,XX +XXX,XX @@ static inline long vfp_reg_offset(bool dp, unsigned reg)
16
@@ -XXX,XX +XXX,XX @@ The sbsa-ref board supports:
18
}
17
- System bus EHCI controller
19
}
18
- CDROM and hard disc on AHCI bus
20
19
- E1000E ethernet card on PCIe bus
21
-/* Return the offset of a 32-bit piece of a NEON register.
20
- - VGA display adaptor on PCIe bus
22
- zero is the least significant end of the register. */
21
+ - Bochs display adapter on PCIe bus
23
-static inline long
22
- A generic SBSA watchdog device
24
-neon_reg_offset (int reg, int n)
25
-{
26
- int sreg;
27
- sreg = reg * 2 + n;
28
- return vfp_reg_offset(0, sreg);
29
-}
30
-
31
static TCGv_i32 neon_load_reg(int reg, int pass)
32
{
33
TCGv_i32 tmp = tcg_temp_new_i32();
34
- tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
35
+ tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
36
return tmp;
37
}
38
39
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
40
{
41
- tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
42
+ tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
43
tcg_temp_free_i32(var);
44
}
45
23
46
--
24
--
47
2.20.1
25
2.34.1
48
49
diff view generated by jsdifflib
Deleted patch
1
In the neon_padd/pmax/pmin helpers for float16, a cut-and-paste error
2
meant we were using the H4() address swizzler macro rather than the
3
H2() which is required for 2-byte data. This had no effect on
4
little-endian hosts but meant we put the result data into the
5
destination Dreg in the wrong order on big-endian hosts.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20201028191712.4910-2-peter.maydell@linaro.org
11
---
12
target/arm/vec_helper.c | 8 ++++----
13
1 file changed, 4 insertions(+), 4 deletions(-)
14
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/vec_helper.c
18
+++ b/target/arm/vec_helper.c
19
@@ -XXX,XX +XXX,XX @@ DO_ABA(gvec_uaba_d, uint64_t)
20
r2 = float16_##OP(m[H2(0)], m[H2(1)], fpst); \
21
r3 = float16_##OP(m[H2(2)], m[H2(3)], fpst); \
22
\
23
- d[H4(0)] = r0; \
24
- d[H4(1)] = r1; \
25
- d[H4(2)] = r2; \
26
- d[H4(3)] = r3; \
27
+ d[H2(0)] = r0; \
28
+ d[H2(1)] = r1; \
29
+ d[H2(2)] = r2; \
30
+ d[H2(3)] = r3; \
31
}
32
33
DO_NEON_PAIRWISE(neon_padd, add)
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
Deleted patch
1
The helper functions for performing the udot/sdot operations against
2
a scalar were not using an address-swizzling macro when converting
3
the index of the scalar element into a pointer into the vm array.
4
This had no effect on little-endian hosts but meant we generated
5
incorrect results on big-endian hosts.
6
1
7
For these insns, the index is indexing over group of 4 8-bit values,
8
so 32 bits per indexed entity, and H4() is therefore what we want.
9
(For Neon the only possible input indexes are 0 and 1.)
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20201028191712.4910-3-peter.maydell@linaro.org
15
---
16
target/arm/vec_helper.c | 4 ++--
17
1 file changed, 2 insertions(+), 2 deletions(-)
18
19
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/vec_helper.c
22
+++ b/target/arm/vec_helper.c
23
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
24
intptr_t index = simd_data(desc);
25
uint32_t *d = vd;
26
int8_t *n = vn;
27
- int8_t *m_indexed = (int8_t *)vm + index * 4;
28
+ int8_t *m_indexed = (int8_t *)vm + H4(index) * 4;
29
30
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
31
* Otherwise opr_sz is a multiple of 16.
32
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
33
intptr_t index = simd_data(desc);
34
uint32_t *d = vd;
35
uint8_t *n = vn;
36
- uint8_t *m_indexed = (uint8_t *)vm + index * 4;
37
+ uint8_t *m_indexed = (uint8_t *)vm + H4(index) * 4;
38
39
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
40
* Otherwise opr_sz is a multiple of 16.
41
--
42
2.20.1
43
44
diff view generated by jsdifflib
Deleted patch
1
On some hosts (eg Ubuntu Bionic) pkg-config returns a set of
2
libraries for gio-2.0 which don't actually work when compiling
3
statically. (Specifically, the returned library string includes
4
-lmount, but not -lblkid which -lmount depends upon, so linking
5
fails due to missing symbols.)
6
1
7
Check that the libraries work, and don't enable gio if they don't,
8
in the same way we do for gnutls.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20200928160402.7961-1-peter.maydell@linaro.org
14
---
15
configure | 10 +++++++++-
16
1 file changed, 9 insertions(+), 1 deletion(-)
17
18
diff --git a/configure b/configure
19
index XXXXXXX..XXXXXXX 100755
20
--- a/configure
21
+++ b/configure
22
@@ -XXX,XX +XXX,XX @@ if test "$static" = yes && test "$mingw32" = yes; then
23
fi
24
25
if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then
26
- gio=yes
27
gio_cflags=$($pkg_config --cflags gio-2.0)
28
gio_libs=$($pkg_config --libs gio-2.0)
29
gdbus_codegen=$($pkg_config --variable=gdbus_codegen gio-2.0)
30
if [ ! -x "$gdbus_codegen" ]; then
31
gdbus_codegen=
32
fi
33
+ # Check that the libraries actually work -- Ubuntu 18.04 ships
34
+ # with pkg-config --static --libs data for gio-2.0 that is missing
35
+ # -lblkid and will give a link error.
36
+ write_c_skeleton
37
+ if compile_prog "" "gio_libs" ; then
38
+ gio=yes
39
+ else
40
+ gio=no
41
+ fi
42
else
43
gio=no
44
fi
45
--
46
2.20.1
47
48
diff view generated by jsdifflib
Deleted patch
1
In gicv3_init_cpuif() we copy the ARMCPU gicv3_maintenance_interrupt
2
into the GICv3CPUState struct's maintenance_irq field. This will
3
only work if the board happens to have already wired up the CPU
4
maintenance IRQ before the GIC was realized. Unfortunately this is
5
not the case for the 'virt' board, and so the value that gets copied
6
is NULL (since a qemu_irq is really a pointer to an IRQState struct
7
under the hood). The effect is that the CPU interface code never
8
actually raises the maintenance interrupt line.
9
1
10
Instead, since the GICv3CPUState has a pointer to the CPUState, make
11
the dereference at the point where we want to raise the interrupt, to
12
avoid an implicit requirement on board code to wire things up in a
13
particular order.
14
15
Reported-by: Jose Martins <josemartins90@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20201009153904.28529-1-peter.maydell@linaro.org
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
19
---
20
include/hw/intc/arm_gicv3_common.h | 1 -
21
hw/intc/arm_gicv3_cpuif.c | 5 ++---
22
2 files changed, 2 insertions(+), 4 deletions(-)
23
24
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/intc/arm_gicv3_common.h
27
+++ b/include/hw/intc/arm_gicv3_common.h
28
@@ -XXX,XX +XXX,XX @@ struct GICv3CPUState {
29
qemu_irq parent_fiq;
30
qemu_irq parent_virq;
31
qemu_irq parent_vfiq;
32
- qemu_irq maintenance_irq;
33
34
/* Redistributor */
35
uint32_t level; /* Current IRQ level */
36
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/arm_gicv3_cpuif.c
39
+++ b/hw/intc/arm_gicv3_cpuif.c
40
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
41
int irqlevel = 0;
42
int fiqlevel = 0;
43
int maintlevel = 0;
44
+ ARMCPU *cpu = ARM_CPU(cs->cpu);
45
46
idx = hppvi_index(cs);
47
trace_gicv3_cpuif_virt_update(gicv3_redist_affid(cs), idx);
48
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
49
50
qemu_set_irq(cs->parent_vfiq, fiqlevel);
51
qemu_set_irq(cs->parent_virq, irqlevel);
52
- qemu_set_irq(cs->maintenance_irq, maintlevel);
53
+ qemu_set_irq(cpu->gicv3_maintenance_interrupt, maintlevel);
54
}
55
56
static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
57
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
58
&& cpu->gic_num_lrs) {
59
int j;
60
61
- cs->maintenance_irq = cpu->gicv3_maintenance_interrupt;
62
-
63
cs->num_list_regs = cpu->gic_num_lrs;
64
cs->vpribits = cpu->gic_vpribits;
65
cs->vprebits = cpu->gic_vprebits;
66
--
67
2.20.1
68
69
diff view generated by jsdifflib
Deleted patch
1
The kerneldoc script currently emits Sphinx markup for a macro with
2
arguments that uses the c:function directive. This is correct for
3
Sphinx versions earlier than Sphinx 3, where c:macro doesn't allow
4
documentation of macros with arguments and c:function is not picky
5
about the syntax of what it is passed. However, in Sphinx 3 the
6
c:macro directive was enhanced to support macros with arguments,
7
and c:function was made more picky about what syntax it accepted.
8
1
9
When kerneldoc is told that it needs to produce output for Sphinx
10
3 or later, make it emit c:function only for functions and c:macro
11
for macros with arguments. We assume that anything with a return
12
type is a function and anything without is a macro.
13
14
This fixes the Sphinx error:
15
16
/home/petmay01/linaro/qemu-from-laptop/qemu/docs/../include/qom/object.h:155:Error in declarator
17
If declarator-id with parameters (e.g., 'void f(int arg)'):
18
Invalid C declaration: Expected identifier in nested name. [error at 25]
19
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
20
-------------------------^
21
If parenthesis in noptr-declarator (e.g., 'void (*f(int arg))(double)'):
22
Error in declarator or parameters
23
Invalid C declaration: Expecting "(" in parameters. [error at 39]
24
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
25
---------------------------------------^
26
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
29
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
30
Message-id: 20201030174700.7204-2-peter.maydell@linaro.org
31
---
32
scripts/kernel-doc | 18 +++++++++++++++++-
33
1 file changed, 17 insertions(+), 1 deletion(-)
34
35
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
36
index XXXXXXX..XXXXXXX 100755
37
--- a/scripts/kernel-doc
38
+++ b/scripts/kernel-doc
39
@@ -XXX,XX +XXX,XX @@ sub output_function_rst(%) {
40
    output_highlight_rst($args{'purpose'});
41
    $start = "\n\n**Syntax**\n\n ``";
42
} else {
43
-    print ".. c:function:: ";
44
+ if ((split(/\./, $sphinx_version))[0] >= 3) {
45
+ # Sphinx 3 and later distinguish macros and functions and
46
+ # complain if you use c:function with something that's not
47
+ # syntactically valid as a function declaration.
48
+ # We assume that anything with a return type is a function
49
+ # and anything without is a macro.
50
+ if ($args{'functiontype'} ne "") {
51
+ print ".. c:function:: ";
52
+ } else {
53
+ print ".. c:macro:: ";
54
+ }
55
+ } else {
56
+ # Older Sphinx don't support documenting macros that take
57
+ # arguments with c:macro, and don't complain about the use
58
+ # of c:function for this.
59
+ print ".. c:function:: ";
60
+ }
61
}
62
if ($args{'functiontype'} ne "") {
63
    $start .= $args{'functiontype'} . " " . $args{'function'} . " (";
64
--
65
2.20.1
66
67
diff view generated by jsdifflib