1
ARM bugfixes for rc1...
1
Big pullreq this week, though none of the new features are
2
particularly earthshaking. Most of the bulk is from code cleanup
3
patches from me or rth.
2
4
5
thanks
6
-- PMM
3
7
4
The following changes since commit f291910db61b5812e68f1e76afb3ade41d567bea:
8
The following changes since commit b651b80822fa8cb66ca30087ac7fbc75507ae5d2:
5
9
6
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2017-11-09' into staging (2017-11-13 13:13:12 +0000)
10
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.0-pull-request' into staging (2020-02-20 17:35:42 +0000)
7
11
8
are available in the git repository at:
12
are available in the Git repository at:
9
13
10
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20171113
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200221
11
15
12
for you to fetch changes up to d25f2a72272b9ffe0d06710d6217d1169bc2cc7d:
16
for you to fetch changes up to 270a679b3f950d7c4c600f324aab8bff292d0971:
13
17
14
accel/tcg/translate-all: expand cpu_restore_state addr check (2017-11-13 13:55:27 +0000)
18
target/arm: Add missing checks for fpsp_v2 (2020-02-21 12:54:25 +0000)
15
19
16
----------------------------------------------------------------
20
----------------------------------------------------------------
17
target-arm queue:
21
target-arm queue:
18
* translate-a64.c: silence gcc5 warning
22
* aspeed/scu: Implement chip ID register
19
* highbank: validate register offset before access
23
* hw/misc/iotkit-secctl: Fix writing to 'PPC Interrupt Clear' register
20
* MAINTAINERS: Add entries for Smartfusion2
24
* mainstone: Make providing flash images non-mandatory
21
* accel/tcg/translate-all: expand cpu_restore_state addr check
25
* z2: Make providing flash images non-mandatory
22
(so usermode insn aborts don't crash with an assertion failure)
26
* Fix failures to flush SVE high bits after AdvSIMD INS/ZIP/UZP/TRN/TBL/TBX/EXT
23
* fix TCG initialization of some Arm boards by allowing them
27
* Minor performance improvement: spend less time recalculating hflags values
24
to specify min/default number of CPUs to create
28
* Code cleanup to isar_feature function tests
29
* Implement ARMv8.1-PMU and ARMv8.4-PMU extensions
30
* Bugfix: correct handling of PMCR_EL0.LC bit
31
* Bugfix: correct definition of PMCRDP
32
* Correctly implement ACTLR2, HACTLR2
33
* allwinner: Wire up USB ports
34
* Vectorize emulation of USHL, SSHL, PMUL*
35
* xilinx_spips: Correct the number of dummy cycles for the FAST_READ_4 cmd
36
* sh4: Fix PCI ISA IO memory subregion
37
* Code cleanup to use more isar_feature tests and fewer ARM_FEATURE_* tests
25
38
26
----------------------------------------------------------------
39
----------------------------------------------------------------
27
Alex Bennée (1):
40
Francisco Iglesias (1):
28
accel/tcg/translate-all: expand cpu_restore_state addr check
41
xilinx_spips: Correct the number of dummy cycles for the FAST_READ_4 cmd
29
42
30
Alistair Francis (2):
43
Guenter Roeck (6):
31
xlnx-zynqmp: Properly support the smp command line option
44
mainstone: Make providing flash images non-mandatory
32
xlnx-zcu102: Add an info message deprecating the EP108
45
z2: Make providing flash images non-mandatory
46
hw: usb: hcd-ohci: Move OHCISysBusState and TYPE_SYSBUS_OHCI to include file
47
hcd-ehci: Introduce "companion-enable" sysbus property
48
arm: allwinner: Wire up USB ports
49
sh4: Fix PCI ISA IO memory subregion
33
50
34
Emilio G. Cota (4):
51
Joel Stanley (2):
35
arm/translate-a64: mark path as unreachable to eliminate warning
52
aspeed/scu: Create separate write callbacks
36
qom: move CPUClass.tcg_initialize to a global
53
aspeed/scu: Implement chip ID register
37
xlnx-zcu102: Specify the max number of CPUs for the EP108
38
hw: add .min_cpus and .default_cpus fields to machine_class
39
54
40
Prasad J Pandit (1):
55
Peter Maydell (21):
41
highbank: validate register offset before access
56
target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers
57
target/arm: Check aa32_pan in take_aarch32_exception(), not aa64_pan
58
target/arm: Add isar_feature_any_fp16 and document naming/usage conventions
59
target/arm: Define and use any_predinv isar_feature test
60
target/arm: Factor out PMU register definitions
61
target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1
62
target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field
63
target/arm: Define an aa32_pmu_8_1 isar feature test function
64
target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks
65
target/arm: Stop assuming DBGDIDR always exists
66
target/arm: Move DBGDIDR into ARMISARegisters
67
target/arm: Read debug-related ID registers from KVM
68
target/arm: Implement ARMv8.1-PMU extension
69
target/arm: Implement ARMv8.4-PMU extension
70
target/arm: Provide ARMv8.4-PMU in '-cpu max'
71
target/arm: Correct definition of PMCRDP
72
target/arm: Correct handling of PMCR_EL0.LC bit
73
target/arm: Test correct register in aa32_pan and aa32_ats1e1 checks
74
target/arm: Use isar_feature function for testing AA32HPD feature
75
target/arm: Use FIELD_EX32 for testing 32-bit fields
76
target/arm: Correctly implement ACTLR2, HACTLR2
42
77
43
Subbaraya Sundeep (1):
78
Philippe Mathieu-Daudé (1):
44
MAINTAINERS: Add entries for Smartfusion2
79
hw/misc/iotkit-secctl: Fix writing to 'PPC Interrupt Clear' register
45
80
46
include/exec/exec-all.h | 11 ++++++++++
81
Richard Henderson (21):
47
include/hw/boards.h | 5 +++++
82
target/arm: Flush high bits of sve register after AdvSIMD EXT
48
include/qom/cpu.h | 1 -
83
target/arm: Flush high bits of sve register after AdvSIMD TBL/TBX
49
accel/tcg/translate-all.c | 52 ++++++++++++++++++++++++++--------------------
84
target/arm: Flush high bits of sve register after AdvSIMD ZIP/UZP/TRN
50
exec.c | 5 +++--
85
target/arm: Flush high bits of sve register after AdvSIMD INS
51
hw/arm/exynos4_boards.c | 12 ++++-------
86
target/arm: Use bit 55 explicitly for pauth
52
hw/arm/highbank.c | 17 +++++++++++++--
87
target/arm: Fix select for aa64_va_parameters_both
53
hw/arm/raspi.c | 2 ++
88
target/arm: Remove ttbr1_valid check from get_phys_addr_lpae
54
hw/arm/xlnx-zcu102.c | 9 +++++++-
89
target/arm: Split out aa64_va_parameter_tbi, aa64_va_parameter_tbid
55
hw/arm/xlnx-zynqmp.c | 26 ++++++++++++++---------
90
target/arm: Vectorize USHL and SSHL
56
target/arm/translate-a64.c | 2 ++
91
target/arm: Convert PMUL.8 to gvec
57
vl.c | 21 ++++++++++++++++---
92
target/arm: Convert PMULL.64 to gvec
58
MAINTAINERS | 17 +++++++++++++++
93
target/arm: Convert PMULL.8 to gvec
59
qemu-doc.texi | 7 +++++++
94
target/arm: Rename isar_feature_aa32_simd_r32
60
14 files changed, 137 insertions(+), 50 deletions(-)
95
target/arm: Use isar_feature_aa32_simd_r32 more places
96
target/arm: Set MVFR0.FPSP for ARMv5 cpus
97
target/arm: Add isar_feature_aa32_simd_r16
98
target/arm: Rename isar_feature_aa32_fpdp_v2
99
target/arm: Add isar_feature_aa32_{fpsp_v2, fpsp_v3, fpdp_v3}
100
target/arm: Perform fpdp_v2 check first
101
target/arm: Replace ARM_FEATURE_VFP3 checks with fp{sp, dp}_v3
102
target/arm: Add missing checks for fpsp_v2
61
103
104
hw/usb/hcd-ohci.h | 16 ++
105
include/hw/arm/allwinner-a10.h | 6 +
106
target/arm/cpu.h | 173 ++++++++++++---
107
target/arm/helper-sve.h | 2 +
108
target/arm/helper.h | 21 +-
109
target/arm/internals.h | 47 +++-
110
target/arm/translate.h | 6 +
111
hw/arm/allwinner-a10.c | 43 ++++
112
hw/arm/mainstone.c | 11 +-
113
hw/arm/z2.c | 6 -
114
hw/intc/armv7m_nvic.c | 30 +--
115
hw/misc/aspeed_scu.c | 93 ++++++--
116
hw/misc/iotkit-secctl.c | 2 +-
117
hw/sh4/sh_pci.c | 11 +-
118
hw/ssi/xilinx_spips.c | 2 +-
119
hw/usb/hcd-ehci-sysbus.c | 2 +
120
hw/usb/hcd-ohci.c | 15 --
121
linux-user/arm/signal.c | 4 +-
122
linux-user/elfload.c | 4 +-
123
target/arm/arch_dump.c | 11 +-
124
target/arm/cpu.c | 175 +++++++--------
125
target/arm/cpu64.c | 58 +++--
126
target/arm/debug_helper.c | 6 +-
127
target/arm/helper.c | 472 +++++++++++++++++++++++------------------
128
target/arm/kvm32.c | 25 +++
129
target/arm/kvm64.c | 46 ++++
130
target/arm/m_helper.c | 11 +-
131
target/arm/machine.c | 3 +-
132
target/arm/neon_helper.c | 117 ----------
133
target/arm/pauth_helper.c | 3 +-
134
target/arm/translate-a64.c | 92 ++++----
135
target/arm/translate-vfp.inc.c | 263 ++++++++++++++---------
136
target/arm/translate.c | 356 ++++++++++++++++++++++++++-----
137
target/arm/vec_helper.c | 211 ++++++++++++++++++
138
target/arm/vfp_helper.c | 2 +-
139
35 files changed, 1564 insertions(+), 781 deletions(-)
140
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
This splits the common write callback into separate ast2400 and ast2500
4
implementations. This makes it clearer when implementing differing
5
behaviour.
6
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
9
Reviewed-by: Cédric Le Goater <clg@kaod.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20200121013302.43839-2-joel@jms.id.au
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/misc/aspeed_scu.c | 80 +++++++++++++++++++++++++++++++-------------
15
1 file changed, 57 insertions(+), 23 deletions(-)
16
17
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/misc/aspeed_scu.c
20
+++ b/hw/misc/aspeed_scu.c
21
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
22
return s->regs[reg];
23
}
24
25
-static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
26
- unsigned size)
27
+static void aspeed_ast2400_scu_write(void *opaque, hwaddr offset,
28
+ uint64_t data, unsigned size)
29
+{
30
+ AspeedSCUState *s = ASPEED_SCU(opaque);
31
+ int reg = TO_REG(offset);
32
+
33
+ if (reg >= ASPEED_SCU_NR_REGS) {
34
+ qemu_log_mask(LOG_GUEST_ERROR,
35
+ "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
36
+ __func__, offset);
37
+ return;
38
+ }
39
+
40
+ if (reg > PROT_KEY && reg < CPU2_BASE_SEG1 &&
41
+ !s->regs[PROT_KEY]) {
42
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: SCU is locked!\n", __func__);
43
+ }
44
+
45
+ trace_aspeed_scu_write(offset, size, data);
46
+
47
+ switch (reg) {
48
+ case PROT_KEY:
49
+ s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
50
+ return;
51
+ case SILICON_REV:
52
+ case FREQ_CNTR_EVAL:
53
+ case VGA_SCRATCH1 ... VGA_SCRATCH8:
54
+ case RNG_DATA:
55
+ case FREE_CNTR4:
56
+ case FREE_CNTR4_EXT:
57
+ qemu_log_mask(LOG_GUEST_ERROR,
58
+ "%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
59
+ __func__, offset);
60
+ return;
61
+ }
62
+
63
+ s->regs[reg] = data;
64
+}
65
+
66
+static void aspeed_ast2500_scu_write(void *opaque, hwaddr offset,
67
+ uint64_t data, unsigned size)
68
{
69
AspeedSCUState *s = ASPEED_SCU(opaque);
70
int reg = TO_REG(offset);
71
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
72
case PROT_KEY:
73
s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
74
return;
75
- case CLK_SEL:
76
- s->regs[reg] = data;
77
- break;
78
case HW_STRAP1:
79
- if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
80
- s->regs[HW_STRAP1] |= data;
81
- return;
82
- }
83
- /* Jump to assignment below */
84
- break;
85
+ s->regs[HW_STRAP1] |= data;
86
+ return;
87
case SILICON_REV:
88
- if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
89
- s->regs[HW_STRAP1] &= ~data;
90
- } else {
91
- qemu_log_mask(LOG_GUEST_ERROR,
92
- "%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
93
- __func__, offset);
94
- }
95
- /* Avoid assignment below, we've handled everything */
96
+ s->regs[HW_STRAP1] &= ~data;
97
return;
98
case FREQ_CNTR_EVAL:
99
case VGA_SCRATCH1 ... VGA_SCRATCH8:
100
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
101
s->regs[reg] = data;
102
}
103
104
-static const MemoryRegionOps aspeed_scu_ops = {
105
+static const MemoryRegionOps aspeed_ast2400_scu_ops = {
106
.read = aspeed_scu_read,
107
- .write = aspeed_scu_write,
108
+ .write = aspeed_ast2400_scu_write,
109
+ .endianness = DEVICE_LITTLE_ENDIAN,
110
+ .valid.min_access_size = 4,
111
+ .valid.max_access_size = 4,
112
+ .valid.unaligned = false,
113
+};
114
+
115
+static const MemoryRegionOps aspeed_ast2500_scu_ops = {
116
+ .read = aspeed_scu_read,
117
+ .write = aspeed_ast2500_scu_write,
118
.endianness = DEVICE_LITTLE_ENDIAN,
119
.valid.min_access_size = 4,
120
.valid.max_access_size = 4,
121
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_scu_class_init(ObjectClass *klass, void *data)
122
asc->calc_hpll = aspeed_2400_scu_calc_hpll;
123
asc->apb_divider = 2;
124
asc->nr_regs = ASPEED_SCU_NR_REGS;
125
- asc->ops = &aspeed_scu_ops;
126
+ asc->ops = &aspeed_ast2400_scu_ops;
127
}
128
129
static const TypeInfo aspeed_2400_scu_info = {
130
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_scu_class_init(ObjectClass *klass, void *data)
131
asc->calc_hpll = aspeed_2500_scu_calc_hpll;
132
asc->apb_divider = 4;
133
asc->nr_regs = ASPEED_SCU_NR_REGS;
134
- asc->ops = &aspeed_scu_ops;
135
+ asc->ops = &aspeed_ast2500_scu_ops;
136
}
137
138
static const TypeInfo aspeed_2500_scu_info = {
139
--
140
2.20.1
141
142
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
This returns a fixed but non-zero value for the chip id.
4
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
6
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20200121013302.43839-3-joel@jms.id.au
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/misc/aspeed_scu.c | 13 +++++++++++++
13
1 file changed, 13 insertions(+)
14
15
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/aspeed_scu.c
18
+++ b/hw/misc/aspeed_scu.c
19
@@ -XXX,XX +XXX,XX @@
20
#define CPU2_BASE_SEG4 TO_REG(0x110)
21
#define CPU2_BASE_SEG5 TO_REG(0x114)
22
#define CPU2_CACHE_CTRL TO_REG(0x118)
23
+#define CHIP_ID0 TO_REG(0x150)
24
+#define CHIP_ID1 TO_REG(0x154)
25
#define UART_HPLL_CLK TO_REG(0x160)
26
#define PCIE_CTRL TO_REG(0x180)
27
#define BMC_MMIO_CTRL TO_REG(0x184)
28
@@ -XXX,XX +XXX,XX @@
29
#define AST2600_HW_STRAP2_PROT TO_REG(0x518)
30
#define AST2600_RNG_CTRL TO_REG(0x524)
31
#define AST2600_RNG_DATA TO_REG(0x540)
32
+#define AST2600_CHIP_ID0 TO_REG(0x5B0)
33
+#define AST2600_CHIP_ID1 TO_REG(0x5B4)
34
35
#define AST2600_CLK TO_REG(0x40)
36
37
@@ -XXX,XX +XXX,XX @@ static const uint32_t ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
38
[CPU2_BASE_SEG1] = 0x80000000U,
39
[CPU2_BASE_SEG4] = 0x1E600000U,
40
[CPU2_BASE_SEG5] = 0xC0000000U,
41
+ [CHIP_ID0] = 0x1234ABCDU,
42
+ [CHIP_ID1] = 0x88884444U,
43
[UART_HPLL_CLK] = 0x00001903U,
44
[PCIE_CTRL] = 0x0000007BU,
45
[BMC_DEV_ID] = 0x00002402U
46
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2500_scu_write(void *opaque, hwaddr offset,
47
case RNG_DATA:
48
case FREE_CNTR4:
49
case FREE_CNTR4_EXT:
50
+ case CHIP_ID0:
51
+ case CHIP_ID1:
52
qemu_log_mask(LOG_GUEST_ERROR,
53
"%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
54
__func__, offset);
55
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
56
case AST2600_RNG_DATA:
57
case AST2600_SILICON_REV:
58
case AST2600_SILICON_REV2:
59
+ case AST2600_CHIP_ID0:
60
+ case AST2600_CHIP_ID1:
61
/* Add read only registers here */
62
qemu_log_mask(LOG_GUEST_ERROR,
63
"%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
64
@@ -XXX,XX +XXX,XX @@ static const uint32_t ast2600_a0_resets[ASPEED_AST2600_SCU_NR_REGS] = {
65
[AST2600_CLK_STOP_CTRL2] = 0xFFF0FFF0,
66
[AST2600_SDRAM_HANDSHAKE] = 0x00000040, /* SoC completed DRAM init */
67
[AST2600_HPLL_PARAM] = 0x1000405F,
68
+ [AST2600_CHIP_ID0] = 0x1234ABCD,
69
+ [AST2600_CHIP_ID1] = 0x88884444,
70
+
71
};
72
73
static void aspeed_ast2600_scu_reset(DeviceState *dev)
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
2
3
Fix warning reported by Clang static code analyzer:
4
5
CC hw/misc/iotkit-secctl.o
6
hw/misc/iotkit-secctl.c:343:9: warning: Value stored to 'value' is never read
7
value &= 0x00f000f3;
8
^ ~~~~~~~~~~
9
10
Fixes: b3717c23e1c
11
Reported-by: Clang Static Analyzer
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20200217132922.24607-1-f4bug@amsat.org
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/misc/iotkit-secctl.c | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
19
20
diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/iotkit-secctl.c
23
+++ b/hw/misc/iotkit-secctl.c
24
@@ -XXX,XX +XXX,XX @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
25
qemu_set_irq(s->sec_resp_cfg, s->secrespcfg);
26
break;
27
case A_SECPPCINTCLR:
28
- value &= 0x00f000f3;
29
+ s->secppcintstat &= ~(value & 0x00f000f3);
30
foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear);
31
break;
32
case A_SECPPCINTEN:
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
New patch
1
From: Guenter Roeck <linux@roeck-us.net>
1
2
3
Up to now, the mainstone machine only boots if two flash images are
4
provided. This is not really necessary; the machine can boot from initrd
5
or from SD without it. At the same time, having to provide dummy flash
6
images is a nuisance and does not add any real value. Make it optional.
7
8
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20200217210824.18513-1-linux@roeck-us.net
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/mainstone.c | 11 +----------
14
1 file changed, 1 insertion(+), 10 deletions(-)
15
16
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/mainstone.c
19
+++ b/hw/arm/mainstone.c
20
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
21
/* There are two 32MiB flash devices on the board */
22
for (i = 0; i < 2; i ++) {
23
dinfo = drive_get(IF_PFLASH, 0, i);
24
- if (!dinfo) {
25
- if (qtest_enabled()) {
26
- break;
27
- }
28
- error_report("Two flash images must be given with the "
29
- "'pflash' parameter");
30
- exit(1);
31
- }
32
-
33
if (!pflash_cfi01_register(mainstone_flash_base[i],
34
i ? "mainstone.flash1" : "mainstone.flash0",
35
MAINSTONE_FLASH,
36
- blk_by_legacy_dinfo(dinfo),
37
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
38
sector_len, 4, 0, 0, 0, 0, be)) {
39
error_report("Error registering flash memory");
40
exit(1);
41
--
42
2.20.1
43
44
diff view generated by jsdifflib
New patch
1
From: Guenter Roeck <linux@roeck-us.net>
1
2
3
Up to now, the z2 machine only boots if a flash image is provided.
4
This is not really necessary; the machine can boot from initrd or from
5
SD without it. At the same time, having to provide dummy flash images
6
is a nuisance and does not add any real value. Make it optional.
7
8
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20200217210903.18602-1-linux@roeck-us.net
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/z2.c | 6 ------
14
1 file changed, 6 deletions(-)
15
16
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/z2.c
19
+++ b/hw/arm/z2.c
20
@@ -XXX,XX +XXX,XX @@ static void z2_init(MachineState *machine)
21
be = 0;
22
#endif
23
dinfo = drive_get(IF_PFLASH, 0, 0);
24
- if (!dinfo && !qtest_enabled()) {
25
- error_report("Flash image must be given with the "
26
- "'pflash' parameter");
27
- exit(1);
28
- }
29
-
30
if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
31
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
32
sector_len, 4, 0, 0, 0, 0, be)) {
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Writes to AdvSIMD registers flush the bits above 128.
4
5
Buglink: https://bugs.launchpad.net/bugs/1863247
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214194643.23317-2-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_ext(DisasContext *s, uint32_t insn)
19
tcg_temp_free_i64(tcg_resl);
20
write_vec_element(s, tcg_resh, rd, 1, MO_64);
21
tcg_temp_free_i64(tcg_resh);
22
+ clear_vec_high(s, true, rd);
23
}
24
25
/* TBL/TBX
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Writes to AdvSIMD registers flush the bits above 128.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200214194643.23317-3-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
18
tcg_temp_free_i64(tcg_resl);
19
write_vec_element(s, tcg_resh, rd, 1, MO_64);
20
tcg_temp_free_i64(tcg_resh);
21
+ clear_vec_high(s, true, rd);
22
}
23
24
/* ZIP/UZP/TRN
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Just like the zcu102, the ep108 can instantiate several CPUs.
3
Writes to AdvSIMD registers flush the bits above 128.
4
4
5
Signed-off-by: Emilio G. Cota <cota@braap.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
6
Message-id: 20200214194643.23317-4-richard.henderson@linaro.org
7
Message-id: 1510343626-25861-5-git-send-email-cota@braap.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
hw/arm/xlnx-zcu102.c | 1 +
10
target/arm/translate-a64.c | 1 +
11
1 file changed, 1 insertion(+)
11
1 file changed, 1 insertion(+)
12
12
13
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/xlnx-zcu102.c
15
--- a/target/arm/translate-a64.c
16
+++ b/hw/arm/xlnx-zcu102.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void xlnx_ep108_machine_class_init(ObjectClass *oc, void *data)
17
@@ -XXX,XX +XXX,XX @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn)
18
mc->block_default_type = IF_IDE;
18
tcg_temp_free_i64(tcg_resl);
19
mc->units_per_default_bus = 1;
19
write_vec_element(s, tcg_resh, rd, 1, MO_64);
20
mc->ignore_memory_transaction_failures = true;
20
tcg_temp_free_i64(tcg_resh);
21
+ mc->max_cpus = XLNX_ZYNQMP_NUM_APU_CPUS + XLNX_ZYNQMP_NUM_RPU_CPUS;
21
+ clear_vec_high(s, true, rd);
22
}
22
}
23
23
24
static const TypeInfo xlnx_ep108_machine_init_typeinfo = {
24
/*
25
--
25
--
26
2.7.4
26
2.20.1
27
27
28
28
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Fixes the following warning when compiling with gcc 5.4.0 with -O1
3
Writes to AdvSIMD registers flush the bits above 128.
4
optimizations and --enable-debug:
5
4
6
target/arm/translate-a64.c: In function ‘aarch64_tr_translate_insn’:
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
target/arm/translate-a64.c:2361:8: error: ‘post_index’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
6
Message-id: 20200214194643.23317-5-richard.henderson@linaro.org
8
if (!post_index) {
9
^
10
target/arm/translate-a64.c:2307:10: note: ‘post_index’ was declared here
11
bool post_index;
12
^
13
target/arm/translate-a64.c:2386:8: error: ‘writeback’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
14
if (writeback) {
15
^
16
target/arm/translate-a64.c:2308:10: note: ‘writeback’ was declared here
17
bool writeback;
18
^
19
20
Note that idx comes from selecting 2 bits, and therefore its value
21
can be at most 3.
22
23
Signed-off-by: Emilio G. Cota <cota@braap.org>
24
Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Message-id: 1510087611-1851-1-git-send-email-cota@braap.org
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
---
9
---
29
target/arm/translate-a64.c | 2 ++
10
target/arm/translate-a64.c | 6 ++++++
30
1 file changed, 2 insertions(+)
11
1 file changed, 6 insertions(+)
31
12
32
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
33
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-a64.c
15
--- a/target/arm/translate-a64.c
35
+++ b/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
36
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
17
@@ -XXX,XX +XXX,XX @@ static void handle_simd_inse(DisasContext *s, int rd, int rn,
37
post_index = false;
18
write_vec_element(s, tmp, rd, dst_index, size);
38
writeback = true;
19
39
break;
20
tcg_temp_free_i64(tmp);
40
+ default:
21
+
41
+ g_assert_not_reached();
22
+ /* INS is considered a 128-bit write for SVE. */
42
}
23
+ clear_vec_high(s, true, rd);
43
24
}
44
if (rn == 31) {
25
26
27
@@ -XXX,XX +XXX,XX @@ static void handle_simd_insg(DisasContext *s, int rd, int rn, int imm5)
28
29
idx = extract32(imm5, 1 + size, 4 - size);
30
write_vec_element(s, cpu_reg(s, rn), rd, idx, size);
31
+
32
+ /* INS is considered a 128-bit write for SVE. */
33
+ clear_vec_high(s, true, rd);
34
}
35
36
/*
45
--
37
--
46
2.7.4
38
2.20.1
47
39
48
40
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The psuedocode in aarch64/functions/pac/auth/Auth and
4
aarch64/functions/pac/strip/Strip always uses bit 55 for
5
extfield and do not consider if the current regime has 2 ranges.
6
7
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20200216194343.21331-2-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/pauth_helper.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/pauth_helper.c
19
+++ b/target/arm/pauth_helper.c
20
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
21
22
static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
23
{
24
- uint64_t extfield = -param.select;
25
+ /* Note that bit 55 is used whether or not the regime has 2 ranges. */
26
+ uint64_t extfield = sextract64(ptr, 55, 1);
27
int bot_pac_bit = 64 - param.tsz;
28
int top_pac_bit = 64 - 8 * param.tbi;
29
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Select should always be 0 for a regime with one range.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200216194343.21331-3-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.c | 46 +++++++++++++++++++++++----------------------
11
1 file changed, 24 insertions(+), 22 deletions(-)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
18
bool tbi, tbid, epd, hpd, using16k, using64k;
19
int select, tsz;
20
21
- /*
22
- * Bit 55 is always between the two regions, and is canonical for
23
- * determining if address tagging is enabled.
24
- */
25
- select = extract64(va, 55, 1);
26
-
27
if (!regime_has_2_ranges(mmu_idx)) {
28
+ select = 0;
29
tsz = extract32(tcr, 0, 6);
30
using64k = extract32(tcr, 14, 1);
31
using16k = extract32(tcr, 15, 1);
32
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
33
tbid = extract32(tcr, 29, 1);
34
}
35
epd = false;
36
- } else if (!select) {
37
- tsz = extract32(tcr, 0, 6);
38
- epd = extract32(tcr, 7, 1);
39
- using64k = extract32(tcr, 14, 1);
40
- using16k = extract32(tcr, 15, 1);
41
- tbi = extract64(tcr, 37, 1);
42
- hpd = extract64(tcr, 41, 1);
43
- tbid = extract64(tcr, 51, 1);
44
} else {
45
- int tg = extract32(tcr, 30, 2);
46
- using16k = tg == 1;
47
- using64k = tg == 3;
48
- tsz = extract32(tcr, 16, 6);
49
- epd = extract32(tcr, 23, 1);
50
- tbi = extract64(tcr, 38, 1);
51
- hpd = extract64(tcr, 42, 1);
52
- tbid = extract64(tcr, 52, 1);
53
+ /*
54
+ * Bit 55 is always between the two regions, and is canonical for
55
+ * determining if address tagging is enabled.
56
+ */
57
+ select = extract64(va, 55, 1);
58
+ if (!select) {
59
+ tsz = extract32(tcr, 0, 6);
60
+ epd = extract32(tcr, 7, 1);
61
+ using64k = extract32(tcr, 14, 1);
62
+ using16k = extract32(tcr, 15, 1);
63
+ tbi = extract64(tcr, 37, 1);
64
+ hpd = extract64(tcr, 41, 1);
65
+ tbid = extract64(tcr, 51, 1);
66
+ } else {
67
+ int tg = extract32(tcr, 30, 2);
68
+ using16k = tg == 1;
69
+ using64k = tg == 3;
70
+ tsz = extract32(tcr, 16, 6);
71
+ epd = extract32(tcr, 23, 1);
72
+ tbi = extract64(tcr, 38, 1);
73
+ hpd = extract64(tcr, 42, 1);
74
+ tbid = extract64(tcr, 52, 1);
75
+ }
76
}
77
tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
78
tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
79
--
80
2.20.1
81
82
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Now that aa64_va_parameters_both sets select based on the number
4
of ranges in the regime, the ttbr1_valid check is redundant.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200216194343.21331-4-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper.c | 6 +-----
12
1 file changed, 1 insertion(+), 5 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
19
TCR *tcr = regime_tcr(env, mmu_idx);
20
int ap, ns, xn, pxn;
21
uint32_t el = regime_el(env, mmu_idx);
22
- bool ttbr1_valid;
23
uint64_t descaddrmask;
24
bool aarch64 = arm_el_is_aa64(env, el);
25
bool guarded = false;
26
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
27
param = aa64_va_parameters(env, address, mmu_idx,
28
access_type != MMU_INST_FETCH);
29
level = 0;
30
- ttbr1_valid = regime_has_2_ranges(mmu_idx);
31
addrsize = 64 - 8 * param.tbi;
32
inputsize = 64 - param.tsz;
33
} else {
34
param = aa32_va_parameters(env, address, mmu_idx);
35
level = 1;
36
- /* There is no TTBR1 for EL2 */
37
- ttbr1_valid = (el != 2);
38
addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
39
inputsize = addrsize - param.tsz;
40
}
41
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
42
if (inputsize < addrsize) {
43
target_ulong top_bits = sextract64(address, inputsize,
44
addrsize - inputsize);
45
- if (-top_bits != param.select || (param.select && !ttbr1_valid)) {
46
+ if (-top_bits != param.select) {
47
/* The gap between the two regions is a Translation fault */
48
fault_type = ARMFault_Translation;
49
goto do_fault;
50
--
51
2.20.1
52
53
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
For the purpose of rebuild_hflags_a64, we do not need to compute
4
all of the va parameters, only tbi. Moreover, we can compute them
5
in a form that is more useful to storing in hflags.
6
7
This eliminates the need for aa64_va_parameter_both, so fold that
8
in to aa64_va_parameter. The remaining calls to aa64_va_parameter
9
are in get_phys_addr_lpae and in pauth_helper.c.
10
11
This reduces the total cpu consumption of aa64_va_parameter in a
12
kernel boot plus a kvm guest kernel boot from 3% to 0.5%.
13
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20200216194343.21331-5-richard.henderson@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
target/arm/internals.h | 3 --
20
target/arm/helper.c | 68 +++++++++++++++++++++++-------------------
21
2 files changed, 37 insertions(+), 34 deletions(-)
22
23
diff --git a/target/arm/internals.h b/target/arm/internals.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/internals.h
26
+++ b/target/arm/internals.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
28
unsigned tsz : 8;
29
unsigned select : 1;
30
bool tbi : 1;
31
- bool tbid : 1;
32
bool epd : 1;
33
bool hpd : 1;
34
bool using16k : 1;
35
bool using64k : 1;
36
} ARMVAParameters;
37
38
-ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
39
- ARMMMUIdx mmu_idx);
40
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
41
ARMMMUIdx mmu_idx, bool data);
42
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/helper.c
46
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
48
}
49
#endif /* !CONFIG_USER_ONLY */
50
51
-ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
52
- ARMMMUIdx mmu_idx)
53
+static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
54
+{
55
+ if (regime_has_2_ranges(mmu_idx)) {
56
+ return extract64(tcr, 37, 2);
57
+ } else if (mmu_idx == ARMMMUIdx_Stage2) {
58
+ return 0; /* VTCR_EL2 */
59
+ } else {
60
+ return extract32(tcr, 20, 1);
61
+ }
62
+}
63
+
64
+static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
65
+{
66
+ if (regime_has_2_ranges(mmu_idx)) {
67
+ return extract64(tcr, 51, 2);
68
+ } else if (mmu_idx == ARMMMUIdx_Stage2) {
69
+ return 0; /* VTCR_EL2 */
70
+ } else {
71
+ return extract32(tcr, 29, 1);
72
+ }
73
+}
74
+
75
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
76
+ ARMMMUIdx mmu_idx, bool data)
77
{
78
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
79
- bool tbi, tbid, epd, hpd, using16k, using64k;
80
- int select, tsz;
81
+ bool epd, hpd, using16k, using64k;
82
+ int select, tsz, tbi;
83
84
if (!regime_has_2_ranges(mmu_idx)) {
85
select = 0;
86
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
87
using16k = extract32(tcr, 15, 1);
88
if (mmu_idx == ARMMMUIdx_Stage2) {
89
/* VTCR_EL2 */
90
- tbi = tbid = hpd = false;
91
+ hpd = false;
92
} else {
93
- tbi = extract32(tcr, 20, 1);
94
hpd = extract32(tcr, 24, 1);
95
- tbid = extract32(tcr, 29, 1);
96
}
97
epd = false;
98
} else {
99
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
100
epd = extract32(tcr, 7, 1);
101
using64k = extract32(tcr, 14, 1);
102
using16k = extract32(tcr, 15, 1);
103
- tbi = extract64(tcr, 37, 1);
104
hpd = extract64(tcr, 41, 1);
105
- tbid = extract64(tcr, 51, 1);
106
} else {
107
int tg = extract32(tcr, 30, 2);
108
using16k = tg == 1;
109
using64k = tg == 3;
110
tsz = extract32(tcr, 16, 6);
111
epd = extract32(tcr, 23, 1);
112
- tbi = extract64(tcr, 38, 1);
113
hpd = extract64(tcr, 42, 1);
114
- tbid = extract64(tcr, 52, 1);
115
}
116
}
117
tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
118
tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
119
120
+ /* Present TBI as a composite with TBID. */
121
+ tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
122
+ if (!data) {
123
+ tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
124
+ }
125
+ tbi = (tbi >> select) & 1;
126
+
127
return (ARMVAParameters) {
128
.tsz = tsz,
129
.select = select,
130
.tbi = tbi,
131
- .tbid = tbid,
132
.epd = epd,
133
.hpd = hpd,
134
.using16k = using16k,
135
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
136
};
137
}
138
139
-ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
140
- ARMMMUIdx mmu_idx, bool data)
141
-{
142
- ARMVAParameters ret = aa64_va_parameters_both(env, va, mmu_idx);
143
-
144
- /* Present TBI as a composite with TBID. */
145
- ret.tbi &= (data || !ret.tbid);
146
- return ret;
147
-}
148
-
149
#ifndef CONFIG_USER_ONLY
150
static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
151
ARMMMUIdx mmu_idx)
152
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
153
{
154
uint32_t flags = rebuild_hflags_aprofile(env);
155
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
156
- ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
157
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
158
uint64_t sctlr;
159
int tbii, tbid;
160
161
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
162
163
/* Get control bits for tagged addresses. */
164
- if (regime_has_2_ranges(mmu_idx)) {
165
- ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
166
- tbid = (p1.tbi << 1) | p0.tbi;
167
- tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
168
- } else {
169
- tbid = p0.tbi;
170
- tbii = tbid & !p0.tbid;
171
- }
172
+ tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
173
+ tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
174
175
flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
176
flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
177
--
178
2.20.1
179
180
diff view generated by jsdifflib
New patch
1
Enforce a convention that an isar_feature function that tests a
2
32-bit ID register always has _aa32_ in its name, and one that
3
tests a 64-bit ID register always has _aa64_ in its name.
4
We already follow this except for three cases: thumb_div,
5
arm_div and jazelle, which all need _aa32_ adding.
1
6
7
(As noted in the comment, isar_feature_aa32_fp16_arith()
8
is an exception in that it currently tests ID_AA64PFR0_EL1,
9
but will switch to MVFR1 once we've properly implemented
10
FP16 for AArch32.)
11
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20200214175116.9164-2-peter.maydell@linaro.org
16
---
17
target/arm/cpu.h | 13 ++++++++++---
18
target/arm/internals.h | 2 +-
19
linux-user/elfload.c | 4 ++--
20
target/arm/cpu.c | 6 ++++--
21
target/arm/helper.c | 2 +-
22
target/arm/translate.c | 6 +++---
23
6 files changed, 21 insertions(+), 12 deletions(-)
24
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
28
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
30
/* Shared between translate-sve.c and sve_helper.c. */
31
extern const uint64_t pred_esz_masks[4];
32
33
+/*
34
+ * Naming convention for isar_feature functions:
35
+ * Functions which test 32-bit ID registers should have _aa32_ in
36
+ * their name. Functions which test 64-bit ID registers should have
37
+ * _aa64_ in their name.
38
+ */
39
+
40
/*
41
* 32-bit feature tests via id registers.
42
*/
43
-static inline bool isar_feature_thumb_div(const ARMISARegisters *id)
44
+static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id)
45
{
46
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
47
}
48
49
-static inline bool isar_feature_arm_div(const ARMISARegisters *id)
50
+static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
51
{
52
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
53
}
54
55
-static inline bool isar_feature_jazelle(const ARMISARegisters *id)
56
+static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
57
{
58
return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
59
}
60
diff --git a/target/arm/internals.h b/target/arm/internals.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/internals.h
63
+++ b/target/arm/internals.h
64
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
65
if ((features >> ARM_FEATURE_THUMB2) & 1) {
66
valid |= CPSR_IT;
67
}
68
- if (isar_feature_jazelle(id)) {
69
+ if (isar_feature_aa32_jazelle(id)) {
70
valid |= CPSR_J;
71
}
72
if (isar_feature_aa32_pan(id)) {
73
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/linux-user/elfload.c
76
+++ b/linux-user/elfload.c
77
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
78
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
79
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
80
GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
81
- GET_FEATURE_ID(arm_div, ARM_HWCAP_ARM_IDIVA);
82
- GET_FEATURE_ID(thumb_div, ARM_HWCAP_ARM_IDIVT);
83
+ GET_FEATURE_ID(aa32_arm_div, ARM_HWCAP_ARM_IDIVA);
84
+ GET_FEATURE_ID(aa32_thumb_div, ARM_HWCAP_ARM_IDIVT);
85
/* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
86
* Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
87
* ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
88
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/cpu.c
91
+++ b/target/arm/cpu.c
92
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
93
* Presence of EL2 itself is ARM_FEATURE_EL2, and of the
94
* Security Extensions is ARM_FEATURE_EL3.
95
*/
96
- assert(!tcg_enabled() || no_aa32 || cpu_isar_feature(arm_div, cpu));
97
+ assert(!tcg_enabled() || no_aa32 ||
98
+ cpu_isar_feature(aa32_arm_div, cpu));
99
set_feature(env, ARM_FEATURE_LPAE);
100
set_feature(env, ARM_FEATURE_V7);
101
}
102
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
103
if (arm_feature(env, ARM_FEATURE_V6)) {
104
set_feature(env, ARM_FEATURE_V5);
105
if (!arm_feature(env, ARM_FEATURE_M)) {
106
- assert(!tcg_enabled() || no_aa32 || cpu_isar_feature(jazelle, cpu));
107
+ assert(!tcg_enabled() || no_aa32 ||
108
+ cpu_isar_feature(aa32_jazelle, cpu));
109
set_feature(env, ARM_FEATURE_AUXCR);
110
}
111
}
112
diff --git a/target/arm/helper.c b/target/arm/helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/helper.c
115
+++ b/target/arm/helper.c
116
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
117
if (arm_feature(env, ARM_FEATURE_LPAE)) {
118
define_arm_cp_regs(cpu, lpae_cp_reginfo);
119
}
120
- if (cpu_isar_feature(jazelle, cpu)) {
121
+ if (cpu_isar_feature(aa32_jazelle, cpu)) {
122
define_arm_cp_regs(cpu, jazelle_regs);
123
}
124
/* Slightly awkwardly, the OMAP and StrongARM cores need all of
125
diff --git a/target/arm/translate.c b/target/arm/translate.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/arm/translate.c
128
+++ b/target/arm/translate.c
129
@@ -XXX,XX +XXX,XX @@
130
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
131
/* currently all emulated v5 cores are also v5TE, so don't bother */
132
#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
133
-#define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
134
+#define ENABLE_ARCH_5J dc_isar_feature(aa32_jazelle, s)
135
#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
136
#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
137
#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
138
@@ -XXX,XX +XXX,XX @@ static bool op_div(DisasContext *s, arg_rrr *a, bool u)
139
TCGv_i32 t1, t2;
140
141
if (s->thumb
142
- ? !dc_isar_feature(thumb_div, s)
143
- : !dc_isar_feature(arm_div, s)) {
144
+ ? !dc_isar_feature(aa32_thumb_div, s)
145
+ : !dc_isar_feature(aa32_arm_div, s)) {
146
return false;
147
}
148
149
--
150
2.20.1
151
152
diff view generated by jsdifflib
New patch
1
In take_aarch32_exception(), we know we are dealing with a CPU that
2
has AArch32, so the right isar_feature test is aa32_pan, not aa64_pan.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200214175116.9164-3-peter.maydell@linaro.org
7
---
8
target/arm/helper.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
14
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
16
env->elr_el[2] = env->regs[15];
17
} else {
18
/* CPSR.PAN is normally preserved preserved unless... */
19
- if (cpu_isar_feature(aa64_pan, env_archcpu(env))) {
20
+ if (cpu_isar_feature(aa32_pan, env_archcpu(env))) {
21
switch (new_el) {
22
case 3:
23
if (!arm_is_secure_below_el3(env)) {
24
--
25
2.20.1
26
27
diff view generated by jsdifflib
New patch
1
Our current usage of the isar_feature feature tests almost always
2
uses an _aa32_ test when the code path is known to be AArch32
3
specific and an _aa64_ test when the code path is known to be
4
AArch64 specific. There is just one exception: in the vfp_set_fpscr
5
helper we check aa64_fp16 to determine whether the FZ16 bit in
6
the FP(S)CR exists, but this code is also used for AArch32.
7
There are other places in future where we're likely to want
8
a general "does this feature exist for either AArch32 or
9
AArch64" check (typically where architecturally the feature exists
10
for both CPU states if it exists at all, but the CPU might be
11
AArch32-only or AArch64-only, and so only have one set of ID
12
registers).
1
13
14
Introduce a new category of isar_feature_* functions:
15
isar_feature_any_foo() should be tested when what we want to
16
know is "does this feature exist for either AArch32 or AArch64",
17
and always returns the logical OR of isar_feature_aa32_foo()
18
and isar_feature_aa64_foo().
19
20
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Message-id: 20200214175116.9164-4-peter.maydell@linaro.org
24
---
25
target/arm/cpu.h | 19 ++++++++++++++++++-
26
target/arm/vfp_helper.c | 2 +-
27
2 files changed, 19 insertions(+), 2 deletions(-)
28
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
33
@@ -XXX,XX +XXX,XX @@ extern const uint64_t pred_esz_masks[4];
34
* Naming convention for isar_feature functions:
35
* Functions which test 32-bit ID registers should have _aa32_ in
36
* their name. Functions which test 64-bit ID registers should have
37
- * _aa64_ in their name.
38
+ * _aa64_ in their name. These must only be used in code where we
39
+ * know for certain that the CPU has AArch32 or AArch64 respectively
40
+ * or where the correct answer for a CPU which doesn't implement that
41
+ * CPU state is "false" (eg when generating A32 or A64 code, if adding
42
+ * system registers that are specific to that CPU state, for "should
43
+ * we let this system register bit be set" tests where the 32-bit
44
+ * flavour of the register doesn't have the bit, and so on).
45
+ * Functions which simply ask "does this feature exist at all" have
46
+ * _any_ in their name, and always return the logical OR of the _aa64_
47
+ * and the _aa32_ function.
48
*/
49
50
/*
51
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
52
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
53
}
54
55
+/*
56
+ * Feature tests for "does this exist in either 32-bit or 64-bit?"
57
+ */
58
+static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
59
+{
60
+ return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
61
+}
62
+
63
/*
64
* Forward to the above feature tests given an ARMCPU pointer.
65
*/
66
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/vfp_helper.c
69
+++ b/target/arm/vfp_helper.c
70
@@ -XXX,XX +XXX,XX @@ uint32_t vfp_get_fpscr(CPUARMState *env)
71
void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
72
{
73
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
74
- if (!cpu_isar_feature(aa64_fp16, env_archcpu(env))) {
75
+ if (!cpu_isar_feature(any_fp16, env_archcpu(env))) {
76
val &= ~FPCR_FZ16;
77
}
78
79
--
80
2.20.1
81
82
diff view generated by jsdifflib
New patch
1
Instead of open-coding "ARM_FEATURE_AARCH64 ? aa64_predinv: aa32_predinv",
2
define and use an any_predinv isar_feature test function.
1
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200214175116.9164-5-peter.maydell@linaro.org
8
---
9
target/arm/cpu.h | 5 +++++
10
target/arm/helper.c | 9 +--------
11
2 files changed, 6 insertions(+), 8 deletions(-)
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
18
return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
19
}
20
21
+static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
22
+{
23
+ return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
24
+}
25
+
26
/*
27
* Forward to the above feature tests given an ARMCPU pointer.
28
*/
29
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/helper.c
32
+++ b/target/arm/helper.c
33
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
34
#endif /*CONFIG_USER_ONLY*/
35
#endif
36
37
- /*
38
- * While all v8.0 cpus support aarch64, QEMU does have configurations
39
- * that do not set ID_AA64ISAR1, e.g. user-only qemu-arm -cpu max,
40
- * which will set ID_ISAR6.
41
- */
42
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
43
- ? cpu_isar_feature(aa64_predinv, cpu)
44
- : cpu_isar_feature(aa32_predinv, cpu)) {
45
+ if (cpu_isar_feature(any_predinv, cpu)) {
46
define_arm_cp_regs(cpu, predinv_reginfo);
47
}
48
49
--
50
2.20.1
51
52
diff view generated by jsdifflib
New patch
1
1
Pull the code that defines the various PMU registers out
2
into its own function, matching the pattern we have
3
already for the debug registers.
4
5
Apart from one style fix to a multi-line comment, this
6
is purely movement of code with no changes to it.
7
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20200214175116.9164-6-peter.maydell@linaro.org
12
---
13
target/arm/helper.c | 158 +++++++++++++++++++++++---------------------
14
1 file changed, 82 insertions(+), 76 deletions(-)
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
21
}
22
}
23
24
+static void define_pmu_regs(ARMCPU *cpu)
25
+{
26
+ /*
27
+ * v7 performance monitor control register: same implementor
28
+ * field as main ID register, and we implement four counters in
29
+ * addition to the cycle count register.
30
+ */
31
+ unsigned int i, pmcrn = 4;
32
+ ARMCPRegInfo pmcr = {
33
+ .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
34
+ .access = PL0_RW,
35
+ .type = ARM_CP_IO | ARM_CP_ALIAS,
36
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
37
+ .accessfn = pmreg_access, .writefn = pmcr_write,
38
+ .raw_writefn = raw_write,
39
+ };
40
+ ARMCPRegInfo pmcr64 = {
41
+ .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
42
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
43
+ .access = PL0_RW, .accessfn = pmreg_access,
44
+ .type = ARM_CP_IO,
45
+ .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
46
+ .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
47
+ .writefn = pmcr_write, .raw_writefn = raw_write,
48
+ };
49
+ define_one_arm_cp_reg(cpu, &pmcr);
50
+ define_one_arm_cp_reg(cpu, &pmcr64);
51
+ for (i = 0; i < pmcrn; i++) {
52
+ char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
53
+ char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
54
+ char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
55
+ char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
56
+ ARMCPRegInfo pmev_regs[] = {
57
+ { .name = pmevcntr_name, .cp = 15, .crn = 14,
58
+ .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
59
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
60
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
61
+ .accessfn = pmreg_access },
62
+ { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
63
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
64
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
65
+ .type = ARM_CP_IO,
66
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
67
+ .raw_readfn = pmevcntr_rawread,
68
+ .raw_writefn = pmevcntr_rawwrite },
69
+ { .name = pmevtyper_name, .cp = 15, .crn = 14,
70
+ .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
71
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
72
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
73
+ .accessfn = pmreg_access },
74
+ { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
75
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
76
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
77
+ .type = ARM_CP_IO,
78
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
79
+ .raw_writefn = pmevtyper_rawwrite },
80
+ REGINFO_SENTINEL
81
+ };
82
+ define_arm_cp_regs(cpu, pmev_regs);
83
+ g_free(pmevcntr_name);
84
+ g_free(pmevcntr_el0_name);
85
+ g_free(pmevtyper_name);
86
+ g_free(pmevtyper_el0_name);
87
+ }
88
+ if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
89
+ FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
90
+ ARMCPRegInfo v81_pmu_regs[] = {
91
+ { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
92
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
93
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
94
+ .resetvalue = extract64(cpu->pmceid0, 32, 32) },
95
+ { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
96
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
97
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
98
+ .resetvalue = extract64(cpu->pmceid1, 32, 32) },
99
+ REGINFO_SENTINEL
100
+ };
101
+ define_arm_cp_regs(cpu, v81_pmu_regs);
102
+ }
103
+}
104
+
105
/* We don't know until after realize whether there's a GICv3
106
* attached, and that is what registers the gicv3 sysregs.
107
* So we have to fill in the GIC fields in ID_PFR/ID_PFR1_EL1/ID_AA64PFR0_EL1
108
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
109
define_arm_cp_regs(cpu, pmovsset_cp_reginfo);
110
}
111
if (arm_feature(env, ARM_FEATURE_V7)) {
112
- /* v7 performance monitor control register: same implementor
113
- * field as main ID register, and we implement four counters in
114
- * addition to the cycle count register.
115
- */
116
- unsigned int i, pmcrn = 4;
117
- ARMCPRegInfo pmcr = {
118
- .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
119
- .access = PL0_RW,
120
- .type = ARM_CP_IO | ARM_CP_ALIAS,
121
- .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
122
- .accessfn = pmreg_access, .writefn = pmcr_write,
123
- .raw_writefn = raw_write,
124
- };
125
- ARMCPRegInfo pmcr64 = {
126
- .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
127
- .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
128
- .access = PL0_RW, .accessfn = pmreg_access,
129
- .type = ARM_CP_IO,
130
- .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
131
- .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
132
- .writefn = pmcr_write, .raw_writefn = raw_write,
133
- };
134
- define_one_arm_cp_reg(cpu, &pmcr);
135
- define_one_arm_cp_reg(cpu, &pmcr64);
136
- for (i = 0; i < pmcrn; i++) {
137
- char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
138
- char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
139
- char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
140
- char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
141
- ARMCPRegInfo pmev_regs[] = {
142
- { .name = pmevcntr_name, .cp = 15, .crn = 14,
143
- .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
144
- .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
145
- .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
146
- .accessfn = pmreg_access },
147
- { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
148
- .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
149
- .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
150
- .type = ARM_CP_IO,
151
- .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
152
- .raw_readfn = pmevcntr_rawread,
153
- .raw_writefn = pmevcntr_rawwrite },
154
- { .name = pmevtyper_name, .cp = 15, .crn = 14,
155
- .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
156
- .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
157
- .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
158
- .accessfn = pmreg_access },
159
- { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
160
- .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
161
- .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
162
- .type = ARM_CP_IO,
163
- .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
164
- .raw_writefn = pmevtyper_rawwrite },
165
- REGINFO_SENTINEL
166
- };
167
- define_arm_cp_regs(cpu, pmev_regs);
168
- g_free(pmevcntr_name);
169
- g_free(pmevcntr_el0_name);
170
- g_free(pmevtyper_name);
171
- g_free(pmevtyper_el0_name);
172
- }
173
ARMCPRegInfo clidr = {
174
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
175
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
176
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
177
define_one_arm_cp_reg(cpu, &clidr);
178
define_arm_cp_regs(cpu, v7_cp_reginfo);
179
define_debug_regs(cpu);
180
+ define_pmu_regs(cpu);
181
} else {
182
define_arm_cp_regs(cpu, not_v7_cp_reginfo);
183
}
184
- if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
185
- FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
186
- ARMCPRegInfo v81_pmu_regs[] = {
187
- { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
188
- .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
189
- .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
190
- .resetvalue = extract64(cpu->pmceid0, 32, 32) },
191
- { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
192
- .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
193
- .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
194
- .resetvalue = extract64(cpu->pmceid1, 32, 32) },
195
- REGINFO_SENTINEL
196
- };
197
- define_arm_cp_regs(cpu, v81_pmu_regs);
198
- }
199
if (arm_feature(env, ARM_FEATURE_V8)) {
200
/* AArch64 ID registers, which all have impdef reset values.
201
* Note that within the ID register ranges the unused slots
202
--
203
2.20.1
204
205
diff view generated by jsdifflib
New patch
1
Add FIELD() definitions for the ID_AA64DFR0_EL1 and use them
2
where we currently have hard-coded bit values.
1
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200214175116.9164-7-peter.maydell@linaro.org
8
---
9
target/arm/cpu.h | 10 ++++++++++
10
target/arm/cpu.c | 2 +-
11
target/arm/helper.c | 6 +++---
12
3 files changed, 14 insertions(+), 4 deletions(-)
13
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64MMFR2, BBM, 52, 4)
19
FIELD(ID_AA64MMFR2, EVT, 56, 4)
20
FIELD(ID_AA64MMFR2, E0PD, 60, 4)
21
22
+FIELD(ID_AA64DFR0, DEBUGVER, 0, 4)
23
+FIELD(ID_AA64DFR0, TRACEVER, 4, 4)
24
+FIELD(ID_AA64DFR0, PMUVER, 8, 4)
25
+FIELD(ID_AA64DFR0, BRPS, 12, 4)
26
+FIELD(ID_AA64DFR0, WRPS, 20, 4)
27
+FIELD(ID_AA64DFR0, CTX_CMPS, 28, 4)
28
+FIELD(ID_AA64DFR0, PMSVER, 32, 4)
29
+FIELD(ID_AA64DFR0, DOUBLELOCK, 36, 4)
30
+FIELD(ID_AA64DFR0, TRACEFILT, 40, 4)
31
+
32
FIELD(ID_DFR0, COPDBG, 0, 4)
33
FIELD(ID_DFR0, COPSDBG, 4, 4)
34
FIELD(ID_DFR0, MMAPDBG, 8, 4)
35
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.c
38
+++ b/target/arm/cpu.c
39
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
40
cpu);
41
#endif
42
} else {
43
- cpu->id_aa64dfr0 &= ~0xf00;
44
+ cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
45
cpu->id_dfr0 &= ~(0xf << 24);
46
cpu->pmceid0 = 0;
47
cpu->pmceid1 = 0;
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/helper.c
51
+++ b/target/arm/helper.c
52
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
53
* check that if they both exist then they agree.
54
*/
55
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
56
- assert(extract32(cpu->id_aa64dfr0, 12, 4) == brps);
57
- assert(extract32(cpu->id_aa64dfr0, 20, 4) == wrps);
58
- assert(extract32(cpu->id_aa64dfr0, 28, 4) == ctx_cmps);
59
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
60
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
61
+ assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
62
}
63
64
define_one_arm_cp_reg(cpu, &dbgdidr);
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
New patch
1
We already define FIELD macros for ID_DFR0, so use them in the
2
one place where we're doing direct bit value manipulation.
1
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200214175116.9164-8-peter.maydell@linaro.org
8
---
9
target/arm/cpu.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
17
#endif
18
} else {
19
cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
20
- cpu->id_dfr0 &= ~(0xf << 24);
21
+ cpu->id_dfr0 = FIELD_DP32(cpu->id_dfr0, ID_DFR0, PERFMON, 0);
22
cpu->pmceid0 = 0;
23
cpu->pmceid1 = 0;
24
}
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
New patch
1
1
Instead of open-coding a check on the ID_DFR0 PerfMon ID register
2
field, create a standardly-named isar_feature for "does AArch32 have
3
a v8.1 PMUv3" and use it.
4
5
This entails moving the id_dfr0 field into the ARMISARegisters struct.
6
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200214175116.9164-9-peter.maydell@linaro.org
10
---
11
target/arm/cpu.h | 9 ++++++++-
12
hw/intc/armv7m_nvic.c | 2 +-
13
target/arm/cpu.c | 28 ++++++++++++++--------------
14
target/arm/cpu64.c | 6 +++---
15
target/arm/helper.c | 5 ++---
16
5 files changed, 28 insertions(+), 22 deletions(-)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
23
uint32_t mvfr0;
24
uint32_t mvfr1;
25
uint32_t mvfr2;
26
+ uint32_t id_dfr0;
27
uint64_t id_aa64isar0;
28
uint64_t id_aa64isar1;
29
uint64_t id_aa64pfr0;
30
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
31
uint32_t reset_sctlr;
32
uint32_t id_pfr0;
33
uint32_t id_pfr1;
34
- uint32_t id_dfr0;
35
uint64_t pmceid0;
36
uint64_t pmceid1;
37
uint32_t id_afr0;
38
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
39
return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2;
40
}
41
42
+static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
43
+{
44
+ /* 0xf means "non-standard IMPDEF PMU" */
45
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
46
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
47
+}
48
+
49
/*
50
* 64-bit feature tests via id registers.
51
*/
52
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/intc/armv7m_nvic.c
55
+++ b/hw/intc/armv7m_nvic.c
56
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
57
case 0xd44: /* PFR1. */
58
return cpu->id_pfr1;
59
case 0xd48: /* DFR0. */
60
- return cpu->id_dfr0;
61
+ return cpu->isar.id_dfr0;
62
case 0xd4c: /* AFR0. */
63
return cpu->id_afr0;
64
case 0xd50: /* MMFR0. */
65
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/cpu.c
68
+++ b/target/arm/cpu.c
69
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
70
#endif
71
} else {
72
cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
73
- cpu->id_dfr0 = FIELD_DP32(cpu->id_dfr0, ID_DFR0, PERFMON, 0);
74
+ cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
75
cpu->pmceid0 = 0;
76
cpu->pmceid1 = 0;
77
}
78
@@ -XXX,XX +XXX,XX @@ static void arm1136_r2_initfn(Object *obj)
79
cpu->reset_sctlr = 0x00050078;
80
cpu->id_pfr0 = 0x111;
81
cpu->id_pfr1 = 0x1;
82
- cpu->id_dfr0 = 0x2;
83
+ cpu->isar.id_dfr0 = 0x2;
84
cpu->id_afr0 = 0x3;
85
cpu->id_mmfr0 = 0x01130003;
86
cpu->id_mmfr1 = 0x10030302;
87
@@ -XXX,XX +XXX,XX @@ static void arm1136_initfn(Object *obj)
88
cpu->reset_sctlr = 0x00050078;
89
cpu->id_pfr0 = 0x111;
90
cpu->id_pfr1 = 0x1;
91
- cpu->id_dfr0 = 0x2;
92
+ cpu->isar.id_dfr0 = 0x2;
93
cpu->id_afr0 = 0x3;
94
cpu->id_mmfr0 = 0x01130003;
95
cpu->id_mmfr1 = 0x10030302;
96
@@ -XXX,XX +XXX,XX @@ static void arm1176_initfn(Object *obj)
97
cpu->reset_sctlr = 0x00050078;
98
cpu->id_pfr0 = 0x111;
99
cpu->id_pfr1 = 0x11;
100
- cpu->id_dfr0 = 0x33;
101
+ cpu->isar.id_dfr0 = 0x33;
102
cpu->id_afr0 = 0;
103
cpu->id_mmfr0 = 0x01130003;
104
cpu->id_mmfr1 = 0x10030302;
105
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
106
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
107
cpu->id_pfr0 = 0x111;
108
cpu->id_pfr1 = 0x1;
109
- cpu->id_dfr0 = 0;
110
+ cpu->isar.id_dfr0 = 0;
111
cpu->id_afr0 = 0x2;
112
cpu->id_mmfr0 = 0x01100103;
113
cpu->id_mmfr1 = 0x10020302;
114
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
115
cpu->pmsav7_dregion = 8;
116
cpu->id_pfr0 = 0x00000030;
117
cpu->id_pfr1 = 0x00000200;
118
- cpu->id_dfr0 = 0x00100000;
119
+ cpu->isar.id_dfr0 = 0x00100000;
120
cpu->id_afr0 = 0x00000000;
121
cpu->id_mmfr0 = 0x00000030;
122
cpu->id_mmfr1 = 0x00000000;
123
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
124
cpu->isar.mvfr2 = 0x00000000;
125
cpu->id_pfr0 = 0x00000030;
126
cpu->id_pfr1 = 0x00000200;
127
- cpu->id_dfr0 = 0x00100000;
128
+ cpu->isar.id_dfr0 = 0x00100000;
129
cpu->id_afr0 = 0x00000000;
130
cpu->id_mmfr0 = 0x00000030;
131
cpu->id_mmfr1 = 0x00000000;
132
@@ -XXX,XX +XXX,XX @@ static void cortex_m7_initfn(Object *obj)
133
cpu->isar.mvfr2 = 0x00000040;
134
cpu->id_pfr0 = 0x00000030;
135
cpu->id_pfr1 = 0x00000200;
136
- cpu->id_dfr0 = 0x00100000;
137
+ cpu->isar.id_dfr0 = 0x00100000;
138
cpu->id_afr0 = 0x00000000;
139
cpu->id_mmfr0 = 0x00100030;
140
cpu->id_mmfr1 = 0x00000000;
141
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
142
cpu->isar.mvfr2 = 0x00000040;
143
cpu->id_pfr0 = 0x00000030;
144
cpu->id_pfr1 = 0x00000210;
145
- cpu->id_dfr0 = 0x00200000;
146
+ cpu->isar.id_dfr0 = 0x00200000;
147
cpu->id_afr0 = 0x00000000;
148
cpu->id_mmfr0 = 0x00101F40;
149
cpu->id_mmfr1 = 0x00000000;
150
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
151
cpu->midr = 0x411fc153; /* r1p3 */
152
cpu->id_pfr0 = 0x0131;
153
cpu->id_pfr1 = 0x001;
154
- cpu->id_dfr0 = 0x010400;
155
+ cpu->isar.id_dfr0 = 0x010400;
156
cpu->id_afr0 = 0x0;
157
cpu->id_mmfr0 = 0x0210030;
158
cpu->id_mmfr1 = 0x00000000;
159
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
160
cpu->reset_sctlr = 0x00c50078;
161
cpu->id_pfr0 = 0x1031;
162
cpu->id_pfr1 = 0x11;
163
- cpu->id_dfr0 = 0x400;
164
+ cpu->isar.id_dfr0 = 0x400;
165
cpu->id_afr0 = 0;
166
cpu->id_mmfr0 = 0x31100003;
167
cpu->id_mmfr1 = 0x20000000;
168
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
169
cpu->reset_sctlr = 0x00c50078;
170
cpu->id_pfr0 = 0x1031;
171
cpu->id_pfr1 = 0x11;
172
- cpu->id_dfr0 = 0x000;
173
+ cpu->isar.id_dfr0 = 0x000;
174
cpu->id_afr0 = 0;
175
cpu->id_mmfr0 = 0x00100103;
176
cpu->id_mmfr1 = 0x20000000;
177
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
178
cpu->reset_sctlr = 0x00c50078;
179
cpu->id_pfr0 = 0x00001131;
180
cpu->id_pfr1 = 0x00011011;
181
- cpu->id_dfr0 = 0x02010555;
182
+ cpu->isar.id_dfr0 = 0x02010555;
183
cpu->id_afr0 = 0x00000000;
184
cpu->id_mmfr0 = 0x10101105;
185
cpu->id_mmfr1 = 0x40000000;
186
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
187
cpu->reset_sctlr = 0x00c50078;
188
cpu->id_pfr0 = 0x00001131;
189
cpu->id_pfr1 = 0x00011011;
190
- cpu->id_dfr0 = 0x02010555;
191
+ cpu->isar.id_dfr0 = 0x02010555;
192
cpu->id_afr0 = 0x00000000;
193
cpu->id_mmfr0 = 0x10201105;
194
cpu->id_mmfr1 = 0x20000000;
195
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/target/arm/cpu64.c
198
+++ b/target/arm/cpu64.c
199
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
200
cpu->reset_sctlr = 0x00c50838;
201
cpu->id_pfr0 = 0x00000131;
202
cpu->id_pfr1 = 0x00011011;
203
- cpu->id_dfr0 = 0x03010066;
204
+ cpu->isar.id_dfr0 = 0x03010066;
205
cpu->id_afr0 = 0x00000000;
206
cpu->id_mmfr0 = 0x10101105;
207
cpu->id_mmfr1 = 0x40000000;
208
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
209
cpu->reset_sctlr = 0x00c50838;
210
cpu->id_pfr0 = 0x00000131;
211
cpu->id_pfr1 = 0x00011011;
212
- cpu->id_dfr0 = 0x03010066;
213
+ cpu->isar.id_dfr0 = 0x03010066;
214
cpu->id_afr0 = 0x00000000;
215
cpu->id_mmfr0 = 0x10101105;
216
cpu->id_mmfr1 = 0x40000000;
217
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
218
cpu->reset_sctlr = 0x00c50838;
219
cpu->id_pfr0 = 0x00000131;
220
cpu->id_pfr1 = 0x00011011;
221
- cpu->id_dfr0 = 0x03010066;
222
+ cpu->isar.id_dfr0 = 0x03010066;
223
cpu->id_afr0 = 0x00000000;
224
cpu->id_mmfr0 = 0x10201105;
225
cpu->id_mmfr1 = 0x40000000;
226
diff --git a/target/arm/helper.c b/target/arm/helper.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/target/arm/helper.c
229
+++ b/target/arm/helper.c
230
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
231
g_free(pmevtyper_name);
232
g_free(pmevtyper_el0_name);
233
}
234
- if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
235
- FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
236
+ if (cpu_isar_feature(aa32_pmu_8_1, cpu)) {
237
ARMCPRegInfo v81_pmu_regs[] = {
238
{ .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
239
.cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
240
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
241
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
242
.access = PL1_R, .type = ARM_CP_CONST,
243
.accessfn = access_aa32_tid3,
244
- .resetvalue = cpu->id_dfr0 },
245
+ .resetvalue = cpu->isar.id_dfr0 },
246
{ .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
247
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
248
.access = PL1_R, .type = ARM_CP_CONST,
249
--
250
2.20.1
251
252
diff view generated by jsdifflib
New patch
1
Add the 64-bit version of the "is this a v8.1 PMUv3?"
2
ID register check function, and the _any_ version that
3
checks for either AArch32 or AArch64 support. We'll use
4
this in a later commit.
1
5
6
We don't (yet) do any isar_feature checks on ID_AA64DFR1_EL1,
7
but we move id_aa64dfr1 into the ARMISARegisters struct with
8
id_aa64dfr0, for consistency.
9
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20200214175116.9164-10-peter.maydell@linaro.org
14
---
15
target/arm/cpu.h | 15 +++++++++++++--
16
target/arm/cpu.c | 3 ++-
17
target/arm/cpu64.c | 6 +++---
18
target/arm/helper.c | 12 +++++++-----
19
4 files changed, 25 insertions(+), 11 deletions(-)
20
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
26
uint64_t id_aa64mmfr0;
27
uint64_t id_aa64mmfr1;
28
uint64_t id_aa64mmfr2;
29
+ uint64_t id_aa64dfr0;
30
+ uint64_t id_aa64dfr1;
31
} isar;
32
uint32_t midr;
33
uint32_t revidr;
34
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
35
uint32_t id_mmfr2;
36
uint32_t id_mmfr3;
37
uint32_t id_mmfr4;
38
- uint64_t id_aa64dfr0;
39
- uint64_t id_aa64dfr1;
40
uint64_t id_aa64afr0;
41
uint64_t id_aa64afr1;
42
uint32_t dbgdidr;
43
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
44
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
45
}
46
47
+static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
48
+{
49
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
50
+ FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
51
+}
52
+
53
/*
54
* Feature tests for "does this exist in either 32-bit or 64-bit?"
55
*/
56
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
57
return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
58
}
59
60
+static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
61
+{
62
+ return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
63
+}
64
+
65
/*
66
* Forward to the above feature tests given an ARMCPU pointer.
67
*/
68
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/cpu.c
71
+++ b/target/arm/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
73
cpu);
74
#endif
75
} else {
76
- cpu->id_aa64dfr0 = FIELD_DP64(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
77
+ cpu->isar.id_aa64dfr0 =
78
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
79
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
80
cpu->pmceid0 = 0;
81
cpu->pmceid1 = 0;
82
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/target/arm/cpu64.c
85
+++ b/target/arm/cpu64.c
86
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
87
cpu->isar.id_isar5 = 0x00011121;
88
cpu->isar.id_isar6 = 0;
89
cpu->isar.id_aa64pfr0 = 0x00002222;
90
- cpu->id_aa64dfr0 = 0x10305106;
91
+ cpu->isar.id_aa64dfr0 = 0x10305106;
92
cpu->isar.id_aa64isar0 = 0x00011120;
93
cpu->isar.id_aa64mmfr0 = 0x00001124;
94
cpu->dbgdidr = 0x3516d000;
95
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
96
cpu->isar.id_isar5 = 0x00011121;
97
cpu->isar.id_isar6 = 0;
98
cpu->isar.id_aa64pfr0 = 0x00002222;
99
- cpu->id_aa64dfr0 = 0x10305106;
100
+ cpu->isar.id_aa64dfr0 = 0x10305106;
101
cpu->isar.id_aa64isar0 = 0x00011120;
102
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
103
cpu->dbgdidr = 0x3516d000;
104
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
105
cpu->isar.id_isar4 = 0x00011142;
106
cpu->isar.id_isar5 = 0x00011121;
107
cpu->isar.id_aa64pfr0 = 0x00002222;
108
- cpu->id_aa64dfr0 = 0x10305106;
109
+ cpu->isar.id_aa64dfr0 = 0x10305106;
110
cpu->isar.id_aa64isar0 = 0x00011120;
111
cpu->isar.id_aa64mmfr0 = 0x00001124;
112
cpu->dbgdidr = 0x3516d000;
113
diff --git a/target/arm/helper.c b/target/arm/helper.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/helper.c
116
+++ b/target/arm/helper.c
117
@@ -XXX,XX +XXX,XX @@
118
#include "hw/semihosting/semihost.h"
119
#include "sysemu/cpus.h"
120
#include "sysemu/kvm.h"
121
+#include "sysemu/tcg.h"
122
#include "qemu/range.h"
123
#include "qapi/qapi-commands-machine-target.h"
124
#include "qapi/error.h"
125
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
126
* check that if they both exist then they agree.
127
*/
128
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
129
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
130
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
131
- assert(FIELD_EX64(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
132
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
133
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
134
+ assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS)
135
+ == ctx_cmps);
136
}
137
138
define_one_arm_cp_reg(cpu, &dbgdidr);
139
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
140
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
141
.access = PL1_R, .type = ARM_CP_CONST,
142
.accessfn = access_aa64_tid3,
143
- .resetvalue = cpu->id_aa64dfr0 },
144
+ .resetvalue = cpu->isar.id_aa64dfr0 },
145
{ .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
146
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
147
.access = PL1_R, .type = ARM_CP_CONST,
148
.accessfn = access_aa64_tid3,
149
- .resetvalue = cpu->id_aa64dfr1 },
150
+ .resetvalue = cpu->isar.id_aa64dfr1 },
151
{ .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
152
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
153
.access = PL1_R, .type = ARM_CP_CONST,
154
--
155
2.20.1
156
157
diff view generated by jsdifflib
New patch
1
The AArch32 DBGDIDR defines properties like the number of
2
breakpoints, watchpoints and context-matching comparators. On an
3
AArch64 CPU, the register may not even exist if AArch32 is not
4
supported at EL1.
1
5
6
Currently we hard-code use of DBGDIDR to identify the number of
7
breakpoints etc; this works for all our TCG CPUs, but will break if
8
we ever add an AArch64-only CPU. We also have an assert() that the
9
AArch32 and AArch64 registers match, which currently works only by
10
luck for KVM because we don't populate either of these ID registers
11
from the KVM vCPU and so they are both zero.
12
13
Clean this up so we have functions for finding the number
14
of breakpoints, watchpoints and context comparators which look
15
in the appropriate ID register.
16
17
This allows us to drop the "check that AArch64 and AArch32 agree
18
on the number of breakpoints etc" asserts:
19
* we no longer look at the AArch32 versions unless that's the
20
right place to be looking
21
* it's valid to have a CPU (eg AArch64-only) where they don't match
22
* we shouldn't have been asserting the validity of ID registers
23
in a codepath used with KVM anyway
24
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20200214175116.9164-11-peter.maydell@linaro.org
28
---
29
target/arm/cpu.h | 7 +++++++
30
target/arm/internals.h | 42 +++++++++++++++++++++++++++++++++++++++
31
target/arm/debug_helper.c | 6 +++---
32
target/arm/helper.c | 21 +++++---------------
33
4 files changed, 57 insertions(+), 19 deletions(-)
34
35
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.h
38
+++ b/target/arm/cpu.h
39
@@ -XXX,XX +XXX,XX @@ FIELD(ID_DFR0, MPROFDBG, 20, 4)
40
FIELD(ID_DFR0, PERFMON, 24, 4)
41
FIELD(ID_DFR0, TRACEFILT, 28, 4)
42
43
+FIELD(DBGDIDR, SE_IMP, 12, 1)
44
+FIELD(DBGDIDR, NSUHD_IMP, 14, 1)
45
+FIELD(DBGDIDR, VERSION, 16, 4)
46
+FIELD(DBGDIDR, CTX_CMPS, 20, 4)
47
+FIELD(DBGDIDR, BRPS, 24, 4)
48
+FIELD(DBGDIDR, WRPS, 28, 4)
49
+
50
FIELD(MVFR0, SIMDREG, 0, 4)
51
FIELD(MVFR0, FPSP, 4, 4)
52
FIELD(MVFR0, FPDP, 8, 4)
53
diff --git a/target/arm/internals.h b/target/arm/internals.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/internals.h
56
+++ b/target/arm/internals.h
57
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_debug_exception_fsr(CPUARMState *env)
58
}
59
}
60
61
+/**
62
+ * arm_num_brps: Return number of implemented breakpoints.
63
+ * Note that the ID register BRPS field is "number of bps - 1",
64
+ * and we return the actual number of breakpoints.
65
+ */
66
+static inline int arm_num_brps(ARMCPU *cpu)
67
+{
68
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
69
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1;
70
+ } else {
71
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, BRPS) + 1;
72
+ }
73
+}
74
+
75
+/**
76
+ * arm_num_wrps: Return number of implemented watchpoints.
77
+ * Note that the ID register WRPS field is "number of wps - 1",
78
+ * and we return the actual number of watchpoints.
79
+ */
80
+static inline int arm_num_wrps(ARMCPU *cpu)
81
+{
82
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
83
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1;
84
+ } else {
85
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, WRPS) + 1;
86
+ }
87
+}
88
+
89
+/**
90
+ * arm_num_ctx_cmps: Return number of implemented context comparators.
91
+ * Note that the ID register CTX_CMPS field is "number of cmps - 1",
92
+ * and we return the actual number of comparators.
93
+ */
94
+static inline int arm_num_ctx_cmps(ARMCPU *cpu)
95
+{
96
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
97
+ return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1;
98
+ } else {
99
+ return FIELD_EX32(cpu->dbgdidr, DBGDIDR, CTX_CMPS) + 1;
100
+ }
101
+}
102
+
103
/* Note make_memop_idx reserves 4 bits for mmu_idx, and MO_BSWAP is bit 3.
104
* Thus a TCGMemOpIdx, without any MO_ALIGN bits, fits in 8 bits.
105
*/
106
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/debug_helper.c
109
+++ b/target/arm/debug_helper.c
110
@@ -XXX,XX +XXX,XX @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
111
{
112
CPUARMState *env = &cpu->env;
113
uint64_t bcr = env->cp15.dbgbcr[lbn];
114
- int brps = extract32(cpu->dbgdidr, 24, 4);
115
- int ctx_cmps = extract32(cpu->dbgdidr, 20, 4);
116
+ int brps = arm_num_brps(cpu);
117
+ int ctx_cmps = arm_num_ctx_cmps(cpu);
118
int bt;
119
uint32_t contextidr;
120
uint64_t hcr_el2;
121
@@ -XXX,XX +XXX,XX @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
122
* case DBGWCR<n>_EL1.LBN must indicate that breakpoint).
123
* We choose the former.
124
*/
125
- if (lbn > brps || lbn < (brps - ctx_cmps)) {
126
+ if (lbn >= brps || lbn < (brps - ctx_cmps)) {
127
return false;
128
}
129
130
diff --git a/target/arm/helper.c b/target/arm/helper.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/helper.c
133
+++ b/target/arm/helper.c
134
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
135
};
136
137
/* Note that all these register fields hold "number of Xs minus 1". */
138
- brps = extract32(cpu->dbgdidr, 24, 4);
139
- wrps = extract32(cpu->dbgdidr, 28, 4);
140
- ctx_cmps = extract32(cpu->dbgdidr, 20, 4);
141
+ brps = arm_num_brps(cpu);
142
+ wrps = arm_num_wrps(cpu);
143
+ ctx_cmps = arm_num_ctx_cmps(cpu);
144
145
assert(ctx_cmps <= brps);
146
147
- /* The DBGDIDR and ID_AA64DFR0_EL1 define various properties
148
- * of the debug registers such as number of breakpoints;
149
- * check that if they both exist then they agree.
150
- */
151
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
152
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
153
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
154
- assert(FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS)
155
- == ctx_cmps);
156
- }
157
-
158
define_one_arm_cp_reg(cpu, &dbgdidr);
159
define_arm_cp_regs(cpu, debug_cp_reginfo);
160
161
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
162
define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
163
}
164
165
- for (i = 0; i < brps + 1; i++) {
166
+ for (i = 0; i < brps; i++) {
167
ARMCPRegInfo dbgregs[] = {
168
{ .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,
169
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
170
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
171
define_arm_cp_regs(cpu, dbgregs);
172
}
173
174
- for (i = 0; i < wrps + 1; i++) {
175
+ for (i = 0; i < wrps; i++) {
176
ARMCPRegInfo dbgregs[] = {
177
{ .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,
178
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
179
--
180
2.20.1
181
182
diff view generated by jsdifflib
New patch
1
We're going to want to read the DBGDIDR register from KVM in
2
a subsequent commit, which means it needs to be in the
3
ARMISARegisters sub-struct. Move it.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214175116.9164-12-peter.maydell@linaro.org
8
---
9
target/arm/cpu.h | 2 +-
10
target/arm/internals.h | 6 +++---
11
target/arm/cpu.c | 8 ++++----
12
target/arm/cpu64.c | 6 +++---
13
target/arm/helper.c | 2 +-
14
5 files changed, 12 insertions(+), 12 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
uint32_t mvfr1;
22
uint32_t mvfr2;
23
uint32_t id_dfr0;
24
+ uint32_t dbgdidr;
25
uint64_t id_aa64isar0;
26
uint64_t id_aa64isar1;
27
uint64_t id_aa64pfr0;
28
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
29
uint32_t id_mmfr4;
30
uint64_t id_aa64afr0;
31
uint64_t id_aa64afr1;
32
- uint32_t dbgdidr;
33
uint32_t clidr;
34
uint64_t mp_affinity; /* MP ID without feature bits */
35
/* The elements of this array are the CCSIDR values for each cache,
36
diff --git a/target/arm/internals.h b/target/arm/internals.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/internals.h
39
+++ b/target/arm/internals.h
40
@@ -XXX,XX +XXX,XX @@ static inline int arm_num_brps(ARMCPU *cpu)
41
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
42
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1;
43
} else {
44
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, BRPS) + 1;
45
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, BRPS) + 1;
46
}
47
}
48
49
@@ -XXX,XX +XXX,XX @@ static inline int arm_num_wrps(ARMCPU *cpu)
50
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
51
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1;
52
} else {
53
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, WRPS) + 1;
54
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, WRPS) + 1;
55
}
56
}
57
58
@@ -XXX,XX +XXX,XX @@ static inline int arm_num_ctx_cmps(ARMCPU *cpu)
59
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
60
return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1;
61
} else {
62
- return FIELD_EX32(cpu->dbgdidr, DBGDIDR, CTX_CMPS) + 1;
63
+ return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, CTX_CMPS) + 1;
64
}
65
}
66
67
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/cpu.c
70
+++ b/target/arm/cpu.c
71
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
72
cpu->isar.id_isar2 = 0x21232031;
73
cpu->isar.id_isar3 = 0x11112131;
74
cpu->isar.id_isar4 = 0x00111142;
75
- cpu->dbgdidr = 0x15141000;
76
+ cpu->isar.dbgdidr = 0x15141000;
77
cpu->clidr = (1 << 27) | (2 << 24) | 3;
78
cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
79
cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
80
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
81
cpu->isar.id_isar2 = 0x21232041;
82
cpu->isar.id_isar3 = 0x11112131;
83
cpu->isar.id_isar4 = 0x00111142;
84
- cpu->dbgdidr = 0x35141000;
85
+ cpu->isar.dbgdidr = 0x35141000;
86
cpu->clidr = (1 << 27) | (1 << 24) | 3;
87
cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
88
cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */
89
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
90
cpu->isar.id_isar2 = 0x21232041;
91
cpu->isar.id_isar3 = 0x11112131;
92
cpu->isar.id_isar4 = 0x10011142;
93
- cpu->dbgdidr = 0x3515f005;
94
+ cpu->isar.dbgdidr = 0x3515f005;
95
cpu->clidr = 0x0a200023;
96
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
97
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
98
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
99
cpu->isar.id_isar2 = 0x21232041;
100
cpu->isar.id_isar3 = 0x11112131;
101
cpu->isar.id_isar4 = 0x10011142;
102
- cpu->dbgdidr = 0x3515f021;
103
+ cpu->isar.dbgdidr = 0x3515f021;
104
cpu->clidr = 0x0a200023;
105
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
106
cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
107
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/cpu64.c
110
+++ b/target/arm/cpu64.c
111
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
112
cpu->isar.id_aa64dfr0 = 0x10305106;
113
cpu->isar.id_aa64isar0 = 0x00011120;
114
cpu->isar.id_aa64mmfr0 = 0x00001124;
115
- cpu->dbgdidr = 0x3516d000;
116
+ cpu->isar.dbgdidr = 0x3516d000;
117
cpu->clidr = 0x0a200023;
118
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
119
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
120
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
121
cpu->isar.id_aa64dfr0 = 0x10305106;
122
cpu->isar.id_aa64isar0 = 0x00011120;
123
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
124
- cpu->dbgdidr = 0x3516d000;
125
+ cpu->isar.dbgdidr = 0x3516d000;
126
cpu->clidr = 0x0a200023;
127
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
128
cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
129
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
130
cpu->isar.id_aa64dfr0 = 0x10305106;
131
cpu->isar.id_aa64isar0 = 0x00011120;
132
cpu->isar.id_aa64mmfr0 = 0x00001124;
133
- cpu->dbgdidr = 0x3516d000;
134
+ cpu->isar.dbgdidr = 0x3516d000;
135
cpu->clidr = 0x0a200023;
136
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
137
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
138
diff --git a/target/arm/helper.c b/target/arm/helper.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/target/arm/helper.c
141
+++ b/target/arm/helper.c
142
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
143
ARMCPRegInfo dbgdidr = {
144
.name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
145
.access = PL0_R, .accessfn = access_tda,
146
- .type = ARM_CP_CONST, .resetvalue = cpu->dbgdidr,
147
+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
148
};
149
150
/* Note that all these register fields hold "number of Xs minus 1". */
151
--
152
2.20.1
153
154
diff view generated by jsdifflib
New patch
1
Now we have isar_feature test functions that look at fields in the
2
ID_AA64DFR0_EL1 and ID_DFR0 ID registers, add the code that reads
3
these register values from KVM so that the checks behave correctly
4
when we're using KVM.
1
5
6
No isar_feature function tests ID_AA64DFR1_EL1 or DBGDIDR yet, but we
7
add it to maintain the invariant that every field in the
8
ARMISARegisters struct is populated for a KVM CPU and can be relied
9
on. This requirement isn't actually written down yet, so add a note
10
to the relevant comment.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200214175116.9164-13-peter.maydell@linaro.org
15
---
16
target/arm/cpu.h | 5 +++++
17
target/arm/kvm32.c | 8 ++++++++
18
target/arm/kvm64.c | 36 ++++++++++++++++++++++++++++++++++++
19
3 files changed, 49 insertions(+)
20
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
26
* prefix means a constant register.
27
* Some of these registers are split out into a substructure that
28
* is shared with the translators to control the ISA.
29
+ *
30
+ * Note that if you add an ID register to the ARMISARegisters struct
31
+ * you need to also update the 32-bit and 64-bit versions of the
32
+ * kvm_arm_get_host_cpu_features() function to correctly populate the
33
+ * field by reading the value from the KVM vCPU.
34
*/
35
struct ARMISARegisters {
36
uint32_t id_isar0;
37
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/kvm32.c
40
+++ b/target/arm/kvm32.c
41
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
42
ahcf->isar.id_isar6 = 0;
43
}
44
45
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
46
+ ARM_CP15_REG32(0, 0, 1, 2));
47
+
48
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0,
49
KVM_REG_ARM | KVM_REG_SIZE_U32 |
50
KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR0);
51
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
52
* Fortunately there is not yet anything in there that affects migration.
53
*/
54
55
+ /*
56
+ * There is no way to read DBGDIDR, because currently 32-bit KVM
57
+ * doesn't implement debug at all. Leave it at zero.
58
+ */
59
+
60
kvm_arm_destroy_scratch_host_vcpu(fdarray);
61
62
if (err < 0) {
63
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/kvm64.c
66
+++ b/target/arm/kvm64.c
67
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
68
} else {
69
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr1,
70
ARM64_SYS_REG(3, 0, 0, 4, 1));
71
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0,
72
+ ARM64_SYS_REG(3, 0, 0, 5, 0));
73
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1,
74
+ ARM64_SYS_REG(3, 0, 0, 5, 1));
75
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar0,
76
ARM64_SYS_REG(3, 0, 0, 6, 0));
77
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
78
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
79
* than skipping the reads and leaving 0, as we must avoid
80
* considering the values in every case.
81
*/
82
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
83
+ ARM64_SYS_REG(3, 0, 0, 1, 2));
84
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0,
85
ARM64_SYS_REG(3, 0, 0, 2, 0));
86
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1,
87
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
88
ARM64_SYS_REG(3, 0, 0, 3, 1));
89
err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2,
90
ARM64_SYS_REG(3, 0, 0, 3, 2));
91
+
92
+ /*
93
+ * DBGDIDR is a bit complicated because the kernel doesn't
94
+ * provide an accessor for it in 64-bit mode, which is what this
95
+ * scratch VM is in, and there's no architected "64-bit sysreg
96
+ * which reads the same as the 32-bit register" the way there is
97
+ * for other ID registers. Instead we synthesize a value from the
98
+ * AArch64 ID_AA64DFR0, the same way the kernel code in
99
+ * arch/arm64/kvm/sys_regs.c:trap_dbgidr() does.
100
+ * We only do this if the CPU supports AArch32 at EL1.
101
+ */
102
+ if (FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL1) >= 2) {
103
+ int wrps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, WRPS);
104
+ int brps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, BRPS);
105
+ int ctx_cmps =
106
+ FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS);
107
+ int version = 6; /* ARMv8 debug architecture */
108
+ bool has_el3 =
109
+ !!FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL3);
110
+ uint32_t dbgdidr = 0;
111
+
112
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, WRPS, wrps);
113
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, BRPS, brps);
114
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, CTX_CMPS, ctx_cmps);
115
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, VERSION, version);
116
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, NSUHD_IMP, has_el3);
117
+ dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, SE_IMP, has_el3);
118
+ dbgdidr |= (1 << 15); /* RES1 bit */
119
+ ahcf->isar.dbgdidr = dbgdidr;
120
+ }
121
}
122
123
sve_supported = ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_SVE) > 0;
124
--
125
2.20.1
126
127
diff view generated by jsdifflib
New patch
1
The ARMv8.1-PMU extension requires:
2
* the evtCount field in PMETYPER<n>_EL0 is 16 bits, not 10
3
* MDCR_EL2.HPMD allows event counting to be disabled at EL2
4
* two new required events, STALL_FRONTEND and STALL_BACKEND
5
* ID register bits in ID_AA64DFR0_EL1 and ID_DFR0
1
6
7
We already implement the 16-bit evtCount field and the
8
HPMD bit, so all that is missing is the two new events:
9
STALL_FRONTEND
10
"counts every cycle counted by the CPU_CYCLES event on which no
11
operation was issued because there are no operations available
12
to issue to this PE from the frontend"
13
STALL_BACKEND
14
"counts every cycle counted by the CPU_CYCLES event on which no
15
operation was issued because the backend is unable to accept
16
any available operations from the frontend"
17
18
QEMU never stalls in this sense, so our implementation is trivial:
19
always return a zero count.
20
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Message-id: 20200214175116.9164-14-peter.maydell@linaro.org
24
---
25
target/arm/helper.c | 32 ++++++++++++++++++++++++++++++--
26
1 file changed, 30 insertions(+), 2 deletions(-)
27
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/helper.c
31
+++ b/target/arm/helper.c
32
@@ -XXX,XX +XXX,XX @@ static int64_t instructions_ns_per(uint64_t icount)
33
}
34
#endif
35
36
+static bool pmu_8_1_events_supported(CPUARMState *env)
37
+{
38
+ /* For events which are supported in any v8.1 PMU */
39
+ return cpu_isar_feature(any_pmu_8_1, env_archcpu(env));
40
+}
41
+
42
+static uint64_t zero_event_get_count(CPUARMState *env)
43
+{
44
+ /* For events which on QEMU never fire, so their count is always zero */
45
+ return 0;
46
+}
47
+
48
+static int64_t zero_event_ns_per(uint64_t cycles)
49
+{
50
+ /* An event which never fires can never overflow */
51
+ return -1;
52
+}
53
+
54
static const pm_event pm_events[] = {
55
{ .number = 0x000, /* SW_INCR */
56
.supported = event_always_supported,
57
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
58
.supported = event_always_supported,
59
.get_count = cycles_get_count,
60
.ns_per_count = cycles_ns_per,
61
- }
62
+ },
63
#endif
64
+ { .number = 0x023, /* STALL_FRONTEND */
65
+ .supported = pmu_8_1_events_supported,
66
+ .get_count = zero_event_get_count,
67
+ .ns_per_count = zero_event_ns_per,
68
+ },
69
+ { .number = 0x024, /* STALL_BACKEND */
70
+ .supported = pmu_8_1_events_supported,
71
+ .get_count = zero_event_get_count,
72
+ .ns_per_count = zero_event_ns_per,
73
+ },
74
};
75
76
/*
77
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
78
* should first be updated to something sparse instead of the current
79
* supported_event_map[] array.
80
*/
81
-#define MAX_EVENT_ID 0x11
82
+#define MAX_EVENT_ID 0x24
83
#define UNSUPPORTED_EVENT UINT16_MAX
84
static uint16_t supported_event_map[MAX_EVENT_ID + 1];
85
86
--
87
2.20.1
88
89
diff view generated by jsdifflib
New patch
1
The ARMv8.4-PMU extension adds:
2
* one new required event, STALL
3
* one new system register PMMIR_EL1
1
4
5
(There are also some more L1-cache related events, but since
6
we don't implement any cache we don't provide these, in the
7
same way we don't provide the base-PMUv3 cache events.)
8
9
The STALL event "counts every attributable cycle on which no
10
attributable instruction or operation was sent for execution on this
11
PE". QEMU doesn't stall in this sense, so this is another
12
always-reads-zero event.
13
14
The PMMIR_EL1 register is a read-only register providing
15
implementation-specific information about the PMU; currently it has
16
only one field, SLOTS, which defines behaviour of the STALL_SLOT PMU
17
event. Since QEMU doesn't implement the STALL_SLOT event, we can
18
validly make the register read zero.
19
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20200214175116.9164-15-peter.maydell@linaro.org
23
---
24
target/arm/cpu.h | 18 ++++++++++++++++++
25
target/arm/helper.c | 22 +++++++++++++++++++++-
26
2 files changed, 39 insertions(+), 1 deletion(-)
27
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
33
FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
34
}
35
36
+static inline bool isar_feature_aa32_pmu_8_4(const ARMISARegisters *id)
37
+{
38
+ /* 0xf means "non-standard IMPDEF PMU" */
39
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 &&
40
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
41
+}
42
+
43
/*
44
* 64-bit feature tests via id registers.
45
*/
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
47
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
48
}
49
50
+static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id)
51
+{
52
+ return FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
53
+ FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
54
+}
55
+
56
/*
57
* Feature tests for "does this exist in either 32-bit or 64-bit?"
58
*/
59
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
60
return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
61
}
62
63
+static inline bool isar_feature_any_pmu_8_4(const ARMISARegisters *id)
64
+{
65
+ return isar_feature_aa64_pmu_8_4(id) || isar_feature_aa32_pmu_8_4(id);
66
+}
67
+
68
/*
69
* Forward to the above feature tests given an ARMCPU pointer.
70
*/
71
diff --git a/target/arm/helper.c b/target/arm/helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/helper.c
74
+++ b/target/arm/helper.c
75
@@ -XXX,XX +XXX,XX @@ static bool pmu_8_1_events_supported(CPUARMState *env)
76
return cpu_isar_feature(any_pmu_8_1, env_archcpu(env));
77
}
78
79
+static bool pmu_8_4_events_supported(CPUARMState *env)
80
+{
81
+ /* For events which are supported in any v8.1 PMU */
82
+ return cpu_isar_feature(any_pmu_8_4, env_archcpu(env));
83
+}
84
+
85
static uint64_t zero_event_get_count(CPUARMState *env)
86
{
87
/* For events which on QEMU never fire, so their count is always zero */
88
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
89
.get_count = zero_event_get_count,
90
.ns_per_count = zero_event_ns_per,
91
},
92
+ { .number = 0x03c, /* STALL */
93
+ .supported = pmu_8_4_events_supported,
94
+ .get_count = zero_event_get_count,
95
+ .ns_per_count = zero_event_ns_per,
96
+ },
97
};
98
99
/*
100
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
101
* should first be updated to something sparse instead of the current
102
* supported_event_map[] array.
103
*/
104
-#define MAX_EVENT_ID 0x24
105
+#define MAX_EVENT_ID 0x3c
106
#define UNSUPPORTED_EVENT UINT16_MAX
107
static uint16_t supported_event_map[MAX_EVENT_ID + 1];
108
109
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
110
};
111
define_arm_cp_regs(cpu, v81_pmu_regs);
112
}
113
+ if (cpu_isar_feature(any_pmu_8_4, cpu)) {
114
+ static const ARMCPRegInfo v84_pmmir = {
115
+ .name = "PMMIR_EL1", .state = ARM_CP_STATE_BOTH,
116
+ .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 6,
117
+ .access = PL1_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
118
+ .resetvalue = 0
119
+ };
120
+ define_one_arm_cp_reg(cpu, &v84_pmmir);
121
+ }
122
}
123
124
/* We don't know until after realize whether there's a GICv3
125
--
126
2.20.1
127
128
diff view generated by jsdifflib
New patch
1
Set the ID register bits to provide ARMv8.4-PMU (and implicitly
2
also ARMv8.1-PMU) in the 'max' CPU.
1
3
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20200214175116.9164-16-peter.maydell@linaro.org
7
---
8
target/arm/cpu64.c | 8 ++++++++
9
1 file changed, 8 insertions(+)
10
11
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu64.c
14
+++ b/target/arm/cpu64.c
15
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
16
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
17
cpu->id_mmfr3 = u;
18
19
+ u = cpu->isar.id_aa64dfr0;
20
+ u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
21
+ cpu->isar.id_aa64dfr0 = u;
22
+
23
+ u = cpu->isar.id_dfr0;
24
+ u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
25
+ cpu->isar.id_dfr0 = u;
26
+
27
/*
28
* FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
29
* so do not set MVFR1.FPHP. Strictly speaking this is not legal,
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
New patch
1
The PMCR_EL0.DP bit is bit 5, which is 0x20, not 0x10. 0x10 is 'X'.
2
Correct our #define of PMCRDP and add the missing PMCRX.
1
3
4
We do have the correct behaviour for handling the DP bit being
5
set, so this fixes a guest-visible bug.
6
7
Fixes: 033614c47de
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20200214175116.9164-17-peter.maydell@linaro.org
12
---
13
target/arm/helper.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
21
#define PMCRN_MASK 0xf800
22
#define PMCRN_SHIFT 11
23
#define PMCRLC 0x40
24
-#define PMCRDP 0x10
25
+#define PMCRDP 0x20
26
+#define PMCRX 0x10
27
#define PMCRD 0x8
28
#define PMCRC 0x4
29
#define PMCRP 0x2
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
New patch
1
The LC bit in the PMCR_EL0 register is supposed to be:
2
* read/write
3
* RES1 on an AArch64-only implementation
4
* an architecturally UNKNOWN value on reset
5
(and use of LC==0 by software is deprecated).
1
6
7
We were implementing it incorrectly as read-only always zero,
8
though we do have all the code needed to test it and behave
9
accordingly.
10
11
Instead make it a read-write bit which resets to 1 always, which
12
satisfies all the architectural requirements above.
13
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20200214175116.9164-18-peter.maydell@linaro.org
18
---
19
target/arm/helper.c | 13 +++++++++----
20
1 file changed, 9 insertions(+), 4 deletions(-)
21
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.c
25
+++ b/target/arm/helper.c
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
27
#define PMCRC 0x4
28
#define PMCRP 0x2
29
#define PMCRE 0x1
30
+/*
31
+ * Mask of PMCR bits writeable by guest (not including WO bits like C, P,
32
+ * which can be written as 1 to trigger behaviour but which stay RAZ).
33
+ */
34
+#define PMCR_WRITEABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
35
36
#define PMXEVTYPER_P 0x80000000
37
#define PMXEVTYPER_U 0x40000000
38
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
39
}
40
}
41
42
- /* only the DP, X, D and E bits are writable */
43
- env->cp15.c9_pmcr &= ~0x39;
44
- env->cp15.c9_pmcr |= (value & 0x39);
45
+ env->cp15.c9_pmcr &= ~PMCR_WRITEABLE_MASK;
46
+ env->cp15.c9_pmcr |= (value & PMCR_WRITEABLE_MASK);
47
48
pmu_op_finish(env);
49
}
50
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
51
.access = PL0_RW, .accessfn = pmreg_access,
52
.type = ARM_CP_IO,
53
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
54
- .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
55
+ .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) |
56
+ PMCRLC,
57
.writefn = pmcr_write, .raw_writefn = raw_write,
58
};
59
define_one_arm_cp_reg(cpu, &pmcr);
60
--
61
2.20.1
62
63
diff view generated by jsdifflib
New patch
1
The isar_feature_aa32_pan and isar_feature_aa32_ats1e1 functions
2
are supposed to be testing fields in ID_MMFR3; but a cut-and-paste
3
error meant we were looking at MVFR0 instead.
1
4
5
Fix the functions to look at the right register; this requires
6
us to move at least id_mmfr3 to the ARMISARegisters struct; we
7
choose to move all the ID_MMFRn registers for consistency.
8
9
Fixes: 3d6ad6bb466f
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200214175116.9164-19-peter.maydell@linaro.org
13
---
14
target/arm/cpu.h | 14 +++---
15
hw/intc/armv7m_nvic.c | 8 ++--
16
target/arm/cpu.c | 104 +++++++++++++++++++++---------------------
17
target/arm/cpu64.c | 28 ++++++------
18
target/arm/helper.c | 12 ++---
19
target/arm/kvm32.c | 17 +++++++
20
target/arm/kvm64.c | 10 ++++
21
7 files changed, 110 insertions(+), 83 deletions(-)
22
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
28
uint32_t id_isar4;
29
uint32_t id_isar5;
30
uint32_t id_isar6;
31
+ uint32_t id_mmfr0;
32
+ uint32_t id_mmfr1;
33
+ uint32_t id_mmfr2;
34
+ uint32_t id_mmfr3;
35
+ uint32_t id_mmfr4;
36
uint32_t mvfr0;
37
uint32_t mvfr1;
38
uint32_t mvfr2;
39
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
40
uint64_t pmceid0;
41
uint64_t pmceid1;
42
uint32_t id_afr0;
43
- uint32_t id_mmfr0;
44
- uint32_t id_mmfr1;
45
- uint32_t id_mmfr2;
46
- uint32_t id_mmfr3;
47
- uint32_t id_mmfr4;
48
uint64_t id_aa64afr0;
49
uint64_t id_aa64afr1;
50
uint32_t clidr;
51
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
52
53
static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
54
{
55
- return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) != 0;
56
+ return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) != 0;
57
}
58
59
static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
60
{
61
- return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2;
62
+ return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) >= 2;
63
}
64
65
static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
66
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/intc/armv7m_nvic.c
69
+++ b/hw/intc/armv7m_nvic.c
70
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
71
case 0xd4c: /* AFR0. */
72
return cpu->id_afr0;
73
case 0xd50: /* MMFR0. */
74
- return cpu->id_mmfr0;
75
+ return cpu->isar.id_mmfr0;
76
case 0xd54: /* MMFR1. */
77
- return cpu->id_mmfr1;
78
+ return cpu->isar.id_mmfr1;
79
case 0xd58: /* MMFR2. */
80
- return cpu->id_mmfr2;
81
+ return cpu->isar.id_mmfr2;
82
case 0xd5c: /* MMFR3. */
83
- return cpu->id_mmfr3;
84
+ return cpu->isar.id_mmfr3;
85
case 0xd60: /* ISAR0. */
86
return cpu->isar.id_isar0;
87
case 0xd64: /* ISAR1. */
88
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/cpu.c
91
+++ b/target/arm/cpu.c
92
@@ -XXX,XX +XXX,XX @@ static void arm1136_r2_initfn(Object *obj)
93
cpu->id_pfr1 = 0x1;
94
cpu->isar.id_dfr0 = 0x2;
95
cpu->id_afr0 = 0x3;
96
- cpu->id_mmfr0 = 0x01130003;
97
- cpu->id_mmfr1 = 0x10030302;
98
- cpu->id_mmfr2 = 0x01222110;
99
+ cpu->isar.id_mmfr0 = 0x01130003;
100
+ cpu->isar.id_mmfr1 = 0x10030302;
101
+ cpu->isar.id_mmfr2 = 0x01222110;
102
cpu->isar.id_isar0 = 0x00140011;
103
cpu->isar.id_isar1 = 0x12002111;
104
cpu->isar.id_isar2 = 0x11231111;
105
@@ -XXX,XX +XXX,XX @@ static void arm1136_initfn(Object *obj)
106
cpu->id_pfr1 = 0x1;
107
cpu->isar.id_dfr0 = 0x2;
108
cpu->id_afr0 = 0x3;
109
- cpu->id_mmfr0 = 0x01130003;
110
- cpu->id_mmfr1 = 0x10030302;
111
- cpu->id_mmfr2 = 0x01222110;
112
+ cpu->isar.id_mmfr0 = 0x01130003;
113
+ cpu->isar.id_mmfr1 = 0x10030302;
114
+ cpu->isar.id_mmfr2 = 0x01222110;
115
cpu->isar.id_isar0 = 0x00140011;
116
cpu->isar.id_isar1 = 0x12002111;
117
cpu->isar.id_isar2 = 0x11231111;
118
@@ -XXX,XX +XXX,XX @@ static void arm1176_initfn(Object *obj)
119
cpu->id_pfr1 = 0x11;
120
cpu->isar.id_dfr0 = 0x33;
121
cpu->id_afr0 = 0;
122
- cpu->id_mmfr0 = 0x01130003;
123
- cpu->id_mmfr1 = 0x10030302;
124
- cpu->id_mmfr2 = 0x01222100;
125
+ cpu->isar.id_mmfr0 = 0x01130003;
126
+ cpu->isar.id_mmfr1 = 0x10030302;
127
+ cpu->isar.id_mmfr2 = 0x01222100;
128
cpu->isar.id_isar0 = 0x0140011;
129
cpu->isar.id_isar1 = 0x12002111;
130
cpu->isar.id_isar2 = 0x11231121;
131
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
132
cpu->id_pfr1 = 0x1;
133
cpu->isar.id_dfr0 = 0;
134
cpu->id_afr0 = 0x2;
135
- cpu->id_mmfr0 = 0x01100103;
136
- cpu->id_mmfr1 = 0x10020302;
137
- cpu->id_mmfr2 = 0x01222000;
138
+ cpu->isar.id_mmfr0 = 0x01100103;
139
+ cpu->isar.id_mmfr1 = 0x10020302;
140
+ cpu->isar.id_mmfr2 = 0x01222000;
141
cpu->isar.id_isar0 = 0x00100011;
142
cpu->isar.id_isar1 = 0x12002111;
143
cpu->isar.id_isar2 = 0x11221011;
144
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
145
cpu->id_pfr1 = 0x00000200;
146
cpu->isar.id_dfr0 = 0x00100000;
147
cpu->id_afr0 = 0x00000000;
148
- cpu->id_mmfr0 = 0x00000030;
149
- cpu->id_mmfr1 = 0x00000000;
150
- cpu->id_mmfr2 = 0x00000000;
151
- cpu->id_mmfr3 = 0x00000000;
152
+ cpu->isar.id_mmfr0 = 0x00000030;
153
+ cpu->isar.id_mmfr1 = 0x00000000;
154
+ cpu->isar.id_mmfr2 = 0x00000000;
155
+ cpu->isar.id_mmfr3 = 0x00000000;
156
cpu->isar.id_isar0 = 0x01141110;
157
cpu->isar.id_isar1 = 0x02111000;
158
cpu->isar.id_isar2 = 0x21112231;
159
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
160
cpu->id_pfr1 = 0x00000200;
161
cpu->isar.id_dfr0 = 0x00100000;
162
cpu->id_afr0 = 0x00000000;
163
- cpu->id_mmfr0 = 0x00000030;
164
- cpu->id_mmfr1 = 0x00000000;
165
- cpu->id_mmfr2 = 0x00000000;
166
- cpu->id_mmfr3 = 0x00000000;
167
+ cpu->isar.id_mmfr0 = 0x00000030;
168
+ cpu->isar.id_mmfr1 = 0x00000000;
169
+ cpu->isar.id_mmfr2 = 0x00000000;
170
+ cpu->isar.id_mmfr3 = 0x00000000;
171
cpu->isar.id_isar0 = 0x01141110;
172
cpu->isar.id_isar1 = 0x02111000;
173
cpu->isar.id_isar2 = 0x21112231;
174
@@ -XXX,XX +XXX,XX @@ static void cortex_m7_initfn(Object *obj)
175
cpu->id_pfr1 = 0x00000200;
176
cpu->isar.id_dfr0 = 0x00100000;
177
cpu->id_afr0 = 0x00000000;
178
- cpu->id_mmfr0 = 0x00100030;
179
- cpu->id_mmfr1 = 0x00000000;
180
- cpu->id_mmfr2 = 0x01000000;
181
- cpu->id_mmfr3 = 0x00000000;
182
+ cpu->isar.id_mmfr0 = 0x00100030;
183
+ cpu->isar.id_mmfr1 = 0x00000000;
184
+ cpu->isar.id_mmfr2 = 0x01000000;
185
+ cpu->isar.id_mmfr3 = 0x00000000;
186
cpu->isar.id_isar0 = 0x01101110;
187
cpu->isar.id_isar1 = 0x02112000;
188
cpu->isar.id_isar2 = 0x20232231;
189
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
190
cpu->id_pfr1 = 0x00000210;
191
cpu->isar.id_dfr0 = 0x00200000;
192
cpu->id_afr0 = 0x00000000;
193
- cpu->id_mmfr0 = 0x00101F40;
194
- cpu->id_mmfr1 = 0x00000000;
195
- cpu->id_mmfr2 = 0x01000000;
196
- cpu->id_mmfr3 = 0x00000000;
197
+ cpu->isar.id_mmfr0 = 0x00101F40;
198
+ cpu->isar.id_mmfr1 = 0x00000000;
199
+ cpu->isar.id_mmfr2 = 0x01000000;
200
+ cpu->isar.id_mmfr3 = 0x00000000;
201
cpu->isar.id_isar0 = 0x01101110;
202
cpu->isar.id_isar1 = 0x02212000;
203
cpu->isar.id_isar2 = 0x20232232;
204
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
205
cpu->id_pfr1 = 0x001;
206
cpu->isar.id_dfr0 = 0x010400;
207
cpu->id_afr0 = 0x0;
208
- cpu->id_mmfr0 = 0x0210030;
209
- cpu->id_mmfr1 = 0x00000000;
210
- cpu->id_mmfr2 = 0x01200000;
211
- cpu->id_mmfr3 = 0x0211;
212
+ cpu->isar.id_mmfr0 = 0x0210030;
213
+ cpu->isar.id_mmfr1 = 0x00000000;
214
+ cpu->isar.id_mmfr2 = 0x01200000;
215
+ cpu->isar.id_mmfr3 = 0x0211;
216
cpu->isar.id_isar0 = 0x02101111;
217
cpu->isar.id_isar1 = 0x13112111;
218
cpu->isar.id_isar2 = 0x21232141;
219
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
220
cpu->id_pfr1 = 0x11;
221
cpu->isar.id_dfr0 = 0x400;
222
cpu->id_afr0 = 0;
223
- cpu->id_mmfr0 = 0x31100003;
224
- cpu->id_mmfr1 = 0x20000000;
225
- cpu->id_mmfr2 = 0x01202000;
226
- cpu->id_mmfr3 = 0x11;
227
+ cpu->isar.id_mmfr0 = 0x31100003;
228
+ cpu->isar.id_mmfr1 = 0x20000000;
229
+ cpu->isar.id_mmfr2 = 0x01202000;
230
+ cpu->isar.id_mmfr3 = 0x11;
231
cpu->isar.id_isar0 = 0x00101111;
232
cpu->isar.id_isar1 = 0x12112111;
233
cpu->isar.id_isar2 = 0x21232031;
234
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
235
cpu->id_pfr1 = 0x11;
236
cpu->isar.id_dfr0 = 0x000;
237
cpu->id_afr0 = 0;
238
- cpu->id_mmfr0 = 0x00100103;
239
- cpu->id_mmfr1 = 0x20000000;
240
- cpu->id_mmfr2 = 0x01230000;
241
- cpu->id_mmfr3 = 0x00002111;
242
+ cpu->isar.id_mmfr0 = 0x00100103;
243
+ cpu->isar.id_mmfr1 = 0x20000000;
244
+ cpu->isar.id_mmfr2 = 0x01230000;
245
+ cpu->isar.id_mmfr3 = 0x00002111;
246
cpu->isar.id_isar0 = 0x00101111;
247
cpu->isar.id_isar1 = 0x13112111;
248
cpu->isar.id_isar2 = 0x21232041;
249
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
250
cpu->id_pfr1 = 0x00011011;
251
cpu->isar.id_dfr0 = 0x02010555;
252
cpu->id_afr0 = 0x00000000;
253
- cpu->id_mmfr0 = 0x10101105;
254
- cpu->id_mmfr1 = 0x40000000;
255
- cpu->id_mmfr2 = 0x01240000;
256
- cpu->id_mmfr3 = 0x02102211;
257
+ cpu->isar.id_mmfr0 = 0x10101105;
258
+ cpu->isar.id_mmfr1 = 0x40000000;
259
+ cpu->isar.id_mmfr2 = 0x01240000;
260
+ cpu->isar.id_mmfr3 = 0x02102211;
261
/* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
262
* table 4-41 gives 0x02101110, which includes the arm div insns.
263
*/
264
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
265
cpu->id_pfr1 = 0x00011011;
266
cpu->isar.id_dfr0 = 0x02010555;
267
cpu->id_afr0 = 0x00000000;
268
- cpu->id_mmfr0 = 0x10201105;
269
- cpu->id_mmfr1 = 0x20000000;
270
- cpu->id_mmfr2 = 0x01240000;
271
- cpu->id_mmfr3 = 0x02102211;
272
+ cpu->isar.id_mmfr0 = 0x10201105;
273
+ cpu->isar.id_mmfr1 = 0x20000000;
274
+ cpu->isar.id_mmfr2 = 0x01240000;
275
+ cpu->isar.id_mmfr3 = 0x02102211;
276
cpu->isar.id_isar0 = 0x02101110;
277
cpu->isar.id_isar1 = 0x13112111;
278
cpu->isar.id_isar2 = 0x21232041;
279
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
280
t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
281
cpu->isar.mvfr2 = t;
282
283
- t = cpu->id_mmfr3;
284
+ t = cpu->isar.id_mmfr3;
285
t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
286
- cpu->id_mmfr3 = t;
287
+ cpu->isar.id_mmfr3 = t;
288
289
- t = cpu->id_mmfr4;
290
+ t = cpu->isar.id_mmfr4;
291
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
292
- cpu->id_mmfr4 = t;
293
+ cpu->isar.id_mmfr4 = t;
294
}
295
#endif
296
}
297
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
298
index XXXXXXX..XXXXXXX 100644
299
--- a/target/arm/cpu64.c
300
+++ b/target/arm/cpu64.c
301
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
302
cpu->id_pfr1 = 0x00011011;
303
cpu->isar.id_dfr0 = 0x03010066;
304
cpu->id_afr0 = 0x00000000;
305
- cpu->id_mmfr0 = 0x10101105;
306
- cpu->id_mmfr1 = 0x40000000;
307
- cpu->id_mmfr2 = 0x01260000;
308
- cpu->id_mmfr3 = 0x02102211;
309
+ cpu->isar.id_mmfr0 = 0x10101105;
310
+ cpu->isar.id_mmfr1 = 0x40000000;
311
+ cpu->isar.id_mmfr2 = 0x01260000;
312
+ cpu->isar.id_mmfr3 = 0x02102211;
313
cpu->isar.id_isar0 = 0x02101110;
314
cpu->isar.id_isar1 = 0x13112111;
315
cpu->isar.id_isar2 = 0x21232042;
316
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
317
cpu->id_pfr1 = 0x00011011;
318
cpu->isar.id_dfr0 = 0x03010066;
319
cpu->id_afr0 = 0x00000000;
320
- cpu->id_mmfr0 = 0x10101105;
321
- cpu->id_mmfr1 = 0x40000000;
322
- cpu->id_mmfr2 = 0x01260000;
323
- cpu->id_mmfr3 = 0x02102211;
324
+ cpu->isar.id_mmfr0 = 0x10101105;
325
+ cpu->isar.id_mmfr1 = 0x40000000;
326
+ cpu->isar.id_mmfr2 = 0x01260000;
327
+ cpu->isar.id_mmfr3 = 0x02102211;
328
cpu->isar.id_isar0 = 0x02101110;
329
cpu->isar.id_isar1 = 0x13112111;
330
cpu->isar.id_isar2 = 0x21232042;
331
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
332
cpu->id_pfr1 = 0x00011011;
333
cpu->isar.id_dfr0 = 0x03010066;
334
cpu->id_afr0 = 0x00000000;
335
- cpu->id_mmfr0 = 0x10201105;
336
- cpu->id_mmfr1 = 0x40000000;
337
- cpu->id_mmfr2 = 0x01260000;
338
- cpu->id_mmfr3 = 0x02102211;
339
+ cpu->isar.id_mmfr0 = 0x10201105;
340
+ cpu->isar.id_mmfr1 = 0x40000000;
341
+ cpu->isar.id_mmfr2 = 0x01260000;
342
+ cpu->isar.id_mmfr3 = 0x02102211;
343
cpu->isar.id_isar0 = 0x02101110;
344
cpu->isar.id_isar1 = 0x13112111;
345
cpu->isar.id_isar2 = 0x21232042;
346
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
347
u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
348
cpu->isar.id_isar6 = u;
349
350
- u = cpu->id_mmfr3;
351
+ u = cpu->isar.id_mmfr3;
352
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
353
- cpu->id_mmfr3 = u;
354
+ cpu->isar.id_mmfr3 = u;
355
356
u = cpu->isar.id_aa64dfr0;
357
u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
358
diff --git a/target/arm/helper.c b/target/arm/helper.c
359
index XXXXXXX..XXXXXXX 100644
360
--- a/target/arm/helper.c
361
+++ b/target/arm/helper.c
362
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
363
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4,
364
.access = PL1_R, .type = ARM_CP_CONST,
365
.accessfn = access_aa32_tid3,
366
- .resetvalue = cpu->id_mmfr0 },
367
+ .resetvalue = cpu->isar.id_mmfr0 },
368
{ .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,
369
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,
370
.access = PL1_R, .type = ARM_CP_CONST,
371
.accessfn = access_aa32_tid3,
372
- .resetvalue = cpu->id_mmfr1 },
373
+ .resetvalue = cpu->isar.id_mmfr1 },
374
{ .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,
375
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,
376
.access = PL1_R, .type = ARM_CP_CONST,
377
.accessfn = access_aa32_tid3,
378
- .resetvalue = cpu->id_mmfr2 },
379
+ .resetvalue = cpu->isar.id_mmfr2 },
380
{ .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,
381
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,
382
.access = PL1_R, .type = ARM_CP_CONST,
383
.accessfn = access_aa32_tid3,
384
- .resetvalue = cpu->id_mmfr3 },
385
+ .resetvalue = cpu->isar.id_mmfr3 },
386
{ .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
387
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
388
.access = PL1_R, .type = ARM_CP_CONST,
389
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
390
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
391
.access = PL1_R, .type = ARM_CP_CONST,
392
.accessfn = access_aa32_tid3,
393
- .resetvalue = cpu->id_mmfr4 },
394
+ .resetvalue = cpu->isar.id_mmfr4 },
395
{ .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
396
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
397
.access = PL1_R, .type = ARM_CP_CONST,
398
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
399
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
400
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
401
/* TTCBR2 is introduced with ARMv8.2-A32HPD. */
402
- if (FIELD_EX32(cpu->id_mmfr4, ID_MMFR4, HPDS) != 0) {
403
+ if (FIELD_EX32(cpu->isar.id_mmfr4, ID_MMFR4, HPDS) != 0) {
404
define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
405
}
406
}
407
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
408
index XXXXXXX..XXXXXXX 100644
409
--- a/target/arm/kvm32.c
410
+++ b/target/arm/kvm32.c
411
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
412
* Fortunately there is not yet anything in there that affects migration.
413
*/
414
415
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
416
+ ARM_CP15_REG32(0, 0, 1, 4));
417
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
418
+ ARM_CP15_REG32(0, 0, 1, 5));
419
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2,
420
+ ARM_CP15_REG32(0, 0, 1, 6));
421
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3,
422
+ ARM_CP15_REG32(0, 0, 1, 7));
423
+ if (read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4,
424
+ ARM_CP15_REG32(0, 0, 2, 6))) {
425
+ /*
426
+ * Older kernels don't support reading ID_MMFR4 (a new in v8
427
+ * register); assume it's zero.
428
+ */
429
+ ahcf->isar.id_mmfr4 = 0;
430
+ }
431
+
432
/*
433
* There is no way to read DBGDIDR, because currently 32-bit KVM
434
* doesn't implement debug at all. Leave it at zero.
435
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
436
index XXXXXXX..XXXXXXX 100644
437
--- a/target/arm/kvm64.c
438
+++ b/target/arm/kvm64.c
439
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
440
*/
441
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
442
ARM64_SYS_REG(3, 0, 0, 1, 2));
443
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
444
+ ARM64_SYS_REG(3, 0, 0, 1, 4));
445
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1,
446
+ ARM64_SYS_REG(3, 0, 0, 1, 5));
447
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2,
448
+ ARM64_SYS_REG(3, 0, 0, 1, 6));
449
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3,
450
+ ARM64_SYS_REG(3, 0, 0, 1, 7));
451
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0,
452
ARM64_SYS_REG(3, 0, 0, 2, 0));
453
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1,
454
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
455
ARM64_SYS_REG(3, 0, 0, 2, 4));
456
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5,
457
ARM64_SYS_REG(3, 0, 0, 2, 5));
458
+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4,
459
+ ARM64_SYS_REG(3, 0, 0, 2, 6));
460
err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6,
461
ARM64_SYS_REG(3, 0, 0, 2, 7));
462
463
--
464
2.20.1
465
466
diff view generated by jsdifflib
New patch
1
Now we have moved ID_MMFR4 into the ARMISARegisters struct, we
2
can define and use an isar_feature for the presence of the
3
ARMv8.2-AA32HPD feature, rather than open-coding the test.
1
4
5
While we're here, correct a comment typo which missed an 'A'
6
from the feature name.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200214175116.9164-20-peter.maydell@linaro.org
11
---
12
target/arm/cpu.h | 5 +++++
13
target/arm/helper.c | 4 ++--
14
2 files changed, 7 insertions(+), 2 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_pmu_8_4(const ARMISARegisters *id)
21
FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
22
}
23
24
+static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
25
+{
26
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0;
27
+}
28
+
29
/*
30
* 64-bit feature tests via id registers.
31
*/
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
35
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
37
} else {
38
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
39
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
40
- /* TTCBR2 is introduced with ARMv8.2-A32HPD. */
41
- if (FIELD_EX32(cpu->isar.id_mmfr4, ID_MMFR4, HPDS) != 0) {
42
+ /* TTCBR2 is introduced with ARMv8.2-AA32HPD. */
43
+ if (cpu_isar_feature(aa32_hpd, cpu)) {
44
define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
45
}
46
}
47
--
48
2.20.1
49
50
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
Cut-and-paste errors mean we're using FIELD_EX64() to extract fields from
2
some 32-bit ID register fields. Use FIELD_EX32() instead. (This makes
3
no difference in behaviour, it's just more consistent.)
2
4
3
max_cpus needs to be an upper bound on the number of vCPUs
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
initialized; otherwise TCG region initialization breaks.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214175116.9164-21-peter.maydell@linaro.org
8
---
9
target/arm/cpu.h | 18 +++++++++---------
10
1 file changed, 9 insertions(+), 9 deletions(-)
5
11
6
Some boards initialize a hard-coded number of vCPUs, which is not
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
7
captured by the global max_cpus and therefore breaks TCG initialization.
8
Fix it by adding the .min_cpus field to machine_class.
9
10
This commit also changes some user-facing behaviour: we now die if
11
-smp is below this hard-coded vCPU minimum instead of silently
12
ignoring the passed -smp value (sometimes announcing this by printing
13
a warning). However, the introduction of .default_cpus lessens the
14
likelihood that users will notice this: if -smp isn't set, we now
15
assign the value in .default_cpus to both smp_cpus and max_cpus. IOW,
16
if a user does not set -smp, they always get a correct number of vCPUs.
17
18
This change fixes 3468b59 ("tcg: enable multiple TCG contexts in
19
softmmu", 2017-10-24), which broke TCG initialization for some
20
ARM boards.
21
22
Fixes: 3468b59e18b179bc63c7ce934de912dfa9596122
23
Reported-by: Thomas Huth <thuth@redhat.com>
24
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
25
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
26
Signed-off-by: Emilio G. Cota <cota@braap.org>
27
Message-id: 1510343626-25861-6-git-send-email-cota@braap.org
28
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Emilio G. Cota <cota@braap.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
---
32
include/hw/boards.h | 5 +++++
33
hw/arm/exynos4_boards.c | 12 ++++--------
34
hw/arm/raspi.c | 2 ++
35
hw/arm/xlnx-zcu102.c | 2 ++
36
vl.c | 21 ++++++++++++++++++---
37
5 files changed, 31 insertions(+), 11 deletions(-)
38
39
diff --git a/include/hw/boards.h b/include/hw/boards.h
40
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
41
--- a/include/hw/boards.h
14
--- a/target/arm/cpu.h
42
+++ b/include/hw/boards.h
15
+++ b/target/arm/cpu.h
43
@@ -XXX,XX +XXX,XX @@ typedef struct {
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
44
17
static inline bool isar_feature_aa32_fp_d32(const ARMISARegisters *id)
45
/**
46
* MachineClass:
47
+ * @max_cpus: maximum number of CPUs supported. Default: 1
48
+ * @min_cpus: minimum number of CPUs supported. Default: 1
49
+ * @default_cpus: number of CPUs instantiated if none are specified. Default: 1
50
* @get_hotplug_handler: this function is called during bus-less
51
* device hotplug. If defined it returns pointer to an instance
52
* of HotplugHandler object, which handles hotplug operation
53
@@ -XXX,XX +XXX,XX @@ struct MachineClass {
54
BlockInterfaceType block_default_type;
55
int units_per_default_bus;
56
int max_cpus;
57
+ int min_cpus;
58
+ int default_cpus;
59
unsigned int no_serial:1,
60
no_parallel:1,
61
use_virtcon:1,
62
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/arm/exynos4_boards.c
65
+++ b/hw/arm/exynos4_boards.c
66
@@ -XXX,XX +XXX,XX @@
67
#include "qemu-common.h"
68
#include "cpu.h"
69
#include "sysemu/sysemu.h"
70
-#include "sysemu/qtest.h"
71
#include "hw/sysbus.h"
72
#include "net/net.h"
73
#include "hw/arm/arm.h"
74
@@ -XXX,XX +XXX,XX @@ exynos4_boards_init_common(MachineState *machine,
75
Exynos4BoardType board_type)
76
{
18
{
77
Exynos4BoardState *s = g_new(Exynos4BoardState, 1);
19
/* Return true if D16-D31 are implemented */
78
- MachineClass *mc = MACHINE_GET_CLASS(machine);
20
- return FIELD_EX64(id->mvfr0, MVFR0, SIMDREG) >= 2;
79
-
21
+ return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) >= 2;
80
- if (smp_cpus != EXYNOS4210_NCPUS && !qtest_enabled()) {
81
- error_report("%s board supports only %d CPU cores, ignoring smp_cpus"
82
- " value",
83
- mc->name, EXYNOS4210_NCPUS);
84
- }
85
86
exynos4_board_binfo.ram_size = exynos4_board_ram_size[board_type];
87
exynos4_board_binfo.board_id = exynos4_board_id[board_type];
88
@@ -XXX,XX +XXX,XX @@ static void nuri_class_init(ObjectClass *oc, void *data)
89
mc->desc = "Samsung NURI board (Exynos4210)";
90
mc->init = nuri_init;
91
mc->max_cpus = EXYNOS4210_NCPUS;
92
+ mc->min_cpus = EXYNOS4210_NCPUS;
93
+ mc->default_cpus = EXYNOS4210_NCPUS;
94
mc->ignore_memory_transaction_failures = true;
95
}
22
}
96
23
97
@@ -XXX,XX +XXX,XX @@ static void smdkc210_class_init(ObjectClass *oc, void *data)
24
static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
98
mc->desc = "Samsung SMDKC210 board (Exynos4210)";
25
{
99
mc->init = smdkc210_init;
26
- return FIELD_EX64(id->mvfr0, MVFR0, FPSHVEC) > 0;
100
mc->max_cpus = EXYNOS4210_NCPUS;
27
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
101
+ mc->min_cpus = EXYNOS4210_NCPUS;
102
+ mc->default_cpus = EXYNOS4210_NCPUS;
103
mc->ignore_memory_transaction_failures = true;
104
}
28
}
105
29
106
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
30
static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
107
index XXXXXXX..XXXXXXX 100644
31
{
108
--- a/hw/arm/raspi.c
32
/* Return true if CPU supports double precision floating point */
109
+++ b/hw/arm/raspi.c
33
- return FIELD_EX64(id->mvfr0, MVFR0, FPDP) > 0;
110
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
34
+ return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
111
mc->no_floppy = 1;
112
mc->no_cdrom = 1;
113
mc->max_cpus = BCM2836_NCPUS;
114
+ mc->min_cpus = BCM2836_NCPUS;
115
+ mc->default_cpus = BCM2836_NCPUS;
116
mc->default_ram_size = 1024 * 1024 * 1024;
117
mc->ignore_memory_transaction_failures = true;
118
};
119
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/hw/arm/xlnx-zcu102.c
122
+++ b/hw/arm/xlnx-zcu102.c
123
@@ -XXX,XX +XXX,XX @@ static void xlnx_ep108_machine_class_init(ObjectClass *oc, void *data)
124
mc->units_per_default_bus = 1;
125
mc->ignore_memory_transaction_failures = true;
126
mc->max_cpus = XLNX_ZYNQMP_NUM_APU_CPUS + XLNX_ZYNQMP_NUM_RPU_CPUS;
127
+ mc->default_cpus = XLNX_ZYNQMP_NUM_APU_CPUS;
128
}
35
}
129
36
130
static const TypeInfo xlnx_ep108_machine_init_typeinfo = {
37
/*
131
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
38
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
132
mc->units_per_default_bus = 1;
39
*/
133
mc->ignore_memory_transaction_failures = true;
40
static inline bool isar_feature_aa32_fp16_spconv(const ARMISARegisters *id)
134
mc->max_cpus = XLNX_ZYNQMP_NUM_APU_CPUS + XLNX_ZYNQMP_NUM_RPU_CPUS;
41
{
135
+ mc->default_cpus = XLNX_ZYNQMP_NUM_APU_CPUS;
42
- return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 0;
43
+ return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 0;
136
}
44
}
137
45
138
static const TypeInfo xlnx_zcu102_machine_init_typeinfo = {
46
static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
139
diff --git a/vl.c b/vl.c
47
{
140
index XXXXXXX..XXXXXXX 100644
48
- return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 1;
141
--- a/vl.c
49
+ return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 1;
142
+++ b/vl.c
50
}
143
@@ -XXX,XX +XXX,XX @@ Chardev *virtcon_hds[MAX_VIRTIO_CONSOLES];
51
144
Chardev *sclp_hds[MAX_SCLP_CONSOLES];
52
static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id)
145
int win2k_install_hack = 0;
53
{
146
int singlestep = 0;
54
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 1;
147
-int smp_cpus = 1;
55
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 1;
148
-unsigned int max_cpus = 1;
56
}
149
+int smp_cpus;
57
150
+unsigned int max_cpus;
58
static inline bool isar_feature_aa32_vcvt_dr(const ARMISARegisters *id)
151
int smp_cores = 1;
59
{
152
int smp_threads = 1;
60
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 2;
153
int acpi_enabled = 1;
61
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 2;
154
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
62
}
155
exit(0);
63
156
}
64
static inline bool isar_feature_aa32_vrint(const ARMISARegisters *id)
157
65
{
158
+ /* machine_class: default to UP */
66
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 3;
159
+ machine_class->max_cpus = machine_class->max_cpus ?: 1;
67
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 3;
160
+ machine_class->min_cpus = machine_class->min_cpus ?: 1;
68
}
161
+ machine_class->default_cpus = machine_class->default_cpus ?: 1;
69
162
+
70
static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
163
+ /* default to machine_class->default_cpus */
71
{
164
+ smp_cpus = machine_class->default_cpus;
72
- return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 4;
165
+ max_cpus = machine_class->default_cpus;
73
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 4;
166
+
74
}
167
smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
75
168
76
static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
169
- machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
170
+ /* sanity-check smp_cpus and max_cpus against machine_class */
171
+ if (smp_cpus < machine_class->min_cpus) {
172
+ error_report("Invalid SMP CPUs %d. The min CPUs "
173
+ "supported by machine '%s' is %d", smp_cpus,
174
+ machine_class->name, machine_class->min_cpus);
175
+ exit(1);
176
+ }
177
if (max_cpus > machine_class->max_cpus) {
178
error_report("Invalid SMP CPUs %d. The max CPUs "
179
"supported by machine '%s' is %d", max_cpus,
180
--
77
--
181
2.7.4
78
2.20.1
182
79
183
80
diff view generated by jsdifflib
New patch
1
The ACTLR2 and HACTLR2 AArch32 system registers didn't exist in ARMv7
2
or the original ARMv8. They were later added as optional registers,
3
whose presence is signaled by the ID_MMFR4.AC2 field. From ARMv8.2
4
they are mandatory (ie ID_MMFR4.AC2 must be non-zero).
1
5
6
We implemented HACTLR2 in commit 0e0456ab8895a5e85, but we
7
incorrectly made it exist for all v8 CPUs, and we didn't implement
8
ACTLR2 at all.
9
10
Sort this out by implementing both registers only when they are
11
supposed to exist, and setting the ID_MMFR4 bit for -cpu max.
12
13
Note that this removes HACTLR2 from our Cortex-A53, -A47 and -A72
14
CPU models; this is correct, because those CPUs do not implement
15
this register.
16
17
Fixes: 0e0456ab8895a5e85
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20200214175116.9164-22-peter.maydell@linaro.org
21
---
22
target/arm/cpu.h | 5 +++++
23
target/arm/cpu.c | 1 +
24
target/arm/cpu64.c | 4 ++++
25
target/arm/helper.c | 32 +++++++++++++++++++++++---------
26
4 files changed, 33 insertions(+), 9 deletions(-)
27
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
33
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0;
34
}
35
36
+static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id)
37
+{
38
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0;
39
+}
40
+
41
/*
42
* 64-bit feature tests via id registers.
43
*/
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 void arm_max_initfn(Object *obj)
49
50
t = cpu->isar.id_mmfr4;
51
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
52
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
53
cpu->isar.id_mmfr4 = t;
54
}
55
#endif
56
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/cpu64.c
59
+++ b/target/arm/cpu64.c
60
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
61
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
62
cpu->isar.id_mmfr3 = u;
63
64
+ u = cpu->isar.id_mmfr4;
65
+ u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
66
+ cpu->isar.id_mmfr4 = u;
67
+
68
u = cpu->isar.id_aa64dfr0;
69
u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
70
cpu->isar.id_aa64dfr0 = u;
71
diff --git a/target/arm/helper.c b/target/arm/helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/helper.c
74
+++ b/target/arm/helper.c
75
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1cp_reginfo[] = {
76
};
77
#endif
78
79
+/*
80
+ * ACTLR2 and HACTLR2 map to ACTLR_EL1[63:32] and
81
+ * ACTLR_EL2[63:32]. They exist only if the ID_MMFR4.AC2 field
82
+ * is non-zero, which is never for ARMv7, optionally in ARMv8
83
+ * and mandatorily for ARMv8.2 and up.
84
+ * ACTLR2 is banked for S and NS if EL3 is AArch32. Since QEMU's
85
+ * implementation is RAZ/WI we can ignore this detail, as we
86
+ * do for ACTLR.
87
+ */
88
+static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
89
+ { .name = "ACTLR2", .state = ARM_CP_STATE_AA32,
90
+ .cp = 15, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 3,
91
+ .access = PL1_RW, .type = ARM_CP_CONST,
92
+ .resetvalue = 0 },
93
+ { .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
94
+ .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
95
+ .access = PL2_RW, .type = ARM_CP_CONST,
96
+ .resetvalue = 0 },
97
+ REGINFO_SENTINEL
98
+};
99
+
100
void register_cp_regs_for_features(ARMCPU *cpu)
101
{
102
/* Register all the coprocessor registers based on feature bits */
103
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
104
REGINFO_SENTINEL
105
};
106
define_arm_cp_regs(cpu, auxcr_reginfo);
107
- if (arm_feature(env, ARM_FEATURE_V8)) {
108
- /* HACTLR2 maps to ACTLR_EL2[63:32] and is not in ARMv7 */
109
- ARMCPRegInfo hactlr2_reginfo = {
110
- .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
111
- .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
112
- .access = PL2_RW, .type = ARM_CP_CONST,
113
- .resetvalue = 0
114
- };
115
- define_one_arm_cp_reg(cpu, &hactlr2_reginfo);
116
+ if (cpu_isar_feature(aa32_ac2, cpu)) {
117
+ define_arm_cp_regs(cpu, actlr2_hactlr2_reginfo);
118
}
119
}
120
121
--
122
2.20.1
123
124
diff view generated by jsdifflib
New patch
1
From: Guenter Roeck <linux@roeck-us.net>
1
2
3
We need to be able to use OHCISysBusState outside hcd-ohci.c, so move it
4
to its include file.
5
6
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
8
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Message-id: 20200217204812.9857-2-linux@roeck-us.net
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/usb/hcd-ohci.h | 16 ++++++++++++++++
13
hw/usb/hcd-ohci.c | 15 ---------------
14
2 files changed, 16 insertions(+), 15 deletions(-)
15
16
diff --git a/hw/usb/hcd-ohci.h b/hw/usb/hcd-ohci.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/usb/hcd-ohci.h
19
+++ b/hw/usb/hcd-ohci.h
20
@@ -XXX,XX +XXX,XX @@
21
#define HCD_OHCI_H
22
23
#include "sysemu/dma.h"
24
+#include "hw/usb.h"
25
26
/* Number of Downstream Ports on the root hub: */
27
#define OHCI_MAX_PORTS 15
28
@@ -XXX,XX +XXX,XX @@ typedef struct OHCIState {
29
void (*ohci_die)(struct OHCIState *ohci);
30
} OHCIState;
31
32
+#define TYPE_SYSBUS_OHCI "sysbus-ohci"
33
+#define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
34
+
35
+typedef struct {
36
+ /*< private >*/
37
+ SysBusDevice parent_obj;
38
+ /*< public >*/
39
+
40
+ OHCIState ohci;
41
+ char *masterbus;
42
+ uint32_t num_ports;
43
+ uint32_t firstport;
44
+ dma_addr_t dma_offset;
45
+} OHCISysBusState;
46
+
47
extern const VMStateDescription vmstate_ohci_state;
48
49
void usb_ohci_init(OHCIState *ohci, DeviceState *dev, uint32_t num_ports,
50
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/usb/hcd-ohci.c
53
+++ b/hw/usb/hcd-ohci.c
54
@@ -XXX,XX +XXX,XX @@ void ohci_sysbus_die(struct OHCIState *ohci)
55
ohci_bus_stop(ohci);
56
}
57
58
-#define TYPE_SYSBUS_OHCI "sysbus-ohci"
59
-#define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
60
-
61
-typedef struct {
62
- /*< private >*/
63
- SysBusDevice parent_obj;
64
- /*< public >*/
65
-
66
- OHCIState ohci;
67
- char *masterbus;
68
- uint32_t num_ports;
69
- uint32_t firstport;
70
- dma_addr_t dma_offset;
71
-} OHCISysBusState;
72
-
73
static void ohci_realize_pxa(DeviceState *dev, Error **errp)
74
{
75
OHCISysBusState *s = SYSBUS_OHCI(dev);
76
--
77
2.20.1
78
79
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
55c3cee ("qom: Introduce CPUClass.tcg_initialize", 2017-10-24)
3
We'll use this property in a follow-up patch to insantiate an EHCI
4
introduces a per-CPUClass bool that we check so that the target CPU
4
bus with companion support.
5
is initialized for TCG only once. This works well except when
6
we end up creating more than one CPUClass, in which case we end
7
up incorrectly initializing TCG more than once, i.e. once for
8
each CPUClass.
9
5
10
This can be replicated with:
6
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
11
$ aarch64-softmmu/qemu-system-aarch64 -machine xlnx-zcu102 -smp 6 \
7
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
12
-global driver=xlnx,,zynqmp,property=has_rpu,value=on
8
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
13
In this case the class name of the "RPUs" is prefixed by "cortex-r5-",
9
Message-id: 20200217204812.9857-3-linux@roeck-us.net
14
whereas the "regular" CPUs are prefixed by "cortex-a53-". This
15
results in two CPUClass instances being created.
16
17
Fix it by introducing a static variable, so that only the first
18
target CPU being initialized will initialize the target-dependent
19
part of TCG, regardless of CPUClass instances.
20
21
Fixes: 55c3ceef61fcf06fc98ddc752b7cce788ce7680b
22
Signed-off-by: Emilio G. Cota <cota@braap.org>
23
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
24
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Tested-by: Alistair Francis <alistair.francis@xilinx.com>
27
Message-id: 1510343626-25861-2-git-send-email-cota@braap.org
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
11
---
30
include/qom/cpu.h | 1 -
12
hw/usb/hcd-ehci-sysbus.c | 2 ++
31
exec.c | 5 +++--
13
1 file changed, 2 insertions(+)
32
2 files changed, 3 insertions(+), 3 deletions(-)
33
14
34
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
15
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
35
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
36
--- a/include/qom/cpu.h
17
--- a/hw/usb/hcd-ehci-sysbus.c
37
+++ b/include/qom/cpu.h
18
+++ b/hw/usb/hcd-ehci-sysbus.c
38
@@ -XXX,XX +XXX,XX @@ typedef struct CPUClass {
19
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_ehci_sysbus = {
39
/* Keep non-pointer data at the end to minimize holes. */
20
40
int gdb_num_core_regs;
21
static Property ehci_sysbus_properties[] = {
41
bool gdb_stop_before_watchpoint;
22
DEFINE_PROP_UINT32("maxframes", EHCISysBusState, ehci.maxframes, 128),
42
- bool tcg_initialized;
23
+ DEFINE_PROP_BOOL("companion-enable", EHCISysBusState, ehci.companion_enable,
43
} CPUClass;
24
+ false),
44
25
DEFINE_PROP_END_OF_LIST(),
45
#ifdef HOST_WORDS_BIGENDIAN
26
};
46
diff --git a/exec.c b/exec.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/exec.c
49
+++ b/exec.c
50
@@ -XXX,XX +XXX,XX @@ void cpu_exec_initfn(CPUState *cpu)
51
void cpu_exec_realizefn(CPUState *cpu, Error **errp)
52
{
53
CPUClass *cc = CPU_GET_CLASS(cpu);
54
+ static bool tcg_target_initialized;
55
56
cpu_list_add(cpu);
57
58
- if (tcg_enabled() && !cc->tcg_initialized) {
59
- cc->tcg_initialized = true;
60
+ if (tcg_enabled() && !tcg_target_initialized) {
61
+ tcg_target_initialized = true;
62
cc->tcg_initialize();
63
}
64
27
65
--
28
--
66
2.7.4
29
2.20.1
67
30
68
31
diff view generated by jsdifflib
New patch
1
From: Guenter Roeck <linux@roeck-us.net>
1
2
3
Instantiate EHCI and OHCI controllers on Allwinner A10. OHCI ports are
4
modeled as companions of the respective EHCI ports.
5
6
With this patch applied, USB controllers are discovered and instantiated
7
when booting the cubieboard machine with a recent Linux kernel.
8
9
ehci-platform 1c14000.usb: EHCI Host Controller
10
ehci-platform 1c14000.usb: new USB bus registered, assigned bus number 1
11
ehci-platform 1c14000.usb: irq 26, io mem 0x01c14000
12
ehci-platform 1c14000.usb: USB 2.0 started, EHCI 1.00
13
ehci-platform 1c1c000.usb: EHCI Host Controller
14
ehci-platform 1c1c000.usb: new USB bus registered, assigned bus number 2
15
ehci-platform 1c1c000.usb: irq 31, io mem 0x01c1c000
16
ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00
17
ohci-platform 1c14400.usb: Generic Platform OHCI controller
18
ohci-platform 1c14400.usb: new USB bus registered, assigned bus number 3
19
ohci-platform 1c14400.usb: irq 27, io mem 0x01c14400
20
ohci-platform 1c1c400.usb: Generic Platform OHCI controller
21
ohci-platform 1c1c400.usb: new USB bus registered, assigned bus number 4
22
ohci-platform 1c1c400.usb: irq 32, io mem 0x01c1c400
23
usb 2-1: new high-speed USB device number 2 using ehci-platform
24
usb-storage 2-1:1.0: USB Mass Storage device detected
25
scsi host1: usb-storage 2-1:1.0
26
usb 3-1: new full-speed USB device number 2 using ohci-platform
27
input: QEMU QEMU USB Mouse as /devices/platform/soc/1c14400.usb/usb3/3-1/3-1:1.0/0003:0627:0001.0001/input/input0
28
29
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
30
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
31
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
32
Message-id: 20200217204812.9857-4-linux@roeck-us.net
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
---
35
include/hw/arm/allwinner-a10.h | 6 +++++
36
hw/arm/allwinner-a10.c | 43 ++++++++++++++++++++++++++++++++++
37
2 files changed, 49 insertions(+)
38
39
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/include/hw/arm/allwinner-a10.h
42
+++ b/include/hw/arm/allwinner-a10.h
43
@@ -XXX,XX +XXX,XX @@
44
#include "hw/intc/allwinner-a10-pic.h"
45
#include "hw/net/allwinner_emac.h"
46
#include "hw/ide/ahci.h"
47
+#include "hw/usb/hcd-ohci.h"
48
+#include "hw/usb/hcd-ehci.h"
49
50
#include "target/arm/cpu.h"
51
52
53
#define AW_A10_SDRAM_BASE 0x40000000
54
55
+#define AW_A10_NUM_USB 2
56
+
57
#define TYPE_AW_A10 "allwinner-a10"
58
#define AW_A10(obj) OBJECT_CHECK(AwA10State, (obj), TYPE_AW_A10)
59
60
@@ -XXX,XX +XXX,XX @@ typedef struct AwA10State {
61
AwEmacState emac;
62
AllwinnerAHCIState sata;
63
MemoryRegion sram_a;
64
+ EHCISysBusState ehci[AW_A10_NUM_USB];
65
+ OHCISysBusState ohci[AW_A10_NUM_USB];
66
} AwA10State;
67
68
#endif
69
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/arm/allwinner-a10.c
72
+++ b/hw/arm/allwinner-a10.c
73
@@ -XXX,XX +XXX,XX @@
74
#include "hw/arm/allwinner-a10.h"
75
#include "hw/misc/unimp.h"
76
#include "sysemu/sysemu.h"
77
+#include "hw/boards.h"
78
+#include "hw/usb/hcd-ohci.h"
79
80
#define AW_A10_PIC_REG_BASE 0x01c20400
81
#define AW_A10_PIT_REG_BASE 0x01c20c00
82
#define AW_A10_UART0_REG_BASE 0x01c28000
83
#define AW_A10_EMAC_BASE 0x01c0b000
84
+#define AW_A10_EHCI_BASE 0x01c14000
85
+#define AW_A10_OHCI_BASE 0x01c14400
86
#define AW_A10_SATA_BASE 0x01c18000
87
88
static void aw_a10_init(Object *obj)
89
@@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj)
90
91
sysbus_init_child_obj(obj, "sata", &s->sata, sizeof(s->sata),
92
TYPE_ALLWINNER_AHCI);
93
+
94
+ if (machine_usb(current_machine)) {
95
+ int i;
96
+
97
+ for (i = 0; i < AW_A10_NUM_USB; i++) {
98
+ sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]),
99
+ sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI);
100
+ sysbus_init_child_obj(obj, "ohci[*]", OBJECT(&s->ohci[i]),
101
+ sizeof(s->ohci[i]), TYPE_SYSBUS_OHCI);
102
+ }
103
+ }
104
}
105
106
static void aw_a10_realize(DeviceState *dev, Error **errp)
107
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
108
serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2,
109
qdev_get_gpio_in(dev, 1),
110
115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
111
+
112
+ if (machine_usb(current_machine)) {
113
+ int i;
114
+
115
+ for (i = 0; i < AW_A10_NUM_USB; i++) {
116
+ char bus[16];
117
+
118
+ sprintf(bus, "usb-bus.%d", i);
119
+
120
+ object_property_set_bool(OBJECT(&s->ehci[i]), true,
121
+ "companion-enable", &error_fatal);
122
+ object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized",
123
+ &error_fatal);
124
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0,
125
+ AW_A10_EHCI_BASE + i * 0x8000);
126
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
127
+ qdev_get_gpio_in(dev, 39 + i));
128
+
129
+ object_property_set_str(OBJECT(&s->ohci[i]), bus, "masterbus",
130
+ &error_fatal);
131
+ object_property_set_bool(OBJECT(&s->ohci[i]), true, "realized",
132
+ &error_fatal);
133
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ohci[i]), 0,
134
+ AW_A10_OHCI_BASE + i * 0x8000);
135
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci[i]), 0,
136
+ qdev_get_gpio_in(dev, 64 + i));
137
+ }
138
+ }
139
}
140
141
static void aw_a10_class_init(ObjectClass *oc, void *data)
142
--
143
2.20.1
144
145
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
These instructions shift left or right depending on the sign
4
of the input, and 7 bits are significant to the shift. This
5
requires several masks and selects in addition to the actual
6
shifts to form the complete answer.
7
8
That said, the operation is still a small improvement even for
9
two 64-bit elements -- 13 vector operations instead of 2 * 7
10
integer operations.
11
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200216214232.4230-2-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/helper.h | 11 +-
18
target/arm/translate.h | 6 +
19
target/arm/neon_helper.c | 33 ----
20
target/arm/translate-a64.c | 18 +--
21
target/arm/translate.c | 299 +++++++++++++++++++++++++++++++++++--
22
target/arm/vec_helper.c | 88 +++++++++++
23
6 files changed, 389 insertions(+), 66 deletions(-)
24
25
diff --git a/target/arm/helper.h b/target/arm/helper.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/helper.h
28
+++ b/target/arm/helper.h
29
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_abd_s16, i32, i32, i32)
30
DEF_HELPER_2(neon_abd_u32, i32, i32, i32)
31
DEF_HELPER_2(neon_abd_s32, i32, i32, i32)
32
33
-DEF_HELPER_2(neon_shl_u8, i32, i32, i32)
34
-DEF_HELPER_2(neon_shl_s8, i32, i32, i32)
35
DEF_HELPER_2(neon_shl_u16, i32, i32, i32)
36
DEF_HELPER_2(neon_shl_s16, i32, i32, i32)
37
-DEF_HELPER_2(neon_shl_u32, i32, i32, i32)
38
-DEF_HELPER_2(neon_shl_s32, i32, i32, i32)
39
-DEF_HELPER_2(neon_shl_u64, i64, i64, i64)
40
-DEF_HELPER_2(neon_shl_s64, i64, i64, i64)
41
DEF_HELPER_2(neon_rshl_u8, i32, i32, i32)
42
DEF_HELPER_2(neon_rshl_s8, i32, i32, i32)
43
DEF_HELPER_2(neon_rshl_u16, i32, i32, i32)
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(frint64_s, TCG_CALL_NO_RWG, f32, f32, ptr)
45
DEF_HELPER_FLAGS_2(frint32_d, TCG_CALL_NO_RWG, f64, f64, ptr)
46
DEF_HELPER_FLAGS_2(frint64_d, TCG_CALL_NO_RWG, f64, f64, ptr)
47
48
+DEF_HELPER_FLAGS_4(gvec_sshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
49
+DEF_HELPER_FLAGS_4(gvec_sshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
52
+
53
#ifdef TARGET_AARCH64
54
#include "helper-a64.h"
55
#include "helper-sve.h"
56
diff --git a/target/arm/translate.h b/target/arm/translate.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate.h
59
+++ b/target/arm/translate.h
60
@@ -XXX,XX +XXX,XX @@ uint64_t vfp_expand_imm(int size, uint8_t imm8);
61
extern const GVecGen3 mla_op[4];
62
extern const GVecGen3 mls_op[4];
63
extern const GVecGen3 cmtst_op[4];
64
+extern const GVecGen3 sshl_op[4];
65
+extern const GVecGen3 ushl_op[4];
66
extern const GVecGen2i ssra_op[4];
67
extern const GVecGen2i usra_op[4];
68
extern const GVecGen2i sri_op[4];
69
@@ -XXX,XX +XXX,XX @@ extern const GVecGen4 sqadd_op[4];
70
extern const GVecGen4 uqsub_op[4];
71
extern const GVecGen4 sqsub_op[4];
72
void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
73
+void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
74
+void gen_sshl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
75
+void gen_ushl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
76
+void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
77
78
/*
79
* Forward to the isar_feature_* tests given a DisasContext pointer.
80
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/neon_helper.c
83
+++ b/target/arm/neon_helper.c
84
@@ -XXX,XX +XXX,XX @@ NEON_VOP(abd_u32, neon_u32, 1)
85
} else { \
86
dest = src1 << tmp; \
87
}} while (0)
88
-NEON_VOP(shl_u8, neon_u8, 4)
89
NEON_VOP(shl_u16, neon_u16, 2)
90
-NEON_VOP(shl_u32, neon_u32, 1)
91
#undef NEON_FN
92
93
-uint64_t HELPER(neon_shl_u64)(uint64_t val, uint64_t shiftop)
94
-{
95
- int8_t shift = (int8_t)shiftop;
96
- if (shift >= 64 || shift <= -64) {
97
- val = 0;
98
- } else if (shift < 0) {
99
- val >>= -shift;
100
- } else {
101
- val <<= shift;
102
- }
103
- return val;
104
-}
105
-
106
#define NEON_FN(dest, src1, src2) do { \
107
int8_t tmp; \
108
tmp = (int8_t)src2; \
109
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_shl_u64)(uint64_t val, uint64_t shiftop)
110
} else { \
111
dest = src1 << tmp; \
112
}} while (0)
113
-NEON_VOP(shl_s8, neon_s8, 4)
114
NEON_VOP(shl_s16, neon_s16, 2)
115
-NEON_VOP(shl_s32, neon_s32, 1)
116
#undef NEON_FN
117
118
-uint64_t HELPER(neon_shl_s64)(uint64_t valop, uint64_t shiftop)
119
-{
120
- int8_t shift = (int8_t)shiftop;
121
- int64_t val = valop;
122
- if (shift >= 64) {
123
- val = 0;
124
- } else if (shift <= -64) {
125
- val >>= 63;
126
- } else if (shift < 0) {
127
- val >>= -shift;
128
- } else {
129
- val <<= shift;
130
- }
131
- return val;
132
-}
133
-
134
#define NEON_FN(dest, src1, src2) do { \
135
int8_t tmp; \
136
tmp = (int8_t)src2; \
137
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/arm/translate-a64.c
140
+++ b/target/arm/translate-a64.c
141
@@ -XXX,XX +XXX,XX @@ static void handle_3same_64(DisasContext *s, int opcode, bool u,
142
break;
143
case 0x8: /* SSHL, USHL */
144
if (u) {
145
- gen_helper_neon_shl_u64(tcg_rd, tcg_rn, tcg_rm);
146
+ gen_ushl_i64(tcg_rd, tcg_rn, tcg_rm);
147
} else {
148
- gen_helper_neon_shl_s64(tcg_rd, tcg_rn, tcg_rm);
149
+ gen_sshl_i64(tcg_rd, tcg_rn, tcg_rm);
150
}
151
break;
152
case 0x9: /* SQSHL, UQSHL */
153
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
154
is_q ? 16 : 8, vec_full_reg_size(s),
155
(u ? uqsub_op : sqsub_op) + size);
156
return;
157
+ case 0x08: /* SSHL, USHL */
158
+ gen_gvec_op3(s, is_q, rd, rn, rm,
159
+ u ? &ushl_op[size] : &sshl_op[size]);
160
+ return;
161
case 0x0c: /* SMAX, UMAX */
162
if (u) {
163
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
164
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
165
genfn = fns[size][u];
166
break;
167
}
168
- case 0x8: /* SSHL, USHL */
169
- {
170
- static NeonGenTwoOpFn * const fns[3][2] = {
171
- { gen_helper_neon_shl_s8, gen_helper_neon_shl_u8 },
172
- { gen_helper_neon_shl_s16, gen_helper_neon_shl_u16 },
173
- { gen_helper_neon_shl_s32, gen_helper_neon_shl_u32 },
174
- };
175
- genfn = fns[size][u];
176
- break;
177
- }
178
case 0x9: /* SQSHL, UQSHL */
179
{
180
static NeonGenTwoOpEnvFn * const fns[3][2] = {
181
diff --git a/target/arm/translate.c b/target/arm/translate.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/target/arm/translate.c
184
+++ b/target/arm/translate.c
185
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
186
if (u) {
187
switch (size) {
188
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
189
- case 2: gen_helper_neon_shl_u32(var, var, shift); break;
190
+ case 2: gen_ushl_i32(var, var, shift); break;
191
default: abort();
192
}
193
} else {
194
switch (size) {
195
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
196
- case 2: gen_helper_neon_shl_s32(var, var, shift); break;
197
+ case 2: gen_sshl_i32(var, var, shift); break;
198
default: abort();
199
}
200
}
201
@@ -XXX,XX +XXX,XX @@ const GVecGen3 cmtst_op[4] = {
202
.vece = MO_64 },
203
};
204
205
+void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
206
+{
207
+ TCGv_i32 lval = tcg_temp_new_i32();
208
+ TCGv_i32 rval = tcg_temp_new_i32();
209
+ TCGv_i32 lsh = tcg_temp_new_i32();
210
+ TCGv_i32 rsh = tcg_temp_new_i32();
211
+ TCGv_i32 zero = tcg_const_i32(0);
212
+ TCGv_i32 max = tcg_const_i32(32);
213
+
214
+ /*
215
+ * Rely on the TCG guarantee that out of range shifts produce
216
+ * unspecified results, not undefined behaviour (i.e. no trap).
217
+ * Discard out-of-range results after the fact.
218
+ */
219
+ tcg_gen_ext8s_i32(lsh, shift);
220
+ tcg_gen_neg_i32(rsh, lsh);
221
+ tcg_gen_shl_i32(lval, src, lsh);
222
+ tcg_gen_shr_i32(rval, src, rsh);
223
+ tcg_gen_movcond_i32(TCG_COND_LTU, dst, lsh, max, lval, zero);
224
+ tcg_gen_movcond_i32(TCG_COND_LTU, dst, rsh, max, rval, dst);
225
+
226
+ tcg_temp_free_i32(lval);
227
+ tcg_temp_free_i32(rval);
228
+ tcg_temp_free_i32(lsh);
229
+ tcg_temp_free_i32(rsh);
230
+ tcg_temp_free_i32(zero);
231
+ tcg_temp_free_i32(max);
232
+}
233
+
234
+void gen_ushl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
235
+{
236
+ TCGv_i64 lval = tcg_temp_new_i64();
237
+ TCGv_i64 rval = tcg_temp_new_i64();
238
+ TCGv_i64 lsh = tcg_temp_new_i64();
239
+ TCGv_i64 rsh = tcg_temp_new_i64();
240
+ TCGv_i64 zero = tcg_const_i64(0);
241
+ TCGv_i64 max = tcg_const_i64(64);
242
+
243
+ /*
244
+ * Rely on the TCG guarantee that out of range shifts produce
245
+ * unspecified results, not undefined behaviour (i.e. no trap).
246
+ * Discard out-of-range results after the fact.
247
+ */
248
+ tcg_gen_ext8s_i64(lsh, shift);
249
+ tcg_gen_neg_i64(rsh, lsh);
250
+ tcg_gen_shl_i64(lval, src, lsh);
251
+ tcg_gen_shr_i64(rval, src, rsh);
252
+ tcg_gen_movcond_i64(TCG_COND_LTU, dst, lsh, max, lval, zero);
253
+ tcg_gen_movcond_i64(TCG_COND_LTU, dst, rsh, max, rval, dst);
254
+
255
+ tcg_temp_free_i64(lval);
256
+ tcg_temp_free_i64(rval);
257
+ tcg_temp_free_i64(lsh);
258
+ tcg_temp_free_i64(rsh);
259
+ tcg_temp_free_i64(zero);
260
+ tcg_temp_free_i64(max);
261
+}
262
+
263
+static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
264
+ TCGv_vec src, TCGv_vec shift)
265
+{
266
+ TCGv_vec lval = tcg_temp_new_vec_matching(dst);
267
+ TCGv_vec rval = tcg_temp_new_vec_matching(dst);
268
+ TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
269
+ TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
270
+ TCGv_vec msk, max;
271
+
272
+ tcg_gen_neg_vec(vece, rsh, shift);
273
+ if (vece == MO_8) {
274
+ tcg_gen_mov_vec(lsh, shift);
275
+ } else {
276
+ msk = tcg_temp_new_vec_matching(dst);
277
+ tcg_gen_dupi_vec(vece, msk, 0xff);
278
+ tcg_gen_and_vec(vece, lsh, shift, msk);
279
+ tcg_gen_and_vec(vece, rsh, rsh, msk);
280
+ tcg_temp_free_vec(msk);
281
+ }
282
+
283
+ /*
284
+ * Rely on the TCG guarantee that out of range shifts produce
285
+ * unspecified results, not undefined behaviour (i.e. no trap).
286
+ * Discard out-of-range results after the fact.
287
+ */
288
+ tcg_gen_shlv_vec(vece, lval, src, lsh);
289
+ tcg_gen_shrv_vec(vece, rval, src, rsh);
290
+
291
+ max = tcg_temp_new_vec_matching(dst);
292
+ tcg_gen_dupi_vec(vece, max, 8 << vece);
293
+
294
+ /*
295
+ * The choice of LT (signed) and GEU (unsigned) are biased toward
296
+ * the instructions of the x86_64 host. For MO_8, the whole byte
297
+ * is significant so we must use an unsigned compare; otherwise we
298
+ * have already masked to a byte and so a signed compare works.
299
+ * Other tcg hosts have a full set of comparisons and do not care.
300
+ */
301
+ if (vece == MO_8) {
302
+ tcg_gen_cmp_vec(TCG_COND_GEU, vece, lsh, lsh, max);
303
+ tcg_gen_cmp_vec(TCG_COND_GEU, vece, rsh, rsh, max);
304
+ tcg_gen_andc_vec(vece, lval, lval, lsh);
305
+ tcg_gen_andc_vec(vece, rval, rval, rsh);
306
+ } else {
307
+ tcg_gen_cmp_vec(TCG_COND_LT, vece, lsh, lsh, max);
308
+ tcg_gen_cmp_vec(TCG_COND_LT, vece, rsh, rsh, max);
309
+ tcg_gen_and_vec(vece, lval, lval, lsh);
310
+ tcg_gen_and_vec(vece, rval, rval, rsh);
311
+ }
312
+ tcg_gen_or_vec(vece, dst, lval, rval);
313
+
314
+ tcg_temp_free_vec(max);
315
+ tcg_temp_free_vec(lval);
316
+ tcg_temp_free_vec(rval);
317
+ tcg_temp_free_vec(lsh);
318
+ tcg_temp_free_vec(rsh);
319
+}
320
+
321
+static const TCGOpcode ushl_list[] = {
322
+ INDEX_op_neg_vec, INDEX_op_shlv_vec,
323
+ INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
324
+};
325
+
326
+const GVecGen3 ushl_op[4] = {
327
+ { .fniv = gen_ushl_vec,
328
+ .fno = gen_helper_gvec_ushl_b,
329
+ .opt_opc = ushl_list,
330
+ .vece = MO_8 },
331
+ { .fniv = gen_ushl_vec,
332
+ .fno = gen_helper_gvec_ushl_h,
333
+ .opt_opc = ushl_list,
334
+ .vece = MO_16 },
335
+ { .fni4 = gen_ushl_i32,
336
+ .fniv = gen_ushl_vec,
337
+ .opt_opc = ushl_list,
338
+ .vece = MO_32 },
339
+ { .fni8 = gen_ushl_i64,
340
+ .fniv = gen_ushl_vec,
341
+ .opt_opc = ushl_list,
342
+ .vece = MO_64 },
343
+};
344
+
345
+void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
346
+{
347
+ TCGv_i32 lval = tcg_temp_new_i32();
348
+ TCGv_i32 rval = tcg_temp_new_i32();
349
+ TCGv_i32 lsh = tcg_temp_new_i32();
350
+ TCGv_i32 rsh = tcg_temp_new_i32();
351
+ TCGv_i32 zero = tcg_const_i32(0);
352
+ TCGv_i32 max = tcg_const_i32(31);
353
+
354
+ /*
355
+ * Rely on the TCG guarantee that out of range shifts produce
356
+ * unspecified results, not undefined behaviour (i.e. no trap).
357
+ * Discard out-of-range results after the fact.
358
+ */
359
+ tcg_gen_ext8s_i32(lsh, shift);
360
+ tcg_gen_neg_i32(rsh, lsh);
361
+ tcg_gen_shl_i32(lval, src, lsh);
362
+ tcg_gen_umin_i32(rsh, rsh, max);
363
+ tcg_gen_sar_i32(rval, src, rsh);
364
+ tcg_gen_movcond_i32(TCG_COND_LEU, lval, lsh, max, lval, zero);
365
+ tcg_gen_movcond_i32(TCG_COND_LT, dst, lsh, zero, rval, lval);
366
+
367
+ tcg_temp_free_i32(lval);
368
+ tcg_temp_free_i32(rval);
369
+ tcg_temp_free_i32(lsh);
370
+ tcg_temp_free_i32(rsh);
371
+ tcg_temp_free_i32(zero);
372
+ tcg_temp_free_i32(max);
373
+}
374
+
375
+void gen_sshl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
376
+{
377
+ TCGv_i64 lval = tcg_temp_new_i64();
378
+ TCGv_i64 rval = tcg_temp_new_i64();
379
+ TCGv_i64 lsh = tcg_temp_new_i64();
380
+ TCGv_i64 rsh = tcg_temp_new_i64();
381
+ TCGv_i64 zero = tcg_const_i64(0);
382
+ TCGv_i64 max = tcg_const_i64(63);
383
+
384
+ /*
385
+ * Rely on the TCG guarantee that out of range shifts produce
386
+ * unspecified results, not undefined behaviour (i.e. no trap).
387
+ * Discard out-of-range results after the fact.
388
+ */
389
+ tcg_gen_ext8s_i64(lsh, shift);
390
+ tcg_gen_neg_i64(rsh, lsh);
391
+ tcg_gen_shl_i64(lval, src, lsh);
392
+ tcg_gen_umin_i64(rsh, rsh, max);
393
+ tcg_gen_sar_i64(rval, src, rsh);
394
+ tcg_gen_movcond_i64(TCG_COND_LEU, lval, lsh, max, lval, zero);
395
+ tcg_gen_movcond_i64(TCG_COND_LT, dst, lsh, zero, rval, lval);
396
+
397
+ tcg_temp_free_i64(lval);
398
+ tcg_temp_free_i64(rval);
399
+ tcg_temp_free_i64(lsh);
400
+ tcg_temp_free_i64(rsh);
401
+ tcg_temp_free_i64(zero);
402
+ tcg_temp_free_i64(max);
403
+}
404
+
405
+static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
406
+ TCGv_vec src, TCGv_vec shift)
407
+{
408
+ TCGv_vec lval = tcg_temp_new_vec_matching(dst);
409
+ TCGv_vec rval = tcg_temp_new_vec_matching(dst);
410
+ TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
411
+ TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
412
+ TCGv_vec tmp = tcg_temp_new_vec_matching(dst);
413
+
414
+ /*
415
+ * Rely on the TCG guarantee that out of range shifts produce
416
+ * unspecified results, not undefined behaviour (i.e. no trap).
417
+ * Discard out-of-range results after the fact.
418
+ */
419
+ tcg_gen_neg_vec(vece, rsh, shift);
420
+ if (vece == MO_8) {
421
+ tcg_gen_mov_vec(lsh, shift);
422
+ } else {
423
+ tcg_gen_dupi_vec(vece, tmp, 0xff);
424
+ tcg_gen_and_vec(vece, lsh, shift, tmp);
425
+ tcg_gen_and_vec(vece, rsh, rsh, tmp);
426
+ }
427
+
428
+ /* Bound rsh so out of bound right shift gets -1. */
429
+ tcg_gen_dupi_vec(vece, tmp, (8 << vece) - 1);
430
+ tcg_gen_umin_vec(vece, rsh, rsh, tmp);
431
+ tcg_gen_cmp_vec(TCG_COND_GT, vece, tmp, lsh, tmp);
432
+
433
+ tcg_gen_shlv_vec(vece, lval, src, lsh);
434
+ tcg_gen_sarv_vec(vece, rval, src, rsh);
435
+
436
+ /* Select in-bound left shift. */
437
+ tcg_gen_andc_vec(vece, lval, lval, tmp);
438
+
439
+ /* Select between left and right shift. */
440
+ if (vece == MO_8) {
441
+ tcg_gen_dupi_vec(vece, tmp, 0);
442
+ tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, rval, lval);
443
+ } else {
444
+ tcg_gen_dupi_vec(vece, tmp, 0x80);
445
+ tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, lval, rval);
446
+ }
447
+
448
+ tcg_temp_free_vec(lval);
449
+ tcg_temp_free_vec(rval);
450
+ tcg_temp_free_vec(lsh);
451
+ tcg_temp_free_vec(rsh);
452
+ tcg_temp_free_vec(tmp);
453
+}
454
+
455
+static const TCGOpcode sshl_list[] = {
456
+ INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
457
+ INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
458
+};
459
+
460
+const GVecGen3 sshl_op[4] = {
461
+ { .fniv = gen_sshl_vec,
462
+ .fno = gen_helper_gvec_sshl_b,
463
+ .opt_opc = sshl_list,
464
+ .vece = MO_8 },
465
+ { .fniv = gen_sshl_vec,
466
+ .fno = gen_helper_gvec_sshl_h,
467
+ .opt_opc = sshl_list,
468
+ .vece = MO_16 },
469
+ { .fni4 = gen_sshl_i32,
470
+ .fniv = gen_sshl_vec,
471
+ .opt_opc = sshl_list,
472
+ .vece = MO_32 },
473
+ { .fni8 = gen_sshl_i64,
474
+ .fniv = gen_sshl_vec,
475
+ .opt_opc = sshl_list,
476
+ .vece = MO_64 },
477
+};
478
+
479
static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
480
TCGv_vec a, TCGv_vec b)
481
{
482
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
483
vec_size, vec_size);
484
}
485
return 0;
486
+
487
+ case NEON_3R_VSHL:
488
+ /* Note the operation is vshl vd,vm,vn */
489
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
490
+ u ? &ushl_op[size] : &sshl_op[size]);
491
+ return 0;
492
}
493
494
if (size == 3) {
495
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
496
neon_load_reg64(cpu_V0, rn + pass);
497
neon_load_reg64(cpu_V1, rm + pass);
498
switch (op) {
499
- case NEON_3R_VSHL:
500
- if (u) {
501
- gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
502
- } else {
503
- gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
504
- }
505
- break;
506
case NEON_3R_VQSHL:
507
if (u) {
508
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
509
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
510
}
511
pairwise = 0;
512
switch (op) {
513
- case NEON_3R_VSHL:
514
case NEON_3R_VQSHL:
515
case NEON_3R_VRSHL:
516
case NEON_3R_VQRSHL:
517
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
518
case NEON_3R_VHSUB:
519
GEN_NEON_INTEGER_OP(hsub);
520
break;
521
- case NEON_3R_VSHL:
522
- GEN_NEON_INTEGER_OP(shl);
523
- break;
524
case NEON_3R_VQSHL:
525
GEN_NEON_INTEGER_OP_ENV(qshl);
526
break;
527
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
528
}
529
} else {
530
if (input_unsigned) {
531
- gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
532
+ gen_ushl_i64(cpu_V0, in, tmp64);
533
} else {
534
- gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
535
+ gen_sshl_i64(cpu_V0, in, tmp64);
536
}
537
}
538
tmp = tcg_temp_new_i32();
539
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
540
index XXXXXXX..XXXXXXX 100644
541
--- a/target/arm/vec_helper.c
542
+++ b/target/arm/vec_helper.c
543
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fmlal_idx_a64)(void *vd, void *vn, void *vm,
544
do_fmlal_idx(vd, vn, vm, &env->vfp.fp_status, desc,
545
get_flush_inputs_to_zero(&env->vfp.fp_status_f16));
546
}
547
+
548
+void HELPER(gvec_sshl_b)(void *vd, void *vn, void *vm, uint32_t desc)
549
+{
550
+ intptr_t i, opr_sz = simd_oprsz(desc);
551
+ int8_t *d = vd, *n = vn, *m = vm;
552
+
553
+ for (i = 0; i < opr_sz; ++i) {
554
+ int8_t mm = m[i];
555
+ int8_t nn = n[i];
556
+ int8_t res = 0;
557
+ if (mm >= 0) {
558
+ if (mm < 8) {
559
+ res = nn << mm;
560
+ }
561
+ } else {
562
+ res = nn >> (mm > -8 ? -mm : 7);
563
+ }
564
+ d[i] = res;
565
+ }
566
+ clear_tail(d, opr_sz, simd_maxsz(desc));
567
+}
568
+
569
+void HELPER(gvec_sshl_h)(void *vd, void *vn, void *vm, uint32_t desc)
570
+{
571
+ intptr_t i, opr_sz = simd_oprsz(desc);
572
+ int16_t *d = vd, *n = vn, *m = vm;
573
+
574
+ for (i = 0; i < opr_sz / 2; ++i) {
575
+ int8_t mm = m[i]; /* only 8 bits of shift are significant */
576
+ int16_t nn = n[i];
577
+ int16_t res = 0;
578
+ if (mm >= 0) {
579
+ if (mm < 16) {
580
+ res = nn << mm;
581
+ }
582
+ } else {
583
+ res = nn >> (mm > -16 ? -mm : 15);
584
+ }
585
+ d[i] = res;
586
+ }
587
+ clear_tail(d, opr_sz, simd_maxsz(desc));
588
+}
589
+
590
+void HELPER(gvec_ushl_b)(void *vd, void *vn, void *vm, uint32_t desc)
591
+{
592
+ intptr_t i, opr_sz = simd_oprsz(desc);
593
+ uint8_t *d = vd, *n = vn, *m = vm;
594
+
595
+ for (i = 0; i < opr_sz; ++i) {
596
+ int8_t mm = m[i];
597
+ uint8_t nn = n[i];
598
+ uint8_t res = 0;
599
+ if (mm >= 0) {
600
+ if (mm < 8) {
601
+ res = nn << mm;
602
+ }
603
+ } else {
604
+ if (mm > -8) {
605
+ res = nn >> -mm;
606
+ }
607
+ }
608
+ d[i] = res;
609
+ }
610
+ clear_tail(d, opr_sz, simd_maxsz(desc));
611
+}
612
+
613
+void HELPER(gvec_ushl_h)(void *vd, void *vn, void *vm, uint32_t desc)
614
+{
615
+ intptr_t i, opr_sz = simd_oprsz(desc);
616
+ uint16_t *d = vd, *n = vn, *m = vm;
617
+
618
+ for (i = 0; i < opr_sz / 2; ++i) {
619
+ int8_t mm = m[i]; /* only 8 bits of shift are significant */
620
+ uint16_t nn = n[i];
621
+ uint16_t res = 0;
622
+ if (mm >= 0) {
623
+ if (mm < 16) {
624
+ res = nn << mm;
625
+ }
626
+ } else {
627
+ if (mm > -16) {
628
+ res = nn >> -mm;
629
+ }
630
+ }
631
+ d[i] = res;
632
+ }
633
+ clear_tail(d, opr_sz, simd_maxsz(desc));
634
+}
635
--
636
2.20.1
637
638
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The gvec form will be needed for implementing SVE2.
4
5
Extend the implementation to operate on uint64_t instead of uint32_t.
6
Use a counted inner loop instead of terminating when op1 goes to zero,
7
looking toward the required implementation for ARMv8.4-DIT.
8
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200216214232.4230-3-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/helper.h | 3 ++-
16
target/arm/neon_helper.c | 22 ----------------------
17
target/arm/translate-a64.c | 10 +++-------
18
target/arm/translate.c | 11 ++++-------
19
target/arm/vec_helper.c | 30 ++++++++++++++++++++++++++++++
20
5 files changed, 39 insertions(+), 37 deletions(-)
21
22
diff --git a/target/arm/helper.h b/target/arm/helper.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.h
25
+++ b/target/arm/helper.h
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
27
DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
28
DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
29
DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
30
-DEF_HELPER_2(neon_mul_p8, i32, i32, i32)
31
DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
32
33
DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_sshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
38
+DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
+
40
#ifdef TARGET_AARCH64
41
#include "helper-a64.h"
42
#include "helper-sve.h"
43
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/neon_helper.c
46
+++ b/target/arm/neon_helper.c
47
@@ -XXX,XX +XXX,XX @@ NEON_VOP(mul_u16, neon_u16, 2)
48
49
/* Polynomial multiplication is like integer multiplication except the
50
partial products are XORed, not added. */
51
-uint32_t HELPER(neon_mul_p8)(uint32_t op1, uint32_t op2)
52
-{
53
- uint32_t mask;
54
- uint32_t result;
55
- result = 0;
56
- while (op1) {
57
- mask = 0;
58
- if (op1 & 1)
59
- mask |= 0xff;
60
- if (op1 & (1 << 8))
61
- mask |= (0xff << 8);
62
- if (op1 & (1 << 16))
63
- mask |= (0xff << 16);
64
- if (op1 & (1 << 24))
65
- mask |= (0xff << 24);
66
- result ^= op2 & mask;
67
- op1 = (op1 >> 1) & 0x7f7f7f7f;
68
- op2 = (op2 << 1) & 0xfefefefe;
69
- }
70
- return result;
71
-}
72
-
73
uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
74
{
75
uint64_t result = 0;
76
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate-a64.c
79
+++ b/target/arm/translate-a64.c
80
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
81
case 0x13: /* MUL, PMUL */
82
if (!u) { /* MUL */
83
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_mul, size);
84
- return;
85
+ } else { /* PMUL */
86
+ gen_gvec_op3_ool(s, is_q, rd, rn, rm, 0, gen_helper_gvec_pmul_b);
87
}
88
- break;
89
+ return;
90
case 0x12: /* MLA, MLS */
91
if (u) {
92
gen_gvec_op3(s, is_q, rd, rn, rm, &mls_op[size]);
93
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
94
genfn = fns[size][u];
95
break;
96
}
97
- case 0x13: /* MUL, PMUL */
98
- assert(u); /* PMUL */
99
- assert(size == 0);
100
- genfn = gen_helper_neon_mul_p8;
101
- break;
102
case 0x16: /* SQDMULH, SQRDMULH */
103
{
104
static NeonGenTwoOpEnvFn * const fns[2][2] = {
105
diff --git a/target/arm/translate.c b/target/arm/translate.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/translate.c
108
+++ b/target/arm/translate.c
109
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
110
111
case NEON_3R_VMUL: /* VMUL */
112
if (u) {
113
- /* Polynomial case allows only P8 and is handled below. */
114
+ /* Polynomial case allows only P8. */
115
if (size != 0) {
116
return 1;
117
}
118
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
119
+ 0, gen_helper_gvec_pmul_b);
120
} else {
121
tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
122
vec_size, vec_size);
123
- return 0;
124
}
125
- break;
126
+ return 0;
127
128
case NEON_3R_VML: /* VMLA, VMLS */
129
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
130
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
131
tmp2 = neon_load_reg(rd, pass);
132
gen_neon_add(size, tmp, tmp2);
133
break;
134
- case NEON_3R_VMUL:
135
- /* VMUL.P8; other cases already eliminated. */
136
- gen_helper_neon_mul_p8(tmp, tmp, tmp2);
137
- break;
138
case NEON_3R_VPMAX:
139
GEN_NEON_INTEGER_OP(pmax);
140
break;
141
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/target/arm/vec_helper.c
144
+++ b/target/arm/vec_helper.c
145
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_ushl_h)(void *vd, void *vn, void *vm, uint32_t desc)
146
}
147
clear_tail(d, opr_sz, simd_maxsz(desc));
148
}
149
+
150
+/*
151
+ * 8x8->8 polynomial multiply.
152
+ *
153
+ * Polynomial multiplication is like integer multiplication except the
154
+ * partial products are XORed, not added.
155
+ *
156
+ * TODO: expose this as a generic vector operation, as it is a common
157
+ * crypto building block.
158
+ */
159
+void HELPER(gvec_pmul_b)(void *vd, void *vn, void *vm, uint32_t desc)
160
+{
161
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
162
+ uint64_t *d = vd, *n = vn, *m = vm;
163
+
164
+ for (i = 0; i < opr_sz / 8; ++i) {
165
+ uint64_t nn = n[i];
166
+ uint64_t mm = m[i];
167
+ uint64_t rr = 0;
168
+
169
+ for (j = 0; j < 8; ++j) {
170
+ uint64_t mask = (nn & 0x0101010101010101ull) * 0xff;
171
+ rr ^= mm & mask;
172
+ mm = (mm << 1) & 0xfefefefefefefefeull;
173
+ nn >>= 1;
174
+ }
175
+ d[i] = rr;
176
+ }
177
+ clear_tail(d, opr_sz, simd_maxsz(desc));
178
+}
179
--
180
2.20.1
181
182
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The gvec form will be needed for implementing SVE2.
4
5
Tested-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200216214232.4230-4-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper.h | 4 +---
12
target/arm/neon_helper.c | 30 ------------------------------
13
target/arm/translate-a64.c | 28 +++-------------------------
14
target/arm/translate.c | 16 ++--------------
15
target/arm/vec_helper.c | 33 +++++++++++++++++++++++++++++++++
16
5 files changed, 39 insertions(+), 72 deletions(-)
17
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
21
+++ b/target/arm/helper.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
23
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
24
DEF_HELPER_2(dc_zva, void, env, i64)
25
26
-DEF_HELPER_FLAGS_2(neon_pmull_64_lo, TCG_CALL_NO_RWG_SE, i64, i64, i64)
27
-DEF_HELPER_FLAGS_2(neon_pmull_64_hi, TCG_CALL_NO_RWG_SE, i64, i64, i64)
28
-
29
DEF_HELPER_FLAGS_5(gvec_qrdmlah_s16, TCG_CALL_NO_RWG,
30
void, ptr, ptr, ptr, ptr, i32)
31
DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s16, TCG_CALL_NO_RWG,
32
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
35
DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
38
#ifdef TARGET_AARCH64
39
#include "helper-a64.h"
40
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/neon_helper.c
43
+++ b/target/arm/neon_helper.c
44
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_zip16)(void *vd, void *vm)
45
rm[0] = m0;
46
rd[0] = d0;
47
}
48
-
49
-/* Helper function for 64 bit polynomial multiply case:
50
- * perform PolynomialMult(op1, op2) and return either the top or
51
- * bottom half of the 128 bit result.
52
- */
53
-uint64_t HELPER(neon_pmull_64_lo)(uint64_t op1, uint64_t op2)
54
-{
55
- int bitnum;
56
- uint64_t res = 0;
57
-
58
- for (bitnum = 0; bitnum < 64; bitnum++) {
59
- if (op1 & (1ULL << bitnum)) {
60
- res ^= op2 << bitnum;
61
- }
62
- }
63
- return res;
64
-}
65
-uint64_t HELPER(neon_pmull_64_hi)(uint64_t op1, uint64_t op2)
66
-{
67
- int bitnum;
68
- uint64_t res = 0;
69
-
70
- /* bit 0 of op1 can't influence the high 64 bits at all */
71
- for (bitnum = 1; bitnum < 64; bitnum++) {
72
- if (op1 & (1ULL << bitnum)) {
73
- res ^= op2 >> (64 - bitnum);
74
- }
75
- }
76
- return res;
77
-}
78
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/translate-a64.c
81
+++ b/target/arm/translate-a64.c
82
@@ -XXX,XX +XXX,XX @@ static void handle_3rd_narrowing(DisasContext *s, int is_q, int is_u, int size,
83
clear_vec_high(s, is_q, rd);
84
}
85
86
-static void handle_pmull_64(DisasContext *s, int is_q, int rd, int rn, int rm)
87
-{
88
- /* PMULL of 64 x 64 -> 128 is an odd special case because it
89
- * is the only three-reg-diff instruction which produces a
90
- * 128-bit wide result from a single operation. However since
91
- * it's possible to calculate the two halves more or less
92
- * separately we just use two helper calls.
93
- */
94
- TCGv_i64 tcg_op1 = tcg_temp_new_i64();
95
- TCGv_i64 tcg_op2 = tcg_temp_new_i64();
96
- TCGv_i64 tcg_res = tcg_temp_new_i64();
97
-
98
- read_vec_element(s, tcg_op1, rn, is_q, MO_64);
99
- read_vec_element(s, tcg_op2, rm, is_q, MO_64);
100
- gen_helper_neon_pmull_64_lo(tcg_res, tcg_op1, tcg_op2);
101
- write_vec_element(s, tcg_res, rd, 0, MO_64);
102
- gen_helper_neon_pmull_64_hi(tcg_res, tcg_op1, tcg_op2);
103
- write_vec_element(s, tcg_res, rd, 1, MO_64);
104
-
105
- tcg_temp_free_i64(tcg_op1);
106
- tcg_temp_free_i64(tcg_op2);
107
- tcg_temp_free_i64(tcg_res);
108
-}
109
-
110
/* AdvSIMD three different
111
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
112
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
113
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
114
if (!fp_access_check(s)) {
115
return;
116
}
117
- handle_pmull_64(s, is_q, rd, rn, rm);
118
+ /* The Q field specifies lo/hi half input for this insn. */
119
+ gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
120
+ gen_helper_gvec_pmull_q);
121
return;
122
}
123
goto is_widening;
124
diff --git a/target/arm/translate.c b/target/arm/translate.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/target/arm/translate.c
127
+++ b/target/arm/translate.c
128
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
129
* outside the loop below as it only performs a single pass.
130
*/
131
if (op == 14 && size == 2) {
132
- TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
133
-
134
if (!dc_isar_feature(aa32_pmull, s)) {
135
return 1;
136
}
137
- tcg_rn = tcg_temp_new_i64();
138
- tcg_rm = tcg_temp_new_i64();
139
- tcg_rd = tcg_temp_new_i64();
140
- neon_load_reg64(tcg_rn, rn);
141
- neon_load_reg64(tcg_rm, rm);
142
- gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
143
- neon_store_reg64(tcg_rd, rd);
144
- gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
145
- neon_store_reg64(tcg_rd, rd + 1);
146
- tcg_temp_free_i64(tcg_rn);
147
- tcg_temp_free_i64(tcg_rm);
148
- tcg_temp_free_i64(tcg_rd);
149
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
150
+ 0, gen_helper_gvec_pmull_q);
151
return 0;
152
}
153
154
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
155
index XXXXXXX..XXXXXXX 100644
156
--- a/target/arm/vec_helper.c
157
+++ b/target/arm/vec_helper.c
158
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_pmul_b)(void *vd, void *vn, void *vm, uint32_t desc)
159
}
160
clear_tail(d, opr_sz, simd_maxsz(desc));
161
}
162
+
163
+/*
164
+ * 64x64->128 polynomial multiply.
165
+ * Because of the lanes are not accessed in strict columns,
166
+ * this probably cannot be turned into a generic helper.
167
+ */
168
+void HELPER(gvec_pmull_q)(void *vd, void *vn, void *vm, uint32_t desc)
169
+{
170
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
171
+ intptr_t hi = simd_data(desc);
172
+ uint64_t *d = vd, *n = vn, *m = vm;
173
+
174
+ for (i = 0; i < opr_sz / 8; i += 2) {
175
+ uint64_t nn = n[i + hi];
176
+ uint64_t mm = m[i + hi];
177
+ uint64_t rhi = 0;
178
+ uint64_t rlo = 0;
179
+
180
+ /* Bit 0 can only influence the low 64-bit result. */
181
+ if (nn & 1) {
182
+ rlo = mm;
183
+ }
184
+
185
+ for (j = 1; j < 64; ++j) {
186
+ uint64_t mask = -((nn >> j) & 1);
187
+ rlo ^= (mm << j) & mask;
188
+ rhi ^= (mm >> (64 - j)) & mask;
189
+ }
190
+ d[i] = rlo;
191
+ d[i + 1] = rhi;
192
+ }
193
+ clear_tail(d, opr_sz, simd_maxsz(desc));
194
+}
195
--
196
2.20.1
197
198
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
We still need two different helpers, since NEON and SVE2 get the
4
inputs from different locations within the source vector. However,
5
we can convert both to the same internal form for computation.
6
7
The sve2 helper is not used yet, but adding it with this patch
8
helps illustrate why the neon changes are helpful.
9
10
Tested-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200216214232.4230-5-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/helper-sve.h | 2 ++
17
target/arm/helper.h | 3 +-
18
target/arm/neon_helper.c | 32 --------------------
19
target/arm/translate-a64.c | 27 +++++++++++------
20
target/arm/translate.c | 26 ++++++++---------
21
target/arm/vec_helper.c | 60 ++++++++++++++++++++++++++++++++++++++
22
6 files changed, 95 insertions(+), 55 deletions(-)
23
24
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper-sve.h
27
+++ b/target/arm/helper-sve.h
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_stdd_le_zd, TCG_CALL_NO_WG,
29
void, env, ptr, ptr, ptr, tl, i32)
30
DEF_HELPER_FLAGS_6(sve_stdd_be_zd, TCG_CALL_NO_WG,
31
void, env, ptr, ptr, ptr, tl, i32)
32
+
33
+DEF_HELPER_FLAGS_4(sve2_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
diff --git a/target/arm/helper.h b/target/arm/helper.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/helper.h
37
+++ b/target/arm/helper.h
38
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
39
DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
40
DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
41
DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
42
-DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
43
44
DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
45
DEF_HELPER_2(neon_tst_u16, i32, i32, i32)
46
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
47
DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
48
DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
49
50
+DEF_HELPER_FLAGS_4(neon_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
51
+
52
#ifdef TARGET_AARCH64
53
#include "helper-a64.h"
54
#include "helper-sve.h"
55
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/neon_helper.c
58
+++ b/target/arm/neon_helper.c
59
@@ -XXX,XX +XXX,XX @@ NEON_VOP(mul_u8, neon_u8, 4)
60
NEON_VOP(mul_u16, neon_u16, 2)
61
#undef NEON_FN
62
63
-/* Polynomial multiplication is like integer multiplication except the
64
- partial products are XORed, not added. */
65
-uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
66
-{
67
- uint64_t result = 0;
68
- uint64_t mask;
69
- uint64_t op2ex = op2;
70
- op2ex = (op2ex & 0xff) |
71
- ((op2ex & 0xff00) << 8) |
72
- ((op2ex & 0xff0000) << 16) |
73
- ((op2ex & 0xff000000) << 24);
74
- while (op1) {
75
- mask = 0;
76
- if (op1 & 1) {
77
- mask |= 0xffff;
78
- }
79
- if (op1 & (1 << 8)) {
80
- mask |= (0xffffU << 16);
81
- }
82
- if (op1 & (1 << 16)) {
83
- mask |= (0xffffULL << 32);
84
- }
85
- if (op1 & (1 << 24)) {
86
- mask |= (0xffffULL << 48);
87
- }
88
- result ^= op2ex & mask;
89
- op1 = (op1 >> 1) & 0x7f7f7f7f;
90
- op2ex <<= 1;
91
- }
92
- return result;
93
-}
94
-
95
#define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0
96
NEON_VOP(tst_u8, neon_u8, 4)
97
NEON_VOP(tst_u16, neon_u16, 2)
98
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate-a64.c
101
+++ b/target/arm/translate-a64.c
102
@@ -XXX,XX +XXX,XX @@ static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size,
103
gen_helper_neon_addl_saturate_s32(tcg_passres, cpu_env,
104
tcg_passres, tcg_passres);
105
break;
106
- case 14: /* PMULL */
107
- assert(size == 0);
108
- gen_helper_neon_mull_p8(tcg_passres, tcg_op1, tcg_op2);
109
- break;
110
default:
111
g_assert_not_reached();
112
}
113
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
114
handle_3rd_narrowing(s, is_q, is_u, size, opcode, rd, rn, rm);
115
break;
116
case 14: /* PMULL, PMULL2 */
117
- if (is_u || size == 1 || size == 2) {
118
+ if (is_u) {
119
unallocated_encoding(s);
120
return;
121
}
122
- if (size == 3) {
123
+ switch (size) {
124
+ case 0: /* PMULL.P8 */
125
+ if (!fp_access_check(s)) {
126
+ return;
127
+ }
128
+ /* The Q field specifies lo/hi half input for this insn. */
129
+ gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
130
+ gen_helper_neon_pmull_h);
131
+ break;
132
+
133
+ case 3: /* PMULL.P64 */
134
if (!dc_isar_feature(aa64_pmull, s)) {
135
unallocated_encoding(s);
136
return;
137
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
138
/* The Q field specifies lo/hi half input for this insn. */
139
gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
140
gen_helper_gvec_pmull_q);
141
- return;
142
+ break;
143
+
144
+ default:
145
+ unallocated_encoding(s);
146
+ break;
147
}
148
- goto is_widening;
149
+ return;
150
case 9: /* SQDMLAL, SQDMLAL2 */
151
case 11: /* SQDMLSL, SQDMLSL2 */
152
case 13: /* SQDMULL, SQDMULL2 */
153
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
154
unallocated_encoding(s);
155
return;
156
}
157
- is_widening:
158
if (!fp_access_check(s)) {
159
return;
160
}
161
diff --git a/target/arm/translate.c b/target/arm/translate.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/target/arm/translate.c
164
+++ b/target/arm/translate.c
165
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
166
return 1;
167
}
168
169
- /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
170
- * outside the loop below as it only performs a single pass.
171
- */
172
- if (op == 14 && size == 2) {
173
- if (!dc_isar_feature(aa32_pmull, s)) {
174
- return 1;
175
+ /* Handle polynomial VMULL in a single pass. */
176
+ if (op == 14) {
177
+ if (size == 0) {
178
+ /* VMULL.P8 */
179
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
180
+ 0, gen_helper_neon_pmull_h);
181
+ } else {
182
+ /* VMULL.P64 */
183
+ if (!dc_isar_feature(aa32_pmull, s)) {
184
+ return 1;
185
+ }
186
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
187
+ 0, gen_helper_gvec_pmull_q);
188
}
189
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
190
- 0, gen_helper_gvec_pmull_q);
191
return 0;
192
}
193
194
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
195
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
196
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
197
break;
198
- case 14: /* Polynomial VMULL */
199
- gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
200
- tcg_temp_free_i32(tmp2);
201
- tcg_temp_free_i32(tmp);
202
- break;
203
default: /* 15 is RESERVED: caught earlier */
204
abort();
205
}
206
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
207
index XXXXXXX..XXXXXXX 100644
208
--- a/target/arm/vec_helper.c
209
+++ b/target/arm/vec_helper.c
210
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_pmull_q)(void *vd, void *vn, void *vm, uint32_t desc)
211
}
212
clear_tail(d, opr_sz, simd_maxsz(desc));
213
}
214
+
215
+/*
216
+ * 8x8->16 polynomial multiply.
217
+ *
218
+ * The byte inputs are expanded to (or extracted from) half-words.
219
+ * Note that neon and sve2 get the inputs from different positions.
220
+ * This allows 4 bytes to be processed in parallel with uint64_t.
221
+ */
222
+
223
+static uint64_t expand_byte_to_half(uint64_t x)
224
+{
225
+ return (x & 0x000000ff)
226
+ | ((x & 0x0000ff00) << 8)
227
+ | ((x & 0x00ff0000) << 16)
228
+ | ((x & 0xff000000) << 24);
229
+}
230
+
231
+static uint64_t pmull_h(uint64_t op1, uint64_t op2)
232
+{
233
+ uint64_t result = 0;
234
+ int i;
235
+
236
+ for (i = 0; i < 8; ++i) {
237
+ uint64_t mask = (op1 & 0x0001000100010001ull) * 0xffff;
238
+ result ^= op2 & mask;
239
+ op1 >>= 1;
240
+ op2 <<= 1;
241
+ }
242
+ return result;
243
+}
244
+
245
+void HELPER(neon_pmull_h)(void *vd, void *vn, void *vm, uint32_t desc)
246
+{
247
+ int hi = simd_data(desc);
248
+ uint64_t *d = vd, *n = vn, *m = vm;
249
+ uint64_t nn = n[hi], mm = m[hi];
250
+
251
+ d[0] = pmull_h(expand_byte_to_half(nn), expand_byte_to_half(mm));
252
+ nn >>= 32;
253
+ mm >>= 32;
254
+ d[1] = pmull_h(expand_byte_to_half(nn), expand_byte_to_half(mm));
255
+
256
+ clear_tail(d, 16, simd_maxsz(desc));
257
+}
258
+
259
+#ifdef TARGET_AARCH64
260
+void HELPER(sve2_pmull_h)(void *vd, void *vn, void *vm, uint32_t desc)
261
+{
262
+ int shift = simd_data(desc) * 8;
263
+ intptr_t i, opr_sz = simd_oprsz(desc);
264
+ uint64_t *d = vd, *n = vn, *m = vm;
265
+
266
+ for (i = 0; i < opr_sz / 8; ++i) {
267
+ uint64_t nn = (n[i] >> shift) & 0x00ff00ff00ff00ffull;
268
+ uint64_t mm = (m[i] >> shift) & 0x00ff00ff00ff00ffull;
269
+
270
+ d[i] = pmull_h(nn, mm);
271
+ }
272
+}
273
+#endif
274
--
275
2.20.1
276
277
diff view generated by jsdifflib
New patch
1
From: Francisco Iglesias <francisco.iglesias@xilinx.com>
1
2
3
Correct the number of dummy cycles required by the FAST_READ_4 command (to
4
be eight, one dummy byte).
5
6
Fixes: ef06ca3946 ("xilinx_spips: Add support for RX discard and RX drain")
7
Suggested-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20200218113350.6090-1-frasse.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/ssi/xilinx_spips.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/xilinx_spips.c
19
+++ b/hw/ssi/xilinx_spips.c
20
@@ -XXX,XX +XXX,XX @@ static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, uint8_t command)
21
case FAST_READ:
22
case DOR:
23
case QOR:
24
+ case FAST_READ_4:
25
case DOR_4:
26
case QOR_4:
27
return 1;
28
case DIOR:
29
- case FAST_READ_4:
30
case DIOR_4:
31
return 2;
32
case QIOR:
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
We are still seeing signals during translation time when we walk over
3
Booting the r2d machine from flash fails because flash is not discovered.
4
a page protection boundary. This expands the check to ensure the host
4
Looking at the flattened memory tree, we see the following.
5
PC is inside the code generation buffer. The original suggestion was
6
to check versus tcg_ctx.code_gen_ptr but as we now segment the
7
translation buffer we have to settle for just a general check for
8
being inside.
9
5
10
I've also fixed up the declaration to make it clear it can deal with
6
FlatView #1
11
invalid addresses. A later patch will fix up the call sites.
7
AS "memory", root: system
8
AS "cpu-memory-0", root: system
9
AS "sh_pci_host", root: bus master container
10
Root memory region: system
11
0000000000000000-000000000000ffff (prio 0, i/o): io
12
0000000000010000-0000000000ffffff (prio 0, i/o): r2d.flash @0000000000010000
12
13
13
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
14
The overlapping memory region is sh_pci.isa, ie the ISA I/O region bridge.
14
Reported-by: Peter Maydell <peter.maydell@linaro.org>
15
This region is initially assigned to address 0xfe240000, but overwritten
15
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
16
with a write into the PCIIOBR register. This write is expected to adjust
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
the PCI memory window, but not to change the region's base adddress.
17
Message-id: 20171108153245.20740-2-alex.bennee@linaro.org
18
18
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
19
Peter Maydell provided the following detailed explanation.
19
Cc: Richard Henderson <rth@twiddle.net>
20
20
Tested-by: Peter Maydell <peter.maydell@linaro.org>
21
"Section 22.3.7 and in particular figure 22.3 (of "SSH7751R user's manual:
22
hardware") are clear about how this is supposed to work: there is a window
23
at 0xfe240000 in the system register space for PCI I/O space. When the CPU
24
makes an access into that area, the PCI controller calculates the PCI
25
address to use by combining bits 0..17 of the system address with the
26
bits 31..18 value that the guest has put into the PCIIOBR. That is, writing
27
to the PCIIOBR changes which section of the IO address space is visible in
28
the 0xfe240000 window. Instead what QEMU's implementation does is move the
29
window to whatever value the guest writes to the PCIIOBR register -- so if
30
the guest writes 0 we put the window at 0 in system address space."
31
32
Fix the problem by calling memory_region_set_alias_offset() instead of
33
removing and re-adding the PCI ISA subregion on writes into PCIIOBR.
34
At the same time, in sh_pci_device_realize(), don't set iobr since
35
it is overwritten later anyway. Instead, pass the base address to
36
memory_region_add_subregion() directly.
37
38
Many thanks to Peter Maydell for the detailed problem analysis, and for
39
providing suggestions on how to fix the problem.
40
41
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
42
Message-id: 20200218201050.15273-1-linux@roeck-us.net
43
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
45
---
23
include/exec/exec-all.h | 11 ++++++++++
46
hw/sh4/sh_pci.c | 11 +++--------
24
accel/tcg/translate-all.c | 52 ++++++++++++++++++++++++++---------------------
47
1 file changed, 3 insertions(+), 8 deletions(-)
25
2 files changed, 40 insertions(+), 23 deletions(-)
26
48
27
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
49
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
28
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
29
--- a/include/exec/exec-all.h
51
--- a/hw/sh4/sh_pci.c
30
+++ b/include/exec/exec-all.h
52
+++ b/hw/sh4/sh_pci.c
31
@@ -XXX,XX +XXX,XX @@ void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
53
@@ -XXX,XX +XXX,XX @@ static void sh_pci_reg_write (void *p, hwaddr addr, uint64_t val,
32
target_ulong *data);
54
pcic->mbr = val & 0xff000001;
33
55
break;
34
void cpu_gen_init(void);
56
case 0x1c8:
35
+
57
- if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) {
36
+/**
58
- memory_region_del_subregion(get_system_memory(), &pcic->isa);
37
+ * cpu_restore_state:
59
- pcic->iobr = val & 0xfffc0001;
38
+ * @cpu: the vCPU state is to be restore to
60
- memory_region_add_subregion(get_system_memory(),
39
+ * @searched_pc: the host PC the fault occurred at
61
- pcic->iobr & 0xfffc0000, &pcic->isa);
40
+ * @return: true if state was restored, false otherwise
62
- }
41
+ *
63
+ pcic->iobr = val & 0xfffc0001;
42
+ * Attempt to restore the state for a fault occurring in translated
64
+ memory_region_set_alias_offset(&pcic->isa, val & 0xfffc0000);
43
+ * code. If the searched_pc is not in translated code no state is
65
break;
44
+ * restored and the function returns false.
66
case 0x220:
45
+ */
67
pci_data_write(phb->bus, pcic->par, val, 4);
46
bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc);
68
@@ -XXX,XX +XXX,XX @@ static void sh_pci_device_realize(DeviceState *dev, Error **errp)
47
69
get_system_io(), 0, 0x40000);
48
void QEMU_NORETURN cpu_loop_exit_noexc(CPUState *cpu);
70
sysbus_init_mmio(sbd, &s->memconfig_p4);
49
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
71
sysbus_init_mmio(sbd, &s->memconfig_a7);
50
index XXXXXXX..XXXXXXX 100644
72
- s->iobr = 0xfe240000;
51
--- a/accel/tcg/translate-all.c
73
- memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
52
+++ b/accel/tcg/translate-all.c
74
+ memory_region_add_subregion(get_system_memory(), 0xfe240000, &s->isa);
53
@@ -XXX,XX +XXX,XX @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
75
54
return 0;
76
s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host");
55
}
56
57
-bool cpu_restore_state(CPUState *cpu, uintptr_t retaddr)
58
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
59
{
60
TranslationBlock *tb;
61
bool r = false;
62
+ uintptr_t check_offset;
63
64
- /* A retaddr of zero is invalid so we really shouldn't have ended
65
- * up here. The target code has likely forgotten to check retaddr
66
- * != 0 before attempting to restore state. We return early to
67
- * avoid blowing up on a recursive tb_lock(). The target must have
68
- * previously survived a failed cpu_restore_state because
69
- * tb_find_pc(0) would have failed anyway. It still should be
70
- * fixed though.
71
+ /* The host_pc has to be in the region of current code buffer. If
72
+ * it is not we will not be able to resolve it here. The two cases
73
+ * where host_pc will not be correct are:
74
+ *
75
+ * - fault during translation (instruction fetch)
76
+ * - fault from helper (not using GETPC() macro)
77
+ *
78
+ * Either way we need return early to avoid blowing up on a
79
+ * recursive tb_lock() as we can't resolve it here.
80
+ *
81
+ * We are using unsigned arithmetic so if host_pc <
82
+ * tcg_init_ctx.code_gen_buffer check_offset will wrap to way
83
+ * above the code_gen_buffer_size
84
*/
85
-
86
- if (!retaddr) {
87
- return r;
88
- }
89
-
90
- tb_lock();
91
- tb = tb_find_pc(retaddr);
92
- if (tb) {
93
- cpu_restore_state_from_tb(cpu, tb, retaddr);
94
- if (tb->cflags & CF_NOCACHE) {
95
- /* one-shot translation, invalidate it immediately */
96
- tb_phys_invalidate(tb, -1);
97
- tb_remove(tb);
98
+ check_offset = host_pc - (uintptr_t) tcg_init_ctx.code_gen_buffer;
99
+
100
+ if (check_offset < tcg_init_ctx.code_gen_buffer_size) {
101
+ tb_lock();
102
+ tb = tb_find_pc(host_pc);
103
+ if (tb) {
104
+ cpu_restore_state_from_tb(cpu, tb, host_pc);
105
+ if (tb->cflags & CF_NOCACHE) {
106
+ /* one-shot translation, invalidate it immediately */
107
+ tb_phys_invalidate(tb, -1);
108
+ tb_remove(tb);
109
+ }
110
+ r = true;
111
}
112
- r = true;
113
+ tb_unlock();
114
}
115
- tb_unlock();
116
117
return r;
118
}
77
}
119
--
78
--
120
2.7.4
79
2.20.1
121
80
122
81
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
The old name, isar_feature_aa32_fp_d32, does not reflect
4
the MVFR0 field name, SIMDReg.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20200214181547.21408-3-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
[PMM: wrapped one long line]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/cpu.h | 2 +-
14
target/arm/translate-vfp.inc.c | 53 +++++++++++++++++-----------------
15
2 files changed, 28 insertions(+), 27 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
22
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
23
}
24
25
-static inline bool isar_feature_aa32_fp_d32(const ARMISARegisters *id)
26
+static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id)
27
{
28
/* Return true if D16-D31 are implemented */
29
return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) >= 2;
30
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-vfp.inc.c
33
+++ b/target/arm/translate-vfp.inc.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
35
}
36
37
/* UNDEF accesses to D16-D31 if they don't exist */
38
- if (dp && !dc_isar_feature(aa32_fp_d32, s) &&
39
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
40
((a->vm | a->vn | a->vd) & 0x10)) {
41
return false;
42
}
43
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
44
}
45
46
/* UNDEF accesses to D16-D31 if they don't exist */
47
- if (dp && !dc_isar_feature(aa32_fp_d32, s) &&
48
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
49
((a->vm | a->vn | a->vd) & 0x10)) {
50
return false;
51
}
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
53
}
54
55
/* UNDEF accesses to D16-D31 if they don't exist */
56
- if (dp && !dc_isar_feature(aa32_fp_d32, s) &&
57
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
58
((a->vm | a->vd) & 0x10)) {
59
return false;
60
}
61
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
62
}
63
64
/* UNDEF accesses to D16-D31 if they don't exist */
65
- if (dp && !dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
66
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
67
return false;
68
}
69
70
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
71
uint32_t offset;
72
73
/* UNDEF accesses to D16-D31 if they don't exist */
74
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vn & 0x10)) {
75
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
76
return false;
77
}
78
79
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
80
uint32_t offset;
81
82
/* UNDEF accesses to D16-D31 if they don't exist */
83
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vn & 0x10)) {
84
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
85
return false;
86
}
87
88
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
89
}
90
91
/* UNDEF accesses to D16-D31 if they don't exist */
92
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vn & 0x10)) {
93
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
94
return false;
95
}
96
97
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
98
*/
99
100
/* UNDEF accesses to D16-D31 if they don't exist */
101
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
102
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
103
return false;
104
}
105
106
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
107
TCGv_i64 tmp;
108
109
/* UNDEF accesses to D16-D31 if they don't exist */
110
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
111
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
112
return false;
113
}
114
115
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
116
}
117
118
/* UNDEF accesses to D16-D31 if they don't exist */
119
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd + n) > 16) {
120
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd + n) > 16) {
121
return false;
122
}
123
124
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
125
TCGv_ptr fpst;
126
127
/* UNDEF accesses to D16-D31 if they don't exist */
128
- if (!dc_isar_feature(aa32_fp_d32, s) && ((vd | vn | vm) & 0x10)) {
129
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
130
return false;
131
}
132
133
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
134
TCGv_i64 f0, fd;
135
136
/* UNDEF accesses to D16-D31 if they don't exist */
137
- if (!dc_isar_feature(aa32_fp_d32, s) && ((vd | vm) & 0x10)) {
138
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
139
return false;
140
}
141
142
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
143
}
144
145
/* UNDEF accesses to D16-D31 if they don't exist. */
146
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vn | a->vm) & 0x10)) {
147
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
148
+ ((a->vd | a->vn | a->vm) & 0x10)) {
149
return false;
150
}
151
152
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
153
vd = a->vd;
154
155
/* UNDEF accesses to D16-D31 if they don't exist. */
156
- if (!dc_isar_feature(aa32_fp_d32, s) && (vd & 0x10)) {
157
+ if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
158
return false;
159
}
160
161
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
162
}
163
164
/* UNDEF accesses to D16-D31 if they don't exist. */
165
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
166
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
167
return false;
168
}
169
170
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
171
}
172
173
/* UNDEF accesses to D16-D31 if they don't exist. */
174
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
175
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
176
return false;
177
}
178
179
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
180
}
181
182
/* UNDEF accesses to D16-D31 if they don't exist. */
183
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
184
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
185
return false;
186
}
187
188
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
189
}
190
191
/* UNDEF accesses to D16-D31 if they don't exist. */
192
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
193
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
194
return false;
195
}
196
197
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
198
}
199
200
/* UNDEF accesses to D16-D31 if they don't exist. */
201
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
202
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
203
return false;
204
}
205
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
207
}
208
209
/* UNDEF accesses to D16-D31 if they don't exist. */
210
- if (!dc_isar_feature(aa32_fp_d32, s) && ((a->vd | a->vm) & 0x10)) {
211
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((a->vd | a->vm) & 0x10)) {
212
return false;
213
}
214
215
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
216
TCGv_i32 vm;
217
218
/* UNDEF accesses to D16-D31 if they don't exist. */
219
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
220
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
221
return false;
222
}
223
224
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
225
TCGv_i32 vd;
226
227
/* UNDEF accesses to D16-D31 if they don't exist. */
228
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
229
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
230
return false;
231
}
232
233
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
234
TCGv_ptr fpst;
235
236
/* UNDEF accesses to D16-D31 if they don't exist. */
237
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
238
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
239
return false;
240
}
241
242
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
243
}
244
245
/* UNDEF accesses to D16-D31 if they don't exist. */
246
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
247
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
248
return false;
249
}
250
251
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
252
}
253
254
/* UNDEF accesses to D16-D31 if they don't exist. */
255
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
256
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
257
return false;
258
}
259
260
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
261
TCGv_ptr fpst;
262
263
/* UNDEF accesses to D16-D31 if they don't exist. */
264
- if (!dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
265
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
266
return false;
267
}
268
269
--
270
2.20.1
271
272
diff view generated by jsdifflib
1
From: Subbaraya Sundeep <sundeep.lkml@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Voluntarily add myself as maintainer for Smartfusion2
3
Many uses of ARM_FEATURE_VFP3 are testing for the number of simd
4
registers implemented. Use the proper test vs MVFR0.SIMDReg.
4
5
5
Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
7
Message-id: 20200214181547.21408-4-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
[PMM: fix typo in commit message]
8
Message-id: 1510552520-3566-1-git-send-email-sundeep.lkml@gmail.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
MAINTAINERS | 17 +++++++++++++++++
12
target/arm/cpu.c | 9 ++++-----
12
1 file changed, 17 insertions(+)
13
target/arm/helper.c | 13 ++++++-------
14
target/arm/translate.c | 2 +-
15
3 files changed, 11 insertions(+), 13 deletions(-)
13
16
14
diff --git a/MAINTAINERS b/MAINTAINERS
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/MAINTAINERS
19
--- a/target/arm/cpu.c
17
+++ b/MAINTAINERS
20
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ M: Alistair Francis <alistair@alistair23.me>
21
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
19
S: Maintained
22
20
F: hw/arm/netduino2.c
23
if (flags & CPU_DUMP_FPU) {
21
24
int numvfpregs = 0;
22
+SmartFusion2
25
- if (arm_feature(env, ARM_FEATURE_VFP)) {
23
+M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
26
- numvfpregs += 16;
24
+S: Maintained
27
- }
25
+F: hw/arm/msf2-soc.c
28
- if (arm_feature(env, ARM_FEATURE_VFP3)) {
26
+F: hw/misc/msf2-sysreg.c
29
- numvfpregs += 16;
27
+F: hw/timer/mss-timer.c
30
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
28
+F: hw/ssi/mss-spi.c
31
+ numvfpregs = 32;
29
+F: include/hw/arm/msf2-soc.h
32
+ } else if (arm_feature(env, ARM_FEATURE_VFP)) {
30
+F: include/hw/misc/msf2-sysreg.h
33
+ numvfpregs = 16;
31
+F: include/hw/timer/mss-timer.h
34
}
32
+F: include/hw/ssi/mss-spi.h
35
for (i = 0; i < numvfpregs; i++) {
33
+
36
uint64_t v = *aa32_vfp_dreg(env, i);
34
+Emcraft M2S-FG484
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
35
+M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
38
index XXXXXXX..XXXXXXX 100644
36
+S: Maintained
39
--- a/target/arm/helper.c
37
+F: hw/arm/msf2-som.c
40
+++ b/target/arm/helper.c
38
+
41
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode);
39
CRIS Machines
42
40
-------------
43
static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
41
Axis Dev88
44
{
45
- int nregs;
46
+ ARMCPU *cpu = env_archcpu(env);
47
+ int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
48
49
/* VFP data registers are always little-endian. */
50
- nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
51
if (reg < nregs) {
52
stq_le_p(buf, *aa32_vfp_dreg(env, reg));
53
return 8;
54
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
55
56
static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
57
{
58
- int nregs;
59
+ ARMCPU *cpu = env_archcpu(env);
60
+ int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
61
62
- nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
63
if (reg < nregs) {
64
*aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
65
return 8;
66
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
67
/* VFPv3 and upwards with NEON implement 32 double precision
68
* registers (D0-D31).
69
*/
70
- if (!arm_feature(env, ARM_FEATURE_NEON) ||
71
- !arm_feature(env, ARM_FEATURE_VFP3)) {
72
+ if (!cpu_isar_feature(aa32_simd_r32, env_archcpu(env))) {
73
/* D32DIS [30] is RAO/WI if D16-31 are not implemented. */
74
value |= (1 << 30);
75
}
76
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
77
} else if (arm_feature(env, ARM_FEATURE_NEON)) {
78
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
79
51, "arm-neon.xml", 0);
80
- } else if (arm_feature(env, ARM_FEATURE_VFP3)) {
81
+ } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
82
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
83
35, "arm-vfp3.xml", 0);
84
} else if (arm_feature(env, ARM_FEATURE_VFP)) {
85
diff --git a/target/arm/translate.c b/target/arm/translate.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/translate.c
88
+++ b/target/arm/translate.c
89
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
90
#define VFP_SREG(insn, bigbit, smallbit) \
91
((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
92
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
93
- if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
94
+ if (dc_isar_feature(aa32_simd_r32, s)) { \
95
reg = (((insn) >> (bigbit)) & 0x0f) \
96
| (((insn) >> ((smallbit) - 4)) & 0x10); \
97
} else { \
42
--
98
--
43
2.7.4
99
2.20.1
44
100
45
101
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The EP108 was an early access development board that is no longer used.
3
We are going to convert FEATURE tests to ISAR tests,
4
Add an info message to convert any users to the ZCU102 instead. On QEMU
4
so FPSP needs to be set for these cpus, like we have
5
they are both identical.
5
already for FPDP.
6
6
7
This patch also updated the qemu-doc.texi file to indicate that the
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
EP108 has been deprecated.
8
Message-id: 20200214181547.21408-5-richard.henderson@linaro.org
9
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
11
Reviewed-by: Emilio G. Cota <cota@braap.org>
12
Message-id: 1510343626-25861-4-git-send-email-cota@braap.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
hw/arm/xlnx-zcu102.c | 3 +++
12
target/arm/cpu.c | 10 ++++++----
16
qemu-doc.texi | 7 +++++++
13
1 file changed, 6 insertions(+), 4 deletions(-)
17
2 files changed, 10 insertions(+)
18
14
19
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/xlnx-zcu102.c
17
--- a/target/arm/cpu.c
22
+++ b/hw/arm/xlnx-zcu102.c
18
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void xlnx_ep108_init(MachineState *machine)
19
@@ -XXX,XX +XXX,XX @@ static void arm926_initfn(Object *obj)
24
{
20
*/
25
XlnxZCU102 *s = EP108_MACHINE(machine);
21
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
26
22
/*
27
+ info_report("The Xilinx EP108 machine is deprecated, please use the "
23
- * Similarly, we need to set MVFR0 fields to enable double precision
28
+ "ZCU102 machine instead. It has the same features supported.");
24
- * and short vector support even though ARMv5 doesn't have this register.
29
+
25
+ * Similarly, we need to set MVFR0 fields to enable vfp and short vector
30
xlnx_zynqmp_init(s, machine);
26
+ * support even though ARMv5 doesn't have this register.
27
*/
28
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
29
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
30
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
31
}
31
}
32
32
33
diff --git a/qemu-doc.texi b/qemu-doc.texi
33
@@ -XXX,XX +XXX,XX @@ static void arm1026_initfn(Object *obj)
34
index XXXXXXX..XXXXXXX 100644
34
*/
35
--- a/qemu-doc.texi
35
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
36
+++ b/qemu-doc.texi
36
/*
37
@@ -XXX,XX +XXX,XX @@ or ``ivshmem-doorbell`` device types.
37
- * Similarly, we need to set MVFR0 fields to enable double precision
38
The ``spapr-pci-vfio-host-bridge'' device type is replaced by
38
- * and short vector support even though ARMv5 doesn't have this register.
39
the ``spapr-pci-host-bridge'' device type.
39
+ * Similarly, we need to set MVFR0 fields to enable vfp and short vector
40
40
+ * support even though ARMv5 doesn't have this register.
41
+@section System emulator machines
41
*/
42
+
42
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
43
+@subsection Xilinx EP108 (since 2.11.0)
43
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
44
+
44
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
45
+The ``xlnx-ep108'' machine has been replaced by the ``xlnx-zcu102'' machine.
45
46
+The ``xlnx-zcu102'' machine has the same features and capabilites in QEMU.
46
{
47
+
48
@node License
49
@appendix License
50
51
--
47
--
52
2.7.4
48
2.20.1
53
49
54
50
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Use this in the places that were checking ARM_FEATURE_VFP, and
4
are obviously testing for the existance of the register set
5
as opposed to testing for some particular instruction extension.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200214181547.21408-6-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 6 ++++++
13
hw/intc/armv7m_nvic.c | 20 ++++++++++----------
14
linux-user/arm/signal.c | 4 ++--
15
target/arm/arch_dump.c | 11 ++++++-----
16
target/arm/cpu.c | 8 ++++----
17
target/arm/helper.c | 4 ++--
18
target/arm/m_helper.c | 11 ++++++-----
19
target/arm/machine.c | 3 +--
20
8 files changed, 37 insertions(+), 30 deletions(-)
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
27
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
28
}
29
30
+static inline bool isar_feature_aa32_simd_r16(const ARMISARegisters *id)
31
+{
32
+ /* Return true if D0-D15 are implemented */
33
+ return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) > 0;
34
+}
35
+
36
static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id)
37
{
38
/* Return true if D16-D31 are implemented */
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/armv7m_nvic.c
42
+++ b/hw/intc/armv7m_nvic.c
43
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
44
case 0xd84: /* CSSELR */
45
return cpu->env.v7m.csselr[attrs.secure];
46
case 0xd88: /* CPACR */
47
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
48
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
49
return 0;
50
}
51
return cpu->env.v7m.cpacr[attrs.secure];
52
case 0xd8c: /* NSACR */
53
- if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
54
+ if (!attrs.secure || !cpu_isar_feature(aa32_simd_r16, cpu)) {
55
return 0;
56
}
57
return cpu->env.v7m.nsacr;
58
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
59
}
60
return cpu->env.v7m.sfar;
61
case 0xf34: /* FPCCR */
62
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
63
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
64
return 0;
65
}
66
if (attrs.secure) {
67
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
68
return value;
69
}
70
case 0xf38: /* FPCAR */
71
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
72
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
73
return 0;
74
}
75
return cpu->env.v7m.fpcar[attrs.secure];
76
case 0xf3c: /* FPDSCR */
77
- if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
78
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
79
return 0;
80
}
81
return cpu->env.v7m.fpdscr[attrs.secure];
82
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
83
}
84
break;
85
case 0xd88: /* CPACR */
86
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
87
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
88
/* We implement only the Floating Point extension's CP10/CP11 */
89
cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
90
}
91
break;
92
case 0xd8c: /* NSACR */
93
- if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
94
+ if (attrs.secure && cpu_isar_feature(aa32_simd_r16, cpu)) {
95
/* We implement only the Floating Point extension's CP10/CP11 */
96
cpu->env.v7m.nsacr = value & (3 << 10);
97
}
98
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
99
break;
100
}
101
case 0xf34: /* FPCCR */
102
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
103
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
104
/* Not all bits here are banked. */
105
uint32_t fpccr_s;
106
107
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
108
}
109
break;
110
case 0xf38: /* FPCAR */
111
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
112
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
113
value &= ~7;
114
cpu->env.v7m.fpcar[attrs.secure] = value;
115
}
116
break;
117
case 0xf3c: /* FPDSCR */
118
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
119
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
120
value &= 0x07c00000;
121
cpu->env.v7m.fpdscr[attrs.secure] = value;
122
}
123
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/linux-user/arm/signal.c
126
+++ b/linux-user/arm/signal.c
127
@@ -XXX,XX +XXX,XX @@ static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
128
setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
129
/* Save coprocessor signal frame. */
130
regspace = uc->tuc_regspace;
131
- if (arm_feature(env, ARM_FEATURE_VFP)) {
132
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
133
regspace = setup_sigframe_v2_vfp(regspace, env);
134
}
135
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
136
@@ -XXX,XX +XXX,XX @@ static int do_sigframe_return_v2(CPUARMState *env,
137
138
/* Restore coprocessor signal frame */
139
regspace = uc->tuc_regspace;
140
- if (arm_feature(env, ARM_FEATURE_VFP)) {
141
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
142
regspace = restore_sigframe_v2_vfp(env, regspace);
143
if (!regspace) {
144
return 1;
145
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/arch_dump.c
148
+++ b/target/arm/arch_dump.c
149
@@ -XXX,XX +XXX,XX @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
150
int cpuid, void *opaque)
151
{
152
struct arm_note note;
153
- CPUARMState *env = &ARM_CPU(cs)->env;
154
+ ARMCPU *cpu = ARM_CPU(cs);
155
+ CPUARMState *env = &cpu->env;
156
DumpState *s = opaque;
157
- int ret, i, fpvalid = !!arm_feature(env, ARM_FEATURE_VFP);
158
+ int ret, i;
159
+ bool fpvalid = cpu_isar_feature(aa32_simd_r16, cpu);
160
161
arm_note_init(&note, s, "CORE", 5, NT_PRSTATUS, sizeof(note.prstatus));
162
163
@@ -XXX,XX +XXX,XX @@ int cpu_get_dump_info(ArchDumpInfo *info,
164
ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
165
{
166
ARMCPU *cpu = ARM_CPU(first_cpu);
167
- CPUARMState *env = &cpu->env;
168
size_t note_size;
169
170
if (class == ELFCLASS64) {
171
@@ -XXX,XX +XXX,XX @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
172
note_size += AARCH64_PRFPREG_NOTE_SIZE;
173
#ifdef TARGET_AARCH64
174
if (cpu_isar_feature(aa64_sve, cpu)) {
175
- note_size += AARCH64_SVE_NOTE_SIZE(env);
176
+ note_size += AARCH64_SVE_NOTE_SIZE(&cpu->env);
177
}
178
#endif
179
} else {
180
note_size = ARM_PRSTATUS_NOTE_SIZE;
181
- if (arm_feature(env, ARM_FEATURE_VFP)) {
182
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
183
note_size += ARM_VFP_NOTE_SIZE;
184
}
185
}
186
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/target/arm/cpu.c
189
+++ b/target/arm/cpu.c
190
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
191
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
192
}
193
194
- if (arm_feature(env, ARM_FEATURE_VFP)) {
195
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
196
env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
197
env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
198
R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
199
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
200
int numvfpregs = 0;
201
if (cpu_isar_feature(aa32_simd_r32, cpu)) {
202
numvfpregs = 32;
203
- } else if (arm_feature(env, ARM_FEATURE_VFP)) {
204
+ } else if (cpu_isar_feature(aa32_simd_r16, cpu)) {
205
numvfpregs = 16;
206
}
207
for (i = 0; i < numvfpregs; i++) {
208
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
209
* KVM does not currently allow us to lie to the guest about its
210
* ID/feature registers, so the guest always sees what the host has.
211
*/
212
- if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
213
+ if (cpu_isar_feature(aa32_simd_r16, cpu)) {
214
cpu->has_vfp = true;
215
if (!kvm_enabled()) {
216
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property);
217
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
218
* We rely on no XScale CPU having VFP so we can use the same bits in the
219
* TB flags field for VECSTRIDE and XSCALE_CPAR.
220
*/
221
- assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
222
+ assert(!(cpu_isar_feature(aa32_simd_r16, cpu) &&
223
arm_feature(env, ARM_FEATURE_XSCALE)));
224
225
if (arm_feature(env, ARM_FEATURE_V7) &&
226
diff --git a/target/arm/helper.c b/target/arm/helper.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/target/arm/helper.c
229
+++ b/target/arm/helper.c
230
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
231
* ASEDIS [31] and D32DIS [30] are both UNK/SBZP without VFP.
232
* TRCDIS [28] is RAZ/WI since we do not implement a trace macrocell.
233
*/
234
- if (arm_feature(env, ARM_FEATURE_VFP)) {
235
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
236
/* VFP coprocessor: cp10 & cp11 [23:20] */
237
mask |= (1 << 31) | (1 << 30) | (0xf << 20);
238
239
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
240
} else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
241
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
242
35, "arm-vfp3.xml", 0);
243
- } else if (arm_feature(env, ARM_FEATURE_VFP)) {
244
+ } else if (cpu_isar_feature(aa32_simd_r16, cpu)) {
245
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
246
19, "arm-vfp.xml", 0);
247
}
248
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
249
index XXXXXXX..XXXXXXX 100644
250
--- a/target/arm/m_helper.c
251
+++ b/target/arm/m_helper.c
252
@@ -XXX,XX +XXX,XX @@ static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
253
*/
254
uint32_t sig = 0xfefa125a;
255
256
- if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
257
+ if (!cpu_isar_feature(aa32_simd_r16, env_archcpu(env))
258
+ || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
259
sig |= 1;
260
}
261
return sig;
262
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
263
264
if (dotailchain) {
265
/* Sanitize LR FType and PREFIX bits */
266
- if (!arm_feature(env, ARM_FEATURE_VFP)) {
267
+ if (!cpu_isar_feature(aa32_simd_r16, cpu)) {
268
lr |= R_V7M_EXCRET_FTYPE_MASK;
269
}
270
lr = deposit32(lr, 24, 8, 0xff);
271
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
272
273
ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
274
275
- if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
276
+ if (!ftype && !cpu_isar_feature(aa32_simd_r16, cpu)) {
277
qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
278
"exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
279
"if FPU not present\n",
280
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
281
* SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
282
* RES0 if the FPU is not present, and is stored in the S bank
283
*/
284
- if (arm_feature(env, ARM_FEATURE_VFP) &&
285
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env)) &&
286
extract32(env->v7m.nsacr, 10, 1)) {
287
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
288
env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
289
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
290
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
291
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
292
}
293
- if (arm_feature(env, ARM_FEATURE_VFP)) {
294
+ if (cpu_isar_feature(aa32_simd_r16, env_archcpu(env))) {
295
/*
296
* SFPA is RAZ/WI from NS or if no FPU.
297
* FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
298
diff --git a/target/arm/machine.c b/target/arm/machine.c
299
index XXXXXXX..XXXXXXX 100644
300
--- a/target/arm/machine.c
301
+++ b/target/arm/machine.c
302
@@ -XXX,XX +XXX,XX @@
303
static bool vfp_needed(void *opaque)
304
{
305
ARMCPU *cpu = opaque;
306
- CPUARMState *env = &cpu->env;
307
308
- return arm_feature(env, ARM_FEATURE_VFP);
309
+ return cpu_isar_feature(aa32_simd_r16, cpu);
310
}
311
312
static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
313
--
314
2.20.1
315
316
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
The old name, isar_feature_aa32_fpdp, does not reflect
4
that the test includes VFPv2. We will introduce further
5
feature tests for VFPv3.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20200214181547.21408-7-richard.henderson@linaro.org
10
[PMM: fixed grammar in commit message]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/cpu.h | 4 ++--
15
target/arm/translate-vfp.inc.c | 40 +++++++++++++++++-----------------
16
2 files changed, 22 insertions(+), 22 deletions(-)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
23
return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
24
}
25
26
-static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
27
+static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
28
{
29
- /* Return true if CPU supports double precision floating point */
30
+ /* Return true if CPU supports double precision floating point, VFPv2 */
31
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
32
}
33
34
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-vfp.inc.c
37
+++ b/target/arm/translate-vfp.inc.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
39
return false;
40
}
41
42
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
43
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
44
return false;
45
}
46
47
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
48
return false;
49
}
50
51
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
52
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
53
return false;
54
}
55
56
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
57
return false;
58
}
59
60
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
61
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
62
return false;
63
}
64
65
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
66
return false;
67
}
68
69
- if (dp && !dc_isar_feature(aa32_fpdp, s)) {
70
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
71
return false;
72
}
73
74
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
75
return false;
76
}
77
78
- if (!dc_isar_feature(aa32_fpdp, s)) {
79
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
80
return false;
81
}
82
83
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
84
return false;
85
}
86
87
- if (!dc_isar_feature(aa32_fpdp, s)) {
88
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
89
return false;
90
}
91
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
93
return false;
94
}
95
96
- if (!dc_isar_feature(aa32_fpdp, s)) {
97
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
98
return false;
99
}
100
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
102
return false;
103
}
104
105
- if (!dc_isar_feature(aa32_fpdp, s)) {
106
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
107
return false;
108
}
109
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
111
return false;
112
}
113
114
- if (!dc_isar_feature(aa32_fpdp, s)) {
115
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
116
return false;
117
}
118
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
120
return false;
121
}
122
123
- if (!dc_isar_feature(aa32_fpdp, s)) {
124
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
125
return false;
126
}
127
128
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
129
return false;
130
}
131
132
- if (!dc_isar_feature(aa32_fpdp, s)) {
133
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
134
return false;
135
}
136
137
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
138
return false;
139
}
140
141
- if (!dc_isar_feature(aa32_fpdp, s)) {
142
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
143
return false;
144
}
145
146
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
147
return false;
148
}
149
150
- if (!dc_isar_feature(aa32_fpdp, s)) {
151
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
152
return false;
153
}
154
155
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
156
return false;
157
}
158
159
- if (!dc_isar_feature(aa32_fpdp, s)) {
160
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
161
return false;
162
}
163
164
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
165
return false;
166
}
167
168
- if (!dc_isar_feature(aa32_fpdp, s)) {
169
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
170
return false;
171
}
172
173
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
174
return false;
175
}
176
177
- if (!dc_isar_feature(aa32_fpdp, s)) {
178
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
179
return false;
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
183
return false;
184
}
185
186
- if (!dc_isar_feature(aa32_fpdp, s)) {
187
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
188
return false;
189
}
190
191
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
192
return false;
193
}
194
195
- if (!dc_isar_feature(aa32_fpdp, s)) {
196
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
197
return false;
198
}
199
200
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
201
return false;
202
}
203
204
- if (!dc_isar_feature(aa32_fpdp, s)) {
205
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
206
return false;
207
}
208
209
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
210
return false;
211
}
212
213
- if (!dc_isar_feature(aa32_fpdp, s)) {
214
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
215
return false;
216
}
217
218
--
219
2.20.1
220
221
diff view generated by jsdifflib
1
From: Prasad J Pandit <pjp@fedoraproject.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
An 'offset' parameter sent to highbank register r/w functions
3
We will shortly use these to test for VFPv2 and VFPv3
4
could be greater than number(NUM_REGS=0x200) of hb registers,
4
in different situations.
5
leading to an OOB access issue. Add check to avoid it.
6
5
7
Reported-by: Moguofang (Dennis mo) <moguofang@huawei.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
7
Message-id: 20200214181547.21408-8-richard.henderson@linaro.org
9
Message-id: 20171113062658.9697-1-ppandit@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
hw/arm/highbank.c | 17 +++++++++++++++--
11
target/arm/cpu.h | 18 ++++++++++++++++++
14
1 file changed, 15 insertions(+), 2 deletions(-)
12
1 file changed, 18 insertions(+)
15
13
16
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/highbank.c
16
--- a/target/arm/cpu.h
19
+++ b/hw/arm/highbank.c
17
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
21
#include "hw/ide/ahci.h"
19
return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
22
#include "hw/cpu/a9mpcore.h"
23
#include "hw/cpu/a15mpcore.h"
24
+#include "qemu/log.h"
25
26
#define SMP_BOOT_ADDR 0x100
27
#define SMP_BOOT_REG 0x40
28
@@ -XXX,XX +XXX,XX @@ static void hb_regs_write(void *opaque, hwaddr offset,
29
}
30
}
31
32
- regs[offset/4] = value;
33
+ if (offset / 4 >= NUM_REGS) {
34
+ qemu_log_mask(LOG_GUEST_ERROR,
35
+ "highbank: bad write offset 0x%" HWADDR_PRIx "\n", offset);
36
+ return;
37
+ }
38
+ regs[offset / 4] = value;
39
}
20
}
40
21
41
static uint64_t hb_regs_read(void *opaque, hwaddr offset,
22
+static inline bool isar_feature_aa32_fpsp_v2(const ARMISARegisters *id)
42
unsigned size)
23
+{
24
+ /* Return true if CPU supports single precision floating point, VFPv2 */
25
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) > 0;
26
+}
27
+
28
+static inline bool isar_feature_aa32_fpsp_v3(const ARMISARegisters *id)
29
+{
30
+ /* Return true if CPU supports single precision floating point, VFPv3 */
31
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) >= 2;
32
+}
33
+
34
static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
43
{
35
{
44
+ uint32_t value;
36
/* Return true if CPU supports double precision floating point, VFPv2 */
45
uint32_t *regs = opaque;
37
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
46
- uint32_t value = regs[offset/4];
38
}
39
40
+static inline bool isar_feature_aa32_fpdp_v3(const ARMISARegisters *id)
41
+{
42
+ /* Return true if CPU supports double precision floating point, VFPv3 */
43
+ return FIELD_EX32(id->mvfr0, MVFR0, FPDP) >= 2;
44
+}
47
+
45
+
48
+ if (offset / 4 >= NUM_REGS) {
46
/*
49
+ qemu_log_mask(LOG_GUEST_ERROR,
47
* We always set the FP and SIMD FP16 fields to indicate identical
50
+ "highbank: bad read offset 0x%" HWADDR_PRIx "\n", offset);
48
* levels of support (assuming SIMD is implemented at all), so
51
+ return 0;
52
+ }
53
+ value = regs[offset / 4];
54
55
if ((offset == 0x100) || (offset == 0x108) || (offset == 0x10C)) {
56
value |= 0x30000000;
57
--
49
--
58
2.7.4
50
2.20.1
59
51
60
52
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Shuffle the order of the checks so that we test the ISA
4
before we test anything else, such as the register arguments.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200214181547.21408-9-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-vfp.inc.c | 144 ++++++++++++++++-----------------
12
1 file changed, 72 insertions(+), 72 deletions(-)
13
14
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-vfp.inc.c
17
+++ b/target/arm/translate-vfp.inc.c
18
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
19
return false;
20
}
21
22
- /* UNDEF accesses to D16-D31 if they don't exist */
23
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
24
- ((a->vm | a->vn | a->vd) & 0x10)) {
25
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
26
return false;
27
}
28
29
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
30
+ /* UNDEF accesses to D16-D31 if they don't exist */
31
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
32
+ ((a->vm | a->vn | a->vd) & 0x10)) {
33
return false;
34
}
35
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
37
return false;
38
}
39
40
- /* UNDEF accesses to D16-D31 if they don't exist */
41
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
42
- ((a->vm | a->vn | a->vd) & 0x10)) {
43
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
44
return false;
45
}
46
47
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
49
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
50
+ ((a->vm | a->vn | a->vd) & 0x10)) {
51
return false;
52
}
53
54
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
55
return false;
56
}
57
58
- /* UNDEF accesses to D16-D31 if they don't exist */
59
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
60
- ((a->vm | a->vd) & 0x10)) {
61
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
62
return false;
63
}
64
65
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
66
+ /* UNDEF accesses to D16-D31 if they don't exist */
67
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
68
+ ((a->vm | a->vd) & 0x10)) {
69
return false;
70
}
71
72
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
73
return false;
74
}
75
76
- /* UNDEF accesses to D16-D31 if they don't exist */
77
- if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
78
+ if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
79
return false;
80
}
81
82
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
83
+ /* UNDEF accesses to D16-D31 if they don't exist */
84
+ if (dp && !dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
85
return false;
86
}
87
88
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
89
TCGv_i64 f0, f1, fd;
90
TCGv_ptr fpst;
91
92
- /* UNDEF accesses to D16-D31 if they don't exist */
93
- if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
94
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
95
return false;
96
}
97
98
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
99
+ /* UNDEF accesses to D16-D31 if they don't exist */
100
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vn | vm) & 0x10)) {
101
return false;
102
}
103
104
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
105
int veclen = s->vec_len;
106
TCGv_i64 f0, fd;
107
108
- /* UNDEF accesses to D16-D31 if they don't exist */
109
- if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
110
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
111
return false;
112
}
113
114
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
115
+ /* UNDEF accesses to D16-D31 if they don't exist */
116
+ if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
117
return false;
118
}
119
120
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
121
return false;
122
}
123
124
- /* UNDEF accesses to D16-D31 if they don't exist. */
125
- if (!dc_isar_feature(aa32_simd_r32, s) &&
126
- ((a->vd | a->vn | a->vm) & 0x10)) {
127
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
128
return false;
129
}
130
131
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
132
+ /* UNDEF accesses to D16-D31 if they don't exist. */
133
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
134
+ ((a->vd | a->vn | a->vm) & 0x10)) {
135
return false;
136
}
137
138
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
139
140
vd = a->vd;
141
142
- /* UNDEF accesses to D16-D31 if they don't exist. */
143
- if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
144
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
145
return false;
146
}
147
148
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
149
+ /* UNDEF accesses to D16-D31 if they don't exist. */
150
+ if (!dc_isar_feature(aa32_simd_r32, s) && (vd & 0x10)) {
151
return false;
152
}
153
154
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
155
{
156
TCGv_i64 vd, vm;
157
158
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
159
+ return false;
160
+ }
161
+
162
/* Vm/M bits must be zero for the Z variant */
163
if (a->z && a->vm != 0) {
164
return false;
165
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
166
return false;
167
}
168
169
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
170
- return false;
171
- }
172
-
173
if (!vfp_access_check(s)) {
174
return true;
175
}
176
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
177
TCGv_i32 tmp;
178
TCGv_i64 vd;
179
180
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
181
+ return false;
182
+ }
183
+
184
if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
185
return false;
186
}
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
188
return false;
189
}
190
191
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
192
- return false;
193
- }
194
-
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
199
TCGv_i32 tmp;
200
TCGv_i64 vm;
201
202
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
203
+ return false;
204
+ }
205
+
206
if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
207
return false;
208
}
209
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
210
return false;
211
}
212
213
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
214
- return false;
215
- }
216
-
217
if (!vfp_access_check(s)) {
218
return true;
219
}
220
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
221
TCGv_ptr fpst;
222
TCGv_i64 tmp;
223
224
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
225
+ return false;
226
+ }
227
+
228
if (!dc_isar_feature(aa32_vrint, s)) {
229
return false;
230
}
231
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
232
return false;
233
}
234
235
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
236
- return false;
237
- }
238
-
239
if (!vfp_access_check(s)) {
240
return true;
241
}
242
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
243
TCGv_i64 tmp;
244
TCGv_i32 tcg_rmode;
245
246
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
247
+ return false;
248
+ }
249
+
250
if (!dc_isar_feature(aa32_vrint, s)) {
251
return false;
252
}
253
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
254
return false;
255
}
256
257
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
258
- return false;
259
- }
260
-
261
if (!vfp_access_check(s)) {
262
return true;
263
}
264
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
265
TCGv_ptr fpst;
266
TCGv_i64 tmp;
267
268
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
269
+ return false;
270
+ }
271
+
272
if (!dc_isar_feature(aa32_vrint, s)) {
273
return false;
274
}
275
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
276
return false;
277
}
278
279
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
280
- return false;
281
- }
282
-
283
if (!vfp_access_check(s)) {
284
return true;
285
}
286
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
287
TCGv_i64 vd;
288
TCGv_i32 vm;
289
290
- /* UNDEF accesses to D16-D31 if they don't exist. */
291
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
292
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
293
return false;
294
}
295
296
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
297
+ /* UNDEF accesses to D16-D31 if they don't exist. */
298
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
299
return false;
300
}
301
302
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
303
TCGv_i64 vm;
304
TCGv_i32 vd;
305
306
- /* UNDEF accesses to D16-D31 if they don't exist. */
307
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
308
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
309
return false;
310
}
311
312
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
313
+ /* UNDEF accesses to D16-D31 if they don't exist. */
314
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
315
return false;
316
}
317
318
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
319
TCGv_i64 vd;
320
TCGv_ptr fpst;
321
322
- /* UNDEF accesses to D16-D31 if they don't exist. */
323
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
324
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
325
return false;
326
}
327
328
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
329
+ /* UNDEF accesses to D16-D31 if they don't exist. */
330
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
331
return false;
332
}
333
334
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
335
TCGv_i32 vd;
336
TCGv_i64 vm;
337
338
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
339
+ return false;
340
+ }
341
+
342
if (!dc_isar_feature(aa32_jscvt, s)) {
343
return false;
344
}
345
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
346
return false;
347
}
348
349
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
350
- return false;
351
- }
352
-
353
if (!vfp_access_check(s)) {
354
return true;
355
}
356
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
357
TCGv_ptr fpst;
358
int frac_bits;
359
360
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
361
+ return false;
362
+ }
363
+
364
if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
365
return false;
366
}
367
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
368
return false;
369
}
370
371
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
372
- return false;
373
- }
374
-
375
if (!vfp_access_check(s)) {
376
return true;
377
}
378
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
379
TCGv_i64 vm;
380
TCGv_ptr fpst;
381
382
- /* UNDEF accesses to D16-D31 if they don't exist. */
383
- if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
384
+ if (!dc_isar_feature(aa32_fpdp_v2, s)) {
385
return false;
386
}
387
388
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
389
+ /* UNDEF accesses to D16-D31 if they don't exist. */
390
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
391
return false;
392
}
393
394
--
395
2.20.1
396
397
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Allow the -smp command line option to control the number of CPUs we
3
Sort this check to the start of a trans_* function.
4
create.
4
Merge this with any existing test for fpdp_v2.
5
5
6
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
7
Message-id: 20200214181547.21408-10-richard.henderson@linaro.org
8
Reviewed-by: Emilio G. Cota <cota@braap.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Tested-by: Emilio G. Cota <cota@braap.org>
10
Message-id: 1510343626-25861-3-git-send-email-cota@braap.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
hw/arm/xlnx-zcu102.c | 3 ++-
11
target/arm/translate-vfp.inc.c | 24 ++++++++----------------
14
hw/arm/xlnx-zynqmp.c | 26 ++++++++++++++++----------
12
1 file changed, 8 insertions(+), 16 deletions(-)
15
2 files changed, 18 insertions(+), 11 deletions(-)
16
13
17
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
14
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/xlnx-zcu102.c
16
--- a/target/arm/translate-vfp.inc.c
20
+++ b/hw/arm/xlnx-zcu102.c
17
+++ b/target/arm/translate-vfp.inc.c
21
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
18
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
22
{
19
* VFPv2 allows access to FPSID from userspace; VFPv3 restricts
23
MachineClass *mc = MACHINE_CLASS(oc);
20
* all ID registers to privileged access only.
24
21
*/
25
- mc->desc = "Xilinx ZynqMP ZCU102 board";
22
- if (IS_USER(s) && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
26
+ mc->desc = "Xilinx ZynqMP ZCU102 board with 4xA53s and 2xR5s based on " \
23
+ if (IS_USER(s) && dc_isar_feature(aa32_fpsp_v3, s)) {
27
+ "the value of smp";
24
return false;
28
mc->init = xlnx_zcu102_init;
29
mc->block_default_type = IF_IDE;
30
mc->units_per_default_bus = 1;
31
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/xlnx-zynqmp.c
34
+++ b/hw/arm/xlnx-zynqmp.c
35
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_rpu(XlnxZynqMPState *s, const char *boot_cpu,
36
{
37
Error *err = NULL;
38
int i;
39
+ int num_rpus = MIN(smp_cpus - XLNX_ZYNQMP_NUM_APU_CPUS, XLNX_ZYNQMP_NUM_RPU_CPUS);
40
41
- for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) {
42
+ for (i = 0; i < num_rpus; i++) {
43
char *name;
44
45
object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]),
46
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(Object *obj)
47
{
48
XlnxZynqMPState *s = XLNX_ZYNQMP(obj);
49
int i;
50
+ int num_apus = MIN(smp_cpus, XLNX_ZYNQMP_NUM_APU_CPUS);
51
52
- for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
53
+ for (i = 0; i < num_apus; i++) {
54
object_initialize(&s->apu_cpu[i], sizeof(s->apu_cpu[i]),
55
"cortex-a53-" TYPE_ARM_CPU);
56
object_property_add_child(obj, "apu-cpu[*]", OBJECT(&s->apu_cpu[i]),
57
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
58
MemoryRegion *system_memory = get_system_memory();
59
uint8_t i;
60
uint64_t ram_size;
61
+ int num_apus = MIN(smp_cpus, XLNX_ZYNQMP_NUM_APU_CPUS);
62
const char *boot_cpu = s->boot_cpu ? s->boot_cpu : "apu-cpu[0]";
63
ram_addr_t ddr_low_size, ddr_high_size;
64
qemu_irq gic_spi[GIC_NUM_SPI_INTR];
65
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
66
67
qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32);
68
qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2);
69
- qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", XLNX_ZYNQMP_NUM_APU_CPUS);
70
+ qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", num_apus);
71
72
/* Realize APUs before realizing the GIC. KVM requires this. */
73
- for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
74
+ for (i = 0; i < num_apus; i++) {
75
char *name;
76
77
object_property_set_int(OBJECT(&s->apu_cpu[i]), QEMU_PSCI_CONDUIT_SMC,
78
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
79
}
25
}
26
ignore_vfp_enabled = true;
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
28
case ARM_VFP_FPINST:
29
case ARM_VFP_FPINST2:
30
/* Not present in VFPv3 */
31
- if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
32
+ if (IS_USER(s) || dc_isar_feature(aa32_fpsp_v3, s)) {
33
return false;
34
}
35
break;
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
37
38
vd = a->vd;
39
40
- if (!dc_isar_feature(aa32_fpshvec, s) &&
41
- (veclen != 0 || s->vec_stride != 0)) {
42
+ if (!dc_isar_feature(aa32_fpsp_v3, s)) {
43
return false;
80
}
44
}
81
45
82
- for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
46
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
83
+ for (i = 0; i < num_apus; i++) {
47
+ if (!dc_isar_feature(aa32_fpshvec, s) &&
84
qemu_irq irq;
48
+ (veclen != 0 || s->vec_stride != 0)) {
85
49
return false;
86
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i,
87
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
88
}
50
}
89
51
90
if (s->has_rpu) {
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
91
- xlnx_zynqmp_create_rpu(s, boot_cpu, &err);
53
92
- if (err) {
54
vd = a->vd;
93
- error_propagate(errp, err);
55
94
- return;
56
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
95
- }
57
+ if (!dc_isar_feature(aa32_fpdp_v3, s)) {
96
+ info_report("The 'has_rpu' property is no longer required, to use the "
58
return false;
97
+ "RPUs just use -smp 6.");
98
+ }
99
+
100
+ xlnx_zynqmp_create_rpu(s, boot_cpu, &err);
101
+ if (err) {
102
+ error_propagate(errp, err);
103
+ return;
104
}
59
}
105
60
106
if (!s->boot_cpu_ptr) {
61
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
62
return false;
63
}
64
65
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
66
- return false;
67
- }
68
-
69
if (!vfp_access_check(s)) {
70
return true;
71
}
72
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
73
TCGv_ptr fpst;
74
int frac_bits;
75
76
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
77
+ if (!dc_isar_feature(aa32_fpsp_v3, s)) {
78
return false;
79
}
80
81
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
82
TCGv_ptr fpst;
83
int frac_bits;
84
85
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
86
- return false;
87
- }
88
-
89
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
90
+ if (!dc_isar_feature(aa32_fpdp_v3, s)) {
91
return false;
92
}
93
107
--
94
--
108
2.7.4
95
2.20.1
109
96
110
97
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
We will eventually remove the early ARM_FEATURE_VFP test,
4
so add a proper test for each trans_* that does not already
5
have another ISA test.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200214181547.21408-11-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-vfp.inc.c | 78 ++++++++++++++++++++++++++++++----
13
1 file changed, 69 insertions(+), 9 deletions(-)
14
15
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-vfp.inc.c
18
+++ b/target/arm/translate-vfp.inc.c
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
20
int pass;
21
uint32_t offset;
22
23
+ /* SIZE == 2 is a VFP instruction; otherwise NEON. */
24
+ if (a->size == 2
25
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
26
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
27
+ return false;
28
+ }
29
+
30
/* UNDEF accesses to D16-D31 if they don't exist */
31
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
32
return false;
33
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
34
pass = extract32(offset, 2, 1);
35
offset = extract32(offset, 0, 2) * 8;
36
37
- if (a->size != 2 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
38
- return false;
39
- }
40
-
41
if (!vfp_access_check(s)) {
42
return true;
43
}
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
45
int pass;
46
uint32_t offset;
47
48
+ /* SIZE == 2 is a VFP instruction; otherwise NEON. */
49
+ if (a->size == 2
50
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
51
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
52
+ return false;
53
+ }
54
+
55
/* UNDEF accesses to D16-D31 if they don't exist */
56
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vn & 0x10)) {
57
return false;
58
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
59
pass = extract32(offset, 2, 1);
60
offset = extract32(offset, 0, 2) * 8;
61
62
- if (a->size != 2 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
63
- return false;
64
- }
65
-
66
if (!vfp_access_check(s)) {
67
return true;
68
}
69
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
70
TCGv_i32 tmp;
71
bool ignore_vfp_enabled = false;
72
73
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
74
+ return false;
75
+ }
76
+
77
if (arm_dc_feature(s, ARM_FEATURE_M)) {
78
/*
79
* The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
81
{
82
TCGv_i32 tmp;
83
84
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
85
+ return false;
86
+ }
87
+
88
if (!vfp_access_check(s)) {
89
return true;
90
}
91
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
92
{
93
TCGv_i32 tmp;
94
95
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
96
+ return false;
97
+ }
98
+
99
/*
100
* VMOV between two general-purpose registers and two single precision
101
* floating point registers
102
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
103
104
/*
105
* VMOV between two general-purpose registers and one double precision
106
- * floating point register
107
+ * floating point register. Note that this does not require support
108
+ * for double precision arithmetic.
109
*/
110
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
111
+ return false;
112
+ }
113
114
/* UNDEF accesses to D16-D31 if they don't exist */
115
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vm & 0x10)) {
116
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
117
uint32_t offset;
118
TCGv_i32 addr, tmp;
119
120
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
121
+ return false;
122
+ }
123
+
124
if (!vfp_access_check(s)) {
125
return true;
126
}
127
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
128
TCGv_i32 addr;
129
TCGv_i64 tmp;
130
131
+ /* Note that this does not require support for double arithmetic. */
132
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
133
+ return false;
134
+ }
135
+
136
/* UNDEF accesses to D16-D31 if they don't exist */
137
if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
138
return false;
139
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
140
TCGv_i32 addr, tmp;
141
int i, n;
142
143
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
144
+ return false;
145
+ }
146
+
147
n = a->imm;
148
149
if (n == 0 || (a->vd + n) > 32) {
150
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
151
TCGv_i64 tmp;
152
int i, n;
153
154
+ /* Note that this does not require support for double arithmetic. */
155
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
156
+ return false;
157
+ }
158
+
159
n = a->imm >> 1;
160
161
if (n == 0 || (a->vd + n) > 32 || n > 16) {
162
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
163
TCGv_i32 f0, f1, fd;
164
TCGv_ptr fpst;
165
166
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
167
+ return false;
168
+ }
169
+
170
if (!dc_isar_feature(aa32_fpshvec, s) &&
171
(veclen != 0 || s->vec_stride != 0)) {
172
return false;
173
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
174
int veclen = s->vec_len;
175
TCGv_i32 f0, fd;
176
177
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
178
+ return false;
179
+ }
180
+
181
if (!dc_isar_feature(aa32_fpshvec, s) &&
182
(veclen != 0 || s->vec_stride != 0)) {
183
return false;
184
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
185
{
186
TCGv_i32 vd, vm;
187
188
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
189
+ return false;
190
+ }
191
+
192
/* Vm/M bits must be zero for the Z variant */
193
if (a->z && a->vm != 0) {
194
return false;
195
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
196
TCGv_i32 vm;
197
TCGv_ptr fpst;
198
199
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
200
+ return false;
201
+ }
202
+
203
if (!vfp_access_check(s)) {
204
return true;
205
}
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
207
TCGv_i32 vm;
208
TCGv_ptr fpst;
209
210
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
211
+ return false;
212
+ }
213
+
214
if (!vfp_access_check(s)) {
215
return true;
216
}
217
--
218
2.20.1
219
220
diff view generated by jsdifflib