1
Most of this is the Neon decodetree patches, followed by Edgar's versal cleanups.
1
Here's another arm pullreq; nothing too exciting in here I think.
2
2
3
thanks
3
thanks
4
-- PMM
4
-- PMM
5
5
6
The following changes since commit 5fee33d97a7f2e95716417bd164f2f5264acd976:
6
7
7
The following changes since commit 2ef486e76d64436be90f7359a3071fb2a56ce835:
8
Merge tag 'samuel-thibault' of https://people.debian.org/~sthibault/qemu into staging (2024-04-29 14:34:25 -0700)
8
9
Merge remote-tracking branch 'remotes/marcel/tags/rdma-pull-request' into staging (2020-05-03 14:12:56 +0100)
10
9
11
are available in the Git repository at:
10
are available in the Git repository at:
12
11
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200504
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240430
14
13
15
for you to fetch changes up to 9aefc6cf9b73f66062d2f914a0136756e7a28211:
14
for you to fetch changes up to a0c325c4b05cf7815739d6a84e567b95c8c5be7e:
16
15
17
target/arm: Move gen_ function typedefs to translate.h (2020-05-04 12:59:26 +0100)
16
tests/qtest : Add testcase for DM163 (2024-04-30 16:05:08 +0100)
18
17
19
----------------------------------------------------------------
18
----------------------------------------------------------------
20
target-arm queue:
19
target-arm queue:
21
* Start of conversion of Neon insns to decodetree
20
* hw/core/clock: allow clock_propagate on child clocks
22
* versal board: support SD and RTC
21
* hvf: arm: Remove unused PL1_WRITE_MASK define
23
* Implement ARMv8.2-TTS2UXN
22
* target/arm: Restrict translation disabled alignment check to VMSA
24
* Make VQDMULL undefined when U=1
23
* docs/system/arm/emulation.rst: Add missing implemented features
25
* Some minor code cleanups
24
* target/arm: Enable FEAT_CSV2_3, FEAT_ETS2, FEAT_Spec_FPACC for 'max'
25
* tests/avocado: update sunxi kernel from armbian to 6.6.16
26
* target/arm: Make new CPUs default to 1GHz generic timer
27
* hw/dmax/xlnx_dpdma: fix handling of address_extension descriptor fields
28
* hw/char/stm32l4x5_usart: Fix memory corruption by adding correct class_size
29
* hw/arm/npcm7xx: Store derivative OTP fuse key in little endian
30
* hw/arm: Add DM163 display to B-L475E-IOT01A board
26
31
27
----------------------------------------------------------------
32
----------------------------------------------------------------
28
Edgar E. Iglesias (11):
33
Alexandra Diupina (1):
29
hw/arm: versal: Remove inclusion of arm_gicv3_common.h
34
hw/dmax/xlnx_dpdma: fix handling of address_extension descriptor fields
30
hw/arm: versal: Move misplaced comment
31
hw/arm: versal-virt: Fix typo xlnx-ve -> xlnx-versal
32
hw/arm: versal: Embed the UARTs into the SoC type
33
hw/arm: versal: Embed the GEMs into the SoC type
34
hw/arm: versal: Embed the ADMAs into the SoC type
35
hw/arm: versal: Embed the APUs into the SoC type
36
hw/arm: versal: Add support for SD
37
hw/arm: versal: Add support for the RTC
38
hw/arm: versal-virt: Add support for SD
39
hw/arm: versal-virt: Add support for the RTC
40
35
41
Fredrik Strupe (1):
36
Inès Varhol (5):
42
target/arm: Make VQDMULL undefined when U=1
37
hw/display : Add device DM163
38
hw/arm : Pass STM32L4x5 SYSCFG gpios to STM32L4x5 SoC
39
hw/arm : Create Bl475eMachineState
40
hw/arm : Connect DM163 to B-L475E-IOT01A
41
tests/qtest : Add testcase for DM163
43
42
44
Peter Maydell (25):
43
Peter Maydell (10):
45
target/arm: Don't use a TLB for ARMMMUIdx_Stage2
44
docs/system/arm/emulation.rst: Add missing implemented features
46
target/arm: Use enum constant in get_phys_addr_lpae() call
45
target/arm: Enable FEAT_CSV2_3 for -cpu max
47
target/arm: Add new 's1_is_el0' argument to get_phys_addr_lpae()
46
target/arm: Enable FEAT_ETS2 for -cpu max
48
target/arm: Implement ARMv8.2-TTS2UXN
47
target/arm: Implement ID_AA64MMFR3_EL1
49
target/arm: Use correct variable for setting 'max' cpu's ID_AA64DFR0
48
target/arm: Enable FEAT_Spec_FPACC for -cpu max
50
target/arm/translate-vfp.inc.c: Remove duplicate simd_r32 check
49
tests/avocado: update sunxi kernel from armbian to 6.6.16
51
target/arm: Don't allow Thumb Neon insns without FEATURE_NEON
50
target/arm: Refactor default generic timer frequency handling
52
target/arm: Add stubs for AArch32 Neon decodetree
51
hw/arm/sbsa-ref: Force CPU generic timer to 62.5MHz
53
target/arm: Convert VCMLA (vector) to decodetree
52
hw/watchdog/sbsa_gwdt: Make watchdog timer frequency a QOM property
54
target/arm: Convert VCADD (vector) to decodetree
53
target/arm: Default to 1GHz cntfrq for 'max' and new CPUs
55
target/arm: Convert V[US]DOT (vector) to decodetree
56
target/arm: Convert VFM[AS]L (vector) to decodetree
57
target/arm: Convert VCMLA (scalar) to decodetree
58
target/arm: Convert V[US]DOT (scalar) to decodetree
59
target/arm: Convert VFM[AS]L (scalar) to decodetree
60
target/arm: Convert Neon load/store multiple structures to decodetree
61
target/arm: Convert Neon 'load single structure to all lanes' to decodetree
62
target/arm: Convert Neon 'load/store single structure' to decodetree
63
target/arm: Convert Neon 3-reg-same VADD/VSUB to decodetree
64
target/arm: Convert Neon 3-reg-same logic ops to decodetree
65
target/arm: Convert Neon 3-reg-same VMAX/VMIN to decodetree
66
target/arm: Convert Neon 3-reg-same comparisons to decodetree
67
target/arm: Convert Neon 3-reg-same VQADD/VQSUB to decodetree
68
target/arm: Convert Neon 3-reg-same VMUL, VMLA, VMLS, VSHL to decodetree
69
target/arm: Move gen_ function typedefs to translate.h
70
54
71
Philippe Mathieu-Daudé (2):
55
Philippe Mathieu-Daudé (1):
72
hw/arm/mps2-tz: Use TYPE_IOTKIT instead of hardcoded string
56
hw/arm/npcm7xx: Store derivative OTP fuse key in little endian
73
target/arm: Use uint64_t for midr field in CPU state struct
74
57
75
include/hw/arm/xlnx-versal.h | 31 +-
58
Raphael Poggi (1):
76
target/arm/cpu-param.h | 2 +-
59
hw/core/clock: allow clock_propagate on child clocks
77
target/arm/cpu.h | 38 ++-
78
target/arm/translate-a64.h | 9 -
79
target/arm/translate.h | 26 ++
80
target/arm/neon-dp.decode | 86 +++++
81
target/arm/neon-ls.decode | 52 +++
82
target/arm/neon-shared.decode | 66 ++++
83
hw/arm/mps2-tz.c | 2 +-
84
hw/arm/xlnx-versal-virt.c | 74 ++++-
85
hw/arm/xlnx-versal.c | 115 +++++--
86
target/arm/cpu.c | 3 +-
87
target/arm/cpu64.c | 8 +-
88
target/arm/helper.c | 183 ++++------
89
target/arm/translate-a64.c | 17 -
90
target/arm/translate-neon.inc.c | 714 +++++++++++++++++++++++++++++++++++++++
91
target/arm/translate-vfp.inc.c | 6 -
92
target/arm/translate.c | 716 +++-------------------------------------
93
target/arm/Makefile.objs | 18 +
94
19 files changed, 1302 insertions(+), 864 deletions(-)
95
create mode 100644 target/arm/neon-dp.decode
96
create mode 100644 target/arm/neon-ls.decode
97
create mode 100644 target/arm/neon-shared.decode
98
create mode 100644 target/arm/translate-neon.inc.c
99
60
61
Richard Henderson (1):
62
target/arm: Restrict translation disabled alignment check to VMSA
63
64
Thomas Huth (1):
65
hw/char/stm32l4x5_usart: Fix memory corruption by adding correct class_size
66
67
Zenghui Yu (1):
68
hvf: arm: Remove PL1_WRITE_MASK
69
70
docs/system/arm/b-l475e-iot01a.rst | 3 +-
71
docs/system/arm/emulation.rst | 42 ++++-
72
include/hw/display/dm163.h | 59 ++++++
73
include/hw/watchdog/sbsa_gwdt.h | 3 +-
74
target/arm/cpu.h | 28 +++
75
target/arm/internals.h | 15 +-
76
hw/arm/b-l475e-iot01a.c | 105 +++++++++--
77
hw/arm/npcm7xx.c | 3 +-
78
hw/arm/sbsa-ref.c | 16 ++
79
hw/arm/stm32l4x5_soc.c | 6 +-
80
hw/char/stm32l4x5_usart.c | 1 +
81
hw/core/clock.c | 1 -
82
hw/core/machine.c | 4 +-
83
hw/display/dm163.c | 349 ++++++++++++++++++++++++++++++++++++
84
hw/dma/xlnx_dpdma.c | 20 +--
85
hw/watchdog/sbsa_gwdt.c | 15 +-
86
target/arm/cpu.c | 42 +++--
87
target/arm/cpu64.c | 2 +
88
target/arm/helper.c | 22 +--
89
target/arm/hvf/hvf.c | 3 +-
90
target/arm/kvm.c | 2 +
91
target/arm/tcg/cpu32.c | 6 +-
92
target/arm/tcg/cpu64.c | 28 ++-
93
target/arm/tcg/hflags.c | 12 +-
94
tests/qtest/dm163-test.c | 194 ++++++++++++++++++++
95
tests/qtest/stm32l4x5_gpio-test.c | 13 +-
96
tests/qtest/stm32l4x5_syscfg-test.c | 17 +-
97
hw/arm/Kconfig | 1 +
98
hw/display/Kconfig | 3 +
99
hw/display/meson.build | 1 +
100
hw/display/trace-events | 14 ++
101
tests/avocado/boot_linux_console.py | 70 ++++----
102
tests/avocado/replay_kernel.py | 8 +-
103
tests/qtest/meson.build | 2 +
104
34 files changed, 987 insertions(+), 123 deletions(-)
105
create mode 100644 include/hw/display/dm163.h
106
create mode 100644 hw/display/dm163.c
107
create mode 100644 tests/qtest/dm163-test.c
108
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Raphael Poggi <raphael.poggi@lynxleap.co.uk>
2
2
3
Embed the GEMs into the SoC type.
3
clock_propagate() has an assert that clk->source is NULL, i.e. that
4
you are calling it on a clock which has no source clock. This made
5
sense in the original design where the only way for a clock's
6
frequency to change if it had a source clock was when that source
7
clock changed. However, we subsequently added multiplier/divider
8
support, but didn't look at what that meant for propagation.
4
9
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
10
If a clock-management device changes the multiplier or divider value
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
on a clock, it needs to propagate that change down to child clocks,
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
even if the clock has a source clock set. So the assertion is now
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
incorrect.
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
14
10
Message-id: 20200427181649.26851-6-edgar.iglesias@gmail.com
15
Remove the assertion.
16
17
Signed-off-by: Raphael Poggi <raphael.poggi@lynxleap.co.uk>
18
Message-id: 20240419162951.23558-1-raphael.poggi@lynxleap.co.uk
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
[PMM: Rewrote the commit message]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
22
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
23
hw/core/clock.c | 1 -
14
hw/arm/xlnx-versal.c | 15 ++++++++-------
24
1 file changed, 1 deletion(-)
15
2 files changed, 10 insertions(+), 8 deletions(-)
16
25
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
26
diff --git a/hw/core/clock.c b/hw/core/clock.c
18
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
28
--- a/hw/core/clock.c
20
+++ b/include/hw/arm/xlnx-versal.h
29
+++ b/hw/core/clock.c
21
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static void clock_propagate_period(Clock *clk, bool call_callbacks)
22
#include "hw/arm/boot.h"
31
23
#include "hw/intc/arm_gicv3.h"
32
void clock_propagate(Clock *clk)
24
#include "hw/char/pl011.h"
33
{
25
+#include "hw/net/cadence_gem.h"
34
- assert(clk->source == NULL);
26
35
trace_clock_propagate(CLOCK_PATH(clk));
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
36
clock_propagate_period(clk, true);
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
31
struct {
32
PL011State uart[XLNX_VERSAL_NR_UARTS];
33
- SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
34
+ CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
35
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
36
} iou;
37
} lpd;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
43
DeviceState *dev;
44
MemoryRegion *mr;
45
46
- dev = qdev_create(NULL, "cadence_gem");
47
- s->lpd.iou.gem[i] = SYS_BUS_DEVICE(dev);
48
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
49
+ sysbus_init_child_obj(OBJECT(s), name,
50
+ &s->lpd.iou.gem[i], sizeof(s->lpd.iou.gem[i]),
51
+ TYPE_CADENCE_GEM);
52
+ dev = DEVICE(&s->lpd.iou.gem[i]);
53
if (nd->used) {
54
qemu_check_nic_model(nd, "cadence_gem");
55
qdev_set_nic_properties(dev, nd);
56
}
57
- object_property_set_int(OBJECT(s->lpd.iou.gem[i]),
58
+ object_property_set_int(OBJECT(dev),
59
2, "num-priority-queues",
60
&error_abort);
61
- object_property_set_link(OBJECT(s->lpd.iou.gem[i]),
62
+ object_property_set_link(OBJECT(dev),
63
OBJECT(&s->mr_ps), "dma",
64
&error_abort);
65
qdev_init_nofail(dev);
66
67
- mr = sysbus_mmio_get_region(s->lpd.iou.gem[i], 0);
68
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
69
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
70
71
- sysbus_connect_irq(s->lpd.iou.gem[i], 0, pic[irqs[i]]);
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
73
g_free(name);
74
}
75
}
37
}
76
--
38
--
77
2.20.1
39
2.34.1
78
79
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Zenghui Yu <zenghui.yu@linux.dev>
2
2
3
MIDR_EL1 is a 64-bit system register with the top 32-bit being RES0.
3
As it had never been used since the first commit a1477da3ddeb ("hvf: Add
4
Represent it in QEMU's ARMCPU struct with a uint64_t, not a
4
Apple Silicon support").
5
uint32_t.
6
5
7
This fixes an error when compiling with -Werror=conversion
6
Signed-off-by: Zenghui Yu <zenghui.yu@linux.dev>
8
because we were manipulating the register value using a
7
Message-id: 20240422092715.71973-1-zenghui.yu@linux.dev
9
local uint64_t variable:
10
11
target/arm/cpu64.c: In function ‘aarch64_max_initfn’:
12
target/arm/cpu64.c:628:21: error: conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘uint32_t’ {aka ‘unsigned int’} may change value [-Werror=conversion]
13
628 | cpu->midr = t;
14
| ^
15
16
and future-proofs us against a possible future architecture
17
change using some of the top 32 bits.
18
19
Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
20
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
23
Message-id: 20200428172634.29707-1-f4bug@amsat.org
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
10
---
27
target/arm/cpu.h | 2 +-
11
target/arm/hvf/hvf.c | 1 -
28
target/arm/cpu.c | 2 +-
12
1 file changed, 1 deletion(-)
29
2 files changed, 2 insertions(+), 2 deletions(-)
30
13
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
32
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
16
--- a/target/arm/hvf/hvf.c
34
+++ b/target/arm/cpu.h
17
+++ b/target/arm/hvf/hvf.c
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
18
@@ -XXX,XX +XXX,XX @@ void hvf_arm_init_debug(void)
36
uint64_t id_aa64dfr0;
19
37
uint64_t id_aa64dfr1;
20
#define HVF_SYSREG(crn, crm, op0, op1, op2) \
38
} isar;
21
ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, crn, crm, op0, op1, op2)
39
- uint32_t midr;
22
-#define PL1_WRITE_MASK 0x4
40
+ uint64_t midr;
23
41
uint32_t revidr;
24
#define SYSREG_OP0_SHIFT 20
42
uint32_t reset_fpsid;
25
#define SYSREG_OP0_MASK 0x3
43
uint32_t ctr;
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
49
static Property arm_cpu_properties[] = {
50
DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
51
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
52
- DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
53
+ DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
54
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
55
mp_affinity, ARM64_AFFINITY_INVALID),
56
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
57
--
26
--
58
2.20.1
27
2.34.1
59
60
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for SD.
3
For cpus using PMSA, when the MPU is disabled, the default memory
4
type is Normal, Non-cachable. This means that it should not
5
have alignment restrictions enforced.
4
6
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Fixes: 59754f85ed3 ("target/arm: Do memory type alignment check when translation disabled")
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Reported-by: Clément Chigot <chigot@adacore.com>
8
Message-id: 20200427181649.26851-11-edgar.iglesias@gmail.com
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Tested-by: Clément Chigot <chigot@adacore.com>
13
Message-id: 20240422170722.117409-1-richard.henderson@linaro.org
14
[PMM: trivial comment, commit message tweaks]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
hw/arm/xlnx-versal-virt.c | 46 +++++++++++++++++++++++++++++++++++++++
17
target/arm/tcg/hflags.c | 12 ++++++++++--
12
1 file changed, 46 insertions(+)
18
1 file changed, 10 insertions(+), 2 deletions(-)
13
19
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
20
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
22
--- a/target/arm/tcg/hflags.c
17
+++ b/hw/arm/xlnx-versal-virt.c
23
+++ b/target/arm/tcg/hflags.c
18
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static bool aprofile_require_alignment(CPUARMState *env, int el, uint64_t sctlr)
19
#include "hw/arm/sysbus-fdt.h"
20
#include "hw/arm/fdt.h"
21
#include "cpu.h"
22
+#include "hw/qdev-properties.h"
23
#include "hw/arm/xlnx-versal.h"
24
25
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
26
@@ -XXX,XX +XXX,XX @@ static void fdt_add_zdma_nodes(VersalVirt *s)
27
}
25
}
28
}
29
30
+static void fdt_add_sd_nodes(VersalVirt *s)
31
+{
32
+ const char clocknames[] = "clk_xin\0clk_ahb";
33
+ const char compat[] = "arasan,sdhci-8.9a";
34
+ int i;
35
+
36
+ for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
37
+ uint64_t addr = MM_PMC_SD0 + MM_PMC_SD0_SIZE * i;
38
+ char *name = g_strdup_printf("/sdhci@%" PRIx64, addr);
39
+
40
+ qemu_fdt_add_subnode(s->fdt, name);
41
+
42
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
43
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
44
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
45
+ clocknames, sizeof(clocknames));
46
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
47
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_SD0_IRQ_0 + i * 2,
48
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
49
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
50
+ 2, addr, 2, MM_PMC_SD0_SIZE);
51
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
52
+ g_free(name);
53
+ }
54
+}
55
+
56
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
57
{
58
Error *err = NULL;
59
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
60
}
61
}
62
63
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
64
+{
65
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
66
+ DeviceState *card;
67
+
68
+ card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
69
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
70
+ &error_fatal);
71
+ qdev_prop_set_drive(card, "drive", blk, &error_fatal);
72
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
73
+}
74
+
75
static void versal_virt_init(MachineState *machine)
76
{
77
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
78
int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
79
+ int i;
80
26
81
/*
27
/*
82
* If the user provides an Operating System to be loaded, we expect them
28
- * If translation is disabled, then the default memory type is
83
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
29
- * Device(-nGnRnE) instead of Normal, which requires that alignment
84
fdt_add_gic_nodes(s);
30
+ * With PMSA, when the MPU is disabled, all memory types in the
85
fdt_add_timer_nodes(s);
31
+ * default map are Normal, so don't need aligment enforcing.
86
fdt_add_zdma_nodes(s);
32
+ */
87
+ fdt_add_sd_nodes(s);
33
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
88
fdt_add_cpu_nodes(s, psci_conduit);
34
+ return false;
89
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
90
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
91
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
92
memory_region_add_subregion_overlap(get_system_memory(),
93
0, &s->soc.fpd.apu.mr, 0);
94
95
+ /* Plugin SD cards. */
96
+ for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
97
+ sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
98
+ }
35
+ }
99
+
36
+
100
s->binfo.ram_size = machine->ram_size;
37
+ /*
101
s->binfo.loader_start = 0x0;
38
+ * With VMSA, if translation is disabled, then the default memory type
102
s->binfo.get_dtb = versal_virt_get_dtb;
39
+ * is Device(-nGnRnE) instead of Normal, which requires that alignment
40
* be enforced. Since this affects all ram, it is most efficient
41
* to handle this during translation.
42
*/
103
--
43
--
104
2.20.1
44
2.34.1
105
45
106
46
diff view generated by jsdifflib
1
We're going to want at least some of the NeonGen* typedefs
1
As of version DDI0487K.a of the Arm ARM, some architectural features
2
for the refactored 32-bit Neon decoder, so move them all
2
which previously didn't have official names have been named. Add
3
to translate.h since it makes more sense to keep them in
3
these to the list of features which QEMU's TCG emulation supports.
4
one group.
4
Mostly these are features which we thought of as part of baseline 8.0
5
support. For SVE and SVE2, the names have been brought into line
6
with the FEAT_* naming convention of other extensions, and some
7
sub-components split into separate FEAT_ items. In a few cases (eg
8
FEAT_CCIDX, FEAT_DPB2) the omission from our list was just an oversight.
5
9
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200430181003.21682-23-peter.maydell@linaro.org
12
Message-id: 20240418152004.2106516-2-peter.maydell@linaro.org
9
---
13
---
10
target/arm/translate.h | 17 +++++++++++++++++
14
docs/system/arm/emulation.rst | 38 +++++++++++++++++++++++++++++++++--
11
target/arm/translate-a64.c | 17 -----------------
15
1 file changed, 36 insertions(+), 2 deletions(-)
12
2 files changed, 17 insertions(+), 17 deletions(-)
13
16
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
19
--- a/docs/system/arm/emulation.rst
17
+++ b/target/arm/translate.h
20
+++ b/docs/system/arm/emulation.rst
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
21
@@ -XXX,XX +XXX,XX @@ Armv8 versions of the A-profile architecture. It also has support for
19
typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
22
the following architecture extensions:
20
uint32_t, uint32_t, uint32_t);
23
21
24
- FEAT_AA32BF16 (AArch32 BFloat16 instructions)
22
+/* Function prototype for gen_ functions for calling Neon helpers */
25
+- FEAT_AA32EL0 (Support for AArch32 at EL0)
23
+typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
26
+- FEAT_AA32EL1 (Support for AArch32 at EL1)
24
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
27
+- FEAT_AA32EL2 (Support for AArch32 at EL2)
25
+typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
28
+- FEAT_AA32EL3 (Support for AArch32 at EL3)
26
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
29
- FEAT_AA32HPD (AArch32 hierarchical permission disables)
27
+typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
30
- FEAT_AA32I8MM (AArch32 Int8 matrix multiplication instructions)
28
+typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
31
+- FEAT_AA64EL0 (Support for AArch64 at EL0)
29
+typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
32
+- FEAT_AA64EL1 (Support for AArch64 at EL1)
30
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
33
+- FEAT_AA64EL2 (Support for AArch64 at EL2)
31
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
34
+- FEAT_AA64EL3 (Support for AArch64 at EL3)
32
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
35
+- FEAT_AdvSIMD (Advanced SIMD Extension)
33
+typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
36
- FEAT_AES (AESD and AESE instructions)
34
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
37
+- FEAT_Armv9_Crypto (Armv9 Cryptographic Extension)
35
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
38
+- FEAT_ASID16 (16 bit ASID)
36
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
39
- FEAT_BBM at level 2 (Translation table break-before-make levels)
37
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
40
- FEAT_BF16 (AArch64 BFloat16 instructions)
38
+
41
- FEAT_BTI (Branch Target Identification)
39
#endif /* TARGET_ARM_TRANSLATE_H */
42
+- FEAT_CCIDX (Extended cache index)
40
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
43
- FEAT_CRC32 (CRC32 instructions)
41
index XXXXXXX..XXXXXXX 100644
44
+- FEAT_Crypto (Cryptographic Extension)
42
--- a/target/arm/translate-a64.c
45
- FEAT_CSV2 (Cache speculation variant 2)
43
+++ b/target/arm/translate-a64.c
46
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
44
@@ -XXX,XX +XXX,XX @@ typedef struct AArch64DecodeTable {
47
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
45
AArch64DecodeFn *disas_fn;
48
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
46
} AArch64DecodeTable;
49
- FEAT_DGH (Data gathering hint)
47
50
- FEAT_DIT (Data Independent Timing instructions)
48
-/* Function prototype for gen_ functions for calling Neon helpers */
51
- FEAT_DPB (DC CVAP instruction)
49
-typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
52
+- FEAT_DPB2 (DC CVADP instruction)
50
-typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
53
+- FEAT_Debugv8p1 (Debug with VHE)
51
-typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
54
- FEAT_Debugv8p2 (Debug changes for v8.2)
52
-typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
55
- FEAT_Debugv8p4 (Debug changes for v8.4)
53
-typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
56
- FEAT_DotProd (Advanced SIMD dot product instructions)
54
-typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
57
- FEAT_DoubleFault (Double Fault Extension)
55
-typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
58
- FEAT_E0PD (Preventing EL0 access to halves of address maps)
56
-typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
59
- FEAT_ECV (Enhanced Counter Virtualization)
57
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
60
+- FEAT_EL0 (Support for execution at EL0)
58
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
61
+- FEAT_EL1 (Support for execution at EL1)
59
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
62
+- FEAT_EL2 (Support for execution at EL2)
60
-typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
63
+- FEAT_EL3 (Support for execution at EL3)
61
-typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
64
- FEAT_EPAC (Enhanced pointer authentication)
62
-typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
65
- FEAT_ETS (Enhanced Translation Synchronization)
63
-typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
66
- FEAT_EVT (Enhanced Virtualization Traps)
64
-
67
+- FEAT_F32MM (Single-precision Matrix Multiplication)
65
/* initialize TCG globals. */
68
+- FEAT_F64MM (Double-precision Matrix Multiplication)
66
void a64_translate_init(void)
69
- FEAT_FCMA (Floating-point complex number instructions)
67
{
70
- FEAT_FGT (Fine-Grained Traps)
71
- FEAT_FHM (Floating-point half-precision multiplication instructions)
72
+- FEAT_FP (Floating Point extensions)
73
- FEAT_FP16 (Half-precision floating-point data processing)
74
- FEAT_FPAC (Faulting on AUT* instructions)
75
- FEAT_FPACCOMBINE (Faulting on combined pointer authentication instructions)
76
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
77
- FEAT_LSE (Large System Extensions)
78
- FEAT_LSE2 (Large System Extensions v2)
79
- FEAT_LVA (Large Virtual Address space)
80
+- FEAT_MixedEnd (Mixed-endian support)
81
+- FEAT_MixdEndEL0 (Mixed-endian support at EL0)
82
- FEAT_MOPS (Standardization of memory operations)
83
- FEAT_MTE (Memory Tagging Extension)
84
- FEAT_MTE2 (Memory Tagging Extension)
85
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
86
+- FEAT_MTE_ASYM_FAULT (Memory tagging asymmetric faults)
87
- FEAT_NMI (Non-maskable Interrupt)
88
- FEAT_NV (Nested Virtualization)
89
- FEAT_NV2 (Enhanced nested virtualization support)
90
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
91
- FEAT_PAuth (Pointer authentication)
92
- FEAT_PAuth2 (Enhancements to pointer authentication)
93
- FEAT_PMULL (PMULL, PMULL2 instructions)
94
+- FEAT_PMUv3 (PMU extension version 3)
95
- FEAT_PMUv3p1 (PMU Extensions v3.1)
96
- FEAT_PMUv3p4 (PMU Extensions v3.4)
97
- FEAT_PMUv3p5 (PMU Extensions v3.5)
98
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
99
- FEAT_SME_FA64 (Full A64 instruction set in Streaming SVE mode)
100
- FEAT_SME_F64F64 (Double-precision floating-point outer product instructions)
101
- FEAT_SME_I16I64 (16-bit to 64-bit integer widening outer product instructions)
102
+- FEAT_SVE (Scalable Vector Extension)
103
+- FEAT_SVE_AES (Scalable Vector AES instructions)
104
+- FEAT_SVE_BitPerm (Scalable Vector Bit Permutes instructions)
105
+- FEAT_SVE_PMULL128 (Scalable Vector PMULL instructions)
106
+- FEAT_SVE_SHA3 (Scalable Vector SHA3 instructions)
107
+- FEAT_SVE_SM4 (Scalable Vector SM4 instructions)
108
+- FEAT_SVE2 (Scalable Vector Extension version 2)
109
- FEAT_SPECRES (Speculation restriction instructions)
110
- FEAT_SSBS (Speculative Store Bypass Safe)
111
+- FEAT_TGran16K (Support for 16KB memory translation granule size at stage 1)
112
+- FEAT_TGran4K (Support for 4KB memory translation granule size at stage 1)
113
+- FEAT_TGran64K (Support for 64KB memory translation granule size at stage 1)
114
- FEAT_TIDCP1 (EL0 use of IMPLEMENTATION DEFINED functionality)
115
- FEAT_TLBIOS (TLB invalidate instructions in Outer Shareable domain)
116
- FEAT_TLBIRANGE (TLB invalidate range instructions)
117
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
118
- FEAT_VHE (Virtualization Host Extensions)
119
- FEAT_VMID16 (16-bit VMID)
120
- FEAT_XNX (Translation table stage 2 Unprivileged Execute-never)
121
-- SVE (The Scalable Vector Extension)
122
-- SVE2 (The Scalable Vector Extension v2)
123
124
For information on the specifics of these extensions, please refer
125
to the `Armv8-A Arm Architecture Reference Manual
68
--
126
--
69
2.20.1
127
2.34.1
70
71
diff view generated by jsdifflib
1
Convert VCMLA (scalar) in the 2reg-scalar-ext group to decodetree.
1
FEAT_CSV2_3 adds a mechanism to identify if hardware cannot disclose
2
information about whether branch targets and branch history trained
3
in one hardware described context can control speculative execution
4
in a different hardware context.
5
6
There is no branch prediction in TCG, so we don't need to do anything
7
to be compliant with this. Upadte the '-cpu max' ID registers to
8
advertise the feature.
2
9
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-9-peter.maydell@linaro.org
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-id: 20240418152004.2106516-3-peter.maydell@linaro.org
6
---
14
---
7
target/arm/neon-shared.decode | 5 +++++
15
docs/system/arm/emulation.rst | 1 +
8
target/arm/translate-neon.inc.c | 40 +++++++++++++++++++++++++++++++++
16
target/arm/tcg/cpu64.c | 4 ++--
9
target/arm/translate.c | 26 +--------------------
17
2 files changed, 3 insertions(+), 2 deletions(-)
10
3 files changed, 46 insertions(+), 25 deletions(-)
11
18
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
13
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
21
--- a/docs/system/arm/emulation.rst
15
+++ b/target/arm/neon-shared.decode
22
+++ b/docs/system/arm/emulation.rst
16
@@ -XXX,XX +XXX,XX @@ VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
17
vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
24
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
18
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
25
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
26
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
20
+
27
+- FEAT_CSV2_3 (Cache speculation variant 2, version 3)
21
+VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
28
- FEAT_CSV3 (Cache speculation variant 3)
22
+ vn=%vn_dp vd=%vd_dp size=0
29
- FEAT_DGH (Data gathering hint)
23
+VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
30
- FEAT_DIT (Data Independent Timing instructions)
24
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
31
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
26
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate-neon.inc.c
33
--- a/target/arm/tcg/cpu64.c
28
+++ b/target/arm/translate-neon.inc.c
34
+++ b/target/arm/tcg/cpu64.c
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
35
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
30
gen_helper_gvec_fmlal_a32);
36
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
31
return true;
37
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
32
}
38
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
33
+
39
- t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */
34
+static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
40
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 3); /* FEAT_CSV2_3 */
35
+{
41
t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
42
cpu->isar.id_aa64pfr0 = t;
37
+ int opr_sz;
43
38
+ TCGv_ptr fpst;
44
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
39
+
45
t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
40
+ if (!dc_isar_feature(aa32_vcma, s)) {
46
t = FIELD_DP64(t, ID_AA64PFR1, RAS_FRAC, 0); /* FEAT_RASv1p1 + FEAT_DoubleFault */
41
+ return false;
47
t = FIELD_DP64(t, ID_AA64PFR1, SME, 1); /* FEAT_SME */
42
+ }
48
- t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */
43
+ if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
49
+ t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_3 */
44
+ return false;
50
t = FIELD_DP64(t, ID_AA64PFR1, NMI, 1); /* FEAT_NMI */
45
+ }
51
cpu->isar.id_aa64pfr1 = t;
46
+
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
49
+ ((a->vd | a->vn | a->vm) & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if ((a->vd | a->vn) & a->q) {
54
+ return false;
55
+ }
56
+
57
+ if (!vfp_access_check(s)) {
58
+ return true;
59
+ }
60
+
61
+ fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
62
+ : gen_helper_gvec_fcmlah_idx);
63
+ opr_sz = (1 + a->q) * 8;
64
+ fpst = get_fpstatus_ptr(1);
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(1, a->vn),
67
+ vfp_reg_offset(1, a->vm),
68
+ fpst, opr_sz, opr_sz,
69
+ (a->index << 2) | a->rot, fn_gvec_ptr);
70
+ tcg_temp_free_ptr(fpst);
71
+ return true;
72
+}
73
diff --git a/target/arm/translate.c b/target/arm/translate.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/target/arm/translate.c
76
+++ b/target/arm/translate.c
77
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
78
bool is_long = false, q = extract32(insn, 6, 1);
79
bool ptr_is_env = false;
80
81
- if ((insn & 0xff000f10) == 0xfe000800) {
82
- /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
83
- int rot = extract32(insn, 20, 2);
84
- int size = extract32(insn, 23, 1);
85
- int index;
86
-
87
- if (!dc_isar_feature(aa32_vcma, s)) {
88
- return 1;
89
- }
90
- if (size == 0) {
91
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
92
- return 1;
93
- }
94
- /* For fp16, rm is just Vm, and index is M. */
95
- rm = extract32(insn, 0, 4);
96
- index = extract32(insn, 5, 1);
97
- } else {
98
- /* For fp32, rm is the usual M:Vm, and index is 0. */
99
- VFP_DREG_M(rm, insn);
100
- index = 0;
101
- }
102
- data = (index << 2) | rot;
103
- fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
104
- : gen_helper_gvec_fcmlah_idx);
105
- } else if ((insn & 0xffb00f00) == 0xfe200d00) {
106
+ if ((insn & 0xffb00f00) == 0xfe200d00) {
107
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
108
int u = extract32(insn, 4, 1);
109
52
110
--
53
--
111
2.20.1
54
2.34.1
112
55
113
56
diff view generated by jsdifflib
1
Convert the Neon VMUL, VMLA, VMLS and VSHL insns in the
1
FEAT_ETS2 is a tighter set of guarantees about memory ordering
2
3-reg-same grouping to decodetree.
2
involving translation table walks than the old FEAT_ETS; FEAT_ETS has
3
been retired from the Arm ARM and the old ID_AA64MMFR1.ETS == 1
4
now gives no greater guarantees than ETS == 0.
5
6
FEAT_ETS2 requires:
7
* the virtual address of a load or store that appears in program
8
order after a DSB cannot be translated until after the DSB
9
completes (section B2.10.9)
10
* TLB maintenance operations that only affect translations without
11
execute permission are guaranteed complete after a DSB
12
(R_BLDZX)
13
* if a memory access RW2 is ordered-before memory access RW2,
14
then RW1 is also ordered-before any translation table walk
15
generated by RW2 that generates a Translation, Address size
16
or Access flag fault (R_NNFPF, I_CLGHP)
17
18
As with FEAT_ETS, QEMU is already compliant, because we do not
19
reorder translation table walk memory accesses relative to other
20
memory accesses, and we always guarantee to have finished TLB
21
maintenance as soon as the TLB op is done.
22
23
Update the documentation to list FEAT_ETS2 instead of the
24
no-longer-existent FEAT_ETS, and update the 'max' CPU ID registers.
3
25
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-20-peter.maydell@linaro.org
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
29
Message-id: 20240418152004.2106516-4-peter.maydell@linaro.org
7
---
30
---
8
target/arm/neon-dp.decode | 9 +++++++
31
docs/system/arm/emulation.rst | 2 +-
9
target/arm/translate-neon.inc.c | 44 +++++++++++++++++++++++++++++++++
32
target/arm/tcg/cpu32.c | 2 +-
10
target/arm/translate.c | 28 +++------------------
33
target/arm/tcg/cpu64.c | 2 +-
11
3 files changed, 56 insertions(+), 25 deletions(-)
34
3 files changed, 3 insertions(+), 3 deletions(-)
12
35
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
36
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
38
--- a/docs/system/arm/emulation.rst
16
+++ b/target/arm/neon-dp.decode
39
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
40
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
41
- FEAT_EL2 (Support for execution at EL2)
19
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
42
- FEAT_EL3 (Support for execution at EL3)
20
43
- FEAT_EPAC (Enhanced pointer authentication)
21
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
44
-- FEAT_ETS (Enhanced Translation Synchronization)
22
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
45
+- FEAT_ETS2 (Enhanced Translation Synchronization)
23
+
46
- FEAT_EVT (Enhanced Virtualization Traps)
24
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
47
- FEAT_F32MM (Single-precision Matrix Multiplication)
25
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
48
- FEAT_F64MM (Double-precision Matrix Multiplication)
26
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
49
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
27
@@ -XXX,XX +XXX,XX @@ VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
28
29
VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
30
VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
31
+
32
+VMLA_3s 1111 001 0 0 . .. .... .... 1001 . . . 0 .... @3same
33
+VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
34
+
35
+VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
36
+VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
51
--- a/target/arm/tcg/cpu32.c
40
+++ b/target/arm/translate-neon.inc.c
52
+++ b/target/arm/tcg/cpu32.c
41
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
53
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
42
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
54
cpu->isar.id_mmfr4 = t;
43
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
55
44
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
56
t = cpu->isar.id_mmfr5;
45
+DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
57
- t = FIELD_DP32(t, ID_MMFR5, ETS, 1); /* FEAT_ETS */
46
58
+ t = FIELD_DP32(t, ID_MMFR5, ETS, 2); /* FEAT_ETS2 */
47
#define DO_3SAME_CMP(INSN, COND) \
59
cpu->isar.id_mmfr5 = t;
48
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
60
49
@@ -XXX,XX +XXX,XX @@ DO_3SAME_GVEC4(VQADD_S, sqadd_op)
61
t = cpu->isar.id_pfr0;
50
DO_3SAME_GVEC4(VQADD_U, uqadd_op)
62
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
51
DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
52
DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
53
+
54
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
55
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
56
+{
57
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
58
+ 0, gen_helper_gvec_pmul_b);
59
+}
60
+
61
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
62
+{
63
+ if (a->size != 0) {
64
+ return false;
65
+ }
66
+ return do_3same(s, a, gen_VMUL_p_3s);
67
+}
68
+
69
+#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
70
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
71
+ uint32_t rn_ofs, uint32_t rm_ofs, \
72
+ uint32_t oprsz, uint32_t maxsz) \
73
+ { \
74
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
75
+ oprsz, maxsz, &OPARRAY[vece]); \
76
+ } \
77
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
78
+
79
+
80
+DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
81
+DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
82
+
83
+#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
84
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
85
+ uint32_t rn_ofs, uint32_t rm_ofs, \
86
+ uint32_t oprsz, uint32_t maxsz) \
87
+ { \
88
+ /* Note the operation is vshl vd,vm,vn */ \
89
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
90
+ oprsz, maxsz, &OPARRAY[vece]); \
91
+ } \
92
+ DO_3SAME(INSN, gen_##INSN##_3s)
93
+
94
+DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
95
+DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
64
--- a/target/arm/tcg/cpu64.c
99
+++ b/target/arm/translate.c
65
+++ b/target/arm/tcg/cpu64.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
66
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
101
}
67
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
102
return 1;
68
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 3); /* FEAT_PAN3 */
103
69
t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
104
- case NEON_3R_VMUL: /* VMUL */
70
- t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 1); /* FEAT_ETS */
105
- if (u) {
71
+ t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 2); /* FEAT_ETS2 */
106
- /* Polynomial case allows only P8. */
72
t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1); /* FEAT_HCX */
107
- if (size != 0) {
73
t = FIELD_DP64(t, ID_AA64MMFR1, TIDCP1, 1); /* FEAT_TIDCP1 */
108
- return 1;
74
cpu->isar.id_aa64mmfr1 = t;
109
- }
110
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
111
- 0, gen_helper_gvec_pmul_b);
112
- } else {
113
- tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
114
- vec_size, vec_size);
115
- }
116
- return 0;
117
-
118
- case NEON_3R_VML: /* VMLA, VMLS */
119
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
120
- u ? &mls_op[size] : &mla_op[size]);
121
- return 0;
122
-
123
- case NEON_3R_VSHL:
124
- /* Note the operation is vshl vd,vm,vn */
125
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
126
- u ? &ushl_op[size] : &sshl_op[size]);
127
- return 0;
128
-
129
case NEON_3R_VADD_VSUB:
130
case NEON_3R_LOGIC:
131
case NEON_3R_VMAX:
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
133
case NEON_3R_VCGE:
134
case NEON_3R_VQADD:
135
case NEON_3R_VQSUB:
136
+ case NEON_3R_VMUL:
137
+ case NEON_3R_VML:
138
+ case NEON_3R_VSHL:
139
/* Already handled by decodetree */
140
return 1;
141
}
142
--
75
--
143
2.20.1
76
2.34.1
144
77
145
78
diff view generated by jsdifflib
1
We define ARMMMUIdx_Stage2 as being an MMU index which uses a QEMU
1
Newer versions of the Arm ARM (e.g. rev K.a) now define fields for
2
TLB. However we never actually use the TLB -- all stage 2 lookups
2
ID_AA64MMFR3_EL1. Implement this register, so that we can set the
3
are done by direct calls to get_phys_addr_lpae() followed by a
3
fields if we need to. There's no behaviour change here since we
4
physical address load via address_space_ld*().
4
don't currently set the register value to non-zero.
5
6
Remove Stage2 from the list of ARM MMU indexes which correspond to
7
real core MMU indexes, and instead put it in the set of "NOTLB" ARM
8
MMU indexes.
9
10
This allows us to drop NB_MMU_MODES to 11. It also means we can
11
safely add support for the ARMv8.3-TTS2UXN extension, which adds
12
permission bits to the stage 2 descriptors which define execute
13
permission separatel for EL0 and EL1; supporting that while keeping
14
Stage2 in a QEMU TLB would require us to use separate TLBs for
15
"Stage2 for an EL0 access" and "Stage2 for an EL1 access", which is a
16
lot of extra complication given we aren't even using the QEMU TLB.
17
18
In the process of updating the comment on our MMU index use,
19
fix a couple of other minor errors:
20
* NS EL2 EL2&0 was missing from the list in the comment
21
* some text hadn't been updated from when we bumped NB_MMU_MODES
22
above 8
23
5
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20200330210400.11724-2-peter.maydell@linaro.org
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20240418152004.2106516-5-peter.maydell@linaro.org
28
---
10
---
29
target/arm/cpu-param.h | 2 +-
11
target/arm/cpu.h | 17 +++++++++++++++++
30
target/arm/cpu.h | 21 +++++---
12
target/arm/helper.c | 6 ++++--
31
target/arm/helper.c | 112 ++++-------------------------------------
13
target/arm/hvf/hvf.c | 2 ++
32
3 files changed, 27 insertions(+), 108 deletions(-)
14
target/arm/kvm.c | 2 ++
15
4 files changed, 25 insertions(+), 2 deletions(-)
33
16
34
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu-param.h
37
+++ b/target/arm/cpu-param.h
38
@@ -XXX,XX +XXX,XX @@
39
# define TARGET_PAGE_BITS_MIN 10
40
#endif
41
42
-#define NB_MMU_MODES 12
43
+#define NB_MMU_MODES 11
44
45
#endif
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
47
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
49
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
50
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
21
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
51
* handling via the TLB. The only way to do a stage 1 translation without
22
uint64_t id_aa64mmfr0;
52
* the immediate stage 2 translation is via the ATS or AT system insns,
23
uint64_t id_aa64mmfr1;
53
* which can be slow-pathed and always do a page table walk.
24
uint64_t id_aa64mmfr2;
54
+ * The only use of stage 2 translations is either as part of an s1+2
25
+ uint64_t id_aa64mmfr3;
55
+ * lookup or when loading the descriptors during a stage 1 page table walk,
26
uint64_t id_aa64dfr0;
56
+ * and in both those cases we don't use the TLB.
27
uint64_t id_aa64dfr1;
57
* 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
28
uint64_t id_aa64zfr0;
58
* translation regimes, because they map reasonably well to each other
29
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64MMFR2, BBM, 52, 4)
59
* and they can't both be active at the same time.
30
FIELD(ID_AA64MMFR2, EVT, 56, 4)
60
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
31
FIELD(ID_AA64MMFR2, E0PD, 60, 4)
61
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
32
62
* NS EL1 EL1&0 stage 1+2 +PAN
33
+FIELD(ID_AA64MMFR3, TCRX, 0, 4)
63
* NS EL0 EL2&0
34
+FIELD(ID_AA64MMFR3, SCTLRX, 4, 4)
64
+ * NS EL2 EL2&0
35
+FIELD(ID_AA64MMFR3, S1PIE, 8, 4)
65
* NS EL2 EL2&0 +PAN
36
+FIELD(ID_AA64MMFR3, S2PIE, 12, 4)
66
* NS EL2 (aka NS PL2)
37
+FIELD(ID_AA64MMFR3, S1POE, 16, 4)
67
* S EL0 EL1&0 (aka S PL0)
38
+FIELD(ID_AA64MMFR3, S2POE, 20, 4)
68
* S EL1 EL1&0 (not used if EL3 is 32 bit)
39
+FIELD(ID_AA64MMFR3, AIE, 24, 4)
69
* S EL1 EL1&0 +PAN
40
+FIELD(ID_AA64MMFR3, MEC, 28, 4)
70
* S EL3 (aka S PL1)
41
+FIELD(ID_AA64MMFR3, D128, 32, 4)
71
- * NS EL1&0 stage 2
42
+FIELD(ID_AA64MMFR3, D128_2, 36, 4)
72
*
43
+FIELD(ID_AA64MMFR3, SNERR, 40, 4)
73
- * for a total of 12 different mmu_idx.
44
+FIELD(ID_AA64MMFR3, ANERR, 44, 4)
74
+ * for a total of 11 different mmu_idx.
45
+FIELD(ID_AA64MMFR3, SDERR, 52, 4)
75
*
46
+FIELD(ID_AA64MMFR3, ADERR, 56, 4)
76
* R profile CPUs have an MPU, but can use the same set of MMU indexes
47
+FIELD(ID_AA64MMFR3, SPEC_FPACC, 60, 4)
77
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
48
+
78
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
49
FIELD(ID_AA64DFR0, DEBUGVER, 0, 4)
79
* are not quite the same -- different CPU types (most notably M profile
50
FIELD(ID_AA64DFR0, TRACEVER, 4, 4)
80
* vs A/R profile) would like to use MMU indexes with different semantics,
51
FIELD(ID_AA64DFR0, PMUVER, 8, 4)
81
* but since we don't ever need to use all of those in a single CPU we
82
- * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
83
+ * can avoid having to set NB_MMU_MODES to "total number of A profile MMU
84
+ * modes + total number of M profile MMU modes". The lower bits of
85
* ARMMMUIdx are the core TLB mmu index, and the higher bits are always
86
* the same for any particular CPU.
87
* Variables of type ARMMUIdx are always full values, and the core
88
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
89
ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
90
ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
91
92
- ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A,
93
-
94
/*
95
* These are not allocated TLBs and are used only for AT system
96
* instructions or for the first stage of an S12 page table walk.
97
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
98
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
99
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
100
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
101
+ /*
102
+ * Not allocated a TLB: used only for second stage of an S12 page
103
+ * table walk, or for descriptor loads during first stage of an S1
104
+ * page table walk. Note that if we ever want to have a TLB for this
105
+ * then various TLB flush insns which currently are no-ops or flush
106
+ * only stage 1 MMU indexes will need to change to flush stage 2.
107
+ */
108
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
109
110
/*
111
* M-profile.
112
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
113
TO_CORE_BIT(SE10_1),
114
TO_CORE_BIT(SE10_1_PAN),
115
TO_CORE_BIT(SE3),
116
- TO_CORE_BIT(Stage2),
117
118
TO_CORE_BIT(MUser),
119
TO_CORE_BIT(MPriv),
120
diff --git a/target/arm/helper.c b/target/arm/helper.c
52
diff --git a/target/arm/helper.c b/target/arm/helper.c
121
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
122
--- a/target/arm/helper.c
54
--- a/target/arm/helper.c
123
+++ b/target/arm/helper.c
55
+++ b/target/arm/helper.c
124
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
56
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
125
tlb_flush_by_mmuidx(cs,
57
.access = PL1_R, .type = ARM_CP_CONST,
126
ARMMMUIdxBit_E10_1 |
58
.accessfn = access_aa64_tid3,
127
ARMMMUIdxBit_E10_1_PAN |
59
.resetvalue = cpu->isar.id_aa64mmfr2 },
128
- ARMMMUIdxBit_E10_0 |
60
- { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
129
- ARMMMUIdxBit_Stage2);
61
+ { .name = "ID_AA64MMFR3_EL1", .state = ARM_CP_STATE_AA64,
130
+ ARMMMUIdxBit_E10_0);
62
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
131
}
63
.access = PL1_R, .type = ARM_CP_CONST,
132
64
.accessfn = access_aa64_tid3,
133
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
65
- .resetvalue = 0 },
134
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
66
+ .resetvalue = cpu->isar.id_aa64mmfr3 },
135
tlb_flush_by_mmuidx_all_cpus_synced(cs,
67
{ .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
136
ARMMMUIdxBit_E10_1 |
68
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
137
ARMMMUIdxBit_E10_1_PAN |
69
.access = PL1_R, .type = ARM_CP_CONST,
138
- ARMMMUIdxBit_E10_0 |
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
139
- ARMMMUIdxBit_Stage2);
71
.exported_bits = R_ID_AA64MMFR1_AFP_MASK },
140
+ ARMMMUIdxBit_E10_0);
72
{ .name = "ID_AA64MMFR2_EL1",
141
}
73
.exported_bits = R_ID_AA64MMFR2_AT_MASK },
142
74
+ { .name = "ID_AA64MMFR3_EL1",
143
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
75
+ .exported_bits = 0 },
144
- uint64_t value)
76
{ .name = "ID_AA64MMFR*_EL1_RESERVED",
145
-{
77
.is_glob = true },
146
- /* Invalidate by IPA. This has to invalidate any structures that
78
{ .name = "ID_AA64DFR0_EL1",
147
- * contain only stage 2 translation information, but does not need
79
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
148
- * to apply to structures that contain combined stage 1 and stage 2
80
index XXXXXXX..XXXXXXX 100644
149
- * translation information.
81
--- a/target/arm/hvf/hvf.c
150
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
82
+++ b/target/arm/hvf/hvf.c
151
- */
83
@@ -XXX,XX +XXX,XX @@ static struct hvf_sreg_match hvf_sreg_match[] = {
152
- CPUState *cs = env_cpu(env);
84
#endif
153
- uint64_t pageaddr;
85
{ HV_SYS_REG_ID_AA64MMFR1_EL1, HVF_SYSREG(0, 7, 3, 0, 1) },
154
-
86
{ HV_SYS_REG_ID_AA64MMFR2_EL1, HVF_SYSREG(0, 7, 3, 0, 2) },
155
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
87
+ /* Add ID_AA64MMFR3_EL1 here when HVF supports it */
156
- return;
88
157
- }
89
{ HV_SYS_REG_MDSCR_EL1, HVF_SYSREG(0, 2, 2, 0, 2) },
158
-
90
{ HV_SYS_REG_SCTLR_EL1, HVF_SYSREG(1, 0, 3, 0, 0) },
159
- pageaddr = sextract64(value << 12, 0, 40);
91
@@ -XXX,XX +XXX,XX @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
160
-
92
{ HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.id_aa64mmfr0 },
161
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
93
{ HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.id_aa64mmfr1 },
162
-}
94
{ HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.id_aa64mmfr2 },
163
-
95
+ /* Add ID_AA64MMFR3_EL1 here when HVF supports it */
164
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
96
};
165
- uint64_t value)
97
hv_vcpu_t fd;
166
-{
98
hv_return_t r = HV_SUCCESS;
167
- CPUState *cs = env_cpu(env);
99
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
168
- uint64_t pageaddr;
100
index XXXXXXX..XXXXXXX 100644
169
-
101
--- a/target/arm/kvm.c
170
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
102
+++ b/target/arm/kvm.c
171
- return;
103
@@ -XXX,XX +XXX,XX @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
172
- }
104
ARM64_SYS_REG(3, 0, 0, 7, 1));
173
-
105
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2,
174
- pageaddr = sextract64(value << 12, 0, 40);
106
ARM64_SYS_REG(3, 0, 0, 7, 2));
175
-
107
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr3,
176
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
108
+ ARM64_SYS_REG(3, 0, 0, 7, 3));
177
- ARMMMUIdxBit_Stage2);
109
178
-}
110
/*
179
111
* Note that if AArch32 support is not present in the host,
180
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
uint64_t value)
182
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
tlb_flush_by_mmuidx(cs,
184
ARMMMUIdxBit_E10_1 |
185
ARMMMUIdxBit_E10_1_PAN |
186
- ARMMMUIdxBit_E10_0 |
187
- ARMMMUIdxBit_Stage2);
188
+ ARMMMUIdxBit_E10_0);
189
raw_write(env, ri, value);
190
}
191
}
192
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
193
return ARMMMUIdxBit_SE10_1 |
194
ARMMMUIdxBit_SE10_1_PAN |
195
ARMMMUIdxBit_SE10_0;
196
- } else if (arm_feature(env, ARM_FEATURE_EL2)) {
197
- return ARMMMUIdxBit_E10_1 |
198
- ARMMMUIdxBit_E10_1_PAN |
199
- ARMMMUIdxBit_E10_0 |
200
- ARMMMUIdxBit_Stage2;
201
} else {
202
return ARMMMUIdxBit_E10_1 |
203
ARMMMUIdxBit_E10_1_PAN |
204
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
205
ARMMMUIdxBit_SE3);
206
}
207
208
-static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
209
- uint64_t value)
210
-{
211
- /* Invalidate by IPA. This has to invalidate any structures that
212
- * contain only stage 2 translation information, but does not need
213
- * to apply to structures that contain combined stage 1 and stage 2
214
- * translation information.
215
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
216
- */
217
- ARMCPU *cpu = env_archcpu(env);
218
- CPUState *cs = CPU(cpu);
219
- uint64_t pageaddr;
220
-
221
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
222
- return;
223
- }
224
-
225
- pageaddr = sextract64(value << 12, 0, 48);
226
-
227
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
228
-}
229
-
230
-static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
231
- uint64_t value)
232
-{
233
- CPUState *cs = env_cpu(env);
234
- uint64_t pageaddr;
235
-
236
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
237
- return;
238
- }
239
-
240
- pageaddr = sextract64(value << 12, 0, 48);
241
-
242
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
243
- ARMMMUIdxBit_Stage2);
244
-}
245
-
246
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
247
bool isread)
248
{
249
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
250
.writefn = tlbi_aa64_vae1_write },
251
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
252
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
253
- .access = PL2_W, .type = ARM_CP_NO_RAW,
254
- .writefn = tlbi_aa64_ipas2e1is_write },
255
+ .access = PL2_W, .type = ARM_CP_NOP },
256
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
257
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
258
- .access = PL2_W, .type = ARM_CP_NO_RAW,
259
- .writefn = tlbi_aa64_ipas2e1is_write },
260
+ .access = PL2_W, .type = ARM_CP_NOP },
261
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
262
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
263
.access = PL2_W, .type = ARM_CP_NO_RAW,
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
265
.writefn = tlbi_aa64_alle1is_write },
266
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
267
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
268
- .access = PL2_W, .type = ARM_CP_NO_RAW,
269
- .writefn = tlbi_aa64_ipas2e1_write },
270
+ .access = PL2_W, .type = ARM_CP_NOP },
271
{ .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
272
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
273
- .access = PL2_W, .type = ARM_CP_NO_RAW,
274
- .writefn = tlbi_aa64_ipas2e1_write },
275
+ .access = PL2_W, .type = ARM_CP_NOP },
276
{ .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
277
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
278
.access = PL2_W, .type = ARM_CP_NO_RAW,
279
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
280
.writefn = tlbimva_hyp_is_write },
281
{ .name = "TLBIIPAS2",
282
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
283
- .type = ARM_CP_NO_RAW, .access = PL2_W,
284
- .writefn = tlbiipas2_write },
285
+ .type = ARM_CP_NOP, .access = PL2_W },
286
{ .name = "TLBIIPAS2IS",
287
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
288
- .type = ARM_CP_NO_RAW, .access = PL2_W,
289
- .writefn = tlbiipas2_is_write },
290
+ .type = ARM_CP_NOP, .access = PL2_W },
291
{ .name = "TLBIIPAS2L",
292
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
293
- .type = ARM_CP_NO_RAW, .access = PL2_W,
294
- .writefn = tlbiipas2_write },
295
+ .type = ARM_CP_NOP, .access = PL2_W },
296
{ .name = "TLBIIPAS2LIS",
297
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
298
- .type = ARM_CP_NO_RAW, .access = PL2_W,
299
- .writefn = tlbiipas2_is_write },
300
+ .type = ARM_CP_NOP, .access = PL2_W },
301
/* 32 bit cache operations */
302
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
303
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
304
--
112
--
305
2.20.1
113
2.34.1
306
114
307
115
diff view generated by jsdifflib
1
Convert the Neon VQADD/VQSUB insns in the 3-reg-same grouping
1
FEAT_Spec_FPACC is a feature describing speculative behaviour in the
2
to decodetree.
2
event of a PAC authontication failure when FEAT_FPACCOMBINE is
3
implemented. FEAT_Spec_FPACC means that the speculative use of
4
pointers processed by a PAC Authentication is not materially
5
different in terms of the impact on cached microarchitectural state
6
(caches, TLBs, etc) between passing and failing of the PAC
7
Authentication.
8
9
QEMU doesn't do speculative execution, so we can advertise
10
this feature.
3
11
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-19-peter.maydell@linaro.org
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Message-id: 20240418152004.2106516-6-peter.maydell@linaro.org
7
---
16
---
8
target/arm/neon-dp.decode | 6 ++++++
17
docs/system/arm/emulation.rst | 1 +
9
target/arm/translate-neon.inc.c | 15 +++++++++++++++
18
target/arm/tcg/cpu64.c | 4 ++++
10
target/arm/translate.c | 14 ++------------
19
2 files changed, 5 insertions(+)
11
3 files changed, 23 insertions(+), 12 deletions(-)
12
20
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
21
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
23
--- a/docs/system/arm/emulation.rst
16
+++ b/target/arm/neon-dp.decode
24
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
26
- FEAT_FP16 (Half-precision floating-point data processing)
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
- FEAT_FPAC (Faulting on AUT* instructions)
20
28
- FEAT_FPACCOMBINE (Faulting on combined pointer authentication instructions)
21
+VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
29
+- FEAT_FPACC_SPEC (Speculative behavior of combined pointer authentication instructions)
22
+VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
30
- FEAT_FRINTTS (Floating-point to integer instructions)
31
- FEAT_FlagM (Flag manipulation instructions v2)
32
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
33
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/tcg/cpu64.c
36
+++ b/target/arm/tcg/cpu64.c
37
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
38
t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */
39
cpu->isar.id_aa64mmfr2 = t;
40
41
+ t = cpu->isar.id_aa64mmfr3;
42
+ t = FIELD_DP64(t, ID_AA64MMFR3, SPEC_FPACC, 1); /* FEAT_FPACC_SPEC */
43
+ cpu->isar.id_aa64mmfr3 = t;
23
+
44
+
24
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
45
t = cpu->isar.id_aa64zfr0;
25
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
46
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
26
47
t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* FEAT_SVE_PMULL128 */
27
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
28
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
29
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
30
31
+VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
32
+VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
33
+
34
VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
35
VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
36
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
42
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
43
}
44
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
45
+
46
+#define DO_3SAME_GVEC4(INSN, OPARRAY) \
47
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
48
+ uint32_t rn_ofs, uint32_t rm_ofs, \
49
+ uint32_t oprsz, uint32_t maxsz) \
50
+ { \
51
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
52
+ rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
53
+ } \
54
+ DO_3SAME(INSN, gen_##INSN##_3s)
55
+
56
+DO_3SAME_GVEC4(VQADD_S, sqadd_op)
57
+DO_3SAME_GVEC4(VQADD_U, uqadd_op)
58
+DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
59
+DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate.c
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
65
}
66
return 1;
67
68
- case NEON_3R_VQADD:
69
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
70
- rn_ofs, rm_ofs, vec_size, vec_size,
71
- (u ? uqadd_op : sqadd_op) + size);
72
- return 0;
73
-
74
- case NEON_3R_VQSUB:
75
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
76
- rn_ofs, rm_ofs, vec_size, vec_size,
77
- (u ? uqsub_op : sqsub_op) + size);
78
- return 0;
79
-
80
case NEON_3R_VMUL: /* VMUL */
81
if (u) {
82
/* Polynomial case allows only P8. */
83
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
84
case NEON_3R_VTST_VCEQ:
85
case NEON_3R_VCGT:
86
case NEON_3R_VCGE:
87
+ case NEON_3R_VQADD:
88
+ case NEON_3R_VQSUB:
89
/* Already handled by decodetree */
90
return 1;
91
}
92
--
48
--
93
2.20.1
49
2.34.1
94
50
95
51
diff view generated by jsdifflib
1
Convert the Neon comparison ops in the 3-reg-same grouping
1
The Linux kernel 5.10.16 binary for sunxi has been removed from
2
to decodetree.
2
apt.armbian.com. This means that the avocado tests for these machines
3
will be skipped (status CANCEL) if the old binary isn't present in
4
the avocado cache.
3
5
6
Update to 6.6.16, in the same way we did in commit e384db41d8661
7
when we moved to 5.10.16 in 2021.
8
9
Cc: qemu-stable@nongnu.org
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2284
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
6
Message-id: 20200430181003.21682-18-peter.maydell@linaro.org
13
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
14
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
15
Message-id: 20240415151845.1564201-1-peter.maydell@linaro.org
7
---
16
---
8
target/arm/neon-dp.decode | 8 ++++++++
17
tests/avocado/boot_linux_console.py | 70 ++++++++++++++---------------
9
target/arm/translate-neon.inc.c | 22 ++++++++++++++++++++++
18
tests/avocado/replay_kernel.py | 8 ++--
10
target/arm/translate.c | 23 +++--------------------
19
2 files changed, 39 insertions(+), 39 deletions(-)
11
3 files changed, 33 insertions(+), 20 deletions(-)
12
20
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
21
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
23
--- a/tests/avocado/boot_linux_console.py
16
+++ b/target/arm/neon-dp.decode
24
+++ b/tests/avocado/boot_linux_console.py
17
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
25
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
18
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
26
:avocado: tags=accel:tcg
19
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
27
"""
20
28
deb_url = ('https://apt.armbian.com/pool/main/l/'
21
+VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
29
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
22
+VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
30
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
23
+VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
31
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
24
+VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
32
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
25
+
33
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
26
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
34
kernel_path = self.extract_from_deb(deb_path,
27
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
35
- '/boot/vmlinuz-5.10.16-sunxi')
28
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
36
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
29
@@ -XXX,XX +XXX,XX @@ VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
37
+ '/boot/vmlinuz-6.6.16-current-sunxi')
30
38
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
31
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
39
dtb_path = self.extract_from_deb(deb_path, dtb_path)
32
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
40
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
33
+
41
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
34
+VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
42
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_sata(self):
35
+VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
43
:avocado: tags=accel:tcg
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
44
"""
45
deb_url = ('https://apt.armbian.com/pool/main/l/'
46
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
47
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
48
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
49
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
50
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
51
kernel_path = self.extract_from_deb(deb_path,
52
- '/boot/vmlinuz-5.10.16-sunxi')
53
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
54
+ '/boot/vmlinuz-6.6.16-current-sunxi')
55
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
56
dtb_path = self.extract_from_deb(deb_path, dtb_path)
57
rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
58
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
59
@@ -XXX,XX +XXX,XX @@ def test_arm_bpim2u(self):
60
:avocado: tags=machine:bpim2u
61
:avocado: tags=accel:tcg
62
"""
63
- deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
64
- 'linux-image-current-sunxi_21.02.2_armhf.deb')
65
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
66
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
67
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
68
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
69
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
70
kernel_path = self.extract_from_deb(deb_path,
71
- '/boot/vmlinuz-5.10.16-sunxi')
72
- dtb_path = ('/usr/lib/linux-image-current-sunxi/'
73
+ '/boot/vmlinuz-6.6.16-current-sunxi')
74
+ dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
75
'sun8i-r40-bananapi-m2-ultra.dtb')
76
dtb_path = self.extract_from_deb(deb_path, dtb_path)
77
78
@@ -XXX,XX +XXX,XX @@ def test_arm_bpim2u_initrd(self):
79
:avocado: tags=accel:tcg
80
:avocado: tags=machine:bpim2u
81
"""
82
- deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
83
- 'linux-image-current-sunxi_21.02.2_armhf.deb')
84
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
85
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
86
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
87
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
88
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
89
kernel_path = self.extract_from_deb(deb_path,
90
- '/boot/vmlinuz-5.10.16-sunxi')
91
- dtb_path = ('/usr/lib/linux-image-current-sunxi/'
92
+ '/boot/vmlinuz-6.6.16-current-sunxi')
93
+ dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
94
'sun8i-r40-bananapi-m2-ultra.dtb')
95
dtb_path = self.extract_from_deb(deb_path, dtb_path)
96
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
97
@@ -XXX,XX +XXX,XX @@ def test_arm_bpim2u_gmac(self):
98
"""
99
self.require_netdev('user')
100
101
- deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
102
- 'linux-image-current-sunxi_21.02.2_armhf.deb')
103
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
104
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
105
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
106
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
107
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
108
kernel_path = self.extract_from_deb(deb_path,
109
- '/boot/vmlinuz-5.10.16-sunxi')
110
- dtb_path = ('/usr/lib/linux-image-current-sunxi/'
111
+ '/boot/vmlinuz-6.6.16-current-sunxi')
112
+ dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
113
'sun8i-r40-bananapi-m2-ultra.dtb')
114
dtb_path = self.extract_from_deb(deb_path, dtb_path)
115
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
116
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi(self):
117
:avocado: tags=accel:tcg
118
"""
119
deb_url = ('https://apt.armbian.com/pool/main/l/'
120
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
121
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
122
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
123
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
124
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
125
kernel_path = self.extract_from_deb(deb_path,
126
- '/boot/vmlinuz-5.10.16-sunxi')
127
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
128
+ '/boot/vmlinuz-6.6.16-current-sunxi')
129
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
130
dtb_path = self.extract_from_deb(deb_path, dtb_path)
131
132
self.vm.set_console()
133
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_initrd(self):
134
:avocado: tags=machine:orangepi-pc
135
"""
136
deb_url = ('https://apt.armbian.com/pool/main/l/'
137
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
138
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
139
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
140
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
141
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
142
kernel_path = self.extract_from_deb(deb_path,
143
- '/boot/vmlinuz-5.10.16-sunxi')
144
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
145
+ '/boot/vmlinuz-6.6.16-current-sunxi')
146
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
147
dtb_path = self.extract_from_deb(deb_path, dtb_path)
148
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
149
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
150
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
151
self.require_netdev('user')
152
153
deb_url = ('https://apt.armbian.com/pool/main/l/'
154
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
155
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
156
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
157
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
158
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
159
kernel_path = self.extract_from_deb(deb_path,
160
- '/boot/vmlinuz-5.10.16-sunxi')
161
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
162
+ '/boot/vmlinuz-6.6.16-current-sunxi')
163
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
164
dtb_path = self.extract_from_deb(deb_path, dtb_path)
165
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
166
'buildroot-baseline/20221116.0/armel/rootfs.ext2.xz')
167
diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py
37
index XXXXXXX..XXXXXXX 100644
168
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
169
--- a/tests/avocado/replay_kernel.py
39
+++ b/target/arm/translate-neon.inc.c
170
+++ b/tests/avocado/replay_kernel.py
40
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
171
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
41
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
172
:avocado: tags=machine:cubieboard
42
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
173
"""
43
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
174
deb_url = ('https://apt.armbian.com/pool/main/l/'
44
+
175
- 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
45
+#define DO_3SAME_CMP(INSN, COND) \
176
- deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
46
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
177
+ 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
47
+ uint32_t rn_ofs, uint32_t rm_ofs, \
178
+ deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
48
+ uint32_t oprsz, uint32_t maxsz) \
179
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
49
+ { \
180
kernel_path = self.extract_from_deb(deb_path,
50
+ tcg_gen_gvec_cmp(COND, vece, rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz); \
181
- '/boot/vmlinuz-5.10.16-sunxi')
51
+ } \
182
- dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
52
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
183
+ '/boot/vmlinuz-6.6.16-current-sunxi')
53
+
184
+ dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
54
+DO_3SAME_CMP(VCGT_S, TCG_COND_GT)
185
dtb_path = self.extract_from_deb(deb_path, dtb_path)
55
+DO_3SAME_CMP(VCGT_U, TCG_COND_GTU)
186
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
56
+DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
187
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
57
+DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
58
+DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
59
+
60
+static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
61
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
62
+{
63
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
64
+}
65
+DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
u ? &mls_op[size] : &mla_op[size]);
72
return 0;
73
74
- case NEON_3R_VTST_VCEQ:
75
- if (u) { /* VCEQ */
76
- tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
77
- vec_size, vec_size);
78
- } else { /* VTST */
79
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
80
- vec_size, vec_size, &cmtst_op[size]);
81
- }
82
- return 0;
83
-
84
- case NEON_3R_VCGT:
85
- tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
86
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
87
- return 0;
88
-
89
- case NEON_3R_VCGE:
90
- tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
91
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
92
- return 0;
93
-
94
case NEON_3R_VSHL:
95
/* Note the operation is vshl vd,vm,vn */
96
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
case NEON_3R_LOGIC:
99
case NEON_3R_VMAX:
100
case NEON_3R_VMIN:
101
+ case NEON_3R_VTST_VCEQ:
102
+ case NEON_3R_VCGT:
103
+ case NEON_3R_VCGE:
104
/* Already handled by decodetree */
105
return 1;
106
}
107
--
188
--
108
2.20.1
189
2.34.1
109
110
diff view generated by jsdifflib
1
For ARMv8.2-TTS2UXN, the stage 2 page table walk wants to know
1
The generic timer frequency is settable by board code via a QOM
2
whether the stage 1 access is for EL0 or not, because whether
2
property "cntfrq", but otherwise defaults to 62.5MHz. The way this
3
exec permission is given can depend on whether this is an EL0
3
is done includes some complication resulting from how this was
4
or EL1 access. Add a new argument to get_phys_addr_lpae() so
4
originally a fixed value with no QOM property. Clean it up:
5
the call sites can pass this information in.
6
5
7
Since get_phys_addr_lpae() doesn't already have a doc comment,
6
* always set cpu->gt_cntfrq_hz to some sensible value, whether
8
add one so we have a place to put the documentation of the
7
the CPU has the generic timer or not, and whether it's system
9
semantics of the new s1_is_el0 argument.
8
or user-only emulation
9
* this means we can always use gt_cntfrq_hz, and never need
10
the old GTIMER_SCALE define
11
* set the default value in exactly one place, in the realize fn
12
13
The aim here is to pave the way for handling the ARMv8.6 requirement
14
that the generic timer frequency is always 1GHz. We're going to do
15
that by having old CPU types keep their legacy-in-QEMU behaviour and
16
having the default for any new CPU types be a 1GHz rather han 62.5MHz
17
cntfrq, so we want the point where the default is decided to be in
18
one place, and in code, not in a DEFINE_PROP_UINT64() initializer.
19
20
This commit should have no behavioural changes.
10
21
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200330210400.11724-4-peter.maydell@linaro.org
25
Message-id: 20240426122913.3427983-2-peter.maydell@linaro.org
15
---
26
---
16
target/arm/helper.c | 29 ++++++++++++++++++++++++++++-
27
target/arm/internals.h | 7 ++++---
17
1 file changed, 28 insertions(+), 1 deletion(-)
28
target/arm/cpu.c | 31 +++++++++++++++++--------------
29
target/arm/helper.c | 16 ++++++++--------
30
3 files changed, 29 insertions(+), 25 deletions(-)
18
31
32
diff --git a/target/arm/internals.h b/target/arm/internals.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/internals.h
35
+++ b/target/arm/internals.h
36
@@ -XXX,XX +XXX,XX @@ static inline bool excp_is_internal(int excp)
37
|| excp == EXCP_SEMIHOST;
38
}
39
40
-/* Scale factor for generic timers, ie number of ns per tick.
41
- * This gives a 62.5MHz timer.
42
+/*
43
+ * Default frequency for the generic timer, in Hz.
44
+ * This is 62.5MHz, which gives a 16 ns tick period.
45
*/
46
-#define GTIMER_SCALE 16
47
+#define GTIMER_DEFAULT_HZ 62500000
48
49
/* Bit definitions for the v7M CONTROL register */
50
FIELD(V7M_CONTROL, NPRIV, 0, 1)
51
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/cpu.c
54
+++ b/target/arm/cpu.c
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
56
}
57
}
58
59
+/*
60
+ * 0 means "unset, use the default value". That default might vary depending
61
+ * on the CPU type, and is set in the realize fn.
62
+ */
63
static Property arm_cpu_gt_cntfrq_property =
64
- DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq_hz,
65
- NANOSECONDS_PER_SECOND / GTIMER_SCALE);
66
+ DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq_hz, 0);
67
68
static Property arm_cpu_reset_cbar_property =
69
DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
70
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
71
return;
72
}
73
74
+ if (!cpu->gt_cntfrq_hz) {
75
+ /*
76
+ * 0 means "the board didn't set a value, use the default".
77
+ * The default value of the generic timer frequency (as seen in
78
+ * CNTFRQ_EL0) is 62.5MHz, which corresponds to a period of 16ns.
79
+ * This is what you get (a) for a CONFIG_USER_ONLY CPU (b) if the
80
+ * board doesn't set it.
81
+ */
82
+ cpu->gt_cntfrq_hz = GTIMER_DEFAULT_HZ;
83
+ }
84
+
85
#ifndef CONFIG_USER_ONLY
86
/* The NVIC and M-profile CPU are two halves of a single piece of
87
* hardware; trying to use one without the other is a command line
88
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
89
}
90
91
{
92
- uint64_t scale;
93
-
94
- if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
95
- if (!cpu->gt_cntfrq_hz) {
96
- error_setg(errp, "Invalid CNTFRQ: %"PRId64"Hz",
97
- cpu->gt_cntfrq_hz);
98
- return;
99
- }
100
- scale = gt_cntfrq_period_ns(cpu);
101
- } else {
102
- scale = GTIMER_SCALE;
103
- }
104
+ uint64_t scale = gt_cntfrq_period_ns(cpu);
105
106
cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
107
arm_gt_ptimer_cb, cpu);
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
108
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
109
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
110
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
111
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@
112
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
24
113
.resetvalue = 0 },
25
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
114
};
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
115
27
+ bool s1_is_el0,
116
+static void arm_gt_cntfrq_reset(CPUARMState *env, const ARMCPRegInfo *opaque)
28
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
117
+{
29
target_ulong *page_size_ptr,
118
+ ARMCPU *cpu = env_archcpu(env);
30
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
119
+
31
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
120
+ cpu->env.cp15.c14_cntfrq = cpu->gt_cntfrq_hz;
32
}
121
+}
33
122
+
34
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
123
#ifndef CONFIG_USER_ONLY
35
+ false,
124
36
&s2pa, &txattrs, &s2prot, &s2size, fi,
125
static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri,
37
pcacheattrs);
126
@@ -XXX,XX +XXX,XX @@ void arm_gt_hvtimer_cb(void *opaque)
38
if (ret) {
127
gt_recalc_timer(cpu, GTIMER_HYPVIRT);
39
@@ -XXX,XX +XXX,XX @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
40
};
41
}
128
}
42
129
43
+/**
130
-static void arm_gt_cntfrq_reset(CPUARMState *env, const ARMCPRegInfo *opaque)
44
+ * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
131
-{
45
+ *
132
- ARMCPU *cpu = env_archcpu(env);
46
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
133
-
47
+ * prot and page_size may not be filled in, and the populated fsr value provides
134
- cpu->env.cp15.c14_cntfrq = cpu->gt_cntfrq_hz;
48
+ * information on why the translation aborted, in the format of a long-format
135
-}
49
+ * DFSR/IFSR fault register, with the following caveats:
136
-
50
+ * * the WnR bit is never set (the caller must do this).
137
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
51
+ *
138
/*
52
+ * @env: CPUARMState
139
* Note that CNTFRQ is purely reads-as-written for the benefit
53
+ * @address: virtual address to get physical address for
140
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
54
+ * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
141
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
55
+ * @mmu_idx: MMU index indicating required translation regime
142
.type = ARM_CP_CONST, .access = PL0_R /* no PL1_RW in linux-user */,
56
+ * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page table
143
.fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
57
+ * walk), must be true if this is stage 2 of a stage 1+2 walk for an
144
- .resetvalue = NANOSECONDS_PER_SECOND / GTIMER_SCALE,
58
+ * EL0 access). If @mmu_idx is anything else, @s1_is_el0 is ignored.
145
+ .resetfn = arm_gt_cntfrq_reset,
59
+ * @phys_ptr: set to the physical address corresponding to the virtual address
146
},
60
+ * @attrs: set to the memory transaction attributes to use
147
{ .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
61
+ * @prot: set to the permissions for the page containing phys_ptr
148
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
62
+ * @page_size_ptr: set to the size of the page containing phys_ptr
63
+ * @fi: set to fault info if the translation fails
64
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
65
+ */
66
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
67
MMUAccessType access_type, ARMMMUIdx mmu_idx,
68
+ bool s1_is_el0,
69
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
70
target_ulong *page_size_ptr,
71
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
73
74
/* S1 is done. Now do S2 translation. */
75
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
76
+ mmu_idx == ARMMMUIdx_E10_0,
77
phys_ptr, attrs, &s2_prot,
78
page_size, fi,
79
cacheattrs != NULL ? &cacheattrs2 : NULL);
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
81
}
82
83
if (regime_using_lpae_format(env, mmu_idx)) {
84
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
85
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
86
phys_ptr, attrs, prot, page_size,
87
fi, cacheattrs);
88
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
89
--
149
--
90
2.20.1
150
2.34.1
91
151
92
152
diff view generated by jsdifflib
1
The access_type argument to get_phys_addr_lpae() is an MMUAccessType;
1
Currently QEMU CPUs always run with a generic timer counter frequency
2
use the enum constant MMU_DATA_LOAD rather than a literal 0 when we
2
of 62.5MHz, but ARMv8.6 CPUs will run at 1GHz. For older versions of
3
call it in S1_ptw_translate().
3
the TF-A firmware that sbsa-ref runs, the frequency of the generic
4
timer is hardcoded into the firmware, and so if the CPU actually has
5
a different frequency then timers in the guest will be set
6
incorrectly.
7
8
The default frequency used by the 'max' CPU is about to change, so
9
make the sbsa-ref board force the CPU frequency to the value which
10
the firmware expects.
11
12
Newer versions of TF-A will read the frequency from the CPU's
13
CNTFRQ_EL0 register:
14
https://github.com/ARM-software/arm-trusted-firmware/commit/4c77fac98dac0bebc63798aae9101ac865b87148
15
so in the longer term we could make this board use the 1GHz
16
frequency. We will need to make sure we update the binaries used
17
by our avocado test
18
Aarch64SbsarefMachine.test_sbsaref_alpine_linux_max_pauth_impdef
19
before we can do that.
4
20
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Reviewed-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
8
Message-id: 20200330210400.11724-3-peter.maydell@linaro.org
24
Message-id: 20240426122913.3427983-3-peter.maydell@linaro.org
9
---
25
---
10
target/arm/helper.c | 5 +++--
26
hw/arm/sbsa-ref.c | 15 +++++++++++++++
11
1 file changed, 3 insertions(+), 2 deletions(-)
27
1 file changed, 15 insertions(+)
12
28
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
14
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
31
--- a/hw/arm/sbsa-ref.c
16
+++ b/target/arm/helper.c
32
+++ b/hw/arm/sbsa-ref.c
17
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
33
@@ -XXX,XX +XXX,XX @@
18
pcacheattrs = &cacheattrs;
34
#define NUM_SMMU_IRQS 4
35
#define NUM_SATA_PORTS 6
36
37
+/*
38
+ * Generic timer frequency in Hz (which drives both the CPU generic timers
39
+ * and the SBSA watchdog-timer). Older versions of the TF-A firmware
40
+ * typically used with sbsa-ref (including the binaries in our Avocado test
41
+ * Aarch64SbsarefMachine.test_sbsaref_alpine_linux_max_pauth_impdef
42
+ * assume it is this value.
43
+ *
44
+ * TODO: this value is not architecturally correct for an Armv8.6 or
45
+ * better CPU, so we should move to 1GHz once the TF-A fix above has
46
+ * made it into a release and into our Avocado test.
47
+ */
48
+#define SBSA_GTIMER_HZ 62500000
49
+
50
enum {
51
SBSA_FLASH,
52
SBSA_MEM,
53
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
54
&error_abort);
19
}
55
}
20
56
21
- ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_Stage2, &s2pa,
57
+ object_property_set_int(cpuobj, "cntfrq", SBSA_GTIMER_HZ, &error_abort);
22
- &txattrs, &s2prot, &s2size, fi, pcacheattrs);
58
+
23
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
59
object_property_set_link(cpuobj, "memory", OBJECT(sysmem),
24
+ &s2pa, &txattrs, &s2prot, &s2size, fi,
60
&error_abort);
25
+ pcacheattrs);
61
26
if (ret) {
27
assert(fi->type != ARMFault_None);
28
fi->s2addr = addr;
29
--
62
--
30
2.20.1
63
2.34.1
31
64
32
65
diff view generated by jsdifflib
1
Convert the Neon "load/store multiple structures" insns to decodetree.
1
Currently the sbsa_gdwt watchdog device hardcodes its frequency at
2
62.5MHz. In real hardware, this watchdog is supposed to be driven
3
from the system counter, which also drives the CPU generic timers.
4
Newer CPU types (in particular from Armv8.6) should have a CPU
5
generic timer frequency of 1GHz, so we can't leave the watchdog
6
on the old QEMU default of 62.5GHz.
7
8
Make the frequency a QOM property so it can be set by the board,
9
and have our only board that uses this device set that frequency
10
to the same value it sets the CPU frequency.
2
11
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20200430181003.21682-12-peter.maydell@linaro.org
14
Message-id: 20240426122913.3427983-4-peter.maydell@linaro.org
6
---
15
---
7
target/arm/neon-ls.decode | 7 ++
16
include/hw/watchdog/sbsa_gwdt.h | 3 +--
8
target/arm/translate-neon.inc.c | 124 ++++++++++++++++++++++++++++++++
17
hw/arm/sbsa-ref.c | 1 +
9
target/arm/translate.c | 91 +----------------------
18
hw/watchdog/sbsa_gwdt.c | 15 ++++++++++++++-
10
3 files changed, 133 insertions(+), 89 deletions(-)
19
3 files changed, 16 insertions(+), 3 deletions(-)
11
20
12
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
21
diff --git a/include/hw/watchdog/sbsa_gwdt.h b/include/hw/watchdog/sbsa_gwdt.h
13
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-ls.decode
23
--- a/include/hw/watchdog/sbsa_gwdt.h
15
+++ b/target/arm/neon-ls.decode
24
+++ b/include/hw/watchdog/sbsa_gwdt.h
16
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
17
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
26
#define SBSA_GWDT_RMMIO_SIZE 0x1000
18
# This file works on the A32 encoding only; calling code for T32 has to
27
#define SBSA_GWDT_CMMIO_SIZE 0x1000
19
# transform the insn into the A32 version first.
28
20
+
29
-#define SBSA_TIMER_FREQ 62500000 /* Hz */
21
+%vd_dp 22:1 12:4
30
-
22
+
31
typedef struct SBSA_GWDTState {
23
+# Neon load/store multiple structures
32
/* <private> */
24
+
33
SysBusDevice parent_obj;
25
+VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
34
@@ -XXX,XX +XXX,XX @@ typedef struct SBSA_GWDTState {
26
+ vd=%vd_dp
35
qemu_irq irq;
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
37
QEMUTimer *timer;
38
+ uint64_t freq;
39
40
uint32_t id;
41
uint32_t wcs;
42
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
28
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
44
--- a/hw/arm/sbsa-ref.c
30
+++ b/target/arm/translate-neon.inc.c
45
+++ b/hw/arm/sbsa-ref.c
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
46
@@ -XXX,XX +XXX,XX @@ static void create_wdt(const SBSAMachineState *sms)
32
gen_helper_gvec_fmlal_idx_a32);
47
SysBusDevice *s = SYS_BUS_DEVICE(dev);
33
return true;
48
int irq = sbsa_ref_irqmap[SBSA_GWDT_WS0];
49
50
+ qdev_prop_set_uint64(dev, "clock-frequency", SBSA_GTIMER_HZ);
51
sysbus_realize_and_unref(s, &error_fatal);
52
sysbus_mmio_map(s, 0, rbase);
53
sysbus_mmio_map(s, 1, cbase);
54
diff --git a/hw/watchdog/sbsa_gwdt.c b/hw/watchdog/sbsa_gwdt.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/watchdog/sbsa_gwdt.c
57
+++ b/hw/watchdog/sbsa_gwdt.c
58
@@ -XXX,XX +XXX,XX @@
59
#include "qemu/osdep.h"
60
#include "sysemu/reset.h"
61
#include "sysemu/watchdog.h"
62
+#include "hw/qdev-properties.h"
63
#include "hw/watchdog/sbsa_gwdt.h"
64
#include "qemu/timer.h"
65
#include "migration/vmstate.h"
66
@@ -XXX,XX +XXX,XX @@ static void sbsa_gwdt_update_timer(SBSA_GWDTState *s, WdtRefreshType rtype)
67
timeout = s->woru;
68
timeout <<= 32;
69
timeout |= s->worl;
70
- timeout = muldiv64(timeout, NANOSECONDS_PER_SECOND, SBSA_TIMER_FREQ);
71
+ timeout = muldiv64(timeout, NANOSECONDS_PER_SECOND, s->freq);
72
timeout += qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
73
74
if ((rtype == EXPLICIT_REFRESH) || ((rtype == TIMEOUT_REFRESH) &&
75
@@ -XXX,XX +XXX,XX @@ static void wdt_sbsa_gwdt_realize(DeviceState *dev, Error **errp)
76
dev);
34
}
77
}
35
+
78
36
+static struct {
79
+static Property wdt_sbsa_gwdt_props[] = {
37
+ int nregs;
80
+ /*
38
+ int interleave;
81
+ * Timer frequency in Hz. This must match the frequency used by
39
+ int spacing;
82
+ * the CPU's generic timer. Default 62.5Hz matches QEMU's legacy
40
+} const neon_ls_element_type[11] = {
83
+ * CPU timer frequency default.
41
+ {1, 4, 1},
84
+ */
42
+ {1, 4, 2},
85
+ DEFINE_PROP_UINT64("clock-frequency", struct SBSA_GWDTState, freq,
43
+ {4, 1, 1},
86
+ 62500000),
44
+ {2, 2, 2},
87
+ DEFINE_PROP_END_OF_LIST(),
45
+ {1, 3, 1},
46
+ {1, 3, 2},
47
+ {3, 1, 1},
48
+ {1, 1, 1},
49
+ {1, 2, 1},
50
+ {1, 2, 2},
51
+ {2, 1, 1}
52
+};
88
+};
53
+
89
+
54
+static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
90
static void wdt_sbsa_gwdt_class_init(ObjectClass *klass, void *data)
55
+ int stride)
91
{
56
+{
92
DeviceClass *dc = DEVICE_CLASS(klass);
57
+ if (rm != 15) {
93
@@ -XXX,XX +XXX,XX @@ static void wdt_sbsa_gwdt_class_init(ObjectClass *klass, void *data)
58
+ TCGv_i32 base;
94
set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
59
+
95
dc->vmsd = &vmstate_sbsa_gwdt;
60
+ base = load_reg(s, rn);
96
dc->desc = "SBSA-compliant generic watchdog device";
61
+ if (rm == 13) {
97
+ device_class_set_props(dc, wdt_sbsa_gwdt_props);
62
+ tcg_gen_addi_i32(base, base, stride);
63
+ } else {
64
+ TCGv_i32 index;
65
+ index = load_reg(s, rm);
66
+ tcg_gen_add_i32(base, base, index);
67
+ tcg_temp_free_i32(index);
68
+ }
69
+ store_reg(s, rn, base);
70
+ }
71
+}
72
+
73
+static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
74
+{
75
+ /* Neon load/store multiple structures */
76
+ int nregs, interleave, spacing, reg, n;
77
+ MemOp endian = s->be_data;
78
+ int mmu_idx = get_mem_index(s);
79
+ int size = a->size;
80
+ TCGv_i64 tmp64;
81
+ TCGv_i32 addr, tmp;
82
+
83
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
84
+ return false;
85
+ }
86
+
87
+ /* UNDEF accesses to D16-D31 if they don't exist */
88
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
89
+ return false;
90
+ }
91
+ if (a->itype > 10) {
92
+ return false;
93
+ }
94
+ /* Catch UNDEF cases for bad values of align field */
95
+ switch (a->itype & 0xc) {
96
+ case 4:
97
+ if (a->align >= 2) {
98
+ return false;
99
+ }
100
+ break;
101
+ case 8:
102
+ if (a->align == 3) {
103
+ return false;
104
+ }
105
+ break;
106
+ default:
107
+ break;
108
+ }
109
+ nregs = neon_ls_element_type[a->itype].nregs;
110
+ interleave = neon_ls_element_type[a->itype].interleave;
111
+ spacing = neon_ls_element_type[a->itype].spacing;
112
+ if (size == 3 && (interleave | spacing) != 1) {
113
+ return false;
114
+ }
115
+
116
+ if (!vfp_access_check(s)) {
117
+ return true;
118
+ }
119
+
120
+ /* For our purposes, bytes are always little-endian. */
121
+ if (size == 0) {
122
+ endian = MO_LE;
123
+ }
124
+ /*
125
+ * Consecutive little-endian elements from a single register
126
+ * can be promoted to a larger little-endian operation.
127
+ */
128
+ if (interleave == 1 && endian == MO_LE) {
129
+ size = 3;
130
+ }
131
+ tmp64 = tcg_temp_new_i64();
132
+ addr = tcg_temp_new_i32();
133
+ tmp = tcg_const_i32(1 << size);
134
+ load_reg_var(s, addr, a->rn);
135
+ for (reg = 0; reg < nregs; reg++) {
136
+ for (n = 0; n < 8 >> size; n++) {
137
+ int xs;
138
+ for (xs = 0; xs < interleave; xs++) {
139
+ int tt = a->vd + reg + spacing * xs;
140
+
141
+ if (a->l) {
142
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
143
+ neon_store_element64(tt, n, size, tmp64);
144
+ } else {
145
+ neon_load_element64(tmp64, tt, n, size);
146
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
147
+ }
148
+ tcg_gen_add_i32(addr, addr, tmp);
149
+ }
150
+ }
151
+ }
152
+ tcg_temp_free_i32(addr);
153
+ tcg_temp_free_i32(tmp);
154
+ tcg_temp_free_i64(tmp64);
155
+
156
+ gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
157
+ return true;
158
+}
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate.c
162
+++ b/target/arm/translate.c
163
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
164
}
98
}
165
99
166
100
static const TypeInfo wdt_sbsa_gwdt_info = {
167
-static struct {
168
- int nregs;
169
- int interleave;
170
- int spacing;
171
-} const neon_ls_element_type[11] = {
172
- {1, 4, 1},
173
- {1, 4, 2},
174
- {4, 1, 1},
175
- {2, 2, 2},
176
- {1, 3, 1},
177
- {1, 3, 2},
178
- {3, 1, 1},
179
- {1, 1, 1},
180
- {1, 2, 1},
181
- {1, 2, 2},
182
- {2, 1, 1}
183
-};
184
-
185
/* Translate a NEON load/store element instruction. Return nonzero if the
186
instruction is invalid. */
187
static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
188
{
189
int rd, rn, rm;
190
- int op;
191
int nregs;
192
- int interleave;
193
- int spacing;
194
int stride;
195
int size;
196
int reg;
197
int load;
198
- int n;
199
int vec_size;
200
- int mmu_idx;
201
- MemOp endian;
202
TCGv_i32 addr;
203
TCGv_i32 tmp;
204
- TCGv_i32 tmp2;
205
- TCGv_i64 tmp64;
206
207
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
208
return 1;
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
210
rn = (insn >> 16) & 0xf;
211
rm = insn & 0xf;
212
load = (insn & (1 << 21)) != 0;
213
- endian = s->be_data;
214
- mmu_idx = get_mem_index(s);
215
if ((insn & (1 << 23)) == 0) {
216
- /* Load store all elements. */
217
- op = (insn >> 8) & 0xf;
218
- size = (insn >> 6) & 3;
219
- if (op > 10)
220
- return 1;
221
- /* Catch UNDEF cases for bad values of align field */
222
- switch (op & 0xc) {
223
- case 4:
224
- if (((insn >> 5) & 1) == 1) {
225
- return 1;
226
- }
227
- break;
228
- case 8:
229
- if (((insn >> 4) & 3) == 3) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- break;
235
- }
236
- nregs = neon_ls_element_type[op].nregs;
237
- interleave = neon_ls_element_type[op].interleave;
238
- spacing = neon_ls_element_type[op].spacing;
239
- if (size == 3 && (interleave | spacing) != 1) {
240
- return 1;
241
- }
242
- /* For our purposes, bytes are always little-endian. */
243
- if (size == 0) {
244
- endian = MO_LE;
245
- }
246
- /* Consecutive little-endian elements from a single register
247
- * can be promoted to a larger little-endian operation.
248
- */
249
- if (interleave == 1 && endian == MO_LE) {
250
- size = 3;
251
- }
252
- tmp64 = tcg_temp_new_i64();
253
- addr = tcg_temp_new_i32();
254
- tmp2 = tcg_const_i32(1 << size);
255
- load_reg_var(s, addr, rn);
256
- for (reg = 0; reg < nregs; reg++) {
257
- for (n = 0; n < 8 >> size; n++) {
258
- int xs;
259
- for (xs = 0; xs < interleave; xs++) {
260
- int tt = rd + reg + spacing * xs;
261
-
262
- if (load) {
263
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
264
- neon_store_element64(tt, n, size, tmp64);
265
- } else {
266
- neon_load_element64(tmp64, tt, n, size);
267
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
268
- }
269
- tcg_gen_add_i32(addr, addr, tmp2);
270
- }
271
- }
272
- }
273
- tcg_temp_free_i32(addr);
274
- tcg_temp_free_i32(tmp2);
275
- tcg_temp_free_i64(tmp64);
276
- stride = nregs * interleave * 8;
277
+ /* Load store all elements -- handled already by decodetree */
278
+ return 1;
279
} else {
280
size = (insn >> 10) & 3;
281
if (size == 3) {
282
--
101
--
283
2.20.1
102
2.34.1
284
103
285
104
diff view generated by jsdifflib
1
The ARMv8.2-TTS2UXN feature extends the XN field in stage 2
1
In previous versions of the Arm architecture, the frequency of the
2
translation table descriptors from just bit [54] to bits [54:53],
2
generic timers as reported in CNTFRQ_EL0 could be any IMPDEF value,
3
allowing stage 2 to control execution permissions separately for EL0
3
and for QEMU we picked 62.5MHz, giving a timer tick period of 16ns.
4
and EL1. Implement the new semantics of the XN field and enable
4
In Armv8.6, the architecture standardized this frequency to 1GHz.
5
the feature for our 'max' CPU.
5
6
Because there is no ID register feature field that indicates whether
7
a CPU is v8.6 or that it ought to have this counter frequency, we
8
implement this by changing our default CNTFRQ value for all CPUs,
9
with exceptions for backwards compatibility:
10
11
* CPU types which we already implement will retain the old
12
default value. None of these are v8.6 CPUs, so this is
13
architecturally OK.
14
* CPUs used in versioned machine types with a version of 9.0
15
or earlier will retain the old default value.
16
17
The upshot is that the only CPU type that changes is 'max'; but any
18
new type we add in future (whether v8.6 or not) will also get the new
19
1GHz default.
20
21
It remains the case that the machine model can override the default
22
value via the 'cntfrq' QOM property (regardless of the CPU type).
6
23
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200330210400.11724-5-peter.maydell@linaro.org
26
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
27
Message-id: 20240426122913.3427983-5-peter.maydell@linaro.org
11
---
28
---
12
target/arm/cpu.h | 15 +++++++++++++++
29
target/arm/cpu.h | 11 +++++++++++
13
target/arm/cpu.c | 1 +
30
target/arm/internals.h | 12 ++++++++++--
14
target/arm/cpu64.c | 2 ++
31
hw/core/machine.c | 4 +++-
15
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++------
32
target/arm/cpu.c | 23 +++++++++++++++++------
16
4 files changed, 49 insertions(+), 6 deletions(-)
33
target/arm/cpu64.c | 2 ++
34
target/arm/tcg/cpu32.c | 4 ++++
35
target/arm/tcg/cpu64.c | 18 ++++++++++++++++++
36
7 files changed, 65 insertions(+), 9 deletions(-)
17
37
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
38
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
40
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
41
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
42
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
23
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
43
*/
24
}
44
bool host_cpu_probe_failed;
25
45
26
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
46
+ /* QOM property to indicate we should use the back-compat CNTFRQ default */
27
+{
47
+ bool backcompat_cntfrq;
28
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
29
+}
30
+
48
+
49
/* Specify the number of cores in this CPU cluster. Used for the L2CTLR
50
* register.
51
*/
52
@@ -XXX,XX +XXX,XX @@ enum arm_features {
53
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
54
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
55
ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
56
+ /*
57
+ * ARM_FEATURE_BACKCOMPAT_CNTFRQ makes the CPU default cntfrq be 62.5MHz
58
+ * if the board doesn't set a value, instead of 1GHz. It is for backwards
59
+ * compatibility and used only with CPU definitions that were already
60
+ * in QEMU before we changed the default. It should not be set on any
61
+ * CPU types added in future.
62
+ */
63
+ ARM_FEATURE_BACKCOMPAT_CNTFRQ, /* 62.5MHz timer default */
64
};
65
66
static inline int arm_feature(CPUARMState *env, int feature)
67
diff --git a/target/arm/internals.h b/target/arm/internals.h
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/internals.h
70
+++ b/target/arm/internals.h
71
@@ -XXX,XX +XXX,XX @@ static inline bool excp_is_internal(int excp)
72
31
/*
73
/*
32
* 64-bit feature tests via id registers.
74
* Default frequency for the generic timer, in Hz.
75
- * This is 62.5MHz, which gives a 16 ns tick period.
76
+ * ARMv8.6 and later CPUs architecturally must use a 1GHz timer; before
77
+ * that it was an IMPDEF choice, and QEMU initially picked 62.5MHz,
78
+ * which gives a 16ns tick period.
79
+ *
80
+ * We will use the back-compat value:
81
+ * - for QEMU CPU types added before we standardized on 1GHz
82
+ * - for versioned machine types with a version of 9.0 or earlier
83
+ * In any case, the machine model may override via the cntfrq property.
33
*/
84
*/
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
85
-#define GTIMER_DEFAULT_HZ 62500000
35
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
86
+#define GTIMER_DEFAULT_HZ 1000000000
36
}
87
+#define GTIMER_BACKCOMPAT_HZ 62500000
37
88
38
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
89
/* Bit definitions for the v7M CONTROL register */
39
+{
90
FIELD(V7M_CONTROL, NPRIV, 0, 1)
40
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
91
diff --git a/hw/core/machine.c b/hw/core/machine.c
41
+}
92
index XXXXXXX..XXXXXXX 100644
42
+
93
--- a/hw/core/machine.c
43
/*
94
+++ b/hw/core/machine.c
44
* Feature tests for "does this exist in either 32-bit or 64-bit?"
95
@@ -XXX,XX +XXX,XX @@
45
*/
96
#include "hw/virtio/virtio-iommu.h"
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
97
#include "audio/audio.h"
47
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
98
48
}
99
-GlobalProperty hw_compat_9_0[] = {};
49
100
+GlobalProperty hw_compat_9_0[] = {
50
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
101
+ {"arm-cpu", "backcompat-cntfrq", "true" },
51
+{
102
+};
52
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
103
const size_t hw_compat_9_0_len = G_N_ELEMENTS(hw_compat_9_0);
53
+}
104
54
+
105
GlobalProperty hw_compat_8_2[] = {
55
/*
56
* Forward to the above feature tests given an ARMCPU pointer.
57
*/
58
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
106
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
59
index XXXXXXX..XXXXXXX 100644
107
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/cpu.c
108
--- a/target/arm/cpu.c
61
+++ b/target/arm/cpu.c
109
+++ b/target/arm/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
110
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
63
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
111
64
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
112
if (!cpu->gt_cntfrq_hz) {
65
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
113
/*
66
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
114
- * 0 means "the board didn't set a value, use the default".
67
cpu->isar.id_mmfr4 = t;
115
- * The default value of the generic timer frequency (as seen in
68
}
116
- * CNTFRQ_EL0) is 62.5MHz, which corresponds to a period of 16ns.
69
#endif
117
- * This is what you get (a) for a CONFIG_USER_ONLY CPU (b) if the
118
- * board doesn't set it.
119
+ * 0 means "the board didn't set a value, use the default". (We also
120
+ * get here for the CONFIG_USER_ONLY case.)
121
+ * ARMv8.6 and later CPUs architecturally must use a 1GHz timer; before
122
+ * that it was an IMPDEF choice, and QEMU initially picked 62.5MHz,
123
+ * which gives a 16ns tick period.
124
+ *
125
+ * We will use the back-compat value:
126
+ * - for QEMU CPU types added before we standardized on 1GHz
127
+ * - for versioned machine types with a version of 9.0 or earlier
128
*/
129
- cpu->gt_cntfrq_hz = GTIMER_DEFAULT_HZ;
130
+ if (arm_feature(env, ARM_FEATURE_BACKCOMPAT_CNTFRQ) ||
131
+ cpu->backcompat_cntfrq) {
132
+ cpu->gt_cntfrq_hz = GTIMER_BACKCOMPAT_HZ;
133
+ } else {
134
+ cpu->gt_cntfrq_hz = GTIMER_DEFAULT_HZ;
135
+ }
136
}
137
138
#ifndef CONFIG_USER_ONLY
139
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_properties[] = {
140
mp_affinity, ARM64_AFFINITY_INVALID),
141
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
142
DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1),
143
+ /* True to default to the backward-compat old CNTFRQ rather than 1Ghz */
144
+ DEFINE_PROP_BOOL("backcompat-cntfrq", ARMCPU, backcompat_cntfrq, false),
145
DEFINE_PROP_END_OF_LIST()
146
};
147
70
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
148
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
71
index XXXXXXX..XXXXXXX 100644
149
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/cpu64.c
150
--- a/target/arm/cpu64.c
73
+++ b/target/arm/cpu64.c
151
+++ b/target/arm/cpu64.c
74
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
152
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
75
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
153
set_feature(&cpu->env, ARM_FEATURE_V8);
76
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
154
set_feature(&cpu->env, ARM_FEATURE_NEON);
77
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
155
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
78
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
156
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
79
cpu->isar.id_aa64mmfr1 = t;
157
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
80
158
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
81
t = cpu->isar.id_aa64mmfr2;
159
set_feature(&cpu->env, ARM_FEATURE_EL2);
82
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
160
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
83
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
161
set_feature(&cpu->env, ARM_FEATURE_V8);
84
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
162
set_feature(&cpu->env, ARM_FEATURE_NEON);
85
u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
163
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
86
+ u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
164
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
87
cpu->isar.id_mmfr4 = u;
165
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
88
166
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
89
u = cpu->isar.id_aa64dfr0;
167
set_feature(&cpu->env, ARM_FEATURE_EL2);
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
168
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
91
index XXXXXXX..XXXXXXX 100644
169
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/helper.c
170
--- a/target/arm/tcg/cpu32.c
93
+++ b/target/arm/helper.c
171
+++ b/target/arm/tcg/cpu32.c
94
@@ -XXX,XX +XXX,XX @@ simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
172
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
95
*
173
set_feature(&cpu->env, ARM_FEATURE_NEON);
96
* @env: CPUARMState
174
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
97
* @s2ap: The 2-bit stage2 access permissions (S2AP)
175
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
98
- * @xn: XN (execute-never) bit
176
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
99
+ * @xn: XN (execute-never) bits
177
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
100
+ * @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
178
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
101
*/
179
set_feature(&cpu->env, ARM_FEATURE_EL2);
102
-static int get_S2prot(CPUARMState *env, int s2ap, int xn)
180
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
103
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
181
set_feature(&cpu->env, ARM_FEATURE_NEON);
104
{
182
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
105
int prot = 0;
183
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
106
184
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
107
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn)
185
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
108
if (s2ap & 2) {
186
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
109
prot |= PAGE_WRITE;
187
set_feature(&cpu->env, ARM_FEATURE_EL2);
110
}
188
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
111
- if (!xn) {
189
set_feature(&cpu->env, ARM_FEATURE_PMSA);
112
- if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
190
set_feature(&cpu->env, ARM_FEATURE_NEON);
191
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
192
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
193
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
194
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
195
cpu->midr = 0x411fd133; /* r1p3 */
196
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
197
set_feature(&cpu->env, ARM_FEATURE_V8);
198
set_feature(&cpu->env, ARM_FEATURE_NEON);
199
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
200
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
201
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
202
set_feature(&cpu->env, ARM_FEATURE_EL2);
203
set_feature(&cpu->env, ARM_FEATURE_EL3);
204
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/arm/tcg/cpu64.c
207
+++ b/target/arm/tcg/cpu64.c
208
@@ -XXX,XX +XXX,XX @@ static void aarch64_a35_initfn(Object *obj)
209
set_feature(&cpu->env, ARM_FEATURE_V8);
210
set_feature(&cpu->env, ARM_FEATURE_NEON);
211
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
212
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
213
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
214
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
215
set_feature(&cpu->env, ARM_FEATURE_EL2);
216
@@ -XXX,XX +XXX,XX @@ static void aarch64_a55_initfn(Object *obj)
217
set_feature(&cpu->env, ARM_FEATURE_V8);
218
set_feature(&cpu->env, ARM_FEATURE_NEON);
219
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
220
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
221
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
222
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
223
set_feature(&cpu->env, ARM_FEATURE_EL2);
224
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
225
set_feature(&cpu->env, ARM_FEATURE_V8);
226
set_feature(&cpu->env, ARM_FEATURE_NEON);
227
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
228
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
229
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
230
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
231
set_feature(&cpu->env, ARM_FEATURE_EL2);
232
@@ -XXX,XX +XXX,XX @@ static void aarch64_a76_initfn(Object *obj)
233
set_feature(&cpu->env, ARM_FEATURE_V8);
234
set_feature(&cpu->env, ARM_FEATURE_NEON);
235
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
236
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
237
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
238
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
239
set_feature(&cpu->env, ARM_FEATURE_EL2);
240
@@ -XXX,XX +XXX,XX @@ static void aarch64_a64fx_initfn(Object *obj)
241
set_feature(&cpu->env, ARM_FEATURE_V8);
242
set_feature(&cpu->env, ARM_FEATURE_NEON);
243
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
244
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
245
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
246
set_feature(&cpu->env, ARM_FEATURE_EL2);
247
set_feature(&cpu->env, ARM_FEATURE_EL3);
248
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n1_initfn(Object *obj)
249
set_feature(&cpu->env, ARM_FEATURE_V8);
250
set_feature(&cpu->env, ARM_FEATURE_NEON);
251
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
252
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
253
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
254
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
255
set_feature(&cpu->env, ARM_FEATURE_EL2);
256
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_v1_initfn(Object *obj)
257
set_feature(&cpu->env, ARM_FEATURE_V8);
258
set_feature(&cpu->env, ARM_FEATURE_NEON);
259
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
260
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
261
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
262
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
263
set_feature(&cpu->env, ARM_FEATURE_EL2);
264
@@ -XXX,XX +XXX,XX @@ static void aarch64_a710_initfn(Object *obj)
265
set_feature(&cpu->env, ARM_FEATURE_V8);
266
set_feature(&cpu->env, ARM_FEATURE_NEON);
267
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
268
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
269
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
270
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
271
set_feature(&cpu->env, ARM_FEATURE_EL2);
272
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n2_initfn(Object *obj)
273
set_feature(&cpu->env, ARM_FEATURE_V8);
274
set_feature(&cpu->env, ARM_FEATURE_NEON);
275
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
276
+ set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
277
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
278
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
279
set_feature(&cpu->env, ARM_FEATURE_EL2);
280
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
281
uint64_t t;
282
uint32_t u;
283
284
+ /*
285
+ * Unset ARM_FEATURE_BACKCOMPAT_CNTFRQ, which we would otherwise default
286
+ * to because we started with aarch64_a57_initfn(). A 'max' CPU might
287
+ * be a v8.6-or-later one, in which case the cntfrq must be 1GHz; and
288
+ * because it is our "may change" CPU type we are OK with it not being
289
+ * backwards-compatible with how it worked in old QEMU.
290
+ */
291
+ unset_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
113
+
292
+
114
+ if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
293
/*
115
+ switch (xn) {
294
* Reset MIDR so the guest doesn't mistake our 'max' CPU type for a real
116
+ case 0:
295
* one and try to apply errata workarounds or use impdef features we
117
prot |= PAGE_EXEC;
118
+ break;
119
+ case 1:
120
+ if (s1_is_el0) {
121
+ prot |= PAGE_EXEC;
122
+ }
123
+ break;
124
+ case 2:
125
+ break;
126
+ case 3:
127
+ if (!s1_is_el0) {
128
+ prot |= PAGE_EXEC;
129
+ }
130
+ break;
131
+ default:
132
+ g_assert_not_reached();
133
+ }
134
+ } else {
135
+ if (!extract32(xn, 1, 1)) {
136
+ if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
137
+ prot |= PAGE_EXEC;
138
+ }
139
}
140
}
141
return prot;
142
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
143
}
144
145
ap = extract32(attrs, 4, 2);
146
- xn = extract32(attrs, 12, 1);
147
148
if (mmu_idx == ARMMMUIdx_Stage2) {
149
ns = true;
150
- *prot = get_S2prot(env, ap, xn);
151
+ xn = extract32(attrs, 11, 2);
152
+ *prot = get_S2prot(env, ap, xn, s1_is_el0);
153
} else {
154
ns = extract32(attrs, 3, 1);
155
+ xn = extract32(attrs, 12, 1);
156
pxn = extract32(attrs, 11, 1);
157
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
158
}
159
--
296
--
160
2.20.1
297
2.34.1
161
298
162
299
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Alexandra Diupina <adiupina@astralinux.ru>
2
2
3
By using the TYPE_* definitions for devices, we can:
3
The DMA descriptor structures for this device have
4
- quickly find where devices are used with 'git-grep'
4
a set of "address extension" fields which extend the 32
5
- easily rename a device (one-line change).
5
bit source addresses with an extra 16 bits to give a
6
48 bit address:
7
https://docs.amd.com/r/en-US/ug1085-zynq-ultrascale-trm/ADDR_EXT-Field
6
8
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
However, we misimplemented this address extension in several ways:
8
Message-id: 20200428154650.21991-1-f4bug@amsat.org
10
* we only extracted 12 bits of the extension fields, not 16
11
* we didn't shift the extension field up far enough
12
* we accidentally did the shift as 32-bit arithmetic, which
13
meant that we would have an overflow instead of setting
14
bits [47:32] of the resulting 64-bit address
15
16
Add a type cast and use extract64() instead of extract32()
17
to avoid integer overflow on addition. Fix bit fields
18
extraction according to documentation.
19
20
Found by Linux Verification Center (linuxtesting.org) with SVACE.
21
22
Cc: qemu-stable@nongnu.org
23
Fixes: d3c6369a96 ("introduce xlnx-dpdma")
24
Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
25
Message-id: 20240428181131.23801-1-adiupina@astralinux.ru
26
[PMM: adjusted commit message]
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
27
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
29
---
12
hw/arm/mps2-tz.c | 2 +-
30
hw/dma/xlnx_dpdma.c | 20 ++++++++++----------
13
1 file changed, 1 insertion(+), 1 deletion(-)
31
1 file changed, 10 insertions(+), 10 deletions(-)
14
32
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
33
diff --git a/hw/dma/xlnx_dpdma.c b/hw/dma/xlnx_dpdma.c
16
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
35
--- a/hw/dma/xlnx_dpdma.c
18
+++ b/hw/arm/mps2-tz.c
36
+++ b/hw/dma/xlnx_dpdma.c
19
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
37
@@ -XXX,XX +XXX,XX @@ static uint64_t xlnx_dpdma_desc_get_source_address(DPDMADescriptor *desc,
20
exit(EXIT_FAILURE);
38
21
}
39
switch (frag) {
22
40
case 0:
23
- sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
41
- addr = desc->source_address
24
+ sysbus_init_child_obj(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
42
- + (extract32(desc->address_extension, 16, 12) << 20);
25
sizeof(mms->iotkit), mmc->armsse_type);
43
+ addr = (uint64_t)desc->source_address
26
iotkitdev = DEVICE(&mms->iotkit);
44
+ + (extract64(desc->address_extension, 16, 16) << 32);
27
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
45
break;
46
case 1:
47
- addr = desc->source_address2
48
- + (extract32(desc->address_extension_23, 0, 12) << 8);
49
+ addr = (uint64_t)desc->source_address2
50
+ + (extract64(desc->address_extension_23, 0, 16) << 32);
51
break;
52
case 2:
53
- addr = desc->source_address3
54
- + (extract32(desc->address_extension_23, 16, 12) << 20);
55
+ addr = (uint64_t)desc->source_address3
56
+ + (extract64(desc->address_extension_23, 16, 16) << 32);
57
break;
58
case 3:
59
- addr = desc->source_address4
60
- + (extract32(desc->address_extension_45, 0, 12) << 8);
61
+ addr = (uint64_t)desc->source_address4
62
+ + (extract64(desc->address_extension_45, 0, 16) << 32);
63
break;
64
case 4:
65
- addr = desc->source_address5
66
- + (extract32(desc->address_extension_45, 16, 12) << 20);
67
+ addr = (uint64_t)desc->source_address5
68
+ + (extract64(desc->address_extension_45, 16, 16) << 32);
69
break;
70
default:
71
addr = 0;
28
--
72
--
29
2.20.1
73
2.34.1
30
31
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Embed the UARTs into the SoC type.
3
"make check-qtest-aarch64" recently started failing on FreeBSD builds,
4
and valgrind on Linux also detected that there is something fishy with
5
the new stm32l4x5-usart: The code forgot to set the correct class_size
6
here, so the various class_init functions in this file wrote beyond
7
the allocated buffer when setting the subc->type field.
4
8
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
9
Fixes: 4fb37aea7e ("hw/char: Implement STM32L4x5 USART skeleton")
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20240429075908.36302-1-thuth@redhat.com
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-5-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
14
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
15
hw/char/stm32l4x5_usart.c | 1 +
14
hw/arm/xlnx-versal.c | 12 ++++++------
16
1 file changed, 1 insertion(+)
15
2 files changed, 8 insertions(+), 7 deletions(-)
16
17
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
diff --git a/hw/char/stm32l4x5_usart.c b/hw/char/stm32l4x5_usart.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
20
--- a/hw/char/stm32l4x5_usart.c
20
+++ b/include/hw/arm/xlnx-versal.h
21
+++ b/hw/char/stm32l4x5_usart.c
21
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stm32l4x5_usart_types[] = {
22
#include "hw/sysbus.h"
23
.parent = TYPE_SYS_BUS_DEVICE,
23
#include "hw/arm/boot.h"
24
.instance_size = sizeof(Stm32l4x5UsartBaseState),
24
#include "hw/intc/arm_gicv3.h"
25
.instance_init = stm32l4x5_usart_base_init,
25
+#include "hw/char/pl011.h"
26
+ .class_size = sizeof(Stm32l4x5UsartBaseClass),
26
27
.class_init = stm32l4x5_usart_base_class_init,
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
28
.abstract = true,
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
29
}, {
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
MemoryRegion mr_ocm;
31
32
struct {
33
- SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
34
+ PL011State uart[XLNX_VERSAL_NR_UARTS];
35
SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
36
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
37
} iou;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@
43
#include "kvm_arm.h"
44
#include "hw/misc/unimp.h"
45
#include "hw/arm/xlnx-versal.h"
46
-#include "hw/char/pl011.h"
47
48
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
49
#define GEM_REVISION 0x40070106
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
51
DeviceState *dev;
52
MemoryRegion *mr;
53
54
- dev = qdev_create(NULL, TYPE_PL011);
55
- s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
56
+ sysbus_init_child_obj(OBJECT(s), name,
57
+ &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]),
58
+ TYPE_PL011);
59
+ dev = DEVICE(&s->lpd.iou.uart[i]);
60
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
61
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
62
qdev_init_nofail(dev);
63
64
- mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
65
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
66
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
67
68
- sysbus_connect_irq(s->lpd.iou.uart[i], 0, pic[irqs[i]]);
69
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
70
g_free(name);
71
}
72
}
73
--
30
--
74
2.20.1
31
2.34.1
75
32
76
33
diff view generated by jsdifflib
1
From: Fredrik Strupe <fredrik@strupe.net>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
According to Arm ARM, VQDMULL is only valid when U=0, while having
3
Use little endian for derivative OTP fuse key.
4
U=1 is unallocated.
5
4
6
Signed-off-by: Fredrik Strupe <fredrik@strupe.net>
5
Cc: qemu-stable@nongnu.org
7
Fixes: 695272dcb976 ("target-arm: Handle UNDEF cases for Neon 3-regs-different-widths")
6
Fixes: c752bb079b ("hw/nvram: NPCM7xx OTP device model")
7
Suggested-by: Avi Fishman <Avi.Fishman@nuvoton.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20240422125813.1403-1-philmd@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 | 2 +-
13
hw/arm/npcm7xx.c | 3 ++-
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 2 insertions(+), 1 deletion(-)
13
15
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
18
--- a/hw/arm/npcm7xx.c
17
+++ b/target/arm/translate.c
19
+++ b/hw/arm/npcm7xx.c
18
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
20
@@ -XXX,XX +XXX,XX @@
19
{0, 0, 0, 0}, /* VMLSL */
21
#include "hw/qdev-clock.h"
20
{0, 0, 0, 9}, /* VQDMLSL */
22
#include "hw/qdev-properties.h"
21
{0, 0, 0, 0}, /* Integer VMULL */
23
#include "qapi/error.h"
22
- {0, 0, 0, 1}, /* VQDMULL */
24
+#include "qemu/bswap.h"
23
+ {0, 0, 0, 9}, /* VQDMULL */
25
#include "qemu/units.h"
24
{0, 0, 0, 0xa}, /* Polynomial VMULL */
26
#include "sysemu/sysemu.h"
25
{0, 0, 0, 7}, /* Reserved: always UNDEF */
27
#include "target/arm/cpu-qom.h"
26
};
28
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init_fuses(NPCM7xxState *s)
29
* The initial mask of disabled modules indicates the chip derivative (e.g.
30
* NPCM750 or NPCM730).
31
*/
32
- value = tswap32(nc->disabled_modules);
33
+ value = cpu_to_le32(nc->disabled_modules);
34
npcm7xx_otp_array_write(&s->fuse_array, &value, NPCM7XX_FUSE_DERIVATIVE,
35
sizeof(value));
36
}
27
--
37
--
28
2.20.1
38
2.34.1
29
39
30
40
diff view generated by jsdifflib
Deleted patch
1
In aarch64_max_initfn() we update both 32-bit and 64-bit ID
2
registers. The intended pattern is that for 64-bit ID registers we
3
use FIELD_DP64 and the uint64_t 't' register, while 32-bit ID
4
registers use FIELD_DP32 and the uint32_t 'u' register. For
5
ID_AA64DFR0 we accidentally used 'u', meaning that the top 32 bits of
6
this 64-bit ID register would end up always zero. Luckily at the
7
moment that's what they should be anyway, so this bug has no visible
8
effects.
9
1
10
Use the right-sized variable.
11
12
Fixes: 3bec78447a958d481991
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200423110915.10527-1-peter.maydell@linaro.org
17
---
18
target/arm/cpu64.c | 6 +++---
19
1 file changed, 3 insertions(+), 3 deletions(-)
20
21
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu64.c
24
+++ b/target/arm/cpu64.c
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
26
u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
27
cpu->isar.id_mmfr4 = u;
28
29
- u = cpu->isar.id_aa64dfr0;
30
- u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
31
- cpu->isar.id_aa64dfr0 = u;
32
+ t = cpu->isar.id_aa64dfr0;
33
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
34
+ cpu->isar.id_aa64dfr0 = t;
35
36
u = cpu->isar.id_dfr0;
37
u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
38
--
39
2.20.1
40
41
diff view generated by jsdifflib
1
Add the infrastructure for building and invoking a decodetree decoder
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
for the AArch32 Neon encodings. At the moment the new decoder covers
3
nothing, so we always fall back to the existing hand-written decode.
4
2
5
We follow the same pattern we did for the VFP decodetree conversion
3
This device implements the IM120417002 colors shield v1.1 for Arduino
6
(commit 78e138bc1f672c145ef6ace74617d and following): code that deals
4
(which relies on the DM163 8x3-channel led driving logic) and features
7
with Neon will be moving gradually out to translate-neon.vfp.inc,
5
a simple display of an 8x8 RGB matrix. The columns of the matrix are
8
which we #include into translate.c.
6
driven by the DM163 and the rows are driven externally.
9
7
10
In order to share the decode files between A32 and T32, we
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
split Neon into 3 parts:
9
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
12
* data-processing
10
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
13
* load-store
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
* 'shared' encodings
12
Message-id: 20240424200929.240921-2-ines.varhol@telecom-paris.fr
13
[PMM: updated to new reset hold method prototype]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
docs/system/arm/b-l475e-iot01a.rst | 3 +-
17
include/hw/display/dm163.h | 59 +++++
18
hw/display/dm163.c | 349 +++++++++++++++++++++++++++++
19
hw/display/Kconfig | 3 +
20
hw/display/meson.build | 1 +
21
hw/display/trace-events | 14 ++
22
6 files changed, 428 insertions(+), 1 deletion(-)
23
create mode 100644 include/hw/display/dm163.h
24
create mode 100644 hw/display/dm163.c
15
25
16
The first two groups of instructions have similar but not identical
26
diff --git a/docs/system/arm/b-l475e-iot01a.rst b/docs/system/arm/b-l475e-iot01a.rst
17
A32 and T32 encodings, so we need to manually transform the T32
27
index XXXXXXX..XXXXXXX 100644
18
encoding into the A32 one before calling the decoder; the third group
28
--- a/docs/system/arm/b-l475e-iot01a.rst
19
covers the Neon instructions which are identical in A32 and T32.
29
+++ b/docs/system/arm/b-l475e-iot01a.rst
20
30
@@ -XXX,XX +XXX,XX @@ USART, I2C, SPI, CAN and USB OTG, as well as a variety of sensors.
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Supported devices
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
"""""""""""""""""
23
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
33
24
---
34
-Currently B-L475E-IOT01A machine's only supports the following devices:
25
target/arm/neon-dp.decode | 29 ++++++++++++++++++++++++++
35
+Currently B-L475E-IOT01A machines support the following devices:
26
target/arm/neon-ls.decode | 29 ++++++++++++++++++++++++++
36
27
target/arm/neon-shared.decode | 27 +++++++++++++++++++++++++
37
- Cortex-M4F based STM32L4x5 SoC
28
target/arm/translate-neon.inc.c | 32 +++++++++++++++++++++++++++++
38
- STM32L4x5 EXTI (Extended interrupts and events controller)
29
target/arm/translate.c | 36 +++++++++++++++++++++++++++++++--
39
@@ -XXX,XX +XXX,XX @@ Currently B-L475E-IOT01A machine's only supports the following devices:
30
target/arm/Makefile.objs | 18 +++++++++++++++++
40
- STM32L4x5 RCC (Reset and clock control)
31
6 files changed, 169 insertions(+), 2 deletions(-)
41
- STM32L4x5 GPIOs (General-purpose I/Os)
32
create mode 100644 target/arm/neon-dp.decode
42
- STM32L4x5 USARTs, UARTs and LPUART (Serial ports)
33
create mode 100644 target/arm/neon-ls.decode
43
+- optional 8x8 led display (based on DM163 driver)
34
create mode 100644 target/arm/neon-shared.decode
44
35
create mode 100644 target/arm/translate-neon.inc.c
45
Missing devices
36
46
"""""""""""""""
37
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
47
diff --git a/include/hw/display/dm163.h b/include/hw/display/dm163.h
38
new file mode 100644
48
new file mode 100644
39
index XXXXXXX..XXXXXXX
49
index XXXXXXX..XXXXXXX
40
--- /dev/null
50
--- /dev/null
41
+++ b/target/arm/neon-dp.decode
51
+++ b/include/hw/display/dm163.h
42
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@
43
+# AArch32 Neon data-processing instruction descriptions
53
+/*
44
+#
54
+ * QEMU DM163 8x3-channel constant current led driver
45
+# Copyright (c) 2020 Linaro, Ltd
55
+ * driving columns of associated 8x8 RGB matrix.
46
+#
56
+ *
47
+# This library is free software; you can redistribute it and/or
57
+ * Copyright (C) 2024 Samuel Tardieu <sam@rfc1149.net>
48
+# modify it under the terms of the GNU Lesser General Public
58
+ * Copyright (C) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
49
+# License as published by the Free Software Foundation; either
59
+ * Copyright (C) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
50
+# version 2 of the License, or (at your option) any later version.
60
+ *
51
+#
61
+ * SPDX-License-Identifier: GPL-2.0-or-later
52
+# This library is distributed in the hope that it will be useful,
62
+ */
53
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
63
+
54
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
64
+#ifndef HW_DISPLAY_DM163_H
55
+# Lesser General Public License for more details.
65
+#define HW_DISPLAY_DM163_H
56
+#
66
+
57
+# You should have received a copy of the GNU Lesser General Public
67
+#include "qom/object.h"
58
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
68
+#include "hw/qdev-core.h"
59
+
69
+
60
+#
70
+#define TYPE_DM163 "dm163"
61
+# This file is processed by scripts/decodetree.py
71
+OBJECT_DECLARE_SIMPLE_TYPE(DM163State, DM163);
62
+#
72
+
63
+
73
+#define RGB_MATRIX_NUM_ROWS 8
64
+# Encodings for Neon data processing instructions where the T32 encoding
74
+#define RGB_MATRIX_NUM_COLS 8
65
+# is a simple transformation of the A32 encoding.
75
+#define DM163_NUM_LEDS (RGB_MATRIX_NUM_COLS * 3)
66
+# More specifically, this file covers instructions where the A32 encoding is
76
+/* The last row is filled with 0 (turned off row) */
67
+# 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
77
+#define COLOR_BUFFER_SIZE (RGB_MATRIX_NUM_ROWS + 1)
68
+# and the T32 encoding is
78
+
69
+# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
79
+typedef struct DM163State {
70
+# This file works on the A32 encoding only; calling code for T32 has to
80
+ DeviceState parent_obj;
71
+# transform the insn into the A32 version first.
81
+
72
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
82
+ /* DM163 driver */
83
+ uint64_t bank0_shift_register[3];
84
+ uint64_t bank1_shift_register[3];
85
+ uint16_t latched_outputs[DM163_NUM_LEDS];
86
+ uint16_t outputs[DM163_NUM_LEDS];
87
+ qemu_irq sout;
88
+
89
+ uint8_t sin;
90
+ uint8_t dck;
91
+ uint8_t rst_b;
92
+ uint8_t lat_b;
93
+ uint8_t selbk;
94
+ uint8_t en_b;
95
+
96
+ /* IM120417002 colors shield */
97
+ uint8_t activated_rows;
98
+
99
+ /* 8x8 RGB matrix */
100
+ QemuConsole *console;
101
+ uint8_t redraw;
102
+ /* Rows currently being displayed on the matrix. */
103
+ /* The last row is filled with 0 (turned off row) */
104
+ uint32_t buffer[COLOR_BUFFER_SIZE][RGB_MATRIX_NUM_COLS];
105
+ uint8_t last_buffer_idx;
106
+ uint8_t buffer_idx_of_row[RGB_MATRIX_NUM_ROWS];
107
+ /* Used to simulate retinal persistence of rows */
108
+ uint8_t row_persistence_delay[RGB_MATRIX_NUM_ROWS];
109
+} DM163State;
110
+
111
+#endif /* HW_DISPLAY_DM163_H */
112
diff --git a/hw/display/dm163.c b/hw/display/dm163.c
73
new file mode 100644
113
new file mode 100644
74
index XXXXXXX..XXXXXXX
114
index XXXXXXX..XXXXXXX
75
--- /dev/null
115
--- /dev/null
76
+++ b/target/arm/neon-ls.decode
116
+++ b/hw/display/dm163.c
77
@@ -XXX,XX +XXX,XX @@
78
+# AArch32 Neon load/store instruction descriptions
79
+#
80
+# Copyright (c) 2020 Linaro, Ltd
81
+#
82
+# This library is free software; you can redistribute it and/or
83
+# modify it under the terms of the GNU Lesser General Public
84
+# License as published by the Free Software Foundation; either
85
+# version 2 of the License, or (at your option) any later version.
86
+#
87
+# This library is distributed in the hope that it will be useful,
88
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
89
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90
+# Lesser General Public License for more details.
91
+#
92
+# You should have received a copy of the GNU Lesser General Public
93
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
94
+
95
+#
96
+# This file is processed by scripts/decodetree.py
97
+#
98
+
99
+# Encodings for Neon load/store instructions where the T32 encoding
100
+# is a simple transformation of the A32 encoding.
101
+# More specifically, this file covers instructions where the A32 encoding is
102
+# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
103
+# and the T32 encoding is
104
+# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
105
+# This file works on the A32 encoding only; calling code for T32 has to
106
+# transform the insn into the A32 version first.
107
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/target/arm/neon-shared.decode
112
@@ -XXX,XX +XXX,XX @@
113
+# AArch32 Neon instruction descriptions
114
+#
115
+# Copyright (c) 2020 Linaro, Ltd
116
+#
117
+# This library is free software; you can redistribute it and/or
118
+# modify it under the terms of the GNU Lesser General Public
119
+# License as published by the Free Software Foundation; either
120
+# version 2 of the License, or (at your option) any later version.
121
+#
122
+# This library is distributed in the hope that it will be useful,
123
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
124
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
125
+# Lesser General Public License for more details.
126
+#
127
+# You should have received a copy of the GNU Lesser General Public
128
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
129
+
130
+#
131
+# This file is processed by scripts/decodetree.py
132
+#
133
+
134
+# Encodings for Neon instructions whose encoding is the same for
135
+# both A32 and T32.
136
+
137
+# More specifically, this covers:
138
+# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
139
+# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
140
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
141
new file mode 100644
142
index XXXXXXX..XXXXXXX
143
--- /dev/null
144
+++ b/target/arm/translate-neon.inc.c
145
@@ -XXX,XX +XXX,XX @@
117
@@ -XXX,XX +XXX,XX @@
146
+/*
118
+/*
147
+ * ARM translation: AArch32 Neon instructions
119
+ * QEMU DM163 8x3-channel constant current led driver
120
+ * driving columns of associated 8x8 RGB matrix.
148
+ *
121
+ *
149
+ * Copyright (c) 2003 Fabrice Bellard
122
+ * Copyright (C) 2024 Samuel Tardieu <sam@rfc1149.net>
150
+ * Copyright (c) 2005-2007 CodeSourcery
123
+ * Copyright (C) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
151
+ * Copyright (c) 2007 OpenedHand, Ltd.
124
+ * Copyright (C) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
152
+ * Copyright (c) 2020 Linaro, Ltd.
153
+ *
125
+ *
154
+ * This library is free software; you can redistribute it and/or
126
+ * SPDX-License-Identifier: GPL-2.0-or-later
155
+ * modify it under the terms of the GNU Lesser General Public
156
+ * License as published by the Free Software Foundation; either
157
+ * version 2 of the License, or (at your option) any later version.
158
+ *
159
+ * This library is distributed in the hope that it will be useful,
160
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
161
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
162
+ * Lesser General Public License for more details.
163
+ *
164
+ * You should have received a copy of the GNU Lesser General Public
165
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
166
+ */
127
+ */
167
+
128
+
168
+/*
129
+/*
169
+ * This file is intended to be included from translate.c; it uses
130
+ * The reference used for the DM163 is the following :
170
+ * some macros and definitions provided by that file.
131
+ * http://www.siti.com.tw/product/spec/LED/DM163.pdf
171
+ * It might be possible to convert it to a standalone .c file eventually.
172
+ */
132
+ */
173
+
133
+
174
+/* Include the generated Neon decoder */
134
+#include "qemu/osdep.h"
175
+#include "decode-neon-dp.inc.c"
135
+#include "qapi/error.h"
176
+#include "decode-neon-ls.inc.c"
136
+#include "migration/vmstate.h"
177
+#include "decode-neon-shared.inc.c"
137
+#include "hw/irq.h"
178
diff --git a/target/arm/translate.c b/target/arm/translate.c
138
+#include "hw/qdev-properties.h"
139
+#include "hw/display/dm163.h"
140
+#include "ui/console.h"
141
+#include "trace.h"
142
+
143
+#define LED_SQUARE_SIZE 100
144
+/* Number of frames a row stays visible after being turned off. */
145
+#define ROW_PERSISTENCE 3
146
+#define TURNED_OFF_ROW (COLOR_BUFFER_SIZE - 1)
147
+
148
+static const VMStateDescription vmstate_dm163 = {
149
+ .name = TYPE_DM163,
150
+ .version_id = 1,
151
+ .minimum_version_id = 1,
152
+ .fields = (const VMStateField[]) {
153
+ VMSTATE_UINT64_ARRAY(bank0_shift_register, DM163State, 3),
154
+ VMSTATE_UINT64_ARRAY(bank1_shift_register, DM163State, 3),
155
+ VMSTATE_UINT16_ARRAY(latched_outputs, DM163State, DM163_NUM_LEDS),
156
+ VMSTATE_UINT16_ARRAY(outputs, DM163State, DM163_NUM_LEDS),
157
+ VMSTATE_UINT8(dck, DM163State),
158
+ VMSTATE_UINT8(en_b, DM163State),
159
+ VMSTATE_UINT8(lat_b, DM163State),
160
+ VMSTATE_UINT8(rst_b, DM163State),
161
+ VMSTATE_UINT8(selbk, DM163State),
162
+ VMSTATE_UINT8(sin, DM163State),
163
+ VMSTATE_UINT8(activated_rows, DM163State),
164
+ VMSTATE_UINT32_2DARRAY(buffer, DM163State, COLOR_BUFFER_SIZE,
165
+ RGB_MATRIX_NUM_COLS),
166
+ VMSTATE_UINT8(last_buffer_idx, DM163State),
167
+ VMSTATE_UINT8_ARRAY(buffer_idx_of_row, DM163State, RGB_MATRIX_NUM_ROWS),
168
+ VMSTATE_UINT8_ARRAY(row_persistence_delay, DM163State,
169
+ RGB_MATRIX_NUM_ROWS),
170
+ VMSTATE_END_OF_LIST()
171
+ }
172
+};
173
+
174
+static void dm163_reset_hold(Object *obj, ResetType type)
175
+{
176
+ DM163State *s = DM163(obj);
177
+
178
+ s->sin = 0;
179
+ s->dck = 0;
180
+ s->rst_b = 0;
181
+ /* Ensuring the first falling edge of lat_b isn't missed */
182
+ s->lat_b = 1;
183
+ s->selbk = 0;
184
+ s->en_b = 0;
185
+ /* Reset stops the PWM, not the shift and latched registers. */
186
+ memset(s->outputs, 0, sizeof(s->outputs));
187
+
188
+ s->activated_rows = 0;
189
+ s->redraw = 0;
190
+ trace_dm163_redraw(s->redraw);
191
+ for (unsigned i = 0; i < COLOR_BUFFER_SIZE; i++) {
192
+ memset(s->buffer[i], 0, sizeof(s->buffer[0]));
193
+ }
194
+ s->last_buffer_idx = 0;
195
+ memset(s->buffer_idx_of_row, TURNED_OFF_ROW, sizeof(s->buffer_idx_of_row));
196
+ memset(s->row_persistence_delay, 0, sizeof(s->row_persistence_delay));
197
+}
198
+
199
+static void dm163_dck_gpio_handler(void *opaque, int line, int new_state)
200
+{
201
+ DM163State *s = opaque;
202
+
203
+ if (new_state && !s->dck) {
204
+ /*
205
+ * On raising dck, sample selbk to get the bank to use, and
206
+ * sample sin for the bit to enter into the bank shift buffer.
207
+ */
208
+ uint64_t *sb =
209
+ s->selbk ? s->bank1_shift_register : s->bank0_shift_register;
210
+ /* Output the outgoing bit on sout */
211
+ const bool sout = (s->selbk ? sb[2] & MAKE_64BIT_MASK(63, 1) :
212
+ sb[2] & MAKE_64BIT_MASK(15, 1)) != 0;
213
+ qemu_set_irq(s->sout, sout);
214
+ /* Enter sin into the shift buffer */
215
+ sb[2] = (sb[2] << 1) | ((sb[1] >> 63) & 1);
216
+ sb[1] = (sb[1] << 1) | ((sb[0] >> 63) & 1);
217
+ sb[0] = (sb[0] << 1) | s->sin;
218
+ }
219
+
220
+ s->dck = new_state;
221
+ trace_dm163_dck(new_state);
222
+}
223
+
224
+static void dm163_propagate_outputs(DM163State *s)
225
+{
226
+ s->last_buffer_idx = (s->last_buffer_idx + 1) % RGB_MATRIX_NUM_ROWS;
227
+ /* Values are output when reset is high and enable is low. */
228
+ if (s->rst_b && !s->en_b) {
229
+ memcpy(s->outputs, s->latched_outputs, sizeof(s->outputs));
230
+ } else {
231
+ memset(s->outputs, 0, sizeof(s->outputs));
232
+ }
233
+ for (unsigned x = 0; x < RGB_MATRIX_NUM_COLS; x++) {
234
+ /* Grouping the 3 RGB channels in a pixel value */
235
+ const uint16_t b = extract16(s->outputs[3 * x + 0], 6, 8);
236
+ const uint16_t g = extract16(s->outputs[3 * x + 1], 6, 8);
237
+ const uint16_t r = extract16(s->outputs[3 * x + 2], 6, 8);
238
+ uint32_t rgba = 0;
239
+
240
+ trace_dm163_channels(3 * x + 2, r);
241
+ trace_dm163_channels(3 * x + 1, g);
242
+ trace_dm163_channels(3 * x + 0, b);
243
+
244
+ rgba = deposit32(rgba, 0, 8, r);
245
+ rgba = deposit32(rgba, 8, 8, g);
246
+ rgba = deposit32(rgba, 16, 8, b);
247
+
248
+ /* Led values are sent from the last one to the first one */
249
+ s->buffer[s->last_buffer_idx][RGB_MATRIX_NUM_COLS - x - 1] = rgba;
250
+ }
251
+ for (unsigned row = 0; row < RGB_MATRIX_NUM_ROWS; row++) {
252
+ if (s->activated_rows & (1 << row)) {
253
+ s->buffer_idx_of_row[row] = s->last_buffer_idx;
254
+ s->redraw |= (1 << row);
255
+ trace_dm163_redraw(s->redraw);
256
+ }
257
+ }
258
+}
259
+
260
+static void dm163_en_b_gpio_handler(void *opaque, int line, int new_state)
261
+{
262
+ DM163State *s = opaque;
263
+
264
+ s->en_b = new_state;
265
+ dm163_propagate_outputs(s);
266
+ trace_dm163_en_b(new_state);
267
+}
268
+
269
+static uint8_t dm163_bank0(const DM163State *s, uint8_t led)
270
+{
271
+ /*
272
+ * Bank 0 uses 6 bits per led, so a value may be stored accross
273
+ * two uint64_t entries.
274
+ */
275
+ const uint8_t low_bit = 6 * led;
276
+ const uint8_t low_word = low_bit / 64;
277
+ const uint8_t high_word = (low_bit + 5) / 64;
278
+ const uint8_t low_shift = low_bit % 64;
279
+
280
+ if (low_word == high_word) {
281
+ /* Simple case: the value belongs to one entry. */
282
+ return extract64(s->bank0_shift_register[low_word], low_shift, 6);
283
+ }
284
+
285
+ const uint8_t nb_bits_in_low_word = 64 - low_shift;
286
+ const uint8_t nb_bits_in_high_word = 6 - nb_bits_in_low_word;
287
+
288
+ const uint64_t bits_in_low_word = \
289
+ extract64(s->bank0_shift_register[low_word], low_shift,
290
+ nb_bits_in_low_word);
291
+ const uint64_t bits_in_high_word = \
292
+ extract64(s->bank0_shift_register[high_word], 0,
293
+ nb_bits_in_high_word);
294
+ uint8_t val = 0;
295
+
296
+ val = deposit32(val, 0, nb_bits_in_low_word, bits_in_low_word);
297
+ val = deposit32(val, nb_bits_in_low_word, nb_bits_in_high_word,
298
+ bits_in_high_word);
299
+
300
+ return val;
301
+}
302
+
303
+static uint8_t dm163_bank1(const DM163State *s, uint8_t led)
304
+{
305
+ const uint64_t entry = s->bank1_shift_register[led / RGB_MATRIX_NUM_COLS];
306
+ return extract64(entry, 8 * (led % RGB_MATRIX_NUM_COLS), 8);
307
+}
308
+
309
+static void dm163_lat_b_gpio_handler(void *opaque, int line, int new_state)
310
+{
311
+ DM163State *s = opaque;
312
+
313
+ if (s->lat_b && !new_state) {
314
+ for (int led = 0; led < DM163_NUM_LEDS; led++) {
315
+ s->latched_outputs[led] = dm163_bank0(s, led) * dm163_bank1(s, led);
316
+ }
317
+ dm163_propagate_outputs(s);
318
+ }
319
+
320
+ s->lat_b = new_state;
321
+ trace_dm163_lat_b(new_state);
322
+}
323
+
324
+static void dm163_rst_b_gpio_handler(void *opaque, int line, int new_state)
325
+{
326
+ DM163State *s = opaque;
327
+
328
+ s->rst_b = new_state;
329
+ dm163_propagate_outputs(s);
330
+ trace_dm163_rst_b(new_state);
331
+}
332
+
333
+static void dm163_selbk_gpio_handler(void *opaque, int line, int new_state)
334
+{
335
+ DM163State *s = opaque;
336
+
337
+ s->selbk = new_state;
338
+ trace_dm163_selbk(new_state);
339
+}
340
+
341
+static void dm163_sin_gpio_handler(void *opaque, int line, int new_state)
342
+{
343
+ DM163State *s = opaque;
344
+
345
+ s->sin = new_state;
346
+ trace_dm163_sin(new_state);
347
+}
348
+
349
+static void dm163_rows_gpio_handler(void *opaque, int line, int new_state)
350
+{
351
+ DM163State *s = opaque;
352
+
353
+ if (new_state) {
354
+ s->activated_rows |= (1 << line);
355
+ s->buffer_idx_of_row[line] = s->last_buffer_idx;
356
+ s->redraw |= (1 << line);
357
+ trace_dm163_redraw(s->redraw);
358
+ } else {
359
+ s->activated_rows &= ~(1 << line);
360
+ s->row_persistence_delay[line] = ROW_PERSISTENCE;
361
+ }
362
+ trace_dm163_activated_rows(s->activated_rows);
363
+}
364
+
365
+static void dm163_invalidate_display(void *opaque)
366
+{
367
+ DM163State *s = (DM163State *)opaque;
368
+ s->redraw = 0xFF;
369
+ trace_dm163_redraw(s->redraw);
370
+}
371
+
372
+static void update_row_persistence_delay(DM163State *s, unsigned row)
373
+{
374
+ if (s->row_persistence_delay[row]) {
375
+ s->row_persistence_delay[row]--;
376
+ } else {
377
+ /*
378
+ * If the ROW_PERSISTENCE delay is up,
379
+ * the row is turned off.
380
+ */
381
+ s->buffer_idx_of_row[row] = TURNED_OFF_ROW;
382
+ s->redraw |= (1 << row);
383
+ trace_dm163_redraw(s->redraw);
384
+ }
385
+}
386
+
387
+static uint32_t *update_display_of_row(DM163State *s, uint32_t *dest,
388
+ unsigned row)
389
+{
390
+ for (unsigned _ = 0; _ < LED_SQUARE_SIZE; _++) {
391
+ for (int x = 0; x < RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE; x++) {
392
+ /* UI layer guarantees that there's 32 bits per pixel (Mar 2024) */
393
+ *dest++ = s->buffer[s->buffer_idx_of_row[row]][x / LED_SQUARE_SIZE];
394
+ }
395
+ }
396
+
397
+ dpy_gfx_update(s->console, 0, LED_SQUARE_SIZE * row,
398
+ RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE, LED_SQUARE_SIZE);
399
+ s->redraw &= ~(1 << row);
400
+ trace_dm163_redraw(s->redraw);
401
+
402
+ return dest;
403
+}
404
+
405
+static void dm163_update_display(void *opaque)
406
+{
407
+ DM163State *s = (DM163State *)opaque;
408
+ DisplaySurface *surface = qemu_console_surface(s->console);
409
+ uint32_t *dest;
410
+
411
+ dest = surface_data(surface);
412
+ for (unsigned row = 0; row < RGB_MATRIX_NUM_ROWS; row++) {
413
+ update_row_persistence_delay(s, row);
414
+ if (!extract8(s->redraw, row, 1)) {
415
+ dest += LED_SQUARE_SIZE * LED_SQUARE_SIZE * RGB_MATRIX_NUM_COLS;
416
+ continue;
417
+ }
418
+ dest = update_display_of_row(s, dest, row);
419
+ }
420
+}
421
+
422
+static const GraphicHwOps dm163_ops = {
423
+ .invalidate = dm163_invalidate_display,
424
+ .gfx_update = dm163_update_display,
425
+};
426
+
427
+static void dm163_realize(DeviceState *dev, Error **errp)
428
+{
429
+ DM163State *s = DM163(dev);
430
+
431
+ qdev_init_gpio_in(dev, dm163_rows_gpio_handler, RGB_MATRIX_NUM_ROWS);
432
+ qdev_init_gpio_in(dev, dm163_sin_gpio_handler, 1);
433
+ qdev_init_gpio_in(dev, dm163_dck_gpio_handler, 1);
434
+ qdev_init_gpio_in(dev, dm163_rst_b_gpio_handler, 1);
435
+ qdev_init_gpio_in(dev, dm163_lat_b_gpio_handler, 1);
436
+ qdev_init_gpio_in(dev, dm163_selbk_gpio_handler, 1);
437
+ qdev_init_gpio_in(dev, dm163_en_b_gpio_handler, 1);
438
+ qdev_init_gpio_out_named(dev, &s->sout, "sout", 1);
439
+
440
+ s->console = graphic_console_init(dev, 0, &dm163_ops, s);
441
+ qemu_console_resize(s->console, RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE,
442
+ RGB_MATRIX_NUM_ROWS * LED_SQUARE_SIZE);
443
+}
444
+
445
+static void dm163_class_init(ObjectClass *klass, void *data)
446
+{
447
+ DeviceClass *dc = DEVICE_CLASS(klass);
448
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
449
+
450
+ dc->desc = "DM163";
451
+ dc->vmsd = &vmstate_dm163;
452
+ dc->realize = dm163_realize;
453
+ rc->phases.hold = dm163_reset_hold;
454
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
455
+}
456
+
457
+static const TypeInfo dm163_types[] = {
458
+ {
459
+ .name = TYPE_DM163,
460
+ .parent = TYPE_DEVICE,
461
+ .instance_size = sizeof(DM163State),
462
+ .class_init = dm163_class_init
463
+ }
464
+};
465
+
466
+DEFINE_TYPES(dm163_types)
467
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
179
index XXXXXXX..XXXXXXX 100644
468
index XXXXXXX..XXXXXXX 100644
180
--- a/target/arm/translate.c
469
--- a/hw/display/Kconfig
181
+++ b/target/arm/translate.c
470
+++ b/hw/display/Kconfig
182
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
471
@@ -XXX,XX +XXX,XX @@ config XLNX_DISPLAYPORT
183
472
bool
184
#define ARM_CP_RW_BIT (1 << 20)
473
# defaults to "N", enabled by specific boards
185
474
depends on PIXMAN
186
-/* Include the VFP decoder */
475
+
187
+/* Include the VFP and Neon decoders */
476
+config DM163
188
#include "translate-vfp.inc.c"
477
+ bool
189
+#include "translate-neon.inc.c"
478
diff --git a/hw/display/meson.build b/hw/display/meson.build
190
191
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
192
{
193
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
194
/* Unconditional instructions. */
195
/* TODO: Perhaps merge these into one decodetree output file. */
196
if (disas_a32_uncond(s, insn) ||
197
- disas_vfp_uncond(s, insn)) {
198
+ disas_vfp_uncond(s, insn) ||
199
+ disas_neon_dp(s, insn) ||
200
+ disas_neon_ls(s, insn) ||
201
+ disas_neon_shared(s, insn)) {
202
return;
203
}
204
/* fall back to legacy decoder */
205
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
206
ARCH(6T2);
207
}
208
209
+ if ((insn & 0xef000000) == 0xef000000) {
210
+ /*
211
+ * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
212
+ * transform into
213
+ * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
214
+ */
215
+ uint32_t a32_insn = (insn & 0xe2ffffff) |
216
+ ((insn & (1 << 28)) >> 4) | (1 << 28);
217
+
218
+ if (disas_neon_dp(s, a32_insn)) {
219
+ return;
220
+ }
221
+ }
222
+
223
+ if ((insn & 0xff100000) == 0xf9000000) {
224
+ /*
225
+ * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
226
+ * transform into
227
+ * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
228
+ */
229
+ uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
230
+
231
+ if (disas_neon_ls(s, a32_insn)) {
232
+ return;
233
+ }
234
+ }
235
+
236
/*
237
* TODO: Perhaps merge these into one decodetree output file.
238
* Note disas_vfp is written for a32 with cond field in the
239
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
240
*/
241
if (disas_t32(s, insn) ||
242
disas_vfp_uncond(s, insn) ||
243
+ disas_neon_shared(s, insn) ||
244
((insn >> 28) == 0xe && disas_vfp(s, insn))) {
245
return;
246
}
247
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
248
index XXXXXXX..XXXXXXX 100644
479
index XXXXXXX..XXXXXXX 100644
249
--- a/target/arm/Makefile.objs
480
--- a/hw/display/meson.build
250
+++ b/target/arm/Makefile.objs
481
+++ b/hw/display/meson.build
251
@@ -XXX,XX +XXX,XX @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
482
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_NEXTCUBE', if_true: files('next-fb.c'))
252
     $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
483
253
     "GEN", $(TARGET_DIR)$@)
484
system_ss.add(when: 'CONFIG_VGA', if_true: files('vga.c'))
254
485
system_ss.add(when: 'CONFIG_VIRTIO', if_true: files('virtio-dmabuf.c'))
255
+target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
486
+system_ss.add(when: 'CONFIG_DM163', if_true: files('dm163.c'))
256
+    $(call quiet-command,\
487
257
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_shared -o $@ $<,\
488
if (config_all_devices.has_key('CONFIG_VGA_CIRRUS') or
258
+     "GEN", $(TARGET_DIR)$@)
489
config_all_devices.has_key('CONFIG_VGA_PCI') or
259
+
490
diff --git a/hw/display/trace-events b/hw/display/trace-events
260
+target/arm/decode-neon-dp.inc.c: $(SRC_PATH)/target/arm/neon-dp.decode $(DECODETREE)
491
index XXXXXXX..XXXXXXX 100644
261
+    $(call quiet-command,\
492
--- a/hw/display/trace-events
262
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_dp -o $@ $<,\
493
+++ b/hw/display/trace-events
263
+     "GEN", $(TARGET_DIR)$@)
494
@@ -XXX,XX +XXX,XX @@ macfb_ctrl_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%"PRI
264
+
495
macfb_sense_read(uint32_t value) "video sense: 0x%"PRIx32
265
+target/arm/decode-neon-ls.inc.c: $(SRC_PATH)/target/arm/neon-ls.decode $(DECODETREE)
496
macfb_sense_write(uint32_t value) "video sense: 0x%"PRIx32
266
+    $(call quiet-command,\
497
macfb_update_mode(uint32_t width, uint32_t height, uint8_t depth) "setting mode to width %"PRId32 " height %"PRId32 " size %d"
267
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_ls -o $@ $<,\
498
+
268
+     "GEN", $(TARGET_DIR)$@)
499
+# dm163.c
269
+
500
+dm163_redraw(uint8_t redraw) "0x%02x"
270
target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE)
501
+dm163_dck(unsigned new_state) "dck : %u"
271
    $(call quiet-command,\
502
+dm163_en_b(unsigned new_state) "en_b : %u"
272
     $(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\
503
+dm163_rst_b(unsigned new_state) "rst_b : %u"
273
@@ -XXX,XX +XXX,XX @@ target/arm/decode-t16.inc.c: $(SRC_PATH)/target/arm/t16.decode $(DECODETREE)
504
+dm163_lat_b(unsigned new_state) "lat_b : %u"
274
     "GEN", $(TARGET_DIR)$@)
505
+dm163_sin(unsigned new_state) "sin : %u"
275
506
+dm163_selbk(unsigned new_state) "selbk : %u"
276
target/arm/translate-sve.o: target/arm/decode-sve.inc.c
507
+dm163_activated_rows(int new_state) "Activated rows : 0x%" PRIx32 ""
277
+target/arm/translate.o: target/arm/decode-neon-shared.inc.c
508
+dm163_bits_ppi(unsigned dest_width) "dest_width : %u"
278
+target/arm/translate.o: target/arm/decode-neon-dp.inc.c
509
+dm163_leds(int led, uint32_t value) "led %d: 0x%x"
279
+target/arm/translate.o: target/arm/decode-neon-ls.inc.c
510
+dm163_channels(int channel, uint8_t value) "channel %d: 0x%x"
280
target/arm/translate.o: target/arm/decode-vfp.inc.c
511
+dm163_refresh_rate(uint32_t rr) "refresh rate %d"
281
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
282
target/arm/translate.o: target/arm/decode-a32.inc.c
283
--
512
--
284
2.20.1
513
2.34.1
285
514
286
515
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Add support for SD.
3
Exposing SYSCFG inputs to the SoC is practical in order to wire the SoC
4
to the optional DM163 display from the board code (GPIOs outputs need
5
to be connected to both SYSCFG inputs and DM163 inputs).
4
6
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
STM32L4x5 SYSCFG in-irq interception needed to be changed accordingly.
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
9
Message-id: 20200427181649.26851-9-edgar.iglesias@gmail.com
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20240424200929.240921-3-ines.varhol@telecom-paris.fr
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
include/hw/arm/xlnx-versal.h | 12 ++++++++++++
15
hw/arm/stm32l4x5_soc.c | 6 ++++--
13
hw/arm/xlnx-versal.c | 31 +++++++++++++++++++++++++++++++
16
tests/qtest/stm32l4x5_gpio-test.c | 13 ++++++++-----
14
2 files changed, 43 insertions(+)
17
tests/qtest/stm32l4x5_syscfg-test.c | 17 ++++++++++-------
18
3 files changed, 22 insertions(+), 14 deletions(-)
15
19
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
20
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
22
--- a/hw/arm/stm32l4x5_soc.c
19
+++ b/include/hw/arm/xlnx-versal.h
23
+++ b/hw/arm/stm32l4x5_soc.c
20
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
21
25
/*
22
#include "hw/sysbus.h"
26
* STM32L4x5 SoC family
23
#include "hw/arm/boot.h"
27
*
24
+#include "hw/sd/sdhci.h"
28
- * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
25
#include "hw/intc/arm_gicv3.h"
29
- * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
26
#include "hw/char/pl011.h"
30
+ * Copyright (c) 2023-2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
27
#include "hw/dma/xlnx-zdma.h"
31
+ * Copyright (c) 2023-2024 Inès Varhol <ines.varhol@telecom-paris.fr>
32
*
33
* SPDX-License-Identifier: GPL-2.0-or-later
34
*
35
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
36
}
37
}
38
39
+ qdev_pass_gpios(DEVICE(&s->syscfg), dev_soc, NULL);
40
+
41
/* EXTI device */
42
busdev = SYS_BUS_DEVICE(&s->exti);
43
if (!sysbus_realize(busdev, errp)) {
44
diff --git a/tests/qtest/stm32l4x5_gpio-test.c b/tests/qtest/stm32l4x5_gpio-test.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/tests/qtest/stm32l4x5_gpio-test.c
47
+++ b/tests/qtest/stm32l4x5_gpio-test.c
28
@@ -XXX,XX +XXX,XX @@
48
@@ -XXX,XX +XXX,XX @@
29
#define XLNX_VERSAL_NR_UARTS 2
49
#define OTYPER_PUSH_PULL 0
30
#define XLNX_VERSAL_NR_GEMS 2
50
#define OTYPER_OPEN_DRAIN 1
31
#define XLNX_VERSAL_NR_ADMAS 8
51
32
+#define XLNX_VERSAL_NR_SDS 2
52
+/* SoC forwards GPIOs to SysCfg */
33
#define XLNX_VERSAL_NR_IRQS 192
53
+#define SYSCFG "/machine/soc"
34
35
typedef struct Versal {
36
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
37
} iou;
38
} lpd;
39
40
+ /* The Platform Management Controller subsystem. */
41
+ struct {
42
+ struct {
43
+ SDHCIState sd[XLNX_VERSAL_NR_SDS];
44
+ } iou;
45
+ } pmc;
46
+
54
+
47
struct {
55
const uint32_t moder_reset[NUM_GPIOS] = {
48
MemoryRegion *mr_ddr;
56
0xABFFFFFF,
49
uint32_t psci_conduit;
57
0xFFFFFEBF,
50
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
58
@@ -XXX,XX +XXX,XX @@ static void test_gpio_output_mode(const void *data)
51
#define VERSAL_GEM1_IRQ_0 58
59
uint32_t gpio = test_gpio_addr(data);
52
#define VERSAL_GEM1_WAKE_IRQ_0 59
60
unsigned int gpio_id = get_gpio_id(gpio);
53
#define VERSAL_ADMA_IRQ_0 60
61
54
+#define VERSAL_SD0_IRQ_0 126
62
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
55
63
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
56
/* Architecturally reserved IRQs suitable for virtualization. */
64
57
#define VERSAL_RSVD_IRQ_FIRST 111
65
/* Set a bit in ODR and check nothing happens */
58
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
66
gpio_set_bit(gpio, ODR, pin, 1);
59
#define MM_FPD_CRF 0xfd1a0000U
67
@@ -XXX,XX +XXX,XX @@ static void test_gpio_input_mode(const void *data)
60
#define MM_FPD_CRF_SIZE 0x140000
68
uint32_t gpio = test_gpio_addr(data);
61
69
unsigned int gpio_id = get_gpio_id(gpio);
62
+#define MM_PMC_SD0 0xf1040000U
70
63
+#define MM_PMC_SD0_SIZE 0x10000
71
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
64
#define MM_PMC_CRP 0xf1260000U
72
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
65
#define MM_PMC_CRP_SIZE 0x10000
73
66
#endif
74
/* Configure a line as input, raise it, and check that the pin is high */
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
75
gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
76
@@ -XXX,XX +XXX,XX @@ static void test_pull_up_pull_down(const void *data)
77
uint32_t gpio = test_gpio_addr(data);
78
unsigned int gpio_id = get_gpio_id(gpio);
79
80
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
81
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
82
83
/* Configure a line as input with pull-up, check the line is set high */
84
gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
85
@@ -XXX,XX +XXX,XX @@ static void test_push_pull(const void *data)
86
uint32_t gpio = test_gpio_addr(data);
87
uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
88
89
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
90
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
91
92
/* Setting a line high externally, configuring it in push-pull output */
93
/* And checking the pin was disconnected */
94
@@ -XXX,XX +XXX,XX @@ static void test_open_drain(const void *data)
95
uint32_t gpio = test_gpio_addr(data);
96
uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
97
98
- qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
99
+ qtest_irq_intercept_in(global_qtest, SYSCFG);
100
101
/* Setting a line high externally, configuring it in open-drain output */
102
/* And checking the pin was disconnected */
103
diff --git a/tests/qtest/stm32l4x5_syscfg-test.c b/tests/qtest/stm32l4x5_syscfg-test.c
68
index XXXXXXX..XXXXXXX 100644
104
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/xlnx-versal.c
105
--- a/tests/qtest/stm32l4x5_syscfg-test.c
70
+++ b/hw/arm/xlnx-versal.c
106
+++ b/tests/qtest/stm32l4x5_syscfg-test.c
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
107
@@ -XXX,XX +XXX,XX @@
72
}
108
/*
109
* QTest testcase for STM32L4x5_SYSCFG
110
*
111
- * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
112
- * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
113
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
114
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
115
*
116
* This work is licensed under the terms of the GNU GPL, version 2 or later.
117
* See the COPYING file in the top-level directory.
118
@@ -XXX,XX +XXX,XX @@
119
#define SYSCFG_SWPR2 0x28
120
#define INVALID_ADDR 0x2C
121
122
+/* SoC forwards GPIOs to SysCfg */
123
+#define SYSCFG "/machine/soc"
124
+#define EXTI "/machine/soc/exti"
125
+
126
static void syscfg_writel(unsigned int offset, uint32_t value)
127
{
128
writel(SYSCFG_BASE_ADDR + offset, value);
129
@@ -XXX,XX +XXX,XX @@ static uint32_t syscfg_readl(unsigned int offset)
130
131
static void syscfg_set_irq(int num, int level)
132
{
133
- qtest_set_irq_in(global_qtest, "/machine/soc/syscfg",
134
- NULL, num, level);
135
+ qtest_set_irq_in(global_qtest, SYSCFG, NULL, num, level);
73
}
136
}
74
137
75
+#define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */
138
static void system_reset(void)
76
+static void versal_create_sds(Versal *s, qemu_irq *pic)
139
@@ -XXX,XX +XXX,XX @@ static void test_interrupt(void)
77
+{
140
* Test that GPIO rising lines result in an irq
78
+ int i;
141
* with the right configuration
79
+
142
*/
80
+ for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
143
- qtest_irq_intercept_in(global_qtest, "/machine/soc/exti");
81
+ DeviceState *dev;
144
+ qtest_irq_intercept_in(global_qtest, EXTI);
82
+ MemoryRegion *mr;
145
83
+
146
/* GPIOA is the default source for EXTI lines 0 to 15 */
84
+ sysbus_init_child_obj(OBJECT(s), "sd[*]",
147
85
+ &s->pmc.iou.sd[i], sizeof(s->pmc.iou.sd[i]),
148
@@ -XXX,XX +XXX,XX @@ static void test_irq_pin_multiplexer(void)
86
+ TYPE_SYSBUS_SDHCI);
149
* Test that syscfg irq sets the right exti irq
87
+ dev = DEVICE(&s->pmc.iou.sd[i]);
150
*/
88
+
151
89
+ object_property_set_uint(OBJECT(dev),
152
- qtest_irq_intercept_in(global_qtest, "/machine/soc/exti");
90
+ 3, "sd-spec-version", &error_fatal);
153
+ qtest_irq_intercept_in(global_qtest, EXTI);
91
+ object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg",
154
92
+ &error_fatal);
155
syscfg_set_irq(0, 1);
93
+ object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal);
156
94
+ qdev_init_nofail(dev);
157
@@ -XXX,XX +XXX,XX @@ static void test_irq_gpio_multiplexer(void)
95
+
158
* Test that an irq is generated only by the right GPIO
96
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
159
*/
97
+ memory_region_add_subregion(&s->mr_ps,
160
98
+ MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
161
- qtest_irq_intercept_in(global_qtest, "/machine/soc/exti");
99
+
162
+ qtest_irq_intercept_in(global_qtest, EXTI);
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
163
101
+ pic[VERSAL_SD0_IRQ_0 + i * 2]);
164
/* GPIOA is the default source for EXTI lines 0 to 15 */
102
+ }
103
+}
104
+
105
/* This takes the board allocated linear DDR memory and creates aliases
106
* for each split DDR range/aperture on the Versal address map.
107
*/
108
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
109
versal_create_uarts(s, pic);
110
versal_create_gems(s, pic);
111
versal_create_admas(s, pic);
112
+ versal_create_sds(s, pic);
113
versal_map_ddr(s);
114
versal_unimp(s);
115
165
116
--
166
--
117
2.20.1
167
2.34.1
118
168
119
169
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Embed the APUs into the SoC type.
3
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
4
4
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Message-id: 20240424200929.240921-4-ines.varhol@telecom-paris.fr
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-8-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
8
---
13
include/hw/arm/xlnx-versal.h | 2 +-
9
hw/arm/b-l475e-iot01a.c | 46 ++++++++++++++++++++++++++++-------------
14
hw/arm/xlnx-versal-virt.c | 4 ++--
10
1 file changed, 32 insertions(+), 14 deletions(-)
15
hw/arm/xlnx-versal.c | 19 +++++--------------
16
3 files changed, 8 insertions(+), 17 deletions(-)
17
11
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
12
diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/xlnx-versal.h
14
--- a/hw/arm/b-l475e-iot01a.c
21
+++ b/include/hw/arm/xlnx-versal.h
15
+++ b/hw/arm/b-l475e-iot01a.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
16
@@ -XXX,XX +XXX,XX @@
23
struct {
17
* B-L475E-IOT01A Discovery Kit machine
24
struct {
18
* (B-L475E-IOT01A IoT Node)
25
MemoryRegion mr;
19
*
26
- ARMCPU *cpu[XLNX_VERSAL_NR_ACPUS];
20
- * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
27
+ ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
21
- * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
28
GICv3State gic;
22
+ * Copyright (c) 2023-2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
29
} apu;
23
+ * Copyright (c) 2023-2024 Inès Varhol <ines.varhol@telecom-paris.fr>
30
} fpd;
24
*
31
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
25
* SPDX-License-Identifier: GPL-2.0-or-later
32
index XXXXXXX..XXXXXXX 100644
26
*
33
--- a/hw/arm/xlnx-versal-virt.c
27
@@ -XXX,XX +XXX,XX @@
34
+++ b/hw/arm/xlnx-versal-virt.c
28
35
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
29
/* B-L475E-IOT01A implementation is derived from netduinoplus2 */
36
s->binfo.get_dtb = versal_virt_get_dtb;
30
37
s->binfo.modify_dtb = versal_virt_modify_dtb;
31
-static void b_l475e_iot01a_init(MachineState *machine)
38
if (machine->kernel_filename) {
32
+#define TYPE_B_L475E_IOT01A MACHINE_TYPE_NAME("b-l475e-iot01a")
39
- arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo);
33
+OBJECT_DECLARE_SIMPLE_TYPE(Bl475eMachineState, B_L475E_IOT01A)
40
+ arm_load_kernel(&s->soc.fpd.apu.cpu[0], machine, &s->binfo);
34
+
41
} else {
35
+typedef struct Bl475eMachineState {
42
- AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
36
+ MachineState parent_obj;
43
+ AddressSpace *as = arm_boot_address_space(&s->soc.fpd.apu.cpu[0],
37
+
44
&s->binfo);
38
+ Stm32l4x5SocState soc;
45
/* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
39
+} Bl475eMachineState;
46
* Offset things by 4K. */
40
+
47
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
41
+static void bl475e_init(MachineState *machine)
48
index XXXXXXX..XXXXXXX 100644
42
{
49
--- a/hw/arm/xlnx-versal.c
43
+ Bl475eMachineState *s = B_L475E_IOT01A(machine);
50
+++ b/hw/arm/xlnx-versal.c
44
const Stm32l4x5SocClass *sc;
51
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
45
- DeviceState *dev;
52
46
53
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
47
- dev = qdev_new(TYPE_STM32L4X5XG_SOC);
54
Object *obj;
48
- object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
55
- char *name;
49
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
56
-
50
+ object_initialize_child(OBJECT(machine), "soc", &s->soc,
57
- obj = object_new(XLNX_VERSAL_ACPU_TYPE);
51
+ TYPE_STM32L4X5XG_SOC);
58
- if (!obj) {
52
+ sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);
59
- error_report("Unable to create apu.cpu[%d] of type %s",
53
60
- i, XLNX_VERSAL_ACPU_TYPE);
54
- sc = STM32L4X5_SOC_GET_CLASS(dev);
61
- exit(EXIT_FAILURE);
55
- armv7m_load_kernel(ARM_CPU(first_cpu),
62
- }
56
- machine->kernel_filename,
63
-
57
- 0, sc->flash_size);
64
- name = g_strdup_printf("apu-cpu[%d]", i);
58
+ sc = STM32L4X5_SOC_GET_CLASS(&s->soc);
65
- object_property_add_child(OBJECT(s), name, obj, &error_fatal);
59
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0,
66
- g_free(name);
60
+ sc->flash_size);
67
68
+ object_initialize_child(OBJECT(s), "apu-cpu[*]",
69
+ &s->fpd.apu.cpu[i], sizeof(s->fpd.apu.cpu[i]),
70
+ XLNX_VERSAL_ACPU_TYPE, &error_abort, NULL);
71
+ obj = OBJECT(&s->fpd.apu.cpu[i]);
72
object_property_set_int(obj, s->cfg.psci_conduit,
73
"psci-conduit", &error_abort);
74
if (i) {
75
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
76
object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory",
77
&error_abort);
78
object_property_set_bool(obj, true, "realized", &error_fatal);
79
- s->fpd.apu.cpu[i] = ARM_CPU(obj);
80
}
81
}
61
}
82
62
83
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
63
-static void b_l475e_iot01a_machine_init(MachineClass *mc)
84
}
64
+static void bl475e_machine_init(ObjectClass *oc, void *data)
85
65
{
86
for (i = 0; i < nr_apu_cpus; i++) {
66
+ MachineClass *mc = MACHINE_CLASS(oc);
87
- DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
67
static const char *machine_valid_cpu_types[] = {
88
+ DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
68
ARM_CPU_TYPE_NAME("cortex-m4"),
89
int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
69
NULL
90
qemu_irq maint_irq;
70
};
91
int ti;
71
mc->desc = "B-L475E-IOT01A Discovery Kit (Cortex-M4)";
72
- mc->init = b_l475e_iot01a_init;
73
+ mc->init = bl475e_init;
74
mc->valid_cpu_types = machine_valid_cpu_types;
75
76
/* SRAM pre-allocated as part of the SoC instantiation */
77
mc->default_ram_size = 0;
78
}
79
80
-DEFINE_MACHINE("b-l475e-iot01a", b_l475e_iot01a_machine_init)
81
+static const TypeInfo bl475e_machine_type[] = {
82
+ {
83
+ .name = TYPE_B_L475E_IOT01A,
84
+ .parent = TYPE_MACHINE,
85
+ .instance_size = sizeof(Bl475eMachineState),
86
+ .class_init = bl475e_machine_init,
87
+ }
88
+};
89
+
90
+DEFINE_TYPES(bl475e_machine_type)
92
--
91
--
93
2.20.1
92
2.34.1
94
93
95
94
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Add support for the RTC.
3
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
4
4
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-id: 20240424200929.240921-5-ines.varhol@telecom-paris.fr
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20200427181649.26851-12-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
8
---
11
hw/arm/xlnx-versal-virt.c | 22 ++++++++++++++++++++++
9
hw/arm/b-l475e-iot01a.c | 59 +++++++++++++++++++++++++++++++++++++++--
12
1 file changed, 22 insertions(+)
10
hw/arm/Kconfig | 1 +
11
2 files changed, 58 insertions(+), 2 deletions(-)
13
12
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
13
diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
15
--- a/hw/arm/b-l475e-iot01a.c
17
+++ b/hw/arm/xlnx-versal-virt.c
16
+++ b/hw/arm/b-l475e-iot01a.c
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_sd_nodes(VersalVirt *s)
17
@@ -XXX,XX +XXX,XX @@
19
}
18
#include "hw/boards.h"
19
#include "hw/qdev-properties.h"
20
#include "qemu/error-report.h"
21
-#include "hw/arm/stm32l4x5_soc.h"
22
#include "hw/arm/boot.h"
23
+#include "hw/core/split-irq.h"
24
+#include "hw/arm/stm32l4x5_soc.h"
25
+#include "hw/gpio/stm32l4x5_gpio.h"
26
+#include "hw/display/dm163.h"
27
28
-/* B-L475E-IOT01A implementation is derived from netduinoplus2 */
29
+/* B-L475E-IOT01A implementation is inspired from netduinoplus2 and arduino */
30
+
31
+/*
32
+ * There are actually 14 input pins in the DM163 device.
33
+ * Here the DM163 input pin EN isn't connected to the STM32L4x5
34
+ * GPIOs as the IM120417002 colors shield doesn't actually use
35
+ * this pin to drive the RGB matrix.
36
+ */
37
+#define NUM_DM163_INPUTS 13
38
+
39
+static const unsigned dm163_input[NUM_DM163_INPUTS] = {
40
+ 1 * GPIO_NUM_PINS + 2, /* ROW0 PB2 */
41
+ 0 * GPIO_NUM_PINS + 15, /* ROW1 PA15 */
42
+ 0 * GPIO_NUM_PINS + 2, /* ROW2 PA2 */
43
+ 0 * GPIO_NUM_PINS + 7, /* ROW3 PA7 */
44
+ 0 * GPIO_NUM_PINS + 6, /* ROW4 PA6 */
45
+ 0 * GPIO_NUM_PINS + 5, /* ROW5 PA5 */
46
+ 1 * GPIO_NUM_PINS + 0, /* ROW6 PB0 */
47
+ 0 * GPIO_NUM_PINS + 3, /* ROW7 PA3 */
48
+ 0 * GPIO_NUM_PINS + 4, /* SIN (SDA) PA4 */
49
+ 1 * GPIO_NUM_PINS + 1, /* DCK (SCK) PB1 */
50
+ 2 * GPIO_NUM_PINS + 3, /* RST_B (RST) PC3 */
51
+ 2 * GPIO_NUM_PINS + 4, /* LAT_B (LAT) PC4 */
52
+ 2 * GPIO_NUM_PINS + 5, /* SELBK (SB) PC5 */
53
+};
54
55
#define TYPE_B_L475E_IOT01A MACHINE_TYPE_NAME("b-l475e-iot01a")
56
OBJECT_DECLARE_SIMPLE_TYPE(Bl475eMachineState, B_L475E_IOT01A)
57
@@ -XXX,XX +XXX,XX @@ typedef struct Bl475eMachineState {
58
MachineState parent_obj;
59
60
Stm32l4x5SocState soc;
61
+ SplitIRQ gpio_splitters[NUM_DM163_INPUTS];
62
+ DM163State dm163;
63
} Bl475eMachineState;
64
65
static void bl475e_init(MachineState *machine)
66
{
67
Bl475eMachineState *s = B_L475E_IOT01A(machine);
68
const Stm32l4x5SocClass *sc;
69
+ DeviceState *dev, *gpio_out_splitter;
70
+ unsigned gpio, pin;
71
72
object_initialize_child(OBJECT(machine), "soc", &s->soc,
73
TYPE_STM32L4X5XG_SOC);
74
@@ -XXX,XX +XXX,XX @@ static void bl475e_init(MachineState *machine)
75
sc = STM32L4X5_SOC_GET_CLASS(&s->soc);
76
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0,
77
sc->flash_size);
78
+
79
+ if (object_class_by_name(TYPE_DM163)) {
80
+ object_initialize_child(OBJECT(machine), "dm163",
81
+ &s->dm163, TYPE_DM163);
82
+ dev = DEVICE(&s->dm163);
83
+ qdev_realize(dev, NULL, &error_abort);
84
+
85
+ for (unsigned i = 0; i < NUM_DM163_INPUTS; i++) {
86
+ object_initialize_child(OBJECT(machine), "gpio-out-splitters[*]",
87
+ &s->gpio_splitters[i], TYPE_SPLIT_IRQ);
88
+ gpio_out_splitter = DEVICE(&s->gpio_splitters[i]);
89
+ qdev_prop_set_uint32(gpio_out_splitter, "num-lines", 2);
90
+ qdev_realize(gpio_out_splitter, NULL, &error_fatal);
91
+
92
+ qdev_connect_gpio_out(gpio_out_splitter, 0,
93
+ qdev_get_gpio_in(DEVICE(&s->soc), dm163_input[i]));
94
+ qdev_connect_gpio_out(gpio_out_splitter, 1,
95
+ qdev_get_gpio_in(dev, i));
96
+ gpio = dm163_input[i] / GPIO_NUM_PINS;
97
+ pin = dm163_input[i] % GPIO_NUM_PINS;
98
+ qdev_connect_gpio_out(DEVICE(&s->soc.gpio[gpio]), pin,
99
+ qdev_get_gpio_in(DEVICE(gpio_out_splitter), 0));
100
+ }
101
+ }
20
}
102
}
21
103
22
+static void fdt_add_rtc_node(VersalVirt *s)
104
static void bl475e_machine_init(ObjectClass *oc, void *data)
23
+{
105
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
24
+ const char compat[] = "xlnx,zynqmp-rtc";
106
index XXXXXXX..XXXXXXX 100644
25
+ const char interrupt_names[] = "alarm\0sec";
107
--- a/hw/arm/Kconfig
26
+ char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
108
+++ b/hw/arm/Kconfig
27
+
109
@@ -XXX,XX +XXX,XX @@ config B_L475E_IOT01A
28
+ qemu_fdt_add_subnode(s->fdt, name);
110
default y
29
+
111
depends on TCG && ARM
30
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
112
select STM32L4X5_SOC
31
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_ALARM_IRQ,
113
+ imply DM163
32
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI,
114
33
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_SECONDS_IRQ,
115
config STM32L4X5_SOC
34
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
116
bool
35
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
36
+ interrupt_names, sizeof(interrupt_names));
37
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
38
+ 2, MM_PMC_RTC, 2, MM_PMC_RTC_SIZE);
39
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
40
+ g_free(name);
41
+}
42
+
43
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
44
{
45
Error *err = NULL;
46
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
47
fdt_add_timer_nodes(s);
48
fdt_add_zdma_nodes(s);
49
fdt_add_sd_nodes(s);
50
+ fdt_add_rtc_node(s);
51
fdt_add_cpu_nodes(s, psci_conduit);
52
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
53
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
54
--
117
--
55
2.20.1
118
2.34.1
56
119
57
120
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Remove inclusion of arm_gicv3_common.h, this already gets
3
`test_dm163_bank()`
4
included via xlnx-versal.h.
4
Checks that the pin "sout" of the DM163 led driver outputs the values
5
5
received on pin "sin" with the expected latency (depending on the bank).
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
`test_dm163_gpio_connection()`
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Check that changes to relevant STM32L4x5 GPIO pins are propagated to the
9
Message-id: 20200427181649.26851-2-edgar.iglesias@gmail.com
9
DM163 device.
10
11
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
12
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
13
Acked-by: Thomas Huth <thuth@redhat.com>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Message-id: 20240424200929.240921-6-ines.varhol@telecom-paris.fr
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
hw/arm/xlnx-versal.c | 1 -
18
tests/qtest/dm163-test.c | 194 +++++++++++++++++++++++++++++++++++++++
13
1 file changed, 1 deletion(-)
19
tests/qtest/meson.build | 2 +
14
20
2 files changed, 196 insertions(+)
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
21
create mode 100644 tests/qtest/dm163-test.c
22
23
diff --git a/tests/qtest/dm163-test.c b/tests/qtest/dm163-test.c
24
new file mode 100644
25
index XXXXXXX..XXXXXXX
26
--- /dev/null
27
+++ b/tests/qtest/dm163-test.c
28
@@ -XXX,XX +XXX,XX @@
29
+/*
30
+ * QTest testcase for DM163
31
+ *
32
+ * Copyright (C) 2024 Samuel Tardieu <sam@rfc1149.net>
33
+ * Copyright (C) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
34
+ * Copyright (C) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
35
+ *
36
+ * SPDX-License-Identifier: GPL-2.0-or-later
37
+ */
38
+
39
+#include "qemu/osdep.h"
40
+#include "libqtest.h"
41
+
42
+enum DM163_INPUTS {
43
+ SIN = 8,
44
+ DCK = 9,
45
+ RST_B = 10,
46
+ LAT_B = 11,
47
+ SELBK = 12,
48
+ EN_B = 13
49
+};
50
+
51
+#define DEVICE_NAME "/machine/dm163"
52
+#define GPIO_OUT(name, value) qtest_set_irq_in(qts, DEVICE_NAME, NULL, name, \
53
+ value)
54
+#define GPIO_PULSE(name) \
55
+ do { \
56
+ GPIO_OUT(name, 1); \
57
+ GPIO_OUT(name, 0); \
58
+ } while (0)
59
+
60
+
61
+static void rise_gpio_pin_dck(QTestState *qts)
62
+{
63
+ /* Configure output mode for pin PB1 */
64
+ qtest_writel(qts, 0x48000400, 0xFFFFFEB7);
65
+ /* Write 1 in ODR for PB1 */
66
+ qtest_writel(qts, 0x48000414, 0x00000002);
67
+}
68
+
69
+static void lower_gpio_pin_dck(QTestState *qts)
70
+{
71
+ /* Configure output mode for pin PB1 */
72
+ qtest_writel(qts, 0x48000400, 0xFFFFFEB7);
73
+ /* Write 0 in ODR for PB1 */
74
+ qtest_writel(qts, 0x48000414, 0x00000000);
75
+}
76
+
77
+static void rise_gpio_pin_selbk(QTestState *qts)
78
+{
79
+ /* Configure output mode for pin PC5 */
80
+ qtest_writel(qts, 0x48000800, 0xFFFFF7FF);
81
+ /* Write 1 in ODR for PC5 */
82
+ qtest_writel(qts, 0x48000814, 0x00000020);
83
+}
84
+
85
+static void lower_gpio_pin_selbk(QTestState *qts)
86
+{
87
+ /* Configure output mode for pin PC5 */
88
+ qtest_writel(qts, 0x48000800, 0xFFFFF7FF);
89
+ /* Write 0 in ODR for PC5 */
90
+ qtest_writel(qts, 0x48000814, 0x00000000);
91
+}
92
+
93
+static void rise_gpio_pin_lat_b(QTestState *qts)
94
+{
95
+ /* Configure output mode for pin PC4 */
96
+ qtest_writel(qts, 0x48000800, 0xFFFFFDFF);
97
+ /* Write 1 in ODR for PC4 */
98
+ qtest_writel(qts, 0x48000814, 0x00000010);
99
+}
100
+
101
+static void lower_gpio_pin_lat_b(QTestState *qts)
102
+{
103
+ /* Configure output mode for pin PC4 */
104
+ qtest_writel(qts, 0x48000800, 0xFFFFFDFF);
105
+ /* Write 0 in ODR for PC4 */
106
+ qtest_writel(qts, 0x48000814, 0x00000000);
107
+}
108
+
109
+static void rise_gpio_pin_rst_b(QTestState *qts)
110
+{
111
+ /* Configure output mode for pin PC3 */
112
+ qtest_writel(qts, 0x48000800, 0xFFFFFF7F);
113
+ /* Write 1 in ODR for PC3 */
114
+ qtest_writel(qts, 0x48000814, 0x00000008);
115
+}
116
+
117
+static void lower_gpio_pin_rst_b(QTestState *qts)
118
+{
119
+ /* Configure output mode for pin PC3 */
120
+ qtest_writel(qts, 0x48000800, 0xFFFFFF7F);
121
+ /* Write 0 in ODR for PC3 */
122
+ qtest_writel(qts, 0x48000814, 0x00000000);
123
+}
124
+
125
+static void rise_gpio_pin_sin(QTestState *qts)
126
+{
127
+ /* Configure output mode for pin PA4 */
128
+ qtest_writel(qts, 0x48000000, 0xFFFFFDFF);
129
+ /* Write 1 in ODR for PA4 */
130
+ qtest_writel(qts, 0x48000014, 0x00000010);
131
+}
132
+
133
+static void lower_gpio_pin_sin(QTestState *qts)
134
+{
135
+ /* Configure output mode for pin PA4 */
136
+ qtest_writel(qts, 0x48000000, 0xFFFFFDFF);
137
+ /* Write 0 in ODR for PA4 */
138
+ qtest_writel(qts, 0x48000014, 0x00000000);
139
+}
140
+
141
+static void test_dm163_bank(const void *opaque)
142
+{
143
+ const unsigned bank = (uintptr_t) opaque;
144
+ const int width = bank ? 192 : 144;
145
+
146
+ QTestState *qts = qtest_initf("-M b-l475e-iot01a");
147
+ qtest_irq_intercept_out_named(qts, DEVICE_NAME, "sout");
148
+ GPIO_OUT(RST_B, 1);
149
+ GPIO_OUT(EN_B, 0);
150
+ GPIO_OUT(DCK, 0);
151
+ GPIO_OUT(SELBK, bank);
152
+ GPIO_OUT(LAT_B, 1);
153
+
154
+ /* Fill bank with zeroes */
155
+ GPIO_OUT(SIN, 0);
156
+ for (int i = 0; i < width; i++) {
157
+ GPIO_PULSE(DCK);
158
+ }
159
+ /* Fill bank with ones, check that we get the previous zeroes */
160
+ GPIO_OUT(SIN, 1);
161
+ for (int i = 0; i < width; i++) {
162
+ GPIO_PULSE(DCK);
163
+ g_assert(!qtest_get_irq(qts, 0));
164
+ }
165
+
166
+ /* Pulse one more bit in the bank, check that we get a one */
167
+ GPIO_PULSE(DCK);
168
+ g_assert(qtest_get_irq(qts, 0));
169
+
170
+ qtest_quit(qts);
171
+}
172
+
173
+static void test_dm163_gpio_connection(void)
174
+{
175
+ QTestState *qts = qtest_init("-M b-l475e-iot01a");
176
+ qtest_irq_intercept_in(qts, DEVICE_NAME);
177
+
178
+ g_assert_false(qtest_get_irq(qts, SIN));
179
+ g_assert_false(qtest_get_irq(qts, DCK));
180
+ g_assert_false(qtest_get_irq(qts, RST_B));
181
+ g_assert_false(qtest_get_irq(qts, LAT_B));
182
+ g_assert_false(qtest_get_irq(qts, SELBK));
183
+
184
+ rise_gpio_pin_dck(qts);
185
+ g_assert_true(qtest_get_irq(qts, DCK));
186
+ lower_gpio_pin_dck(qts);
187
+ g_assert_false(qtest_get_irq(qts, DCK));
188
+
189
+ rise_gpio_pin_lat_b(qts);
190
+ g_assert_true(qtest_get_irq(qts, LAT_B));
191
+ lower_gpio_pin_lat_b(qts);
192
+ g_assert_false(qtest_get_irq(qts, LAT_B));
193
+
194
+ rise_gpio_pin_selbk(qts);
195
+ g_assert_true(qtest_get_irq(qts, SELBK));
196
+ lower_gpio_pin_selbk(qts);
197
+ g_assert_false(qtest_get_irq(qts, SELBK));
198
+
199
+ rise_gpio_pin_rst_b(qts);
200
+ g_assert_true(qtest_get_irq(qts, RST_B));
201
+ lower_gpio_pin_rst_b(qts);
202
+ g_assert_false(qtest_get_irq(qts, RST_B));
203
+
204
+ rise_gpio_pin_sin(qts);
205
+ g_assert_true(qtest_get_irq(qts, SIN));
206
+ lower_gpio_pin_sin(qts);
207
+ g_assert_false(qtest_get_irq(qts, SIN));
208
+
209
+ g_assert_false(qtest_get_irq(qts, DCK));
210
+ g_assert_false(qtest_get_irq(qts, LAT_B));
211
+ g_assert_false(qtest_get_irq(qts, SELBK));
212
+ g_assert_false(qtest_get_irq(qts, RST_B));
213
+}
214
+
215
+int main(int argc, char **argv)
216
+{
217
+ g_test_init(&argc, &argv, NULL);
218
+ qtest_add_data_func("/dm163/bank0", (void *)0, test_dm163_bank);
219
+ qtest_add_data_func("/dm163/bank1", (void *)1, test_dm163_bank);
220
+ qtest_add_func("/dm163/gpio_connection", test_dm163_gpio_connection);
221
+ return g_test_run();
222
+}
223
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
16
index XXXXXXX..XXXXXXX 100644
224
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
225
--- a/tests/qtest/meson.build
18
+++ b/hw/arm/xlnx-versal.c
226
+++ b/tests/qtest/meson.build
19
@@ -XXX,XX +XXX,XX @@
227
@@ -XXX,XX +XXX,XX @@ qtests_arm = \
20
#include "hw/arm/boot.h"
228
(config_all_devices.has_key('CONFIG_MICROBIT') ? ['microbit-test'] : []) + \
21
#include "kvm_arm.h"
229
(config_all_devices.has_key('CONFIG_STM32L4X5_SOC') ? qtests_stm32l4x5 : []) + \
22
#include "hw/misc/unimp.h"
230
(config_all_devices.has_key('CONFIG_FSI_APB2OPB_ASPEED') ? ['aspeed_fsi-test'] : []) + \
23
-#include "hw/intc/arm_gicv3_common.h"
231
+ (config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and
24
#include "hw/arm/xlnx-versal.h"
232
+ config_all_devices.has_key('CONFIG_DM163')? ['dm163-test'] : []) + \
25
#include "hw/char/pl011.h"
233
['arm-cpu-features',
234
'boot-serial-test']
26
235
27
--
236
--
28
2.20.1
237
2.34.1
29
238
30
239
diff view generated by jsdifflib
Deleted patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
1
3
Move misplaced comment.
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-3-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/xlnx-versal.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
18
+++ b/hw/arm/xlnx-versal.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
20
21
obj = object_new(XLNX_VERSAL_ACPU_TYPE);
22
if (!obj) {
23
- /* Secondary CPUs start in PSCI powered-down state */
24
error_report("Unable to create apu.cpu[%d] of type %s",
25
i, XLNX_VERSAL_ACPU_TYPE);
26
exit(EXIT_FAILURE);
27
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
28
object_property_set_int(obj, s->cfg.psci_conduit,
29
"psci-conduit", &error_abort);
30
if (i) {
31
+ /* Secondary CPUs start in PSCI powered-down state */
32
object_property_set_bool(obj, true,
33
"start-powered-off", &error_abort);
34
}
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
1
3
Fix typo xlnx-ve -> xlnx-versal.
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-4-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/xlnx-versal-virt.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal-virt.c
18
+++ b/hw/arm/xlnx-versal-virt.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
20
psci_conduit = QEMU_PSCI_CONDUIT_SMC;
21
}
22
23
- sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
24
+ sysbus_init_child_obj(OBJECT(machine), "xlnx-versal", &s->soc,
25
sizeof(s->soc), TYPE_XLNX_VERSAL);
26
object_property_set_link(OBJECT(&s->soc), OBJECT(machine->ram),
27
"ddr", &error_abort);
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
Deleted patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
1
3
Embed the ADMAs into the SoC type.
4
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-7-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
14
hw/arm/xlnx-versal.c | 14 +++++++-------
15
2 files changed, 9 insertions(+), 8 deletions(-)
16
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
20
+++ b/include/hw/arm/xlnx-versal.h
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/arm/boot.h"
23
#include "hw/intc/arm_gicv3.h"
24
#include "hw/char/pl011.h"
25
+#include "hw/dma/xlnx-zdma.h"
26
#include "hw/net/cadence_gem.h"
27
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
struct {
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
33
- SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
34
+ XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
35
} iou;
36
} lpd;
37
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
43
DeviceState *dev;
44
MemoryRegion *mr;
45
46
- dev = qdev_create(NULL, "xlnx.zdma");
47
- s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
48
- object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
49
- &error_abort);
50
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
51
+ sysbus_init_child_obj(OBJECT(s), name,
52
+ &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]),
53
+ TYPE_XLNX_ZDMA);
54
+ dev = DEVICE(&s->lpd.iou.adma[i]);
55
+ object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort);
56
qdev_init_nofail(dev);
57
58
- mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
59
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
60
memory_region_add_subregion(&s->mr_ps,
61
MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
62
63
- sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
64
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
65
g_free(name);
66
}
67
}
68
--
69
2.20.1
70
71
diff view generated by jsdifflib
Deleted patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
1
3
hw/arm: versal: Add support for the RTC.
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-10-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/xlnx-versal.h | 8 ++++++++
13
hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
14
2 files changed, 29 insertions(+)
15
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
19
+++ b/include/hw/arm/xlnx-versal.h
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/char/pl011.h"
22
#include "hw/dma/xlnx-zdma.h"
23
#include "hw/net/cadence_gem.h"
24
+#include "hw/rtc/xlnx-zynqmp-rtc.h"
25
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
28
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
29
struct {
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
31
} iou;
32
+
33
+ XlnxZynqMPRTC rtc;
34
} pmc;
35
36
struct {
37
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
38
#define VERSAL_GEM1_IRQ_0 58
39
#define VERSAL_GEM1_WAKE_IRQ_0 59
40
#define VERSAL_ADMA_IRQ_0 60
41
+#define VERSAL_RTC_APB_ERR_IRQ 121
42
#define VERSAL_SD0_IRQ_0 126
43
+#define VERSAL_RTC_ALARM_IRQ 142
44
+#define VERSAL_RTC_SECONDS_IRQ 143
45
46
/* Architecturally reserved IRQs suitable for virtualization. */
47
#define VERSAL_RSVD_IRQ_FIRST 111
48
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
49
#define MM_PMC_SD0_SIZE 0x10000
50
#define MM_PMC_CRP 0xf1260000U
51
#define MM_PMC_CRP_SIZE 0x10000
52
+#define MM_PMC_RTC 0xf12a0000
53
+#define MM_PMC_RTC_SIZE 0x10000
54
#endif
55
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/xlnx-versal.c
58
+++ b/hw/arm/xlnx-versal.c
59
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
60
}
61
}
62
63
+static void versal_create_rtc(Versal *s, qemu_irq *pic)
64
+{
65
+ SysBusDevice *sbd;
66
+ MemoryRegion *mr;
67
+
68
+ sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc),
69
+ TYPE_XLNX_ZYNQMP_RTC);
70
+ sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
71
+ qdev_init_nofail(DEVICE(sbd));
72
+
73
+ mr = sysbus_mmio_get_region(sbd, 0);
74
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
75
+
76
+ /*
77
+ * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
78
+ * supports them.
79
+ */
80
+ sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
81
+}
82
+
83
/* This takes the board allocated linear DDR memory and creates aliases
84
* for each split DDR range/aperture on the Versal address map.
85
*/
86
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
87
versal_create_gems(s, pic);
88
versal_create_admas(s, pic);
89
versal_create_sds(s, pic);
90
+ versal_create_rtc(s, pic);
91
versal_map_ddr(s);
92
versal_unimp(s);
93
94
--
95
2.20.1
96
97
diff view generated by jsdifflib
Deleted patch
1
Somewhere along theline we accidentally added a duplicate
2
"using D16-D31 when they don't exist" check to do_vfm_dp()
3
(probably an artifact of a patchseries rebase). Remove it.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200430181003.21682-2-peter.maydell@linaro.org
9
---
10
target/arm/translate-vfp.inc.c | 6 ------
11
1 file changed, 6 deletions(-)
12
13
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-vfp.inc.c
16
+++ b/target/arm/translate-vfp.inc.c
17
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
18
return false;
19
}
20
21
- /* UNDEF accesses to D16-D31 if they don't exist. */
22
- if (!dc_isar_feature(aa32_simd_r32, s) &&
23
- ((a->vd | a->vn | a->vm) & 0x10)) {
24
- return false;
25
- }
26
-
27
if (!vfp_access_check(s)) {
28
return true;
29
}
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
Deleted patch
1
We were accidentally permitting decode of Thumb Neon insns even if
2
the CPU didn't have the FEATURE_NEON bit set, because the feature
3
check was being done before the call to disas_neon_data_insn() and
4
disas_neon_ls_insn() in the Arm decoder but was omitted from the
5
Thumb decoder. Push the feature bit check down into the called
6
functions so it is done for both Arm and Thumb encodings.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200430181003.21682-3-peter.maydell@linaro.org
12
---
13
target/arm/translate.c | 16 ++++++++--------
14
1 file changed, 8 insertions(+), 8 deletions(-)
15
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
19
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
21
TCGv_i32 tmp2;
22
TCGv_i64 tmp64;
23
24
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
25
+ return 1;
26
+ }
27
+
28
/* FIXME: this access check should not take precedence over UNDEF
29
* for invalid encodings; we will generate incorrect syndrome information
30
* for attempts to execute invalid vfp/neon encodings with FP disabled.
31
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
32
TCGv_ptr ptr1, ptr2, ptr3;
33
TCGv_i64 tmp64;
34
35
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
36
+ return 1;
37
+ }
38
+
39
/* FIXME: this access check should not take precedence over UNDEF
40
* for invalid encodings; we will generate incorrect syndrome information
41
* for attempts to execute invalid vfp/neon encodings with FP disabled.
42
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
43
44
if (((insn >> 25) & 7) == 1) {
45
/* NEON Data processing. */
46
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
47
- goto illegal_op;
48
- }
49
-
50
if (disas_neon_data_insn(s, insn)) {
51
goto illegal_op;
52
}
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
54
}
55
if ((insn & 0x0f100000) == 0x04000000) {
56
/* NEON load/store. */
57
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
58
- goto illegal_op;
59
- }
60
-
61
if (disas_neon_ls_insn(s, insn)) {
62
goto illegal_op;
63
}
64
--
65
2.20.1
66
67
diff view generated by jsdifflib
Deleted patch
1
Convert the VCMLA (vector) insns in the 3same extension group to
2
decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-5-peter.maydell@linaro.org
7
---
8
target/arm/neon-shared.decode | 11 ++++++++++
9
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 11 +---------
11
3 files changed, 49 insertions(+), 10 deletions(-)
12
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@
18
# More specifically, this covers:
19
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
20
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
21
+
22
+# VFP/Neon register fields; same as vfp.decode
23
+%vm_dp 5:1 0:4
24
+%vm_sp 0:4 5:1
25
+%vn_dp 7:1 16:4
26
+%vn_sp 16:4 7:1
27
+%vd_dp 22:1 12:4
28
+%vd_sp 12:4 22:1
29
+
30
+VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
31
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
32
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.inc.c
35
+++ b/target/arm/translate-neon.inc.c
36
@@ -XXX,XX +XXX,XX @@
37
#include "decode-neon-dp.inc.c"
38
#include "decode-neon-ls.inc.c"
39
#include "decode-neon-shared.inc.c"
40
+
41
+static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
42
+{
43
+ int opr_sz;
44
+ TCGv_ptr fpst;
45
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
46
+
47
+ if (!dc_isar_feature(aa32_vcma, s)
48
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
49
+ return false;
50
+ }
51
+
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
54
+ ((a->vd | a->vn | a->vm) & 0x10)) {
55
+ return false;
56
+ }
57
+
58
+ if ((a->vn | a->vm | a->vd) & a->q) {
59
+ return false;
60
+ }
61
+
62
+ if (!vfp_access_check(s)) {
63
+ return true;
64
+ }
65
+
66
+ opr_sz = (1 + a->q) * 8;
67
+ fpst = get_fpstatus_ptr(1);
68
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
69
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
70
+ vfp_reg_offset(1, a->vn),
71
+ vfp_reg_offset(1, a->vm),
72
+ fpst, opr_sz, opr_sz, a->rot,
73
+ fn_gvec_ptr);
74
+ tcg_temp_free_ptr(fpst);
75
+ return true;
76
+}
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate.c
80
+++ b/target/arm/translate.c
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
82
bool is_long = false, q = extract32(insn, 6, 1);
83
bool ptr_is_env = false;
84
85
- if ((insn & 0xfe200f10) == 0xfc200800) {
86
- /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
87
- int size = extract32(insn, 20, 1);
88
- data = extract32(insn, 23, 2); /* rot */
89
- if (!dc_isar_feature(aa32_vcma, s)
90
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
91
- return 1;
92
- }
93
- fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
94
- } else if ((insn & 0xfea00f10) == 0xfc800800) {
95
+ if ((insn & 0xfea00f10) == 0xfc800800) {
96
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
97
int size = extract32(insn, 20, 1);
98
data = extract32(insn, 24, 1); /* rot */
99
--
100
2.20.1
101
102
diff view generated by jsdifflib
Deleted patch
1
Convert the VCADD (vector) insns to decodetree.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-6-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 3 +++
8
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 11 +---------
10
3 files changed, 41 insertions(+), 10 deletions(-)
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@
17
18
VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
+
21
+VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
22
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
23
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-neon.inc.c
26
+++ b/target/arm/translate-neon.inc.c
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
28
tcg_temp_free_ptr(fpst);
29
return true;
30
}
31
+
32
+static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
33
+{
34
+ int opr_sz;
35
+ TCGv_ptr fpst;
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
37
+
38
+ if (!dc_isar_feature(aa32_vcma, s)
39
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
40
+ return false;
41
+ }
42
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn | a->vm) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vn | a->vm | a->vd) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ opr_sz = (1 + a->q) * 8;
58
+ fpst = get_fpstatus_ptr(1);
59
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
60
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->vm),
63
+ fpst, opr_sz, opr_sz, a->rot,
64
+ fn_gvec_ptr);
65
+ tcg_temp_free_ptr(fpst);
66
+ return true;
67
+}
68
diff --git a/target/arm/translate.c b/target/arm/translate.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/translate.c
71
+++ b/target/arm/translate.c
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
73
bool is_long = false, q = extract32(insn, 6, 1);
74
bool ptr_is_env = false;
75
76
- if ((insn & 0xfea00f10) == 0xfc800800) {
77
- /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
78
- int size = extract32(insn, 20, 1);
79
- data = extract32(insn, 24, 1); /* rot */
80
- if (!dc_isar_feature(aa32_vcma, s)
81
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
82
- return 1;
83
- }
84
- fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
85
- } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
86
+ if ((insn & 0xfeb00f00) == 0xfc200d00) {
87
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
88
bool u = extract32(insn, 4, 1);
89
if (!dc_isar_feature(aa32_dp, s)) {
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
Convert the V[US]DOT (vector) insns to decodetree.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-7-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 4 ++++
8
target/arm/translate-neon.inc.c | 32 ++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 9 +--------
10
3 files changed, 37 insertions(+), 8 deletions(-)
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@ VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
17
18
VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
+
21
+# VUDOT and VSDOT
22
+VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
29
tcg_temp_free_ptr(fpst);
30
return true;
31
}
32
+
33
+static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
34
+{
35
+ int opr_sz;
36
+ gen_helper_gvec_3 *fn_gvec;
37
+
38
+ if (!dc_isar_feature(aa32_dp, s)) {
39
+ return false;
40
+ }
41
+
42
+ /* UNDEF accesses to D16-D31 if they don't exist. */
43
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
44
+ ((a->vd | a->vn | a->vm) & 0x10)) {
45
+ return false;
46
+ }
47
+
48
+ if ((a->vn | a->vm | a->vd) & a->q) {
49
+ return false;
50
+ }
51
+
52
+ if (!vfp_access_check(s)) {
53
+ return true;
54
+ }
55
+
56
+ opr_sz = (1 + a->q) * 8;
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
58
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
59
+ vfp_reg_offset(1, a->vn),
60
+ vfp_reg_offset(1, a->vm),
61
+ opr_sz, opr_sz, 0, fn_gvec);
62
+ return true;
63
+}
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
69
bool is_long = false, q = extract32(insn, 6, 1);
70
bool ptr_is_env = false;
71
72
- if ((insn & 0xfeb00f00) == 0xfc200d00) {
73
- /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
74
- bool u = extract32(insn, 4, 1);
75
- if (!dc_isar_feature(aa32_dp, s)) {
76
- return 1;
77
- }
78
- fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
79
- } else if ((insn & 0xff300f10) == 0xfc200810) {
80
+ if ((insn & 0xff300f10) == 0xfc200810) {
81
/* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
82
int is_s = extract32(insn, 23, 1);
83
if (!dc_isar_feature(aa32_fhm, s)) {
84
--
85
2.20.1
86
87
diff view generated by jsdifflib
Deleted patch
1
Convert the VFM[AS]L (vector) insns to decodetree. This is the last
2
insn in the legacy decoder for the 3same_ext group, so we can
3
delete the legacy decoder function for the group entirely.
4
1
5
Note that in disas_thumb2_insn() the parts of this encoding space
6
where the decodetree decoder returns false will correctly be directed
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-8-peter.maydell@linaro.org
13
---
14
target/arm/neon-shared.decode | 6 +++
15
target/arm/translate-neon.inc.c | 31 +++++++++++
16
target/arm/translate.c | 92 +--------------------------------
17
3 files changed, 38 insertions(+), 91 deletions(-)
18
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
22
+++ b/target/arm/neon-shared.decode
23
@@ -XXX,XX +XXX,XX @@ VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
24
# VUDOT and VSDOT
25
VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
+
28
+# VFM[AS]L
29
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
30
+ vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
31
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
32
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
36
+++ b/target/arm/translate-neon.inc.c
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
38
opr_sz, opr_sz, 0, fn_gvec);
39
return true;
40
}
41
+
42
+static bool trans_VFML(DisasContext *s, arg_VFML *a)
43
+{
44
+ int opr_sz;
45
+
46
+ if (!dc_isar_feature(aa32_fhm, s)) {
47
+ return false;
48
+ }
49
+
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
52
+ (a->vd & 0x10)) {
53
+ return false;
54
+ }
55
+
56
+ if (a->vd & a->q) {
57
+ return false;
58
+ }
59
+
60
+ if (!vfp_access_check(s)) {
61
+ return true;
62
+ }
63
+
64
+ opr_sz = (1 + a->q) * 8;
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(a->q, a->vn),
67
+ vfp_reg_offset(a->q, a->vm),
68
+ cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */
69
+ gen_helper_gvec_fmlal_a32);
70
+ return true;
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
return 0;
78
}
79
80
-/* Advanced SIMD three registers of the same length extension.
81
- * 31 25 23 22 20 16 12 11 10 9 8 3 0
82
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
83
- * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
84
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
85
- */
86
-static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
87
-{
88
- gen_helper_gvec_3 *fn_gvec = NULL;
89
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
90
- int rd, rn, rm, opr_sz;
91
- int data = 0;
92
- int off_rn, off_rm;
93
- bool is_long = false, q = extract32(insn, 6, 1);
94
- bool ptr_is_env = false;
95
-
96
- if ((insn & 0xff300f10) == 0xfc200810) {
97
- /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
98
- int is_s = extract32(insn, 23, 1);
99
- if (!dc_isar_feature(aa32_fhm, s)) {
100
- return 1;
101
- }
102
- is_long = true;
103
- data = is_s; /* is_2 == 0 */
104
- fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
105
- ptr_is_env = true;
106
- } else {
107
- return 1;
108
- }
109
-
110
- VFP_DREG_D(rd, insn);
111
- if (rd & q) {
112
- return 1;
113
- }
114
- if (q || !is_long) {
115
- VFP_DREG_N(rn, insn);
116
- VFP_DREG_M(rm, insn);
117
- if ((rn | rm) & q & !is_long) {
118
- return 1;
119
- }
120
- off_rn = vfp_reg_offset(1, rn);
121
- off_rm = vfp_reg_offset(1, rm);
122
- } else {
123
- rn = VFP_SREG_N(insn);
124
- rm = VFP_SREG_M(insn);
125
- off_rn = vfp_reg_offset(0, rn);
126
- off_rm = vfp_reg_offset(0, rm);
127
- }
128
-
129
- if (s->fp_excp_el) {
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
131
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
132
- return 0;
133
- }
134
- if (!s->vfp_enabled) {
135
- return 1;
136
- }
137
-
138
- opr_sz = (1 + q) * 8;
139
- if (fn_gvec_ptr) {
140
- TCGv_ptr ptr;
141
- if (ptr_is_env) {
142
- ptr = cpu_env;
143
- } else {
144
- ptr = get_fpstatus_ptr(1);
145
- }
146
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
147
- opr_sz, opr_sz, data, fn_gvec_ptr);
148
- if (!ptr_is_env) {
149
- tcg_temp_free_ptr(ptr);
150
- }
151
- } else {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
153
- opr_sz, opr_sz, data, fn_gvec);
154
- }
155
- return 0;
156
-}
157
-
158
/* Advanced SIMD two registers and a scalar extension.
159
* 31 24 23 22 20 16 12 11 10 9 8 3 0
160
* +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
161
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
162
}
163
}
164
}
165
- } else if ((insn & 0x0e000a00) == 0x0c000800
166
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
167
- if (disas_neon_insn_3same_ext(s, insn)) {
168
- goto illegal_op;
169
- }
170
- return;
171
} else if ((insn & 0x0f000a00) == 0x0e000800
172
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
173
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
174
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
175
}
176
break;
177
}
178
- if ((insn & 0xfe000a00) == 0xfc000800
179
+ if ((insn & 0xff000a00) == 0xfe000800
180
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
181
/* The Thumb2 and ARM encodings are identical. */
182
- if (disas_neon_insn_3same_ext(s, insn)) {
183
- goto illegal_op;
184
- }
185
- } else if ((insn & 0xff000a00) == 0xfe000800
186
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
187
- /* The Thumb2 and ARM encodings are identical. */
188
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
189
goto illegal_op;
190
}
191
--
192
2.20.1
193
194
diff view generated by jsdifflib
Deleted patch
1
Convert the V[US]DOT (scalar) insns in the 2reg-scalar-ext group
2
to decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-10-peter.maydell@linaro.org
7
---
8
target/arm/neon-shared.decode | 3 +++
9
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 13 +-----------
11
3 files changed, 39 insertions(+), 12 deletions(-)
12
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
18
vn=%vn_dp vd=%vd_dp size=0
19
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
21
+
22
+VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
29
tcg_temp_free_ptr(fpst);
30
return true;
31
}
32
+
33
+static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
34
+{
35
+ gen_helper_gvec_3 *fn_gvec;
36
+ int opr_sz;
37
+ TCGv_ptr fpst;
38
+
39
+ if (!dc_isar_feature(aa32_dp, s)) {
40
+ return false;
41
+ }
42
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vd | a->vn) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
58
+ opr_sz = (1 + a->q) * 8;
59
+ fpst = get_fpstatus_ptr(1);
60
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->rm),
63
+ opr_sz, opr_sz, a->index, fn_gvec);
64
+ tcg_temp_free_ptr(fpst);
65
+ return true;
66
+}
67
diff --git a/target/arm/translate.c b/target/arm/translate.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/translate.c
70
+++ b/target/arm/translate.c
71
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
72
bool is_long = false, q = extract32(insn, 6, 1);
73
bool ptr_is_env = false;
74
75
- if ((insn & 0xffb00f00) == 0xfe200d00) {
76
- /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
77
- int u = extract32(insn, 4, 1);
78
-
79
- if (!dc_isar_feature(aa32_dp, s)) {
80
- return 1;
81
- }
82
- fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
83
- /* rm is just Vm, and index is M. */
84
- data = extract32(insn, 5, 1); /* index */
85
- rm = extract32(insn, 0, 4);
86
- } else if ((insn & 0xffa00f10) == 0xfe000810) {
87
+ if ((insn & 0xffa00f10) == 0xfe000810) {
88
/* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
89
int is_s = extract32(insn, 20, 1);
90
int vm20 = extract32(insn, 0, 3);
91
--
92
2.20.1
93
94
diff view generated by jsdifflib
Deleted patch
1
Convert the VFM[AS]L (scalar) insns in the 2reg-scalar-ext group
2
to decodetree. These are the last ones in the group so we can remove
3
all the legacy decode for the group.
4
1
5
Note that in disas_thumb2_insn() the parts of this encoding space
6
where the decodetree decoder returns false will correctly be directed
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-11-peter.maydell@linaro.org
13
---
14
target/arm/neon-shared.decode | 7 +++
15
target/arm/translate-neon.inc.c | 32 ++++++++++
16
target/arm/translate.c | 107 +-------------------------------
17
3 files changed, 40 insertions(+), 106 deletions(-)
18
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
22
+++ b/target/arm/neon-shared.decode
23
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
24
25
VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
+
28
+%vfml_scalar_q0_rm 0:3 5:1
29
+%vfml_scalar_q1_index 5:1 3:1
30
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
31
+ rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
32
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
33
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-neon.inc.c
37
+++ b/target/arm/translate-neon.inc.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
39
tcg_temp_free_ptr(fpst);
40
return true;
41
}
42
+
43
+static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
44
+{
45
+ int opr_sz;
46
+
47
+ if (!dc_isar_feature(aa32_fhm, s)) {
48
+ return false;
49
+ }
50
+
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
53
+ ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) {
54
+ return false;
55
+ }
56
+
57
+ if (a->vd & a->q) {
58
+ return false;
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ opr_sz = (1 + a->q) * 8;
66
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
67
+ vfp_reg_offset(a->q, a->vn),
68
+ vfp_reg_offset(a->q, a->rm),
69
+ cpu_env, opr_sz, opr_sz,
70
+ (a->index << 2) | a->s, /* is_2 == 0 */
71
+ gen_helper_gvec_fmlal_idx_a32);
72
+ return true;
73
+}
74
diff --git a/target/arm/translate.c b/target/arm/translate.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/translate.c
77
+++ b/target/arm/translate.c
78
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
79
}
80
81
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
82
-#define VFP_SREG(insn, bigbit, smallbit) \
83
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
84
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
85
if (dc_isar_feature(aa32_simd_r32, s)) { \
86
reg = (((insn) >> (bigbit)) & 0x0f) \
87
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
88
reg = ((insn) >> (bigbit)) & 0x0f; \
89
}} while (0)
90
91
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
92
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
93
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
94
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
95
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
96
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
97
98
static void gen_neon_dup_low16(TCGv_i32 var)
99
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
100
return 0;
101
}
102
103
-/* Advanced SIMD two registers and a scalar extension.
104
- * 31 24 23 22 20 16 12 11 10 9 8 3 0
105
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
106
- * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
107
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
108
- *
109
- */
110
-
111
-static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
112
-{
113
- gen_helper_gvec_3 *fn_gvec = NULL;
114
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
115
- int rd, rn, rm, opr_sz, data;
116
- int off_rn, off_rm;
117
- bool is_long = false, q = extract32(insn, 6, 1);
118
- bool ptr_is_env = false;
119
-
120
- if ((insn & 0xffa00f10) == 0xfe000810) {
121
- /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
122
- int is_s = extract32(insn, 20, 1);
123
- int vm20 = extract32(insn, 0, 3);
124
- int vm3 = extract32(insn, 3, 1);
125
- int m = extract32(insn, 5, 1);
126
- int index;
127
-
128
- if (!dc_isar_feature(aa32_fhm, s)) {
129
- return 1;
130
- }
131
- if (q) {
132
- rm = vm20;
133
- index = m * 2 + vm3;
134
- } else {
135
- rm = vm20 * 2 + m;
136
- index = vm3;
137
- }
138
- is_long = true;
139
- data = (index << 2) | is_s; /* is_2 == 0 */
140
- fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
141
- ptr_is_env = true;
142
- } else {
143
- return 1;
144
- }
145
-
146
- VFP_DREG_D(rd, insn);
147
- if (rd & q) {
148
- return 1;
149
- }
150
- if (q || !is_long) {
151
- VFP_DREG_N(rn, insn);
152
- if (rn & q & !is_long) {
153
- return 1;
154
- }
155
- off_rn = vfp_reg_offset(1, rn);
156
- off_rm = vfp_reg_offset(1, rm);
157
- } else {
158
- rn = VFP_SREG_N(insn);
159
- off_rn = vfp_reg_offset(0, rn);
160
- off_rm = vfp_reg_offset(0, rm);
161
- }
162
- if (s->fp_excp_el) {
163
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
164
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
165
- return 0;
166
- }
167
- if (!s->vfp_enabled) {
168
- return 1;
169
- }
170
-
171
- opr_sz = (1 + q) * 8;
172
- if (fn_gvec_ptr) {
173
- TCGv_ptr ptr;
174
- if (ptr_is_env) {
175
- ptr = cpu_env;
176
- } else {
177
- ptr = get_fpstatus_ptr(1);
178
- }
179
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
180
- opr_sz, opr_sz, data, fn_gvec_ptr);
181
- if (!ptr_is_env) {
182
- tcg_temp_free_ptr(ptr);
183
- }
184
- } else {
185
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
186
- opr_sz, opr_sz, data, fn_gvec);
187
- }
188
- return 0;
189
-}
190
-
191
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
192
{
193
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
194
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
195
}
196
}
197
}
198
- } else if ((insn & 0x0f000a00) == 0x0e000800
199
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
200
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
201
- goto illegal_op;
202
- }
203
- return;
204
}
205
goto illegal_op;
206
}
207
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
208
}
209
break;
210
}
211
- if ((insn & 0xff000a00) == 0xfe000800
212
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
213
- /* The Thumb2 and ARM encodings are identical. */
214
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
215
- goto illegal_op;
216
- }
217
- } else if (((insn >> 24) & 3) == 3) {
218
+ if (((insn >> 24) & 3) == 3) {
219
/* Translate into the equivalent ARM encoding. */
220
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
221
if (disas_neon_data_insn(s, insn)) {
222
--
223
2.20.1
224
225
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon "load single structure to all lanes" insns to
2
decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-13-peter.maydell@linaro.org
7
---
8
target/arm/neon-ls.decode | 5 +++
9
target/arm/translate-neon.inc.c | 73 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 55 +------------------------
11
3 files changed, 80 insertions(+), 53 deletions(-)
12
13
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-ls.decode
16
+++ b/target/arm/neon-ls.decode
17
@@ -XXX,XX +XXX,XX @@
18
19
VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
20
vd=%vd_dp
21
+
22
+# Neon load single element to all lanes
23
+
24
+VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
25
+ vd=%vd_dp
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate-neon.inc.c
29
+++ b/target/arm/translate-neon.inc.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
31
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
32
return true;
33
}
34
+
35
+static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
36
+{
37
+ /* Neon load single structure to all lanes */
38
+ int reg, stride, vec_size;
39
+ int vd = a->vd;
40
+ int size = a->size;
41
+ int nregs = a->n + 1;
42
+ TCGv_i32 addr, tmp;
43
+
44
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
45
+ return false;
46
+ }
47
+
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
49
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if (size == 3) {
54
+ if (nregs != 4 || a->a == 0) {
55
+ return false;
56
+ }
57
+ /* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
58
+ size = 2;
59
+ }
60
+ if (nregs == 1 && a->a == 1 && size == 0) {
61
+ return false;
62
+ }
63
+ if (nregs == 3 && a->a == 1) {
64
+ return false;
65
+ }
66
+
67
+ if (!vfp_access_check(s)) {
68
+ return true;
69
+ }
70
+
71
+ /*
72
+ * VLD1 to all lanes: T bit indicates how many Dregs to write.
73
+ * VLD2/3/4 to all lanes: T bit indicates register stride.
74
+ */
75
+ stride = a->t ? 2 : 1;
76
+ vec_size = nregs == 1 ? stride * 8 : 8;
77
+
78
+ tmp = tcg_temp_new_i32();
79
+ addr = tcg_temp_new_i32();
80
+ load_reg_var(s, addr, a->rn);
81
+ for (reg = 0; reg < nregs; reg++) {
82
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
83
+ s->be_data | size);
84
+ if ((vd & 1) && vec_size == 16) {
85
+ /*
86
+ * We cannot write 16 bytes at once because the
87
+ * destination is unaligned.
88
+ */
89
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
90
+ 8, 8, tmp);
91
+ tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
92
+ neon_reg_offset(vd, 0), 8, 8);
93
+ } else {
94
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
95
+ vec_size, vec_size, tmp);
96
+ }
97
+ tcg_gen_addi_i32(addr, addr, 1 << size);
98
+ vd += stride;
99
+ }
100
+ tcg_temp_free_i32(tmp);
101
+ tcg_temp_free_i32(addr);
102
+
103
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
104
+
105
+ return true;
106
+}
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
112
int size;
113
int reg;
114
int load;
115
- int vec_size;
116
TCGv_i32 addr;
117
TCGv_i32 tmp;
118
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
120
} else {
121
size = (insn >> 10) & 3;
122
if (size == 3) {
123
- /* Load single element to all lanes. */
124
- int a = (insn >> 4) & 1;
125
- if (!load) {
126
- return 1;
127
- }
128
- size = (insn >> 6) & 3;
129
- nregs = ((insn >> 8) & 3) + 1;
130
-
131
- if (size == 3) {
132
- if (nregs != 4 || a == 0) {
133
- return 1;
134
- }
135
- /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
136
- size = 2;
137
- }
138
- if (nregs == 1 && a == 1 && size == 0) {
139
- return 1;
140
- }
141
- if (nregs == 3 && a == 1) {
142
- return 1;
143
- }
144
- addr = tcg_temp_new_i32();
145
- load_reg_var(s, addr, rn);
146
-
147
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
148
- * VLD2/3/4 to all lanes: bit 5 indicates register stride.
149
- */
150
- stride = (insn & (1 << 5)) ? 2 : 1;
151
- vec_size = nregs == 1 ? stride * 8 : 8;
152
-
153
- tmp = tcg_temp_new_i32();
154
- for (reg = 0; reg < nregs; reg++) {
155
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
156
- s->be_data | size);
157
- if ((rd & 1) && vec_size == 16) {
158
- /* We cannot write 16 bytes at once because the
159
- * destination is unaligned.
160
- */
161
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
162
- 8, 8, tmp);
163
- tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
164
- neon_reg_offset(rd, 0), 8, 8);
165
- } else {
166
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
167
- vec_size, vec_size, tmp);
168
- }
169
- tcg_gen_addi_i32(addr, addr, 1 << size);
170
- rd += stride;
171
- }
172
- tcg_temp_free_i32(tmp);
173
- tcg_temp_free_i32(addr);
174
- stride = (1 << size) * nregs;
175
+ /* Load single element to all lanes -- handled by decodetree */
176
+ return 1;
177
} else {
178
/* Single element. */
179
int idx = (insn >> 4) & 0xf;
180
--
181
2.20.1
182
183
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon "load/store single structure to one lane" insns to
2
decodetree.
3
1
4
As this is the last set of insns in the neon load/store group,
5
we can remove the whole disas_neon_ls_insn() function.
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200430181003.21682-14-peter.maydell@linaro.org
10
---
11
target/arm/neon-ls.decode | 11 +++
12
target/arm/translate-neon.inc.c | 89 +++++++++++++++++++
13
target/arm/translate.c | 147 --------------------------------
14
3 files changed, 100 insertions(+), 147 deletions(-)
15
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/neon-ls.decode
19
+++ b/target/arm/neon-ls.decode
20
@@ -XXX,XX +XXX,XX @@ VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
21
22
VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
23
vd=%vd_dp
24
+
25
+# Neon load/store single structure to one lane
26
+%imm1_5_p1 5:1 !function=plus1
27
+%imm1_6_p1 6:1 !function=plus1
28
+
29
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
30
+ vd=%vd_dp size=0 stride=1
31
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
32
+ vd=%vd_dp size=1 stride=%imm1_5_p1
33
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
34
+ vd=%vd_dp size=2 stride=%imm1_6_p1
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
38
+++ b/target/arm/translate-neon.inc.c
39
@@ -XXX,XX +XXX,XX @@
40
* It might be possible to convert it to a standalone .c file eventually.
41
*/
42
43
+static inline int plus1(DisasContext *s, int x)
44
+{
45
+ return x + 1;
46
+}
47
+
48
/* Include the generated Neon decoder */
49
#include "decode-neon-dp.inc.c"
50
#include "decode-neon-ls.inc.c"
51
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
52
53
return true;
54
}
55
+
56
+static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
57
+{
58
+ /* Neon load/store single structure to one lane */
59
+ int reg;
60
+ int nregs = a->n + 1;
61
+ int vd = a->vd;
62
+ TCGv_i32 addr, tmp;
63
+
64
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
65
+ return false;
66
+ }
67
+
68
+ /* UNDEF accesses to D16-D31 if they don't exist */
69
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
70
+ return false;
71
+ }
72
+
73
+ /* Catch the UNDEF cases. This is unavoidably a bit messy. */
74
+ switch (nregs) {
75
+ case 1:
76
+ if (((a->align & (1 << a->size)) != 0) ||
77
+ (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
78
+ return false;
79
+ }
80
+ break;
81
+ case 3:
82
+ if ((a->align & 1) != 0) {
83
+ return false;
84
+ }
85
+ /* fall through */
86
+ case 2:
87
+ if (a->size == 2 && (a->align & 2) != 0) {
88
+ return false;
89
+ }
90
+ break;
91
+ case 4:
92
+ if ((a->size == 2) && ((a->align & 3) == 3)) {
93
+ return false;
94
+ }
95
+ break;
96
+ default:
97
+ abort();
98
+ }
99
+ if ((vd + a->stride * (nregs - 1)) > 31) {
100
+ /*
101
+ * Attempts to write off the end of the register file are
102
+ * UNPREDICTABLE; we choose to UNDEF because otherwise we would
103
+ * access off the end of the array that holds the register data.
104
+ */
105
+ return false;
106
+ }
107
+
108
+ if (!vfp_access_check(s)) {
109
+ return true;
110
+ }
111
+
112
+ tmp = tcg_temp_new_i32();
113
+ addr = tcg_temp_new_i32();
114
+ load_reg_var(s, addr, a->rn);
115
+ /*
116
+ * TODO: if we implemented alignment exceptions, we should check
117
+ * addr against the alignment encoded in a->align here.
118
+ */
119
+ for (reg = 0; reg < nregs; reg++) {
120
+ if (a->l) {
121
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
122
+ s->be_data | a->size);
123
+ neon_store_element(vd, a->reg_idx, a->size, tmp);
124
+ } else { /* Store */
125
+ neon_load_element(tmp, vd, a->reg_idx, a->size);
126
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
127
+ s->be_data | a->size);
128
+ }
129
+ vd += a->stride;
130
+ tcg_gen_addi_i32(addr, addr, 1 << a->size);
131
+ }
132
+ tcg_temp_free_i32(addr);
133
+ tcg_temp_free_i32(tmp);
134
+
135
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
136
+
137
+ return true;
138
+}
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/translate.c
142
+++ b/target/arm/translate.c
143
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
144
tcg_temp_free_i32(rd);
145
}
146
147
-
148
-/* Translate a NEON load/store element instruction. Return nonzero if the
149
- instruction is invalid. */
150
-static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
151
-{
152
- int rd, rn, rm;
153
- int nregs;
154
- int stride;
155
- int size;
156
- int reg;
157
- int load;
158
- TCGv_i32 addr;
159
- TCGv_i32 tmp;
160
-
161
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
- return 1;
163
- }
164
-
165
- /* FIXME: this access check should not take precedence over UNDEF
166
- * for invalid encodings; we will generate incorrect syndrome information
167
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
168
- */
169
- if (s->fp_excp_el) {
170
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
171
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
172
- return 0;
173
- }
174
-
175
- if (!s->vfp_enabled)
176
- return 1;
177
- VFP_DREG_D(rd, insn);
178
- rn = (insn >> 16) & 0xf;
179
- rm = insn & 0xf;
180
- load = (insn & (1 << 21)) != 0;
181
- if ((insn & (1 << 23)) == 0) {
182
- /* Load store all elements -- handled already by decodetree */
183
- return 1;
184
- } else {
185
- size = (insn >> 10) & 3;
186
- if (size == 3) {
187
- /* Load single element to all lanes -- handled by decodetree */
188
- return 1;
189
- } else {
190
- /* Single element. */
191
- int idx = (insn >> 4) & 0xf;
192
- int reg_idx;
193
- switch (size) {
194
- case 0:
195
- reg_idx = (insn >> 5) & 7;
196
- stride = 1;
197
- break;
198
- case 1:
199
- reg_idx = (insn >> 6) & 3;
200
- stride = (insn & (1 << 5)) ? 2 : 1;
201
- break;
202
- case 2:
203
- reg_idx = (insn >> 7) & 1;
204
- stride = (insn & (1 << 6)) ? 2 : 1;
205
- break;
206
- default:
207
- abort();
208
- }
209
- nregs = ((insn >> 8) & 3) + 1;
210
- /* Catch the UNDEF cases. This is unavoidably a bit messy. */
211
- switch (nregs) {
212
- case 1:
213
- if (((idx & (1 << size)) != 0) ||
214
- (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
215
- return 1;
216
- }
217
- break;
218
- case 3:
219
- if ((idx & 1) != 0) {
220
- return 1;
221
- }
222
- /* fall through */
223
- case 2:
224
- if (size == 2 && (idx & 2) != 0) {
225
- return 1;
226
- }
227
- break;
228
- case 4:
229
- if ((size == 2) && ((idx & 3) == 3)) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- abort();
235
- }
236
- if ((rd + stride * (nregs - 1)) > 31) {
237
- /* Attempts to write off the end of the register file
238
- * are UNPREDICTABLE; we choose to UNDEF because otherwise
239
- * the neon_load_reg() would write off the end of the array.
240
- */
241
- return 1;
242
- }
243
- tmp = tcg_temp_new_i32();
244
- addr = tcg_temp_new_i32();
245
- load_reg_var(s, addr, rn);
246
- for (reg = 0; reg < nregs; reg++) {
247
- if (load) {
248
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
249
- s->be_data | size);
250
- neon_store_element(rd, reg_idx, size, tmp);
251
- } else { /* Store */
252
- neon_load_element(tmp, rd, reg_idx, size);
253
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
254
- s->be_data | size);
255
- }
256
- rd += stride;
257
- tcg_gen_addi_i32(addr, addr, 1 << size);
258
- }
259
- tcg_temp_free_i32(addr);
260
- tcg_temp_free_i32(tmp);
261
- stride = nregs * (1 << size);
262
- }
263
- }
264
- if (rm != 15) {
265
- TCGv_i32 base;
266
-
267
- base = load_reg(s, rn);
268
- if (rm == 13) {
269
- tcg_gen_addi_i32(base, base, stride);
270
- } else {
271
- TCGv_i32 index;
272
- index = load_reg(s, rm);
273
- tcg_gen_add_i32(base, base, index);
274
- tcg_temp_free_i32(index);
275
- }
276
- store_reg(s, rn, base);
277
- }
278
- return 0;
279
-}
280
-
281
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
282
{
283
switch (size) {
284
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
285
}
286
return;
287
}
288
- if ((insn & 0x0f100000) == 0x04000000) {
289
- /* NEON load/store. */
290
- if (disas_neon_ls_insn(s, insn)) {
291
- goto illegal_op;
292
- }
293
- return;
294
- }
295
if ((insn & 0x0e000f00) == 0x0c000100) {
296
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
297
/* iWMMXt register transfer. */
298
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
299
}
300
break;
301
case 12:
302
- if ((insn & 0x01100000) == 0x01000000) {
303
- if (disas_neon_ls_insn(s, insn)) {
304
- goto illegal_op;
305
- }
306
- break;
307
- }
308
goto illegal_op;
309
default:
310
illegal_op:
311
--
312
2.20.1
313
314
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon 3-reg-same VADD and VSUB insns to decodetree.
2
1
3
Note that we don't need the neon_3r_sizes[op] check here because all
4
size values are OK for VADD and VSUB; we'll add this when we convert
5
the first insn that has size restrictions.
6
7
For this we need one of the GVecGen*Fn typedefs currently in
8
translate-a64.h; move them all to translate.h as a block so they
9
are visible to the 32-bit decoder.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200430181003.21682-15-peter.maydell@linaro.org
14
---
15
target/arm/translate-a64.h | 9 --------
16
target/arm/translate.h | 9 ++++++++
17
target/arm/neon-dp.decode | 17 +++++++++++++++
18
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
19
target/arm/translate.c | 14 ++++--------
20
5 files changed, 68 insertions(+), 19 deletions(-)
21
22
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate-a64.h
25
+++ b/target/arm/translate-a64.h
26
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
27
28
bool disas_sve(DisasContext *, uint32_t);
29
30
-/* Note that the gvec expanders operate on offsets + sizes. */
31
-typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
32
-typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
33
- uint32_t, uint32_t);
34
-typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
35
- uint32_t, uint32_t, uint32_t);
36
-typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
37
- uint32_t, uint32_t, uint32_t);
38
-
39
#endif /* TARGET_ARM_TRANSLATE_A64_H */
40
diff --git a/target/arm/translate.h b/target/arm/translate.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate.h
43
+++ b/target/arm/translate.h
44
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
45
#define dc_isar_feature(name, ctx) \
46
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
47
48
+/* Note that the gvec expanders operate on offsets + sizes. */
49
+typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
50
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
51
+ uint32_t, uint32_t);
52
+typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
53
+ uint32_t, uint32_t, uint32_t);
54
+typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
55
+ uint32_t, uint32_t, uint32_t);
56
+
57
#endif /* TARGET_ARM_TRANSLATE_H */
58
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/neon-dp.decode
61
+++ b/target/arm/neon-dp.decode
62
@@ -XXX,XX +XXX,XX @@
63
#
64
# This file is processed by scripts/decodetree.py
65
#
66
+# VFP/Neon register fields; same as vfp.decode
67
+%vm_dp 5:1 0:4
68
+%vn_dp 7:1 16:4
69
+%vd_dp 22:1 12:4
70
71
# Encodings for Neon data processing instructions where the T32 encoding
72
# is a simple transformation of the A32 encoding.
73
@@ -XXX,XX +XXX,XX @@
74
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
75
# This file works on the A32 encoding only; calling code for T32 has to
76
# transform the insn into the A32 version first.
77
+
78
+######################################################################
79
+# 3-reg-same grouping:
80
+# 1111 001 U 0 D sz:2 Vn:4 Vd:4 opc:4 N Q M op Vm:4
81
+######################################################################
82
+
83
+&3same vm vn vd q size
84
+
85
+@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
86
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
87
+
88
+VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
89
+VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
90
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-neon.inc.c
93
+++ b/target/arm/translate-neon.inc.c
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
95
96
return true;
97
}
98
+
99
+static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
100
+{
101
+ int vec_size = a->q ? 16 : 8;
102
+ int rd_ofs = neon_reg_offset(a->vd, 0);
103
+ int rn_ofs = neon_reg_offset(a->vn, 0);
104
+ int rm_ofs = neon_reg_offset(a->vm, 0);
105
+
106
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
107
+ return false;
108
+ }
109
+
110
+ /* UNDEF accesses to D16-D31 if they don't exist. */
111
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
112
+ ((a->vd | a->vn | a->vm) & 0x10)) {
113
+ return false;
114
+ }
115
+
116
+ if ((a->vn | a->vm | a->vd) & a->q) {
117
+ return false;
118
+ }
119
+
120
+ if (!vfp_access_check(s)) {
121
+ return true;
122
+ }
123
+
124
+ fn(a->size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
125
+ return true;
126
+}
127
+
128
+#define DO_3SAME(INSN, FUNC) \
129
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
130
+ { \
131
+ return do_3same(s, a, FUNC); \
132
+ }
133
+
134
+DO_3SAME(VADD, tcg_gen_gvec_add)
135
+DO_3SAME(VSUB, tcg_gen_gvec_sub)
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/translate.c
139
+++ b/target/arm/translate.c
140
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
141
}
142
return 0;
143
144
- case NEON_3R_VADD_VSUB:
145
- if (u) {
146
- tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
147
- vec_size, vec_size);
148
- } else {
149
- tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
150
- vec_size, vec_size);
151
- }
152
- return 0;
153
-
154
case NEON_3R_VQADD:
155
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
156
rn_ofs, rm_ofs, vec_size, vec_size,
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
159
u ? &ushl_op[size] : &sshl_op[size]);
160
return 0;
161
+
162
+ case NEON_3R_VADD_VSUB:
163
+ /* Already handled by decodetree */
164
+ return 1;
165
}
166
167
if (size == 3) {
168
--
169
2.20.1
170
171
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon logic ops in the 3-reg-same grouping to decodetree.
2
Note that for the logic ops the 'size' field forms part of their
3
decode and the actual operations are always bitwise.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200430181003.21682-16-peter.maydell@linaro.org
8
---
9
target/arm/neon-dp.decode | 12 +++++++++++
10
target/arm/translate-neon.inc.c | 19 +++++++++++++++++
11
target/arm/translate.c | 38 +--------------------------------
12
3 files changed, 32 insertions(+), 37 deletions(-)
13
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
17
+++ b/target/arm/neon-dp.decode
18
@@ -XXX,XX +XXX,XX @@
19
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
20
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
21
22
+@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
23
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
24
+
25
+VAND_3s 1111 001 0 0 . 00 .... .... 0001 ... 1 .... @3same_logic
26
+VBIC_3s 1111 001 0 0 . 01 .... .... 0001 ... 1 .... @3same_logic
27
+VORR_3s 1111 001 0 0 . 10 .... .... 0001 ... 1 .... @3same_logic
28
+VORN_3s 1111 001 0 0 . 11 .... .... 0001 ... 1 .... @3same_logic
29
+VEOR_3s 1111 001 1 0 . 00 .... .... 0001 ... 1 .... @3same_logic
30
+VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
31
+VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
32
+VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
33
+
34
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
35
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
39
+++ b/target/arm/translate-neon.inc.c
40
@@ -XXX,XX +XXX,XX @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
41
42
DO_3SAME(VADD, tcg_gen_gvec_add)
43
DO_3SAME(VSUB, tcg_gen_gvec_sub)
44
+DO_3SAME(VAND, tcg_gen_gvec_and)
45
+DO_3SAME(VBIC, tcg_gen_gvec_andc)
46
+DO_3SAME(VORR, tcg_gen_gvec_or)
47
+DO_3SAME(VORN, tcg_gen_gvec_orc)
48
+DO_3SAME(VEOR, tcg_gen_gvec_xor)
49
+
50
+/* These insns are all gvec_bitsel but with the inputs in various orders. */
51
+#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
52
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
53
+ uint32_t rn_ofs, uint32_t rm_ofs, \
54
+ uint32_t oprsz, uint32_t maxsz) \
55
+ { \
56
+ tcg_gen_gvec_bitsel(vece, rd_ofs, O1, O2, O3, oprsz, maxsz); \
57
+ } \
58
+ DO_3SAME(INSN, gen_##INSN##_3s)
59
+
60
+DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
61
+DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
62
+DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate.c
66
+++ b/target/arm/translate.c
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
68
}
69
return 1;
70
71
- case NEON_3R_LOGIC: /* Logic ops. */
72
- switch ((u << 2) | size) {
73
- case 0: /* VAND */
74
- tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
75
- vec_size, vec_size);
76
- break;
77
- case 1: /* VBIC */
78
- tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
79
- vec_size, vec_size);
80
- break;
81
- case 2: /* VORR */
82
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
83
- vec_size, vec_size);
84
- break;
85
- case 3: /* VORN */
86
- tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
87
- vec_size, vec_size);
88
- break;
89
- case 4: /* VEOR */
90
- tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
91
- vec_size, vec_size);
92
- break;
93
- case 5: /* VBSL */
94
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
95
- vec_size, vec_size);
96
- break;
97
- case 6: /* VBIT */
98
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
99
- vec_size, vec_size);
100
- break;
101
- case 7: /* VBIF */
102
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
103
- vec_size, vec_size);
104
- break;
105
- }
106
- return 0;
107
-
108
case NEON_3R_VQADD:
109
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
110
rn_ofs, rm_ofs, vec_size, vec_size,
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
return 0;
113
114
case NEON_3R_VADD_VSUB:
115
+ case NEON_3R_LOGIC:
116
/* Already handled by decodetree */
117
return 1;
118
}
119
--
120
2.20.1
121
122
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon 3-reg-same VMAX and VMIN insns to decodetree.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-17-peter.maydell@linaro.org
6
---
7
target/arm/neon-dp.decode | 5 +++++
8
target/arm/translate-neon.inc.c | 14 ++++++++++++++
9
target/arm/translate.c | 21 ++-------------------
10
3 files changed, 21 insertions(+), 19 deletions(-)
11
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
15
+++ b/target/arm/neon-dp.decode
16
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
17
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
18
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
19
20
+VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
21
+VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
22
+VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
23
+VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
24
+
25
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
26
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
30
+++ b/target/arm/translate-neon.inc.c
31
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VEOR, tcg_gen_gvec_xor)
32
DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
33
DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
34
DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
35
+
36
+#define DO_3SAME_NO_SZ_3(INSN, FUNC) \
37
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
38
+ { \
39
+ if (a->size == 3) { \
40
+ return false; \
41
+ } \
42
+ return do_3same(s, a, FUNC); \
43
+ }
44
+
45
+DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
46
+DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
47
+DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
48
+DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/translate.c
52
+++ b/target/arm/translate.c
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
54
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
55
return 0;
56
57
- case NEON_3R_VMAX:
58
- if (u) {
59
- tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
60
- vec_size, vec_size);
61
- } else {
62
- tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
63
- vec_size, vec_size);
64
- }
65
- return 0;
66
- case NEON_3R_VMIN:
67
- if (u) {
68
- tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
69
- vec_size, vec_size);
70
- } else {
71
- tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
72
- vec_size, vec_size);
73
- }
74
- return 0;
75
-
76
case NEON_3R_VSHL:
77
/* Note the operation is vshl vd,vm,vn */
78
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
79
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
80
81
case NEON_3R_VADD_VSUB:
82
case NEON_3R_LOGIC:
83
+ case NEON_3R_VMAX:
84
+ case NEON_3R_VMIN:
85
/* Already handled by decodetree */
86
return 1;
87
}
88
--
89
2.20.1
90
91
diff view generated by jsdifflib