1
Mostly my FEAT_NV/NV2 stuff, but some other smaller series too.
1
First arm pullreq of the cycle; this is mostly my softfloat NaN
2
handling series. (Lots more in my to-review queue, but I don't
3
like pullreqs growing too close to a hundred patches at a time :-))
2
4
5
thanks
3
-- PMM
6
-- PMM
4
7
5
The following changes since commit 9468484fe904ab4691de6d9c34616667f377ceac:
8
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
6
9
7
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2024-01-09 10:32:23 +0000)
10
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
8
11
9
are available in the Git repository at:
12
are available in the Git repository at:
10
13
11
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240111
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
12
15
13
for you to fetch changes up to e2862554c257e908a3833265e38365e794abd362:
16
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
14
17
15
target/arm: Add FEAT_NV2 to max, neoverse-n2, neoverse-v1 CPUs (2024-01-09 14:44:45 +0000)
18
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
16
19
17
----------------------------------------------------------------
20
----------------------------------------------------------------
18
target-arm queue:
21
target-arm queue:
19
* Emulate FEAT_NV, FEAT_NV2
22
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
20
* add cache controller for Freescale i.MX6
23
* fpu: Make muladd NaN handling runtime-selected, not compile-time
21
* Add minimal support for the B-L475E-IOT01A board
24
* fpu: Make default NaN pattern runtime-selected, not compile-time
22
* Allow SoC models to configure M-profile CPUs with correct number
25
* fpu: Minor NaN-related cleanups
23
of NVIC priority bits
26
* MAINTAINERS: email address updates
24
* Add missing QOM parent for v7-M SoCs
25
* Set CTR_EL0.{IDC,DIC} for the 'max' CPU
26
* hw/intc/arm_gicv3_cpuif: handle LPIs in in the list registers
27
27
28
----------------------------------------------------------------
28
----------------------------------------------------------------
29
Inès Varhol (2):
29
Bernhard Beschow (5):
30
hw/arm: Add minimal support for the STM32L4x5 SoC
30
hw/net/lan9118: Extract lan9118_phy
31
hw/arm: Add minimal support for the B-L475E-IOT01A board
31
hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations
32
hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register
33
hw/net/lan9118_phy: Reuse MII constants
34
hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement
32
35
33
Nikita Ostrenkov (1):
36
Leif Lindholm (1):
34
hw/arm: add cache controller for Freescale i.MX6
37
MAINTAINERS: update email address for Leif Lindholm
35
38
36
Peter Maydell (34):
39
Peter Maydell (54):
37
target/arm: Set CTR_EL0.{IDC,DIC} for the 'max' CPU
40
fpu: handle raising Invalid for infzero in pick_nan_muladd
38
hw/intc/arm_gicv3_cpuif: handle LPIs in in the list registers
41
fpu: Check for default_nan_mode before calling pickNaNMulAdd
39
target/arm: Handle HCR_EL2 accesses for bits introduced with FEAT_NV
42
softfloat: Allow runtime choice of inf * 0 + NaN result
40
target/arm: Implement HCR_EL2.AT handling
43
tests/fp: Explicitly set inf-zero-nan rule
41
target/arm: Enable trapping of ERET for FEAT_NV
44
target/arm: Set FloatInfZeroNaNRule explicitly
42
target/arm: Always honour HCR_EL2.TSC when HCR_EL2.NV is set
45
target/s390: Set FloatInfZeroNaNRule explicitly
43
target/arm: Allow use of upper 32 bits of TBFLAG_A64
46
target/ppc: Set FloatInfZeroNaNRule explicitly
44
target/arm: Record correct opcode fields in cpreg for E2H aliases
47
target/mips: Set FloatInfZeroNaNRule explicitly
45
target/arm: *_EL12 registers should UNDEF when HCR_EL2.E2H is 0
48
target/sparc: Set FloatInfZeroNaNRule explicitly
46
target/arm: Make EL2 cpreg accessfns safe for FEAT_NV EL1 accesses
49
target/xtensa: Set FloatInfZeroNaNRule explicitly
47
target/arm: Move FPU/SVE/SME access checks up above ARM_CP_SPECIAL_MASK check
50
target/x86: Set FloatInfZeroNaNRule explicitly
48
target/arm: Trap sysreg accesses for FEAT_NV
51
target/loongarch: Set FloatInfZeroNaNRule explicitly
49
target/arm: Make NV reads of CurrentEL return EL2
52
target/hppa: Set FloatInfZeroNaNRule explicitly
50
target/arm: Set SPSR_EL1.M correctly when nested virt is enabled
53
softfloat: Pass have_snan to pickNaNMulAdd
51
target/arm: Trap registers when HCR_EL2.{NV, NV1} == {1, 1}
54
softfloat: Allow runtime choice of NaN propagation for muladd
52
target/arm: Always use arm_pan_enabled() when checking if PAN is enabled
55
tests/fp: Explicitly set 3-NaN propagation rule
53
target/arm: Don't honour PSTATE.PAN when HCR_EL2.{NV, NV1} == {1, 1}
56
target/arm: Set Float3NaNPropRule explicitly
54
target/arm: Treat LDTR* and STTR* as LDR/STR when NV, NV1 is 1, 1
57
target/loongarch: Set Float3NaNPropRule explicitly
55
target/arm: Handle FEAT_NV page table attribute changes
58
target/ppc: Set Float3NaNPropRule explicitly
56
target/arm: Add FEAT_NV to max, neoverse-n2, neoverse-v1 CPUs
59
target/s390x: Set Float3NaNPropRule explicitly
57
target/arm: Handle HCR_EL2 accesses for FEAT_NV2 bits
60
target/sparc: Set Float3NaNPropRule explicitly
58
target/arm: Implement VNCR_EL2 register
61
target/mips: Set Float3NaNPropRule explicitly
59
target/arm: Handle FEAT_NV2 changes to when SPSR_EL1.M reports EL2
62
target/xtensa: Set Float3NaNPropRule explicitly
60
target/arm: Handle FEAT_NV2 redirection of SPSR_EL2, ELR_EL2, ESR_EL2, FAR_EL2
63
target/i386: Set Float3NaNPropRule explicitly
61
target/arm: Implement FEAT_NV2 redirection of sysregs to RAM
64
target/hppa: Set Float3NaNPropRule explicitly
62
target/arm: Report VNCR_EL2 based faults correctly
65
fpu: Remove use_first_nan field from float_status
63
target/arm: Mark up VNCR offsets (offsets 0x0..0xff)
66
target/m68k: Don't pass NULL float_status to floatx80_default_nan()
64
target/arm: Mark up VNCR offsets (offsets 0x100..0x160)
67
softfloat: Create floatx80 default NaN from parts64_default_nan
65
target/arm: Mark up VNCR offsets (offsets 0x168..0x1f8)
68
target/loongarch: Use normal float_status in fclass_s and fclass_d helpers
66
target/arm: Mark up VNCR offsets (offsets >= 0x200, except GIC)
69
target/m68k: In frem helper, initialize local float_status from env->fp_status
67
hw/intc/arm_gicv3_cpuif: Mark up VNCR offsets for GIC CPU registers
70
target/m68k: Init local float_status from env fp_status in gdb get/set reg
68
target/arm: Report HCR_EL2.{NV,NV1,NV2} in cpu dumps
71
target/sparc: Initialize local scratch float_status from env->fp_status
69
target/arm: Enhance CPU_LOG_INT to show SPSR on AArch64 exception-entry
72
target/ppc: Use env->fp_status in helper_compute_fprf functions
70
target/arm: Add FEAT_NV2 to max, neoverse-n2, neoverse-v1 CPUs
73
fpu: Allow runtime choice of default NaN value
74
tests/fp: Set default NaN pattern explicitly
75
target/microblaze: Set default NaN pattern explicitly
76
target/i386: Set default NaN pattern explicitly
77
target/hppa: Set default NaN pattern explicitly
78
target/alpha: Set default NaN pattern explicitly
79
target/arm: Set default NaN pattern explicitly
80
target/loongarch: Set default NaN pattern explicitly
81
target/m68k: Set default NaN pattern explicitly
82
target/mips: Set default NaN pattern explicitly
83
target/openrisc: Set default NaN pattern explicitly
84
target/ppc: Set default NaN pattern explicitly
85
target/sh4: Set default NaN pattern explicitly
86
target/rx: Set default NaN pattern explicitly
87
target/s390x: Set default NaN pattern explicitly
88
target/sparc: Set default NaN pattern explicitly
89
target/xtensa: Set default NaN pattern explicitly
90
target/hexagon: Set default NaN pattern explicitly
91
target/riscv: Set default NaN pattern explicitly
92
target/tricore: Set default NaN pattern explicitly
93
fpu: Remove default handling for dnan_pattern
71
94
72
Philippe Mathieu-Daudé (1):
95
Richard Henderson (11):
73
hw/arm: Add missing QOM parent for v7-M SoCs
96
target/arm: Copy entire float_status in is_ebf
97
softfloat: Inline pickNaNMulAdd
98
softfloat: Use goto for default nan case in pick_nan_muladd
99
softfloat: Remove which from parts_pick_nan_muladd
100
softfloat: Pad array size in pick_nan_muladd
101
softfloat: Move propagateFloatx80NaN to softfloat.c
102
softfloat: Use parts_pick_nan in propagateFloatx80NaN
103
softfloat: Inline pickNaN
104
softfloat: Share code between parts_pick_nan cases
105
softfloat: Sink frac_cmp in parts_pick_nan until needed
106
softfloat: Replace WHICH with RET in parts_pick_nan
74
107
75
Samuel Tardieu (3):
108
Vikram Garhwal (1):
76
hw/intc/armv7m_nvic: add "num-prio-bits" property
109
MAINTAINERS: Add correct email address for Vikram Garhwal
77
hw/arm/armv7m: alias the NVIC "num-prio-bits" property
78
hw/arm/socs: configure priority bits for existing SOCs
79
110
80
MAINTAINERS | 15 ++
111
MAINTAINERS | 4 +-
81
docs/system/arm/b-l475e-iot01a.rst | 46 +++++
112
include/fpu/softfloat-helpers.h | 38 +++-
82
docs/system/arm/emulation.rst | 2 +
113
include/fpu/softfloat-types.h | 89 +++++++-
83
docs/system/arm/stm32.rst | 6 +-
114
include/hw/net/imx_fec.h | 9 +-
84
docs/system/target-arm.rst | 1 +
115
include/hw/net/lan9118_phy.h | 37 ++++
85
configs/devices/arm-softmmu/default.mak | 1 +
116
include/hw/net/mii.h | 6 +
86
include/hw/arm/armv7m.h | 1 +
117
target/mips/fpu_helper.h | 20 ++
87
include/hw/arm/stm32l4x5_soc.h | 57 ++++++
118
target/sparc/helper.h | 4 +-
88
target/arm/cpregs.h | 54 +++++-
119
fpu/softfloat.c | 19 ++
89
target/arm/cpu-features.h | 10 +
120
hw/net/imx_fec.c | 146 ++------------
90
target/arm/cpu.h | 24 ++-
121
hw/net/lan9118.c | 137 ++-----------
91
target/arm/syndrome.h | 20 +-
122
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
92
target/arm/tcg/translate.h | 16 +-
123
linux-user/arm/nwfpe/fpa11.c | 5 +
93
hw/arm/armv7m.c | 2 +
124
target/alpha/cpu.c | 2 +
94
hw/arm/b-l475e-iot01a.c | 72 +++++++
125
target/arm/cpu.c | 10 +
95
hw/arm/fsl-imx6.c | 3 +
126
target/arm/tcg/vec_helper.c | 20 +-
96
hw/arm/msf2-som.c | 1 +
127
target/hexagon/cpu.c | 2 +
97
hw/arm/netduino2.c | 1 +
128
target/hppa/fpu_helper.c | 12 ++
98
hw/arm/netduinoplus2.c | 1 +
129
target/i386/tcg/fpu_helper.c | 12 ++
99
hw/arm/olimex-stm32-h405.c | 1 +
130
target/loongarch/tcg/fpu_helper.c | 14 +-
100
hw/arm/stellaris.c | 2 +
131
target/m68k/cpu.c | 14 +-
101
hw/arm/stm32f100_soc.c | 1 +
132
target/m68k/fpu_helper.c | 6 +-
102
hw/arm/stm32f205_soc.c | 1 +
133
target/m68k/helper.c | 6 +-
103
hw/arm/stm32f405_soc.c | 1 +
134
target/microblaze/cpu.c | 2 +
104
hw/arm/stm32l4x5_soc.c | 266 ++++++++++++++++++++++++++
135
target/mips/msa.c | 10 +
105
hw/arm/stm32vldiscovery.c | 1 +
136
target/openrisc/cpu.c | 2 +
106
hw/intc/arm_gicv3_cpuif.c | 28 ++-
137
target/ppc/cpu_init.c | 19 ++
107
hw/intc/armv7m_nvic.c | 23 ++-
138
target/ppc/fpu_helper.c | 3 +-
108
target/arm/cpu.c | 8 +-
139
target/riscv/cpu.c | 2 +
109
target/arm/debug_helper.c | 13 +-
140
target/rx/cpu.c | 2 +
110
target/arm/helper.c | 326 +++++++++++++++++++++++++++++---
141
target/s390x/cpu.c | 5 +
111
target/arm/ptw.c | 21 ++
142
target/sh4/cpu.c | 2 +
112
target/arm/tcg/cpu64.c | 11 ++
143
target/sparc/cpu.c | 6 +
113
target/arm/tcg/hflags.c | 30 ++-
144
target/sparc/fop_helper.c | 8 +-
114
target/arm/tcg/op_helper.c | 16 +-
145
target/sparc/translate.c | 4 +-
115
target/arm/tcg/tlb_helper.c | 27 ++-
146
target/tricore/helper.c | 2 +
116
target/arm/tcg/translate-a64.c | 160 ++++++++++++++--
147
target/xtensa/cpu.c | 4 +
117
hw/arm/Kconfig | 12 ++
148
target/xtensa/fpu_helper.c | 3 +-
118
hw/arm/meson.build | 2 +
149
tests/fp/fp-bench.c | 7 +
119
39 files changed, 1203 insertions(+), 80 deletions(-)
150
tests/fp/fp-test-log2.c | 1 +
120
create mode 100644 docs/system/arm/b-l475e-iot01a.rst
151
tests/fp/fp-test.c | 7 +
121
create mode 100644 include/hw/arm/stm32l4x5_soc.h
152
fpu/softfloat-parts.c.inc | 152 +++++++++++---
122
create mode 100644 hw/arm/b-l475e-iot01a.c
153
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
123
create mode 100644 hw/arm/stm32l4x5_soc.c
154
.mailmap | 5 +-
124
155
hw/net/Kconfig | 5 +
156
hw/net/meson.build | 1 +
157
hw/net/trace-events | 10 +-
158
47 files changed, 778 insertions(+), 730 deletions(-)
159
create mode 100644 include/hw/net/lan9118_phy.h
160
create mode 100644 hw/net/lan9118_phy.c
diff view generated by jsdifflib
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
This patch adds a new STM32L4x5 SoC, it is necessary to add support for
3
A very similar implementation of the same device exists in imx_fec. Prepare for
4
the B-L475E-IOT01A board.
4
a common implementation by extracting a device model into its own files.
5
The implementation is derived from the STM32F405 SoC.
6
The implementation contains no peripherals, only memory regions are
7
implemented.
8
5
9
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Some migration state has been moved into the new device model which breaks
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
migration compatibility for the following machines:
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
8
* smdkc210
12
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
9
* realview-*
13
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
10
* vexpress-*
14
Message-id: 20240108135849.351719-2-ines.varhol@telecom-paris.fr
11
* kzm
12
* mps2-*
13
14
While breaking migration ABI, fix the size of the MII registers to be 16 bit,
15
as defined by IEEE 802.3u.
16
17
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
18
Tested-by: Guenter Roeck <linux@roeck-us.net>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Message-id: 20241102125724.532843-2-shentey@gmail.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
22
---
17
MAINTAINERS | 8 +
23
include/hw/net/lan9118_phy.h | 37 ++++++++
18
include/hw/arm/stm32l4x5_soc.h | 57 +++++++
24
hw/net/lan9118.c | 137 +++++-----------------------
19
hw/arm/stm32l4x5_soc.c | 265 +++++++++++++++++++++++++++++++++
25
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
20
hw/arm/Kconfig | 5 +
26
hw/net/Kconfig | 4 +
21
hw/arm/meson.build | 1 +
27
hw/net/meson.build | 1 +
22
5 files changed, 336 insertions(+)
28
5 files changed, 233 insertions(+), 115 deletions(-)
23
create mode 100644 include/hw/arm/stm32l4x5_soc.h
29
create mode 100644 include/hw/net/lan9118_phy.h
24
create mode 100644 hw/arm/stm32l4x5_soc.c
30
create mode 100644 hw/net/lan9118_phy.c
25
31
26
diff --git a/MAINTAINERS b/MAINTAINERS
32
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/MAINTAINERS
29
+++ b/MAINTAINERS
30
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
31
S: Maintained
32
F: hw/arm/olimex-stm32-h405.c
33
34
+STM32L4x5 SoC Family
35
+M: Arnaud Minier <arnaud.minier@telecom-paris.fr>
36
+M: Inès Varhol <ines.varhol@telecom-paris.fr>
37
+L: qemu-arm@nongnu.org
38
+S: Maintained
39
+F: hw/arm/stm32l4x5_soc.c
40
+F: include/hw/arm/stm32l4x5_soc.h
41
+
42
SmartFusion2
43
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
44
M: Peter Maydell <peter.maydell@linaro.org>
45
diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h
46
new file mode 100644
33
new file mode 100644
47
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
48
--- /dev/null
35
--- /dev/null
49
+++ b/include/hw/arm/stm32l4x5_soc.h
36
+++ b/include/hw/net/lan9118_phy.h
50
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
51
+/*
38
+/*
52
+ * STM32L4x5 SoC family
39
+ * SMSC LAN9118 PHY emulation
53
+ *
40
+ *
54
+ * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
41
+ * Copyright (c) 2009 CodeSourcery, LLC.
55
+ * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
42
+ * Written by Paul Brook
56
+ *
57
+ * SPDX-License-Identifier: GPL-2.0-or-later
58
+ *
43
+ *
59
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
60
+ * See the COPYING file in the top-level directory.
45
+ * See the COPYING file in the top-level directory.
61
+ *
62
+ * This work is heavily inspired by the stm32f405_soc by Alistair Francis.
63
+ * Original code is licensed under the MIT License:
64
+ *
65
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
66
+ */
46
+ */
67
+
47
+
68
+/*
48
+#ifndef HW_NET_LAN9118_PHY_H
69
+ * The reference used is the STMicroElectronics RM0351 Reference manual
49
+#define HW_NET_LAN9118_PHY_H
70
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
50
+
71
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
72
+ */
73
+
74
+#ifndef HW_ARM_STM32L4x5_SOC_H
75
+#define HW_ARM_STM32L4x5_SOC_H
76
+
77
+#include "exec/memory.h"
78
+#include "hw/arm/armv7m.h"
79
+#include "qom/object.h"
51
+#include "qom/object.h"
80
+
52
+#include "hw/sysbus.h"
81
+#define TYPE_STM32L4X5_SOC "stm32l4x5-soc"
53
+
82
+#define TYPE_STM32L4X5XC_SOC "stm32l4x5xc-soc"
54
+#define TYPE_LAN9118_PHY "lan9118-phy"
83
+#define TYPE_STM32L4X5XE_SOC "stm32l4x5xe-soc"
55
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
84
+#define TYPE_STM32L4X5XG_SOC "stm32l4x5xg-soc"
56
+
85
+OBJECT_DECLARE_TYPE(Stm32l4x5SocState, Stm32l4x5SocClass, STM32L4X5_SOC)
57
+typedef struct Lan9118PhyState {
86
+
87
+struct Stm32l4x5SocState {
88
+ SysBusDevice parent_obj;
58
+ SysBusDevice parent_obj;
89
+
59
+
90
+ ARMv7MState armv7m;
60
+ uint16_t status;
91
+
61
+ uint16_t control;
92
+ MemoryRegion sram1;
62
+ uint16_t advertise;
93
+ MemoryRegion sram2;
63
+ uint16_t ints;
94
+ MemoryRegion flash;
64
+ uint16_t int_mask;
95
+ MemoryRegion flash_alias;
65
+ qemu_irq irq;
96
+
66
+ bool link_down;
97
+ Clock *sysclk;
67
+} Lan9118PhyState;
98
+ Clock *refclk;
68
+
99
+};
69
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down);
100
+
70
+void lan9118_phy_reset(Lan9118PhyState *s);
101
+struct Stm32l4x5SocClass {
71
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg);
102
+ SysBusDeviceClass parent_class;
72
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val);
103
+
104
+ size_t flash_size;
105
+};
106
+
73
+
107
+#endif
74
+#endif
108
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
75
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/net/lan9118.c
78
+++ b/hw/net/lan9118.c
79
@@ -XXX,XX +XXX,XX @@
80
#include "net/net.h"
81
#include "net/eth.h"
82
#include "hw/irq.h"
83
+#include "hw/net/lan9118_phy.h"
84
#include "hw/net/lan9118.h"
85
#include "hw/ptimer.h"
86
#include "hw/qdev-properties.h"
87
@@ -XXX,XX +XXX,XX @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
88
#define MAC_CR_RXEN 0x00000004
89
#define MAC_CR_RESERVED 0x7f404213
90
91
-#define PHY_INT_ENERGYON 0x80
92
-#define PHY_INT_AUTONEG_COMPLETE 0x40
93
-#define PHY_INT_FAULT 0x20
94
-#define PHY_INT_DOWN 0x10
95
-#define PHY_INT_AUTONEG_LP 0x08
96
-#define PHY_INT_PARFAULT 0x04
97
-#define PHY_INT_AUTONEG_PAGE 0x02
98
-
99
#define GPT_TIMER_EN 0x20000000
100
101
/*
102
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
103
uint32_t mac_mii_data;
104
uint32_t mac_flow;
105
106
- uint32_t phy_status;
107
- uint32_t phy_control;
108
- uint32_t phy_advertise;
109
- uint32_t phy_int;
110
- uint32_t phy_int_mask;
111
+ Lan9118PhyState mii;
112
+ IRQState mii_irq;
113
114
int32_t eeprom_writable;
115
uint8_t eeprom[128];
116
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
117
118
static const VMStateDescription vmstate_lan9118 = {
119
.name = "lan9118",
120
- .version_id = 2,
121
- .minimum_version_id = 1,
122
+ .version_id = 3,
123
+ .minimum_version_id = 3,
124
.fields = (const VMStateField[]) {
125
VMSTATE_PTIMER(timer, lan9118_state),
126
VMSTATE_UINT32(irq_cfg, lan9118_state),
127
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118 = {
128
VMSTATE_UINT32(mac_mii_acc, lan9118_state),
129
VMSTATE_UINT32(mac_mii_data, lan9118_state),
130
VMSTATE_UINT32(mac_flow, lan9118_state),
131
- VMSTATE_UINT32(phy_status, lan9118_state),
132
- VMSTATE_UINT32(phy_control, lan9118_state),
133
- VMSTATE_UINT32(phy_advertise, lan9118_state),
134
- VMSTATE_UINT32(phy_int, lan9118_state),
135
- VMSTATE_UINT32(phy_int_mask, lan9118_state),
136
VMSTATE_INT32(eeprom_writable, lan9118_state),
137
VMSTATE_UINT8_ARRAY(eeprom, lan9118_state, 128),
138
VMSTATE_INT32(tx_fifo_size, lan9118_state),
139
@@ -XXX,XX +XXX,XX @@ static void lan9118_reload_eeprom(lan9118_state *s)
140
lan9118_mac_changed(s);
141
}
142
143
-static void phy_update_irq(lan9118_state *s)
144
+static void lan9118_update_irq(void *opaque, int n, int level)
145
{
146
- if (s->phy_int & s->phy_int_mask) {
147
+ lan9118_state *s = opaque;
148
+
149
+ if (level) {
150
s->int_sts |= PHY_INT;
151
} else {
152
s->int_sts &= ~PHY_INT;
153
@@ -XXX,XX +XXX,XX @@ static void phy_update_irq(lan9118_state *s)
154
lan9118_update(s);
155
}
156
157
-static void phy_update_link(lan9118_state *s)
158
-{
159
- /* Autonegotiation status mirrors link status. */
160
- if (qemu_get_queue(s->nic)->link_down) {
161
- s->phy_status &= ~0x0024;
162
- s->phy_int |= PHY_INT_DOWN;
163
- } else {
164
- s->phy_status |= 0x0024;
165
- s->phy_int |= PHY_INT_ENERGYON;
166
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
167
- }
168
- phy_update_irq(s);
169
-}
170
-
171
static void lan9118_set_link(NetClientState *nc)
172
{
173
- phy_update_link(qemu_get_nic_opaque(nc));
174
-}
175
-
176
-static void phy_reset(lan9118_state *s)
177
-{
178
- s->phy_status = 0x7809;
179
- s->phy_control = 0x3000;
180
- s->phy_advertise = 0x01e1;
181
- s->phy_int_mask = 0;
182
- s->phy_int = 0;
183
- phy_update_link(s);
184
+ lan9118_phy_update_link(&LAN9118(qemu_get_nic_opaque(nc))->mii,
185
+ nc->link_down);
186
}
187
188
static void lan9118_reset(DeviceState *d)
189
@@ -XXX,XX +XXX,XX @@ static void lan9118_reset(DeviceState *d)
190
s->read_word_n = 0;
191
s->write_word_n = 0;
192
193
- phy_reset(s);
194
-
195
s->eeprom_writable = 0;
196
lan9118_reload_eeprom(s);
197
}
198
@@ -XXX,XX +XXX,XX @@ static void do_tx_packet(lan9118_state *s)
199
uint32_t status;
200
201
/* FIXME: Honor TX disable, and allow queueing of packets. */
202
- if (s->phy_control & 0x4000) {
203
+ if (s->mii.control & 0x4000) {
204
/* This assumes the receive routine doesn't touch the VLANClient. */
205
qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
206
} else {
207
@@ -XXX,XX +XXX,XX @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
208
}
209
}
210
211
-static uint32_t do_phy_read(lan9118_state *s, int reg)
212
-{
213
- uint32_t val;
214
-
215
- switch (reg) {
216
- case 0: /* Basic Control */
217
- return s->phy_control;
218
- case 1: /* Basic Status */
219
- return s->phy_status;
220
- case 2: /* ID1 */
221
- return 0x0007;
222
- case 3: /* ID2 */
223
- return 0xc0d1;
224
- case 4: /* Auto-neg advertisement */
225
- return s->phy_advertise;
226
- case 5: /* Auto-neg Link Partner Ability */
227
- return 0x0f71;
228
- case 6: /* Auto-neg Expansion */
229
- return 1;
230
- /* TODO 17, 18, 27, 29, 30, 31 */
231
- case 29: /* Interrupt source. */
232
- val = s->phy_int;
233
- s->phy_int = 0;
234
- phy_update_irq(s);
235
- return val;
236
- case 30: /* Interrupt mask */
237
- return s->phy_int_mask;
238
- default:
239
- qemu_log_mask(LOG_GUEST_ERROR,
240
- "do_phy_read: PHY read reg %d\n", reg);
241
- return 0;
242
- }
243
-}
244
-
245
-static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
246
-{
247
- switch (reg) {
248
- case 0: /* Basic Control */
249
- if (val & 0x8000) {
250
- phy_reset(s);
251
- break;
252
- }
253
- s->phy_control = val & 0x7980;
254
- /* Complete autonegotiation immediately. */
255
- if (val & 0x1000) {
256
- s->phy_status |= 0x0020;
257
- }
258
- break;
259
- case 4: /* Auto-neg advertisement */
260
- s->phy_advertise = (val & 0x2d7f) | 0x80;
261
- break;
262
- /* TODO 17, 18, 27, 31 */
263
- case 30: /* Interrupt mask */
264
- s->phy_int_mask = val & 0xff;
265
- phy_update_irq(s);
266
- break;
267
- default:
268
- qemu_log_mask(LOG_GUEST_ERROR,
269
- "do_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
270
- }
271
-}
272
-
273
static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
274
{
275
switch (reg) {
276
@@ -XXX,XX +XXX,XX @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
277
if (val & 2) {
278
DPRINTF("PHY write %d = 0x%04x\n",
279
(val >> 6) & 0x1f, s->mac_mii_data);
280
- do_phy_write(s, (val >> 6) & 0x1f, s->mac_mii_data);
281
+ lan9118_phy_write(&s->mii, (val >> 6) & 0x1f, s->mac_mii_data);
282
} else {
283
- s->mac_mii_data = do_phy_read(s, (val >> 6) & 0x1f);
284
+ s->mac_mii_data = lan9118_phy_read(&s->mii, (val >> 6) & 0x1f);
285
DPRINTF("PHY read %d = 0x%04x\n",
286
(val >> 6) & 0x1f, s->mac_mii_data);
287
}
288
@@ -XXX,XX +XXX,XX @@ static void lan9118_writel(void *opaque, hwaddr offset,
289
break;
290
case CSR_PMT_CTRL:
291
if (val & 0x400) {
292
- phy_reset(s);
293
+ lan9118_phy_reset(&s->mii);
294
}
295
s->pmt_ctrl &= ~0x34e;
296
s->pmt_ctrl |= (val & 0x34e);
297
@@ -XXX,XX +XXX,XX @@ static void lan9118_realize(DeviceState *dev, Error **errp)
298
const MemoryRegionOps *mem_ops =
299
s->mode_16bit ? &lan9118_16bit_mem_ops : &lan9118_mem_ops;
300
301
+ qemu_init_irq(&s->mii_irq, lan9118_update_irq, s, 0);
302
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
303
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
304
+ return;
305
+ }
306
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
307
+
308
memory_region_init_io(&s->mmio, OBJECT(dev), mem_ops, s,
309
"lan9118-mmio", 0x100);
310
sysbus_init_mmio(sbd, &s->mmio);
311
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
109
new file mode 100644
312
new file mode 100644
110
index XXXXXXX..XXXXXXX
313
index XXXXXXX..XXXXXXX
111
--- /dev/null
314
--- /dev/null
112
+++ b/hw/arm/stm32l4x5_soc.c
315
+++ b/hw/net/lan9118_phy.c
113
@@ -XXX,XX +XXX,XX @@
316
@@ -XXX,XX +XXX,XX @@
114
+/*
317
+/*
115
+ * STM32L4x5 SoC family
318
+ * SMSC LAN9118 PHY emulation
116
+ *
319
+ *
117
+ * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
320
+ * Copyright (c) 2009 CodeSourcery, LLC.
118
+ * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
321
+ * Written by Paul Brook
119
+ *
322
+ *
120
+ * SPDX-License-Identifier: GPL-2.0-or-later
323
+ * This code is licensed under the GNU GPL v2
121
+ *
324
+ *
122
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
325
+ * Contributions after 2012-01-13 are licensed under the terms of the
123
+ * See the COPYING file in the top-level directory.
326
+ * GNU GPL, version 2 or (at your option) any later version.
124
+ *
125
+ * This work is heavily inspired by the stm32f405_soc by Alistair Francis.
126
+ * Original code is licensed under the MIT License:
127
+ *
128
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
129
+ */
327
+ */
130
+
328
+
131
+/*
132
+ * The reference used is the STMicroElectronics RM0351 Reference manual
133
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
134
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
135
+ */
136
+
137
+#include "qemu/osdep.h"
329
+#include "qemu/osdep.h"
138
+#include "qemu/units.h"
330
+#include "hw/net/lan9118_phy.h"
139
+#include "qapi/error.h"
331
+#include "hw/irq.h"
140
+#include "exec/address-spaces.h"
332
+#include "hw/resettable.h"
141
+#include "sysemu/sysemu.h"
333
+#include "migration/vmstate.h"
142
+#include "hw/arm/stm32l4x5_soc.h"
334
+#include "qemu/log.h"
143
+#include "hw/qdev-clock.h"
335
+
144
+#include "hw/misc/unimp.h"
336
+#define PHY_INT_ENERGYON (1 << 7)
145
+
337
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
146
+#define FLASH_BASE_ADDRESS 0x08000000
338
+#define PHY_INT_FAULT (1 << 5)
147
+#define SRAM1_BASE_ADDRESS 0x20000000
339
+#define PHY_INT_DOWN (1 << 4)
148
+#define SRAM1_SIZE (96 * KiB)
340
+#define PHY_INT_AUTONEG_LP (1 << 3)
149
+#define SRAM2_BASE_ADDRESS 0x10000000
341
+#define PHY_INT_PARFAULT (1 << 2)
150
+#define SRAM2_SIZE (32 * KiB)
342
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
151
+
343
+
152
+static void stm32l4x5_soc_initfn(Object *obj)
344
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
153
+{
345
+{
154
+ Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
346
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
155
+
347
+}
156
+ s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
348
+
157
+ s->refclk = qdev_init_clock_in(DEVICE(s), "refclk", NULL, NULL, 0);
349
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
158
+}
350
+{
159
+
351
+ uint16_t val;
160
+static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
352
+
161
+{
353
+ switch (reg) {
162
+ ERRP_GUARD();
354
+ case 0: /* Basic Control */
163
+ Stm32l4x5SocState *s = STM32L4X5_SOC(dev_soc);
355
+ return s->control;
164
+ const Stm32l4x5SocClass *sc = STM32L4X5_SOC_GET_CLASS(dev_soc);
356
+ case 1: /* Basic Status */
165
+ MemoryRegion *system_memory = get_system_memory();
357
+ return s->status;
166
+ DeviceState *armv7m;
358
+ case 2: /* ID1 */
167
+
359
+ return 0x0007;
168
+ /*
360
+ case 3: /* ID2 */
169
+ * We use s->refclk internally and only define it with qdev_init_clock_in()
361
+ return 0xc0d1;
170
+ * so it is correctly parented and not leaked on an init/deinit; it is not
362
+ case 4: /* Auto-neg advertisement */
171
+ * intended as an externally exposed clock.
363
+ return s->advertise;
172
+ */
364
+ case 5: /* Auto-neg Link Partner Ability */
173
+ if (clock_has_source(s->refclk)) {
365
+ return 0x0f71;
174
+ error_setg(errp, "refclk clock must not be wired up by the board code");
366
+ case 6: /* Auto-neg Expansion */
175
+ return;
367
+ return 1;
368
+ /* TODO 17, 18, 27, 29, 30, 31 */
369
+ case 29: /* Interrupt source. */
370
+ val = s->ints;
371
+ s->ints = 0;
372
+ lan9118_phy_update_irq(s);
373
+ return val;
374
+ case 30: /* Interrupt mask */
375
+ return s->int_mask;
376
+ default:
377
+ qemu_log_mask(LOG_GUEST_ERROR,
378
+ "lan9118_phy_read: PHY read reg %d\n", reg);
379
+ return 0;
176
+ }
380
+ }
177
+
381
+}
178
+ if (!clock_has_source(s->sysclk)) {
382
+
179
+ error_setg(errp, "sysclk clock must be wired up by the board code");
383
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
180
+ return;
384
+{
385
+ switch (reg) {
386
+ case 0: /* Basic Control */
387
+ if (val & 0x8000) {
388
+ lan9118_phy_reset(s);
389
+ break;
390
+ }
391
+ s->control = val & 0x7980;
392
+ /* Complete autonegotiation immediately. */
393
+ if (val & 0x1000) {
394
+ s->status |= 0x0020;
395
+ }
396
+ break;
397
+ case 4: /* Auto-neg advertisement */
398
+ s->advertise = (val & 0x2d7f) | 0x80;
399
+ break;
400
+ /* TODO 17, 18, 27, 31 */
401
+ case 30: /* Interrupt mask */
402
+ s->int_mask = val & 0xff;
403
+ lan9118_phy_update_irq(s);
404
+ break;
405
+ default:
406
+ qemu_log_mask(LOG_GUEST_ERROR,
407
+ "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
181
+ }
408
+ }
182
+
409
+}
183
+ /*
410
+
184
+ * TODO: ideally we should model the SoC RCC and its ability to
411
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
185
+ * change the sysclk frequency and define different sysclk sources.
412
+{
186
+ */
413
+ s->link_down = link_down;
187
+
414
+
188
+ /* The refclk always runs at frequency HCLK / 8 */
415
+ /* Autonegotiation status mirrors link status. */
189
+ clock_set_mul_div(s->refclk, 8, 1);
416
+ if (link_down) {
190
+ clock_set_source(s->refclk, s->sysclk);
417
+ s->status &= ~0x0024;
191
+
418
+ s->ints |= PHY_INT_DOWN;
192
+ if (!memory_region_init_rom(&s->flash, OBJECT(dev_soc), "flash",
419
+ } else {
193
+ sc->flash_size, errp)) {
420
+ s->status |= 0x0024;
194
+ return;
421
+ s->ints |= PHY_INT_ENERGYON;
422
+ s->ints |= PHY_INT_AUTONEG_COMPLETE;
195
+ }
423
+ }
196
+ memory_region_init_alias(&s->flash_alias, OBJECT(dev_soc),
424
+ lan9118_phy_update_irq(s);
197
+ "flash_boot_alias", &s->flash, 0,
425
+}
198
+ sc->flash_size);
426
+
199
+
427
+void lan9118_phy_reset(Lan9118PhyState *s)
200
+ memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, &s->flash);
428
+{
201
+ memory_region_add_subregion(system_memory, 0, &s->flash_alias);
429
+ s->control = 0x3000;
202
+
430
+ s->status = 0x7809;
203
+ if (!memory_region_init_ram(&s->sram1, OBJECT(dev_soc), "SRAM1", SRAM1_SIZE,
431
+ s->advertise = 0x01e1;
204
+ errp)) {
432
+ s->int_mask = 0;
205
+ return;
433
+ s->ints = 0;
206
+ }
434
+ lan9118_phy_update_link(s, s->link_down);
207
+ memory_region_add_subregion(system_memory, SRAM1_BASE_ADDRESS, &s->sram1);
435
+}
208
+
436
+
209
+ if (!memory_region_init_ram(&s->sram2, OBJECT(dev_soc), "SRAM2", SRAM2_SIZE,
437
+static void lan9118_phy_reset_hold(Object *obj, ResetType type)
210
+ errp)) {
438
+{
211
+ return;
439
+ Lan9118PhyState *s = LAN9118_PHY(obj);
212
+ }
440
+
213
+ memory_region_add_subregion(system_memory, SRAM2_BASE_ADDRESS, &s->sram2);
441
+ lan9118_phy_reset(s);
214
+
442
+}
215
+ object_initialize_child(OBJECT(dev_soc), "armv7m", &s->armv7m, TYPE_ARMV7M);
443
+
216
+ armv7m = DEVICE(&s->armv7m);
444
+static void lan9118_phy_init(Object *obj)
217
+ qdev_prop_set_uint32(armv7m, "num-irq", 96);
445
+{
218
+ qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
446
+ Lan9118PhyState *s = LAN9118_PHY(obj);
219
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
447
+
220
+ qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
448
+ qdev_init_gpio_out(DEVICE(s), &s->irq, 1);
221
+ qdev_connect_clock_in(armv7m, "refclk", s->refclk);
449
+}
222
+ object_property_set_link(OBJECT(&s->armv7m), "memory",
450
+
223
+ OBJECT(system_memory), &error_abort);
451
+static const VMStateDescription vmstate_lan9118_phy = {
224
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->armv7m), errp)) {
452
+ .name = "lan9118-phy",
225
+ return;
453
+ .version_id = 1,
226
+ }
454
+ .minimum_version_id = 1,
227
+
455
+ .fields = (const VMStateField[]) {
228
+ /* APB1 BUS */
456
+ VMSTATE_UINT16(control, Lan9118PhyState),
229
+ create_unimplemented_device("TIM2", 0x40000000, 0x400);
457
+ VMSTATE_UINT16(status, Lan9118PhyState),
230
+ create_unimplemented_device("TIM3", 0x40000400, 0x400);
458
+ VMSTATE_UINT16(advertise, Lan9118PhyState),
231
+ create_unimplemented_device("TIM4", 0x40000800, 0x400);
459
+ VMSTATE_UINT16(ints, Lan9118PhyState),
232
+ create_unimplemented_device("TIM5", 0x40000C00, 0x400);
460
+ VMSTATE_UINT16(int_mask, Lan9118PhyState),
233
+ create_unimplemented_device("TIM6", 0x40001000, 0x400);
461
+ VMSTATE_BOOL(link_down, Lan9118PhyState),
234
+ create_unimplemented_device("TIM7", 0x40001400, 0x400);
462
+ VMSTATE_END_OF_LIST()
235
+ /* RESERVED: 0x40001800, 0x1000 */
236
+ create_unimplemented_device("RTC", 0x40002800, 0x400);
237
+ create_unimplemented_device("WWDG", 0x40002C00, 0x400);
238
+ create_unimplemented_device("IWDG", 0x40003000, 0x400);
239
+ /* RESERVED: 0x40001800, 0x400 */
240
+ create_unimplemented_device("SPI2", 0x40003800, 0x400);
241
+ create_unimplemented_device("SPI3", 0x40003C00, 0x400);
242
+ /* RESERVED: 0x40004000, 0x400 */
243
+ create_unimplemented_device("USART2", 0x40004400, 0x400);
244
+ create_unimplemented_device("USART3", 0x40004800, 0x400);
245
+ create_unimplemented_device("UART4", 0x40004C00, 0x400);
246
+ create_unimplemented_device("UART5", 0x40005000, 0x400);
247
+ create_unimplemented_device("I2C1", 0x40005400, 0x400);
248
+ create_unimplemented_device("I2C2", 0x40005800, 0x400);
249
+ create_unimplemented_device("I2C3", 0x40005C00, 0x400);
250
+ /* RESERVED: 0x40006000, 0x400 */
251
+ create_unimplemented_device("CAN1", 0x40006400, 0x400);
252
+ /* RESERVED: 0x40006800, 0x400 */
253
+ create_unimplemented_device("PWR", 0x40007000, 0x400);
254
+ create_unimplemented_device("DAC1", 0x40007400, 0x400);
255
+ create_unimplemented_device("OPAMP", 0x40007800, 0x400);
256
+ create_unimplemented_device("LPTIM1", 0x40007C00, 0x400);
257
+ create_unimplemented_device("LPUART1", 0x40008000, 0x400);
258
+ /* RESERVED: 0x40008400, 0x400 */
259
+ create_unimplemented_device("SWPMI1", 0x40008800, 0x400);
260
+ /* RESERVED: 0x40008C00, 0x800 */
261
+ create_unimplemented_device("LPTIM2", 0x40009400, 0x400);
262
+ /* RESERVED: 0x40009800, 0x6800 */
263
+
264
+ /* APB2 BUS */
265
+ create_unimplemented_device("SYSCFG", 0x40010000, 0x30);
266
+ create_unimplemented_device("VREFBUF", 0x40010030, 0x1D0);
267
+ create_unimplemented_device("COMP", 0x40010200, 0x200);
268
+ create_unimplemented_device("EXTI", 0x40010400, 0x400);
269
+ /* RESERVED: 0x40010800, 0x1400 */
270
+ create_unimplemented_device("FIREWALL", 0x40011C00, 0x400);
271
+ /* RESERVED: 0x40012000, 0x800 */
272
+ create_unimplemented_device("SDMMC1", 0x40012800, 0x400);
273
+ create_unimplemented_device("TIM1", 0x40012C00, 0x400);
274
+ create_unimplemented_device("SPI1", 0x40013000, 0x400);
275
+ create_unimplemented_device("TIM8", 0x40013400, 0x400);
276
+ create_unimplemented_device("USART1", 0x40013800, 0x400);
277
+ /* RESERVED: 0x40013C00, 0x400 */
278
+ create_unimplemented_device("TIM15", 0x40014000, 0x400);
279
+ create_unimplemented_device("TIM16", 0x40014400, 0x400);
280
+ create_unimplemented_device("TIM17", 0x40014800, 0x400);
281
+ /* RESERVED: 0x40014C00, 0x800 */
282
+ create_unimplemented_device("SAI1", 0x40015400, 0x400);
283
+ create_unimplemented_device("SAI2", 0x40015800, 0x400);
284
+ /* RESERVED: 0x40015C00, 0x400 */
285
+ create_unimplemented_device("DFSDM1", 0x40016000, 0x400);
286
+ /* RESERVED: 0x40016400, 0x9C00 */
287
+
288
+ /* AHB1 BUS */
289
+ create_unimplemented_device("DMA1", 0x40020000, 0x400);
290
+ create_unimplemented_device("DMA2", 0x40020400, 0x400);
291
+ /* RESERVED: 0x40020800, 0x800 */
292
+ create_unimplemented_device("RCC", 0x40021000, 0x400);
293
+ /* RESERVED: 0x40021400, 0xC00 */
294
+ create_unimplemented_device("FLASH", 0x40022000, 0x400);
295
+ /* RESERVED: 0x40022400, 0xC00 */
296
+ create_unimplemented_device("CRC", 0x40023000, 0x400);
297
+ /* RESERVED: 0x40023400, 0x400 */
298
+ create_unimplemented_device("TSC", 0x40024000, 0x400);
299
+
300
+ /* RESERVED: 0x40024400, 0x7FDBC00 */
301
+
302
+ /* AHB2 BUS */
303
+ create_unimplemented_device("GPIOA", 0x48000000, 0x400);
304
+ create_unimplemented_device("GPIOB", 0x48000400, 0x400);
305
+ create_unimplemented_device("GPIOC", 0x48000800, 0x400);
306
+ create_unimplemented_device("GPIOD", 0x48000C00, 0x400);
307
+ create_unimplemented_device("GPIOE", 0x48001000, 0x400);
308
+ create_unimplemented_device("GPIOF", 0x48001400, 0x400);
309
+ create_unimplemented_device("GPIOG", 0x48001800, 0x400);
310
+ create_unimplemented_device("GPIOH", 0x48001C00, 0x400);
311
+ /* RESERVED: 0x48002000, 0x7FDBC00 */
312
+ create_unimplemented_device("OTG_FS", 0x50000000, 0x40000);
313
+ create_unimplemented_device("ADC", 0x50040000, 0x400);
314
+ /* RESERVED: 0x50040400, 0x20400 */
315
+ create_unimplemented_device("RNG", 0x50060800, 0x400);
316
+
317
+ /* AHB3 BUS */
318
+ create_unimplemented_device("FMC", 0xA0000000, 0x1000);
319
+ create_unimplemented_device("QUADSPI", 0xA0001000, 0x400);
320
+}
321
+
322
+static void stm32l4x5_soc_class_init(ObjectClass *klass, void *data)
323
+{
324
+
325
+ DeviceClass *dc = DEVICE_CLASS(klass);
326
+
327
+ dc->realize = stm32l4x5_soc_realize;
328
+ /* Reason: Mapped at fixed location on the system bus */
329
+ dc->user_creatable = false;
330
+ /* No vmstate or reset required: device has no internal state */
331
+}
332
+
333
+static void stm32l4x5xc_soc_class_init(ObjectClass *oc, void *data)
334
+{
335
+ Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
336
+
337
+ ssc->flash_size = 256 * KiB;
338
+}
339
+
340
+static void stm32l4x5xe_soc_class_init(ObjectClass *oc, void *data)
341
+{
342
+ Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
343
+
344
+ ssc->flash_size = 512 * KiB;
345
+}
346
+
347
+static void stm32l4x5xg_soc_class_init(ObjectClass *oc, void *data)
348
+{
349
+ Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc);
350
+
351
+ ssc->flash_size = 1 * MiB;
352
+}
353
+
354
+static const TypeInfo stm32l4x5_soc_types[] = {
355
+ {
356
+ .name = TYPE_STM32L4X5XC_SOC,
357
+ .parent = TYPE_STM32L4X5_SOC,
358
+ .class_init = stm32l4x5xc_soc_class_init,
359
+ }, {
360
+ .name = TYPE_STM32L4X5XE_SOC,
361
+ .parent = TYPE_STM32L4X5_SOC,
362
+ .class_init = stm32l4x5xe_soc_class_init,
363
+ }, {
364
+ .name = TYPE_STM32L4X5XG_SOC,
365
+ .parent = TYPE_STM32L4X5_SOC,
366
+ .class_init = stm32l4x5xg_soc_class_init,
367
+ }, {
368
+ .name = TYPE_STM32L4X5_SOC,
369
+ .parent = TYPE_SYS_BUS_DEVICE,
370
+ .instance_size = sizeof(Stm32l4x5SocState),
371
+ .instance_init = stm32l4x5_soc_initfn,
372
+ .class_size = sizeof(Stm32l4x5SocClass),
373
+ .class_init = stm32l4x5_soc_class_init,
374
+ .abstract = true,
375
+ }
463
+ }
376
+};
464
+};
377
+
465
+
378
+DEFINE_TYPES(stm32l4x5_soc_types)
466
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
379
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
467
+{
468
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
469
+ DeviceClass *dc = DEVICE_CLASS(klass);
470
+
471
+ rc->phases.hold = lan9118_phy_reset_hold;
472
+ dc->vmsd = &vmstate_lan9118_phy;
473
+}
474
+
475
+static const TypeInfo types[] = {
476
+ {
477
+ .name = TYPE_LAN9118_PHY,
478
+ .parent = TYPE_SYS_BUS_DEVICE,
479
+ .instance_size = sizeof(Lan9118PhyState),
480
+ .instance_init = lan9118_phy_init,
481
+ .class_init = lan9118_phy_class_init,
482
+ }
483
+};
484
+
485
+DEFINE_TYPES(types)
486
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
380
index XXXXXXX..XXXXXXX 100644
487
index XXXXXXX..XXXXXXX 100644
381
--- a/hw/arm/Kconfig
488
--- a/hw/net/Kconfig
382
+++ b/hw/arm/Kconfig
489
+++ b/hw/net/Kconfig
383
@@ -XXX,XX +XXX,XX @@ config STM32F405_SOC
490
@@ -XXX,XX +XXX,XX @@ config VMXNET3_PCI
384
select STM32F4XX_SYSCFG
491
config SMC91C111
385
select STM32F4XX_EXTI
492
bool
386
493
387
+config STM32L4X5_SOC
494
+config LAN9118_PHY
388
+ bool
495
+ bool
389
+ select ARM_V7M
496
+
390
+ select OR_IRQ
497
config LAN9118
391
+
392
config XLNX_ZYNQMP_ARM
393
bool
498
bool
394
default y if PIXMAN
499
+ select LAN9118_PHY
395
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
500
select PTIMER
501
502
config NE2000_ISA
503
diff --git a/hw/net/meson.build b/hw/net/meson.build
396
index XXXXXXX..XXXXXXX 100644
504
index XXXXXXX..XXXXXXX 100644
397
--- a/hw/arm/meson.build
505
--- a/hw/net/meson.build
398
+++ b/hw/arm/meson.build
506
+++ b/hw/net/meson.build
399
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
507
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('vmxnet3.c'))
400
arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
508
401
arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
509
system_ss.add(when: 'CONFIG_SMC91C111', if_true: files('smc91c111.c'))
402
arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
510
system_ss.add(when: 'CONFIG_LAN9118', if_true: files('lan9118.c'))
403
+arm_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_soc.c'))
511
+system_ss.add(when: 'CONFIG_LAN9118_PHY', if_true: files('lan9118_phy.c'))
404
arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c'))
512
system_ss.add(when: 'CONFIG_NE2000_ISA', if_true: files('ne2000-isa.c'))
405
arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-versal-virt.c'))
513
system_ss.add(when: 'CONFIG_OPENCORES_ETH', if_true: files('opencores_eth.c'))
406
arm_ss.add(when: 'CONFIG_FSL_IMX25', if_true: files('fsl-imx25.c', 'imx25_pdk.c'))
514
system_ss.add(when: 'CONFIG_XGMAC', if_true: files('xgmac.c'))
407
--
515
--
408
2.34.1
516
2.34.1
409
410
diff view generated by jsdifflib
1
From: Samuel Tardieu <sam@rfc1149.net>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Cortex-M NVIC can have a different number of priority bits.
3
imx_fec models the same PHY as lan9118_phy. The code is almost the same with
4
Cortex-M0/M0+/M1 devices must use 2 or more bits, while devices based
4
imx_fec having more logging and tracing. Merge these improvements into
5
on ARMv7m and up must use 3 or more bits.
5
lan9118_phy and reuse in imx_fec to fix the code duplication.
6
6
7
This adds a "num-prio-bits" property which will get sensible default
7
Some migration state how resides in the new device model which breaks migration
8
values if unset (2 or 8 depending on the device). Unless a SOC
8
compatibility for the following machines:
9
specifies the number of bits to use, the previous behavior is
9
* imx25-pdk
10
maintained for backward compatibility.
10
* sabrelite
11
* mcimx7d-sabre
12
* mcimx6ul-evk
11
13
12
Signed-off-by: Samuel Tardieu <sam@rfc1149.net>
14
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
15
Tested-by: Guenter Roeck <linux@roeck-us.net>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20240106181503.1746200-2-sam@rfc1149.net
17
Message-id: 20241102125724.532843-3-shentey@gmail.com
15
Suggested-by: Anton Kochkov <anton.kochkov@proton.me>
16
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1122
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
19
---
20
hw/intc/armv7m_nvic.c | 23 ++++++++++++++++++++++-
20
include/hw/net/imx_fec.h | 9 ++-
21
1 file changed, 22 insertions(+), 1 deletion(-)
21
hw/net/imx_fec.c | 146 ++++-----------------------------------
22
hw/net/lan9118_phy.c | 82 ++++++++++++++++------
23
hw/net/Kconfig | 1 +
24
hw/net/trace-events | 10 +--
25
5 files changed, 85 insertions(+), 163 deletions(-)
22
26
23
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
27
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
24
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/intc/armv7m_nvic.c
29
--- a/include/hw/net/imx_fec.h
26
+++ b/hw/intc/armv7m_nvic.c
30
+++ b/include/hw/net/imx_fec.h
27
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_nvic = {
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
28
static Property props_nvic[] = {
32
#define TYPE_IMX_ENET "imx.enet"
29
/* Number of external IRQ lines (so excluding the 16 internal exceptions) */
33
30
DEFINE_PROP_UINT32("num-irq", NVICState, num_irq, 64),
34
#include "hw/sysbus.h"
31
+ /*
35
+#include "hw/net/lan9118_phy.h"
32
+ * Number of the maximum priority bits that can be used. 0 means
36
+#include "hw/irq.h"
33
+ * to use a reasonable default.
37
#include "net/net.h"
34
+ */
38
35
+ DEFINE_PROP_UINT8("num-prio-bits", NVICState, num_prio_bits, 0),
39
#define ENET_EIR 1
36
DEFINE_PROP_END_OF_LIST()
40
@@ -XXX,XX +XXX,XX @@ struct IMXFECState {
41
uint32_t tx_descriptor[ENET_TX_RING_NUM];
42
uint32_t tx_ring_num;
43
44
- uint32_t phy_status;
45
- uint32_t phy_control;
46
- uint32_t phy_advertise;
47
- uint32_t phy_int;
48
- uint32_t phy_int_mask;
49
+ Lan9118PhyState mii;
50
+ IRQState mii_irq;
51
uint32_t phy_num;
52
bool phy_connected;
53
struct IMXFECState *phy_consumer;
54
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/net/imx_fec.c
57
+++ b/hw/net/imx_fec.c
58
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth_txdescs = {
59
60
static const VMStateDescription vmstate_imx_eth = {
61
.name = TYPE_IMX_FEC,
62
- .version_id = 2,
63
- .minimum_version_id = 2,
64
+ .version_id = 3,
65
+ .minimum_version_id = 3,
66
.fields = (const VMStateField[]) {
67
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
68
VMSTATE_UINT32(rx_descriptor, IMXFECState),
69
VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
70
- VMSTATE_UINT32(phy_status, IMXFECState),
71
- VMSTATE_UINT32(phy_control, IMXFECState),
72
- VMSTATE_UINT32(phy_advertise, IMXFECState),
73
- VMSTATE_UINT32(phy_int, IMXFECState),
74
- VMSTATE_UINT32(phy_int_mask, IMXFECState),
75
VMSTATE_END_OF_LIST()
76
},
77
.subsections = (const VMStateDescription * const []) {
78
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth = {
79
},
37
};
80
};
38
81
39
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
82
-#define PHY_INT_ENERGYON (1 << 7)
40
/* include space for internal exception vectors */
83
-#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
41
s->num_irq += NVIC_FIRST_IRQ;
84
-#define PHY_INT_FAULT (1 << 5)
42
85
-#define PHY_INT_DOWN (1 << 4)
43
- s->num_prio_bits = arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 8 : 2;
86
-#define PHY_INT_AUTONEG_LP (1 << 3)
44
+ if (s->num_prio_bits == 0) {
87
-#define PHY_INT_PARFAULT (1 << 2)
45
+ /*
88
-#define PHY_INT_AUTONEG_PAGE (1 << 1)
46
+ * If left unspecified, use 2 bits by default on Cortex-M0/M0+/M1
89
-
47
+ * and 8 bits otherwise.
90
static void imx_eth_update(IMXFECState *s);
48
+ */
91
49
+ s->num_prio_bits = arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 8 : 2;
92
/*
50
+ } else {
93
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s);
51
+ uint8_t min_prio_bits =
94
* For now we don't handle any GPIO/interrupt line, so the OS will
52
+ arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 3 : 2;
95
* have to poll for the PHY status.
53
+ if (s->num_prio_bits < min_prio_bits || s->num_prio_bits > 8) {
96
*/
54
+ error_setg(errp,
97
-static void imx_phy_update_irq(IMXFECState *s)
55
+ "num-prio-bits %d is outside "
98
+static void imx_phy_update_irq(void *opaque, int n, int level)
56
+ "NVIC acceptable range [%d-8]",
99
{
57
+ s->num_prio_bits, min_prio_bits);
100
- imx_eth_update(s);
58
+ return;
101
-}
59
+ }
102
-
103
-static void imx_phy_update_link(IMXFECState *s)
104
-{
105
- /* Autonegotiation status mirrors link status. */
106
- if (qemu_get_queue(s->nic)->link_down) {
107
- trace_imx_phy_update_link("down");
108
- s->phy_status &= ~0x0024;
109
- s->phy_int |= PHY_INT_DOWN;
110
- } else {
111
- trace_imx_phy_update_link("up");
112
- s->phy_status |= 0x0024;
113
- s->phy_int |= PHY_INT_ENERGYON;
114
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
115
- }
116
- imx_phy_update_irq(s);
117
+ imx_eth_update(opaque);
118
}
119
120
static void imx_eth_set_link(NetClientState *nc)
121
{
122
- imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
123
-}
124
-
125
-static void imx_phy_reset(IMXFECState *s)
126
-{
127
- trace_imx_phy_reset();
128
-
129
- s->phy_status = 0x7809;
130
- s->phy_control = 0x3000;
131
- s->phy_advertise = 0x01e1;
132
- s->phy_int_mask = 0;
133
- s->phy_int = 0;
134
- imx_phy_update_link(s);
135
+ lan9118_phy_update_link(&IMX_FEC(qemu_get_nic_opaque(nc))->mii,
136
+ nc->link_down);
137
}
138
139
static uint32_t imx_phy_read(IMXFECState *s, int reg)
140
{
141
- uint32_t val;
142
uint32_t phy = reg / 32;
143
144
if (!s->phy_connected) {
145
@@ -XXX,XX +XXX,XX @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
146
147
reg %= 32;
148
149
- switch (reg) {
150
- case 0: /* Basic Control */
151
- val = s->phy_control;
152
- break;
153
- case 1: /* Basic Status */
154
- val = s->phy_status;
155
- break;
156
- case 2: /* ID1 */
157
- val = 0x0007;
158
- break;
159
- case 3: /* ID2 */
160
- val = 0xc0d1;
161
- break;
162
- case 4: /* Auto-neg advertisement */
163
- val = s->phy_advertise;
164
- break;
165
- case 5: /* Auto-neg Link Partner Ability */
166
- val = 0x0f71;
167
- break;
168
- case 6: /* Auto-neg Expansion */
169
- val = 1;
170
- break;
171
- case 29: /* Interrupt source. */
172
- val = s->phy_int;
173
- s->phy_int = 0;
174
- imx_phy_update_irq(s);
175
- break;
176
- case 30: /* Interrupt mask */
177
- val = s->phy_int_mask;
178
- break;
179
- case 17:
180
- case 18:
181
- case 27:
182
- case 31:
183
- qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
184
- TYPE_IMX_FEC, __func__, reg);
185
- val = 0;
186
- break;
187
- default:
188
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
189
- TYPE_IMX_FEC, __func__, reg);
190
- val = 0;
191
- break;
192
- }
193
-
194
- trace_imx_phy_read(val, phy, reg);
195
-
196
- return val;
197
+ return lan9118_phy_read(&s->mii, reg);
198
}
199
200
static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
201
@@ -XXX,XX +XXX,XX @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
202
203
reg %= 32;
204
205
- trace_imx_phy_write(val, phy, reg);
206
-
207
- switch (reg) {
208
- case 0: /* Basic Control */
209
- if (val & 0x8000) {
210
- imx_phy_reset(s);
211
- } else {
212
- s->phy_control = val & 0x7980;
213
- /* Complete autonegotiation immediately. */
214
- if (val & 0x1000) {
215
- s->phy_status |= 0x0020;
216
- }
217
- }
218
- break;
219
- case 4: /* Auto-neg advertisement */
220
- s->phy_advertise = (val & 0x2d7f) | 0x80;
221
- break;
222
- case 30: /* Interrupt mask */
223
- s->phy_int_mask = val & 0xff;
224
- imx_phy_update_irq(s);
225
- break;
226
- case 17:
227
- case 18:
228
- case 27:
229
- case 31:
230
- qemu_log_mask(LOG_UNIMP, "[%s.phy)%s: reg %d not implemented\n",
231
- TYPE_IMX_FEC, __func__, reg);
232
- break;
233
- default:
234
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
235
- TYPE_IMX_FEC, __func__, reg);
236
- break;
237
- }
238
+ lan9118_phy_write(&s->mii, reg, val);
239
}
240
241
static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
242
@@ -XXX,XX +XXX,XX @@ static void imx_eth_reset(DeviceState *d)
243
244
s->rx_descriptor = 0;
245
memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
246
-
247
- /* We also reset the PHY */
248
- imx_phy_reset(s);
249
}
250
251
static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
252
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
253
sysbus_init_irq(sbd, &s->irq[0]);
254
sysbus_init_irq(sbd, &s->irq[1]);
255
256
+ qemu_init_irq(&s->mii_irq, imx_phy_update_irq, s, 0);
257
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
258
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
259
+ return;
60
+ }
260
+ }
61
261
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
62
/*
262
+
63
* This device provides a single memory region which covers the
263
qemu_macaddr_default_if_unset(&s->conf.macaddr);
264
265
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
266
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
267
index XXXXXXX..XXXXXXX 100644
268
--- a/hw/net/lan9118_phy.c
269
+++ b/hw/net/lan9118_phy.c
270
@@ -XXX,XX +XXX,XX @@
271
* Copyright (c) 2009 CodeSourcery, LLC.
272
* Written by Paul Brook
273
*
274
+ * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
275
+ *
276
* This code is licensed under the GNU GPL v2
277
*
278
* Contributions after 2012-01-13 are licensed under the terms of the
279
@@ -XXX,XX +XXX,XX @@
280
#include "hw/resettable.h"
281
#include "migration/vmstate.h"
282
#include "qemu/log.h"
283
+#include "trace.h"
284
285
#define PHY_INT_ENERGYON (1 << 7)
286
#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
287
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
288
289
switch (reg) {
290
case 0: /* Basic Control */
291
- return s->control;
292
+ val = s->control;
293
+ break;
294
case 1: /* Basic Status */
295
- return s->status;
296
+ val = s->status;
297
+ break;
298
case 2: /* ID1 */
299
- return 0x0007;
300
+ val = 0x0007;
301
+ break;
302
case 3: /* ID2 */
303
- return 0xc0d1;
304
+ val = 0xc0d1;
305
+ break;
306
case 4: /* Auto-neg advertisement */
307
- return s->advertise;
308
+ val = s->advertise;
309
+ break;
310
case 5: /* Auto-neg Link Partner Ability */
311
- return 0x0f71;
312
+ val = 0x0f71;
313
+ break;
314
case 6: /* Auto-neg Expansion */
315
- return 1;
316
- /* TODO 17, 18, 27, 29, 30, 31 */
317
+ val = 1;
318
+ break;
319
case 29: /* Interrupt source. */
320
val = s->ints;
321
s->ints = 0;
322
lan9118_phy_update_irq(s);
323
- return val;
324
+ break;
325
case 30: /* Interrupt mask */
326
- return s->int_mask;
327
+ val = s->int_mask;
328
+ break;
329
+ case 17:
330
+ case 18:
331
+ case 27:
332
+ case 31:
333
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
334
+ __func__, reg);
335
+ val = 0;
336
+ break;
337
default:
338
- qemu_log_mask(LOG_GUEST_ERROR,
339
- "lan9118_phy_read: PHY read reg %d\n", reg);
340
- return 0;
341
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
342
+ __func__, reg);
343
+ val = 0;
344
+ break;
345
}
346
+
347
+ trace_lan9118_phy_read(val, reg);
348
+
349
+ return val;
350
}
351
352
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
353
{
354
+ trace_lan9118_phy_write(val, reg);
355
+
356
switch (reg) {
357
case 0: /* Basic Control */
358
if (val & 0x8000) {
359
lan9118_phy_reset(s);
360
- break;
361
- }
362
- s->control = val & 0x7980;
363
- /* Complete autonegotiation immediately. */
364
- if (val & 0x1000) {
365
- s->status |= 0x0020;
366
+ } else {
367
+ s->control = val & 0x7980;
368
+ /* Complete autonegotiation immediately. */
369
+ if (val & 0x1000) {
370
+ s->status |= 0x0020;
371
+ }
372
}
373
break;
374
case 4: /* Auto-neg advertisement */
375
s->advertise = (val & 0x2d7f) | 0x80;
376
break;
377
- /* TODO 17, 18, 27, 31 */
378
case 30: /* Interrupt mask */
379
s->int_mask = val & 0xff;
380
lan9118_phy_update_irq(s);
381
break;
382
+ case 17:
383
+ case 18:
384
+ case 27:
385
+ case 31:
386
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
387
+ __func__, reg);
388
+ break;
389
default:
390
- qemu_log_mask(LOG_GUEST_ERROR,
391
- "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
392
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
393
+ __func__, reg);
394
+ break;
395
}
396
}
397
398
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
399
400
/* Autonegotiation status mirrors link status. */
401
if (link_down) {
402
+ trace_lan9118_phy_update_link("down");
403
s->status &= ~0x0024;
404
s->ints |= PHY_INT_DOWN;
405
} else {
406
+ trace_lan9118_phy_update_link("up");
407
s->status |= 0x0024;
408
s->ints |= PHY_INT_ENERGYON;
409
s->ints |= PHY_INT_AUTONEG_COMPLETE;
410
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
411
412
void lan9118_phy_reset(Lan9118PhyState *s)
413
{
414
+ trace_lan9118_phy_reset();
415
+
416
s->control = 0x3000;
417
s->status = 0x7809;
418
s->advertise = 0x01e1;
419
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_phy = {
420
.version_id = 1,
421
.minimum_version_id = 1,
422
.fields = (const VMStateField[]) {
423
- VMSTATE_UINT16(control, Lan9118PhyState),
424
VMSTATE_UINT16(status, Lan9118PhyState),
425
+ VMSTATE_UINT16(control, Lan9118PhyState),
426
VMSTATE_UINT16(advertise, Lan9118PhyState),
427
VMSTATE_UINT16(ints, Lan9118PhyState),
428
VMSTATE_UINT16(int_mask, Lan9118PhyState),
429
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
430
index XXXXXXX..XXXXXXX 100644
431
--- a/hw/net/Kconfig
432
+++ b/hw/net/Kconfig
433
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_SUN8I_EMAC
434
435
config IMX_FEC
436
bool
437
+ select LAN9118_PHY
438
439
config CADENCE
440
bool
441
diff --git a/hw/net/trace-events b/hw/net/trace-events
442
index XXXXXXX..XXXXXXX 100644
443
--- a/hw/net/trace-events
444
+++ b/hw/net/trace-events
445
@@ -XXX,XX +XXX,XX @@ allwinner_sun8i_emac_set_link(bool active) "Set link: active=%u"
446
allwinner_sun8i_emac_read(uint64_t offset, uint64_t val) "MMIO read: offset=0x%" PRIx64 " value=0x%" PRIx64
447
allwinner_sun8i_emac_write(uint64_t offset, uint64_t val) "MMIO write: offset=0x%" PRIx64 " value=0x%" PRIx64
448
449
+# lan9118_phy.c
450
+lan9118_phy_read(uint16_t val, int reg) "[0x%02x] -> 0x%04" PRIx16
451
+lan9118_phy_write(uint16_t val, int reg) "[0x%02x] <- 0x%04" PRIx16
452
+lan9118_phy_update_link(const char *s) "%s"
453
+lan9118_phy_reset(void) ""
454
+
455
# lance.c
456
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x"
457
lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x"
458
@@ -XXX,XX +XXX,XX @@ i82596_set_multicast(uint16_t count) "Added %d multicast entries"
459
i82596_channel_attention(void *s) "%p: Received CHANNEL ATTENTION"
460
461
# imx_fec.c
462
-imx_phy_read(uint32_t val, int phy, int reg) "0x%04"PRIx32" <= phy[%d].reg[%d]"
463
imx_phy_read_num(int phy, int configured) "read request from unconfigured phy %d (configured %d)"
464
-imx_phy_write(uint32_t val, int phy, int reg) "0x%04"PRIx32" => phy[%d].reg[%d]"
465
imx_phy_write_num(int phy, int configured) "write request to unconfigured phy %d (configured %d)"
466
-imx_phy_update_link(const char *s) "%s"
467
-imx_phy_reset(void) ""
468
imx_fec_read_bd(uint64_t addr, int flags, int len, int data) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x"
469
imx_enet_read_bd(uint64_t addr, int flags, int len, int data, int options, int status) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x option 0x%04x status 0x%04x"
470
imx_eth_tx_bd_busy(void) "tx_bd ran out of descriptors to transmit"
64
--
471
--
65
2.34.1
472
2.34.1
diff view generated by jsdifflib
New patch
1
From: Bernhard Beschow <shentey@gmail.com>
1
2
3
Turns 0x70 into 0xe0 (== 0x70 << 1) which adds the missing MII_ANLPAR_TX and
4
fixes the MSB of selector field to be zero, as specified in the datasheet.
5
6
Fixes: 2a424990170b "LAN9118 emulation"
7
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
8
Tested-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20241102125724.532843-4-shentey@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/net/lan9118_phy.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/lan9118_phy.c
19
+++ b/hw/net/lan9118_phy.c
20
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
21
val = s->advertise;
22
break;
23
case 5: /* Auto-neg Link Partner Ability */
24
- val = 0x0f71;
25
+ val = 0x0fe1;
26
break;
27
case 6: /* Auto-neg Expansion */
28
val = 1;
29
--
30
2.34.1
diff view generated by jsdifflib
New patch
1
From: Bernhard Beschow <shentey@gmail.com>
1
2
3
Prefer named constants over magic values for better readability.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
7
Tested-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20241102125724.532843-5-shentey@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/net/mii.h | 6 +++++
12
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
13
2 files changed, 46 insertions(+), 23 deletions(-)
14
15
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/net/mii.h
18
+++ b/include/hw/net/mii.h
19
@@ -XXX,XX +XXX,XX @@
20
#define MII_BMSR_JABBER (1 << 1) /* Jabber detected */
21
#define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */
22
23
+#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */
24
#define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */
25
#define MII_ANAR_PAUSE (1 << 10) /* Try for pause */
26
#define MII_ANAR_TXFD (1 << 8)
27
@@ -XXX,XX +XXX,XX @@
28
#define MII_ANAR_10FD (1 << 6)
29
#define MII_ANAR_10 (1 << 5)
30
#define MII_ANAR_CSMACD (1 << 0)
31
+#define MII_ANAR_SELECT (0x001f) /* Selector bits */
32
33
#define MII_ANLPAR_ACK (1 << 14)
34
#define MII_ANLPAR_PAUSEASY (1 << 11) /* can pause asymmetrically */
35
@@ -XXX,XX +XXX,XX @@
36
#define RTL8201CP_PHYID1 0x0000
37
#define RTL8201CP_PHYID2 0x8201
38
39
+/* SMSC LAN9118 */
40
+#define SMSCLAN9118_PHYID1 0x0007
41
+#define SMSCLAN9118_PHYID2 0xc0d1
42
+
43
/* RealTek 8211E */
44
#define RTL8211E_PHYID1 0x001c
45
#define RTL8211E_PHYID2 0xc915
46
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/net/lan9118_phy.c
49
+++ b/hw/net/lan9118_phy.c
50
@@ -XXX,XX +XXX,XX @@
51
52
#include "qemu/osdep.h"
53
#include "hw/net/lan9118_phy.h"
54
+#include "hw/net/mii.h"
55
#include "hw/irq.h"
56
#include "hw/resettable.h"
57
#include "migration/vmstate.h"
58
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
59
uint16_t val;
60
61
switch (reg) {
62
- case 0: /* Basic Control */
63
+ case MII_BMCR:
64
val = s->control;
65
break;
66
- case 1: /* Basic Status */
67
+ case MII_BMSR:
68
val = s->status;
69
break;
70
- case 2: /* ID1 */
71
- val = 0x0007;
72
+ case MII_PHYID1:
73
+ val = SMSCLAN9118_PHYID1;
74
break;
75
- case 3: /* ID2 */
76
- val = 0xc0d1;
77
+ case MII_PHYID2:
78
+ val = SMSCLAN9118_PHYID2;
79
break;
80
- case 4: /* Auto-neg advertisement */
81
+ case MII_ANAR:
82
val = s->advertise;
83
break;
84
- case 5: /* Auto-neg Link Partner Ability */
85
- val = 0x0fe1;
86
+ case MII_ANLPAR:
87
+ val = MII_ANLPAR_PAUSEASY | MII_ANLPAR_PAUSE | MII_ANLPAR_T4 |
88
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
89
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
90
break;
91
- case 6: /* Auto-neg Expansion */
92
- val = 1;
93
+ case MII_ANER:
94
+ val = MII_ANER_NWAY;
95
break;
96
case 29: /* Interrupt source. */
97
val = s->ints;
98
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
99
trace_lan9118_phy_write(val, reg);
100
101
switch (reg) {
102
- case 0: /* Basic Control */
103
- if (val & 0x8000) {
104
+ case MII_BMCR:
105
+ if (val & MII_BMCR_RESET) {
106
lan9118_phy_reset(s);
107
} else {
108
- s->control = val & 0x7980;
109
+ s->control = val & (MII_BMCR_LOOPBACK | MII_BMCR_SPEED100 |
110
+ MII_BMCR_AUTOEN | MII_BMCR_PDOWN | MII_BMCR_FD |
111
+ MII_BMCR_CTST);
112
/* Complete autonegotiation immediately. */
113
- if (val & 0x1000) {
114
- s->status |= 0x0020;
115
+ if (val & MII_BMCR_AUTOEN) {
116
+ s->status |= MII_BMSR_AN_COMP;
117
}
118
}
119
break;
120
- case 4: /* Auto-neg advertisement */
121
- s->advertise = (val & 0x2d7f) | 0x80;
122
+ case MII_ANAR:
123
+ s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
124
+ MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
125
+ MII_ANAR_SELECT))
126
+ | MII_ANAR_TX;
127
break;
128
case 30: /* Interrupt mask */
129
s->int_mask = val & 0xff;
130
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
131
/* Autonegotiation status mirrors link status. */
132
if (link_down) {
133
trace_lan9118_phy_update_link("down");
134
- s->status &= ~0x0024;
135
+ s->status &= ~(MII_BMSR_AN_COMP | MII_BMSR_LINK_ST);
136
s->ints |= PHY_INT_DOWN;
137
} else {
138
trace_lan9118_phy_update_link("up");
139
- s->status |= 0x0024;
140
+ s->status |= MII_BMSR_AN_COMP | MII_BMSR_LINK_ST;
141
s->ints |= PHY_INT_ENERGYON;
142
s->ints |= PHY_INT_AUTONEG_COMPLETE;
143
}
144
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_reset(Lan9118PhyState *s)
145
{
146
trace_lan9118_phy_reset();
147
148
- s->control = 0x3000;
149
- s->status = 0x7809;
150
- s->advertise = 0x01e1;
151
+ s->control = MII_BMCR_AUTOEN | MII_BMCR_SPEED100;
152
+ s->status = MII_BMSR_100TX_FD
153
+ | MII_BMSR_100TX_HD
154
+ | MII_BMSR_10T_FD
155
+ | MII_BMSR_10T_HD
156
+ | MII_BMSR_AUTONEG
157
+ | MII_BMSR_EXTCAP;
158
+ s->advertise = MII_ANAR_TXFD
159
+ | MII_ANAR_TX
160
+ | MII_ANAR_10FD
161
+ | MII_ANAR_10
162
+ | MII_ANAR_CSMACD;
163
s->int_mask = 0;
164
s->ints = 0;
165
lan9118_phy_update_link(s, s->link_down);
166
--
167
2.34.1
diff view generated by jsdifflib
New patch
1
From: Bernhard Beschow <shentey@gmail.com>
1
2
3
The real device advertises this mode and the device model already advertises
4
100 mbps half duplex and 10 mbps full+half duplex. So advertise this mode to
5
make the model more realistic.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
9
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
Message-id: 20241102125724.532843-6-shentey@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/net/lan9118_phy.c | 4 ++--
14
1 file changed, 2 insertions(+), 2 deletions(-)
15
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/lan9118_phy.c
19
+++ b/hw/net/lan9118_phy.c
20
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
21
break;
22
case MII_ANAR:
23
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
24
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
25
- MII_ANAR_SELECT))
26
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
27
+ MII_ANAR_10 | MII_ANAR_SELECT))
28
| MII_ANAR_TX;
29
break;
30
case 30: /* Interrupt mask */
31
--
32
2.34.1
diff view generated by jsdifflib
1
In handle_sys() we don't do the check for whether the register is
1
For IEEE fused multiply-add, the (0 * inf) + NaN case should raise
2
marked as needing an FPU/SVE/SME access check until after we've
2
Invalid for the multiplication of 0 by infinity. Currently we handle
3
handled the special cases covered by ARM_CP_SPECIAL_MASK. This is
3
this in the per-architecture ifdef ladder in pickNaNMulAdd().
4
conceptually the wrong way around, because if for example we happen
4
However, since this isn't really architecture specific we can hoist
5
to implement an FPU-access-checked register as ARM_CP_NOP, we should
5
it up to the generic code.
6
do the access check first.
7
6
8
Move the access checks up so they are with all the other access
7
For the cases where the infzero test in pickNaNMulAdd was
9
checks, not sandwiched between the special-case read/write handling
8
returning 2, we can delete the check entirely and allow the
10
and the normal-case read/write handling. This doesn't change
9
code to fall into the normal pick-a-NaN handling, because this
11
behaviour at the moment, because we happen not to define any
10
will return 2 anyway (input 'c' being the only NaN in this case).
12
cpregs with both ARM_CPU_{FPU,SVE,SME} and one of the cases
11
For the cases where infzero was returning 3 to indicate "return
13
dealt with by ARM_CP_SPECIAL_MASK.
12
the default NaN", we must retain that "return 3".
14
13
15
Moving this code also means we have the correct place to put the
14
For Arm, this looks like it might be a behaviour change because we
16
FEAT_NV/FEAT_NV2 access handling, which should come after the access
15
used to set float_flag_invalid | float_flag_invalid_imz only if C is
17
checks and before we try to do any read/write action.
16
a quiet NaN. However, it is not, because Arm target code never looks
17
at float_flag_invalid_imz, and for the (0 * inf) + SNaN case we
18
already raised float_flag_invalid via the "abc_mask &
19
float_cmask_snan" check in pick_nan_muladd.
20
21
For any target architecture using the "default implementation" at the
22
bottom of the ifdef, this is a behaviour change but will be fixing a
23
bug (where we failed to raise the Invalid exception for (0 * inf +
24
QNaN). The architectures using the default case are:
25
* hppa
26
* i386
27
* sh4
28
* tricore
29
30
The x86, Tricore and SH4 CPU architecture manuals are clear that this
31
should have raised Invalid; HPPA is a bit vaguer but still seems
32
clear enough.
18
33
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Tested-by: Miguel Luis <miguel.luis@oracle.com>
36
Message-id: 20241202131347.498124-2-peter.maydell@linaro.org
22
---
37
---
23
target/arm/tcg/translate-a64.c | 15 ++++++++-------
38
fpu/softfloat-parts.c.inc | 13 +++++++------
24
1 file changed, 8 insertions(+), 7 deletions(-)
39
fpu/softfloat-specialize.c.inc | 29 +----------------------------
40
2 files changed, 8 insertions(+), 34 deletions(-)
25
41
26
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
42
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
27
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/tcg/translate-a64.c
44
--- a/fpu/softfloat-parts.c.inc
29
+++ b/target/arm/tcg/translate-a64.c
45
+++ b/fpu/softfloat-parts.c.inc
30
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
46
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
31
gen_a64_update_pc(s, 0);
47
int ab_mask, int abc_mask)
48
{
49
int which;
50
+ bool infzero = (ab_mask == float_cmask_infzero);
51
52
if (unlikely(abc_mask & float_cmask_snan)) {
53
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
32
}
54
}
33
55
34
+ if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
56
- which = pickNaNMulAdd(a->cls, b->cls, c->cls,
35
+ return;
57
- ab_mask == float_cmask_infzero, s);
36
+ } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
58
+ if (infzero) {
37
+ return;
59
+ /* This is (0 * inf) + NaN or (inf * 0) + NaN */
38
+ } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
60
+ float_raise(float_flag_invalid | float_flag_invalid_imz, s);
39
+ return;
40
+ }
61
+ }
41
+
62
+
42
/* Handle special cases first */
63
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
43
switch (ri->type & ARM_CP_SPECIAL_MASK) {
64
44
case 0:
65
if (s->default_nan_mode || which == 3) {
45
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
66
- /*
46
default:
67
- * Note that this check is after pickNaNMulAdd so that function
47
g_assert_not_reached();
68
- * has an opportunity to set the Invalid flag for infzero.
69
- */
70
parts_default_nan(a, s);
71
return a;
48
}
72
}
49
- if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
73
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
50
- return;
74
index XXXXXXX..XXXXXXX 100644
51
- } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
75
--- a/fpu/softfloat-specialize.c.inc
52
- return;
76
+++ b/fpu/softfloat-specialize.c.inc
53
- } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
77
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
54
- return;
78
* the default NaN
79
*/
80
if (infzero && is_qnan(c_cls)) {
81
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
82
return 3;
83
}
84
85
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
86
* case sets InvalidOp and returns the default NaN
87
*/
88
if (infzero) {
89
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
90
return 3;
91
}
92
/* Prefer sNaN over qNaN, in the a, b, c order. */
93
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
94
* For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
95
* case sets InvalidOp and returns the input value 'c'
96
*/
97
- if (infzero) {
98
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
99
- return 2;
100
- }
101
/* Prefer sNaN over qNaN, in the c, a, b order. */
102
if (is_snan(c_cls)) {
103
return 2;
104
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
105
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
106
* case sets InvalidOp and returns the input value 'c'
107
*/
108
- if (infzero) {
109
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
110
- return 2;
55
- }
111
- }
56
112
+
57
if (ri->type & ARM_CP_IO) {
113
/* Prefer sNaN over qNaN, in the c, a, b order. */
58
/* I/O operations must end the TB here (whether read or write) */
114
if (is_snan(c_cls)) {
115
return 2;
116
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
117
* to return an input NaN if we have one (ie c) rather than generating
118
* a default NaN
119
*/
120
- if (infzero) {
121
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
122
- return 2;
123
- }
124
125
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
126
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
127
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
128
return 1;
129
}
130
#elif defined(TARGET_RISCV)
131
- /* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */
132
- if (infzero) {
133
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
134
- }
135
return 3; /* default NaN */
136
#elif defined(TARGET_S390X)
137
if (infzero) {
138
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
139
return 3;
140
}
141
142
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
143
return 2;
144
}
145
#elif defined(TARGET_SPARC)
146
- /* For (inf,0,nan) return c. */
147
- if (infzero) {
148
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
149
- return 2;
150
- }
151
/* Prefer SNaN over QNaN, order C, B, A. */
152
if (is_snan(c_cls)) {
153
return 2;
154
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
155
* For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
156
* an input NaN if we have one (ie c).
157
*/
158
- if (infzero) {
159
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
160
- return 2;
161
- }
162
if (status->use_first_nan) {
163
if (is_nan(a_cls)) {
164
return 0;
59
--
165
--
60
2.34.1
166
2.34.1
diff view generated by jsdifflib
New patch
1
If the target sets default_nan_mode then we're always going to return
2
the default NaN, and pickNaNMulAdd() no longer has any side effects.
3
For consistency with pickNaN(), check for default_nan_mode before
4
calling pickNaNMulAdd().
1
5
6
When we convert pickNaNMulAdd() to allow runtime selection of the NaN
7
propagation rule, this means we won't have to make the targets which
8
use default_nan_mode also set a propagation rule.
9
10
Since RiscV always uses default_nan_mode, this allows us to remove
11
its ifdef case from pickNaNMulAdd().
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-3-peter.maydell@linaro.org
16
---
17
fpu/softfloat-parts.c.inc | 8 ++++++--
18
fpu/softfloat-specialize.c.inc | 9 +++++++--
19
2 files changed, 13 insertions(+), 4 deletions(-)
20
21
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
index XXXXXXX..XXXXXXX 100644
23
--- a/fpu/softfloat-parts.c.inc
24
+++ b/fpu/softfloat-parts.c.inc
25
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
26
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
27
}
28
29
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
30
+ if (s->default_nan_mode) {
31
+ which = 3;
32
+ } else {
33
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ }
35
36
- if (s->default_nan_mode || which == 3) {
37
+ if (which == 3) {
38
parts_default_nan(a, s);
39
return a;
40
}
41
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
42
index XXXXXXX..XXXXXXX 100644
43
--- a/fpu/softfloat-specialize.c.inc
44
+++ b/fpu/softfloat-specialize.c.inc
45
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
46
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
47
bool infzero, float_status *status)
48
{
49
+ /*
50
+ * We guarantee not to require the target to tell us how to
51
+ * pick a NaN if we're always returning the default NaN.
52
+ * But if we're not in default-NaN mode then the target must
53
+ * specify.
54
+ */
55
+ assert(!status->default_nan_mode);
56
#if defined(TARGET_ARM)
57
/* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
58
* the default NaN
59
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
60
} else {
61
return 1;
62
}
63
-#elif defined(TARGET_RISCV)
64
- return 3; /* default NaN */
65
#elif defined(TARGET_S390X)
66
if (infzero) {
67
return 3;
68
--
69
2.34.1
diff view generated by jsdifflib
1
For FEAT_VHE, we define a set of register aliases, so that for instance:
1
IEEE 758 does not define a fixed rule for what NaN to return in
2
* the SCTLR_EL1 either accesses the real SCTLR_EL1, or (if E2H is 1)
2
the case of a fused multiply-add of inf * 0 + NaN. Different
3
SCTLR_EL2
3
architectures thus do different things:
4
* a new SCTLR_EL12 register accesses SCTLR_EL1 if E2H is 1
4
* some return the default NaN
5
5
* some return the input NaN
6
However when we create the 'new_reg' cpreg struct for the SCTLR_EL12
6
* Arm returns the default NaN if the input NaN is quiet,
7
register, we duplicate the information in the SCTLR_EL1 cpreg, which
7
and the input NaN if it is signalling
8
means the opcode fields are those of SCTLR_EL1, not SCTLR_EL12. This
8
9
is a problem for code which looks at the cpreg opcode fields to
9
We want to make this logic be runtime selected rather than
10
determine behaviour (e.g. in access_check_cp_reg()). In practice
10
hardcoded into the binary, because:
11
the current checks we do there don't intersect with the *_EL12
11
* this will let us have multiple targets in one QEMU binary
12
registers, but for FEAT_NV this will become a problem.
12
* the Arm FEAT_AFP architectural feature includes letting
13
13
the guest select a NaN propagation rule at runtime
14
Write the correct values from the encoding into the new_reg struct.
14
15
This restores the invariant that the cpreg that you get back
15
In this commit we add an enum for the propagation rule, the field in
16
from the hashtable has opcode fields that match the key you used
16
float_status, and the corresponding getters and setters. We change
17
to retrieve it.
17
pickNaNMulAdd to honour this, but because all targets still leave
18
18
this field at its default 0 value, the fallback logic will pick the
19
When we call the readfn or writefn for the target register, we
19
rule type with the old ifdef ladder.
20
pass it the cpreg struct for that target register, not the one
20
21
for the alias, in case the readfn/writefn want to look at the
21
Note that four architectures both use the muladd softfloat functions
22
opcode fields to determine behaviour. This means we need to
22
and did not have a branch of the ifdef ladder to specify their
23
interpose custom read/writefns for the e12 aliases.
23
behaviour (and so were ending up with the "default" case, probably
24
wrongly): i386, HPPA, SH4 and Tricore. SH4 and Tricore both set
25
default_nan_mode, and so will never get into pickNaNMulAdd(). For
26
HPPA and i386 we retain the same behaviour as the old default-case,
27
which is to not ever return the default NaN. This might not be
28
correct but it is not a behaviour change.
24
29
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Tested-by: Miguel Luis <miguel.luis@oracle.com>
32
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
28
---
33
---
29
target/arm/helper.c | 35 +++++++++++++++++++++++++++++++++++
34
include/fpu/softfloat-helpers.h | 11 ++++
30
1 file changed, 35 insertions(+)
35
include/fpu/softfloat-types.h | 23 +++++++++
31
36
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
37
3 files changed, 95 insertions(+), 30 deletions(-)
38
39
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
33
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
41
--- a/include/fpu/softfloat-helpers.h
35
+++ b/target/arm/helper.c
42
+++ b/include/fpu/softfloat-helpers.h
36
@@ -XXX,XX +XXX,XX @@ static void el2_e2h_write(CPUARMState *env, const ARMCPRegInfo *ri,
43
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
37
writefn(env, ri, value);
44
status->float_2nan_prop_rule = rule;
38
}
45
}
39
46
40
+static uint64_t el2_e2h_e12_read(CPUARMState *env, const ARMCPRegInfo *ri)
47
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
+ float_status *status)
41
+{
49
+{
42
+ /* Pass the EL1 register accessor its ri, not the EL12 alias ri */
50
+ status->float_infzeronan_rule = rule;
43
+ return ri->orig_readfn(env, ri->opaque);
44
+}
51
+}
45
+
52
+
46
+static void el2_e2h_e12_write(CPUARMState *env, const ARMCPRegInfo *ri,
53
static inline void set_flush_to_zero(bool val, float_status *status)
47
+ uint64_t value)
54
{
55
status->flush_to_zero = val;
56
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
57
return status->float_2nan_prop_rule;
58
}
59
60
+static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
48
+{
61
+{
49
+ /* Pass the EL1 register accessor its ri, not the EL12 alias ri */
62
+ return status->float_infzeronan_rule;
50
+ return ri->orig_writefn(env, ri->opaque, value);
51
+}
63
+}
52
+
64
+
53
static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
65
static inline bool get_flush_to_zero(float_status *status)
54
{
66
{
55
struct E2HAlias {
67
return status->flush_to_zero;
56
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
68
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
57
new_reg->type |= ARM_CP_ALIAS;
69
index XXXXXXX..XXXXXXX 100644
58
/* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
70
--- a/include/fpu/softfloat-types.h
59
new_reg->access &= PL2_RW | PL3_RW;
71
+++ b/include/fpu/softfloat-types.h
60
+ /* The new_reg op fields are as per new_key, not the target reg */
72
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
61
+ new_reg->crn = (a->new_key & CP_REG_ARM64_SYSREG_CRN_MASK)
73
float_2nan_prop_x87,
62
+ >> CP_REG_ARM64_SYSREG_CRN_SHIFT;
74
} Float2NaNPropRule;
63
+ new_reg->crm = (a->new_key & CP_REG_ARM64_SYSREG_CRM_MASK)
75
64
+ >> CP_REG_ARM64_SYSREG_CRM_SHIFT;
76
+/*
65
+ new_reg->opc0 = (a->new_key & CP_REG_ARM64_SYSREG_OP0_MASK)
77
+ * Rule for result of fused multiply-add 0 * Inf + NaN.
66
+ >> CP_REG_ARM64_SYSREG_OP0_SHIFT;
78
+ * This must be a NaN, but implementations differ on whether this
67
+ new_reg->opc1 = (a->new_key & CP_REG_ARM64_SYSREG_OP1_MASK)
79
+ * is the input NaN or the default NaN.
68
+ >> CP_REG_ARM64_SYSREG_OP1_SHIFT;
80
+ *
69
+ new_reg->opc2 = (a->new_key & CP_REG_ARM64_SYSREG_OP2_MASK)
81
+ * You don't need to set this if default_nan_mode is enabled.
70
+ >> CP_REG_ARM64_SYSREG_OP2_SHIFT;
82
+ * When not in default-NaN mode, it is an error for the target
71
+ new_reg->opaque = src_reg;
83
+ * not to set the rule in float_status if it uses muladd, and we
72
+ new_reg->orig_readfn = src_reg->readfn ?: raw_read;
84
+ * will assert if we need to handle an input NaN and no rule was
73
+ new_reg->orig_writefn = src_reg->writefn ?: raw_write;
85
+ * selected.
74
+ if (!new_reg->raw_readfn) {
86
+ */
75
+ new_reg->raw_readfn = raw_read;
87
+typedef enum __attribute__((__packed__)) {
88
+ /* No propagation rule specified */
89
+ float_infzeronan_none = 0,
90
+ /* Result is never the default NaN (so always the input NaN) */
91
+ float_infzeronan_dnan_never,
92
+ /* Result is always the default NaN */
93
+ float_infzeronan_dnan_always,
94
+ /* Result is the default NaN if the input NaN is quiet */
95
+ float_infzeronan_dnan_if_qnan,
96
+} FloatInfZeroNaNRule;
97
+
98
/*
99
* Floating Point Status. Individual architectures may maintain
100
* several versions of float_status for different functions. The
101
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
102
FloatRoundMode float_rounding_mode;
103
FloatX80RoundPrec floatx80_rounding_precision;
104
Float2NaNPropRule float_2nan_prop_rule;
105
+ FloatInfZeroNaNRule float_infzeronan_rule;
106
bool tininess_before_rounding;
107
/* should denormalised results go to zero and set the inexact flag? */
108
bool flush_to_zero;
109
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
110
index XXXXXXX..XXXXXXX 100644
111
--- a/fpu/softfloat-specialize.c.inc
112
+++ b/fpu/softfloat-specialize.c.inc
113
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
114
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
115
bool infzero, float_status *status)
116
{
117
+ FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
118
+
119
/*
120
* We guarantee not to require the target to tell us how to
121
* pick a NaN if we're always returning the default NaN.
122
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
123
* specify.
124
*/
125
assert(!status->default_nan_mode);
126
+
127
+ if (rule == float_infzeronan_none) {
128
+ /*
129
+ * Temporarily fall back to ifdef ladder
130
+ */
131
#if defined(TARGET_ARM)
132
- /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
133
- * the default NaN
134
- */
135
- if (infzero && is_qnan(c_cls)) {
136
- return 3;
137
+ /*
138
+ * For ARM, the (inf,zero,qnan) case returns the default NaN,
139
+ * but (inf,zero,snan) returns the input NaN.
140
+ */
141
+ rule = float_infzeronan_dnan_if_qnan;
142
+#elif defined(TARGET_MIPS)
143
+ if (snan_bit_is_one(status)) {
144
+ /*
145
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
146
+ * case sets InvalidOp and returns the default NaN
147
+ */
148
+ rule = float_infzeronan_dnan_always;
149
+ } else {
150
+ /*
151
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
152
+ * case sets InvalidOp and returns the input value 'c'
153
+ */
154
+ rule = float_infzeronan_dnan_never;
76
+ }
155
+ }
77
+ if (!new_reg->raw_writefn) {
156
+#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
78
+ new_reg->raw_writefn = raw_write;
157
+ defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
158
+ defined(TARGET_I386) || defined(TARGET_LOONGARCH)
159
+ /*
160
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
161
+ * case sets InvalidOp and returns the input value 'c'
162
+ */
163
+ /*
164
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
165
+ * to return an input NaN if we have one (ie c) rather than generating
166
+ * a default NaN
167
+ */
168
+ rule = float_infzeronan_dnan_never;
169
+#elif defined(TARGET_S390X)
170
+ rule = float_infzeronan_dnan_always;
171
+#endif
172
}
173
174
+ if (infzero) {
175
+ /*
176
+ * Inf * 0 + NaN -- some implementations return the default NaN here,
177
+ * and some return the input NaN.
178
+ */
179
+ switch (rule) {
180
+ case float_infzeronan_dnan_never:
181
+ return 2;
182
+ case float_infzeronan_dnan_always:
183
+ return 3;
184
+ case float_infzeronan_dnan_if_qnan:
185
+ return is_qnan(c_cls) ? 3 : 2;
186
+ default:
187
+ g_assert_not_reached();
79
+ }
188
+ }
80
+ new_reg->readfn = el2_e2h_e12_read;
189
+ }
81
+ new_reg->writefn = el2_e2h_e12_write;
190
+
82
191
+#if defined(TARGET_ARM)
83
ok = g_hash_table_insert(cpu->cp_regs,
192
+
84
(gpointer)(uintptr_t)a->new_key, new_reg);
193
/* This looks different from the ARM ARM pseudocode, because the ARM ARM
194
* puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
195
*/
196
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
197
}
198
#elif defined(TARGET_MIPS)
199
if (snan_bit_is_one(status)) {
200
- /*
201
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
202
- * case sets InvalidOp and returns the default NaN
203
- */
204
- if (infzero) {
205
- return 3;
206
- }
207
/* Prefer sNaN over qNaN, in the a, b, c order. */
208
if (is_snan(a_cls)) {
209
return 0;
210
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
211
return 2;
212
}
213
} else {
214
- /*
215
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
216
- * case sets InvalidOp and returns the input value 'c'
217
- */
218
/* Prefer sNaN over qNaN, in the c, a, b order. */
219
if (is_snan(c_cls)) {
220
return 2;
221
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
222
}
223
}
224
#elif defined(TARGET_LOONGARCH64)
225
- /*
226
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
227
- * case sets InvalidOp and returns the input value 'c'
228
- */
229
-
230
/* Prefer sNaN over qNaN, in the c, a, b order. */
231
if (is_snan(c_cls)) {
232
return 2;
233
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
234
return 1;
235
}
236
#elif defined(TARGET_PPC)
237
- /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
238
- * to return an input NaN if we have one (ie c) rather than generating
239
- * a default NaN
240
- */
241
-
242
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
243
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
244
*/
245
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
246
return 1;
247
}
248
#elif defined(TARGET_S390X)
249
- if (infzero) {
250
- return 3;
251
- }
252
-
253
if (is_snan(a_cls)) {
254
return 0;
255
} else if (is_snan(b_cls)) {
85
--
256
--
86
2.34.1
257
2.34.1
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for the inf-zero-nan
2
muladd special case. In meson.build we put -DTARGET_ARM in fpcflags,
3
and so we should select here the Arm rule of
4
float_infzeronan_dnan_if_qnan.
1
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241202131347.498124-5-peter.maydell@linaro.org
9
---
10
tests/fp/fp-bench.c | 5 +++++
11
tests/fp/fp-test.c | 5 +++++
12
2 files changed, 10 insertions(+)
13
14
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/fp/fp-bench.c
17
+++ b/tests/fp/fp-bench.c
18
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
19
{
20
bench_func_t f;
21
22
+ /*
23
+ * These implementation-defined choices for various things IEEE
24
+ * doesn't specify match those used by the Arm architecture.
25
+ */
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
28
29
f = bench_funcs[operation][precision];
30
g_assert(f);
31
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/tests/fp/fp-test.c
34
+++ b/tests/fp/fp-test.c
35
@@ -XXX,XX +XXX,XX @@ void run_test(void)
36
{
37
unsigned int i;
38
39
+ /*
40
+ * These implementation-defined choices for various things IEEE
41
+ * doesn't specify match those used by the Arm architecture.
42
+ */
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
44
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
45
46
genCases_setLevel(test_level);
47
verCases_maxErrorCount = n_max_errors;
48
--
49
2.34.1
diff view generated by jsdifflib
1
When interpreting CPU dumps where FEAT_NV and FEAT_NV2 are in use,
1
Set the FloatInfZeroNaNRule explicitly for the Arm target,
2
it's helpful to include the values of HCR_EL2.{NV,NV1,NV2} in the CPU
2
so we can remove the ifdef from pickNaNMulAdd().
3
dump format, as a way of distinguishing when we are in EL1 as part of
4
executing guest-EL2 and when we are just in normal EL1.
5
6
Add the bits to the end of the log line that shows PSTATE and similar
7
information:
8
9
PSTATE=000003c9 ---- EL2h BTYPE=0 NV NV2
10
3
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Miguel Luis <miguel.luis@oracle.com>
6
Message-id: 20241202131347.498124-6-peter.maydell@linaro.org
14
---
7
---
15
target/arm/cpu.c | 5 +++++
8
target/arm/cpu.c | 3 +++
16
1 file changed, 5 insertions(+)
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 4 insertions(+), 7 deletions(-)
17
11
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
14
--- a/target/arm/cpu.c
21
+++ b/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
22
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
23
uint32_t psr = pstate_read(env);
17
* * tininess-before-rounding
24
int i, j;
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
25
int el = arm_current_el(env);
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
26
+ uint64_t hcr = arm_hcr_el2_eff(env);
20
+ * * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
27
const char *ns_status;
21
+ * and the input NaN if it is signalling
28
bool sve;
22
*/
29
23
static void arm_set_default_fp_behaviours(float_status *s)
30
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
24
{
31
if (cpu_isar_feature(aa64_bti, cpu)) {
25
set_float_detect_tininess(float_tininess_before_rounding, s);
32
qemu_fprintf(f, " BTYPE=%d", (psr & PSTATE_BTYPE) >> 10);
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
33
}
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
34
+ qemu_fprintf(f, "%s%s%s",
28
}
35
+ (hcr & HCR_NV) ? " NV" : "",
29
36
+ (hcr & HCR_NV1) ? " NV1" : "",
30
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
37
+ (hcr & HCR_NV2) ? " NV2" : "");
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
38
if (!(flags & CPU_DUMP_FPU)) {
32
index XXXXXXX..XXXXXXX 100644
39
qemu_fprintf(f, "\n");
33
--- a/fpu/softfloat-specialize.c.inc
40
return;
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
/*
37
* Temporarily fall back to ifdef ladder
38
*/
39
-#if defined(TARGET_ARM)
40
- /*
41
- * For ARM, the (inf,zero,qnan) case returns the default NaN,
42
- * but (inf,zero,snan) returns the input NaN.
43
- */
44
- rule = float_infzeronan_dnan_if_qnan;
45
-#elif defined(TARGET_MIPS)
46
+#if defined(TARGET_MIPS)
47
if (snan_bit_is_one(status)) {
48
/*
49
* For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
41
--
50
--
42
2.34.1
51
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for s390, so we
2
can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-7-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_infzeronan_rule(float_infzeronan_dnan_always,
21
+ &env->fpu_status);
22
/* fall through */
23
case RESET_TYPE_S390_CPU_NORMAL:
24
env->psw.mask &= ~PSW_MASK_RI;
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
* a default NaN
31
*/
32
rule = float_infzeronan_dnan_never;
33
-#elif defined(TARGET_S390X)
34
- rule = float_infzeronan_dnan_always;
35
#endif
36
}
37
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the PPC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-8-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 7 +++++++
9
fpu/softfloat-specialize.c.inc | 7 +------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
22
+ * to return an input NaN if we have one (ie c) rather than generating
23
+ * a default NaN
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
27
28
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
29
ppc_spr_t *spr = &env->spr_cb[i];
30
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
31
index XXXXXXX..XXXXXXX 100644
32
--- a/fpu/softfloat-specialize.c.inc
33
+++ b/fpu/softfloat-specialize.c.inc
34
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
*/
36
rule = float_infzeronan_dnan_never;
37
}
38
-#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
39
+#elif defined(TARGET_SPARC) || \
40
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
41
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
42
/*
43
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
44
* case sets InvalidOp and returns the input value 'c'
45
*/
46
- /*
47
- * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
48
- * to return an input NaN if we have one (ie c) rather than generating
49
- * a default NaN
50
- */
51
rule = float_infzeronan_dnan_never;
52
#endif
53
}
54
--
55
2.34.1
diff view generated by jsdifflib
1
Mark up the cpreginfo structs to indicate offsets for system
1
Set the FloatInfZeroNaNRule explicitly for the MIPS target,
2
registers from VNCR_EL2, as defined in table D8-66 in rule R_CSRPQ in
2
so we can remove the ifdef from pickNaNMulAdd().
3
the Arm ARM. This commit covers offsets below 0x100; all of these
4
registers are redirected to memory regardless of the value of
5
HCR_EL2.NV1.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Miguel Luis <miguel.luis@oracle.com>
6
Message-id: 20241202131347.498124-9-peter.maydell@linaro.org
10
---
7
---
11
target/arm/helper.c | 12 ++++++++++++
8
target/mips/fpu_helper.h | 9 +++++++++
12
1 file changed, 12 insertions(+)
9
target/mips/msa.c | 4 ++++
10
fpu/softfloat-specialize.c.inc | 16 +---------------
11
3 files changed, 14 insertions(+), 15 deletions(-)
13
12
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
15
--- a/target/mips/fpu_helper.h
17
+++ b/target/arm/helper.c
16
+++ b/target/mips/fpu_helper.h
18
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo hcrx_el2_reginfo = {
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_flush_mode(CPUMIPSState *env)
19
.name = "HCRX_EL2", .state = ARM_CP_STATE_AA64,
18
static inline void restore_snan_bit_mode(CPUMIPSState *env)
20
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 2,
19
{
21
.access = PL2_RW, .writefn = hcrx_write, .accessfn = access_hxen,
20
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
22
+ .nv2_redirect_offset = 0xa0,
21
+ FloatInfZeroNaNRule izn_rule;
23
.fieldoffset = offsetof(CPUARMState, cp15.hcrx_el2),
22
24
};
23
/*
25
24
* With nan2008, SNaNs are silenced in the usual way.
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
27
.type = ARM_CP_IO,
26
*/
28
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
27
set_snan_bit_is_one(!nan2008, &env->active_fpu.fp_status);
29
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
28
set_default_nan_mode(!nan2008, &env->active_fpu.fp_status);
30
+ .nv2_redirect_offset = 0x78,
29
+ /*
31
.writefn = hcr_write, .raw_writefn = raw_write },
30
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
32
{ .name = "HCR", .state = ARM_CP_STATE_AA32,
31
+ * case sets InvalidOp and returns the default NaN.
33
.type = ARM_CP_ALIAS | ARM_CP_IO,
32
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
34
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
33
+ * case sets InvalidOp and returns the input value 'c'.
35
{ .name = "VTCR_EL2", .state = ARM_CP_STATE_AA64,
34
+ */
36
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
35
+ izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
37
.access = PL2_RW,
36
+ set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
38
+ .nv2_redirect_offset = 0x40,
37
}
39
/* no .writefn needed as this can't cause an ASID change */
38
40
.fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) },
39
static inline void restore_fp_status(CPUMIPSState *env)
41
{ .name = "VTTBR", .state = ARM_CP_STATE_AA32,
40
diff --git a/target/mips/msa.c b/target/mips/msa.c
42
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
41
index XXXXXXX..XXXXXXX 100644
43
{ .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
42
--- a/target/mips/msa.c
44
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
43
+++ b/target/mips/msa.c
45
.access = PL2_RW, .writefn = vttbr_write, .raw_writefn = raw_write,
44
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
46
+ .nv2_redirect_offset = 0x20,
45
47
.fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) },
46
/* set proper signanling bit meaning ("1" means "quiet") */
48
{ .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
47
set_snan_bit_is_one(0, &env->active_tc.msa_fp_status);
49
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
48
+
50
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
49
+ /* Inf * 0 + NaN returns the input NaN */
51
{ .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
50
+ set_float_infzeronan_rule(float_infzeronan_dnan_never,
52
.opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
51
+ &env->active_tc.msa_fp_status);
53
.access = PL2_RW, .resetvalue = 0,
52
}
54
+ .nv2_redirect_offset = 0x90,
53
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
55
.fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) },
54
index XXXXXXX..XXXXXXX 100644
56
{ .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
55
--- a/fpu/softfloat-specialize.c.inc
57
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
56
+++ b/fpu/softfloat-specialize.c.inc
58
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
57
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
59
.opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
58
/*
60
.access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 0,
59
* Temporarily fall back to ifdef ladder
61
.writefn = gt_cntvoff_write,
60
*/
62
+ .nv2_redirect_offset = 0x60,
61
-#if defined(TARGET_MIPS)
63
.fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) },
62
- if (snan_bit_is_one(status)) {
64
{ .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14,
63
- /*
65
.access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS | ARM_CP_IO,
64
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
66
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
65
- * case sets InvalidOp and returns the default NaN
67
{ .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
66
- */
68
.cp = 15, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
67
- rule = float_infzeronan_dnan_always;
69
.access = PL2_RW,
68
- } else {
70
+ .nv2_redirect_offset = 0x80,
69
- /*
71
.fieldoffset = offsetof(CPUARMState, cp15.hstr_el2) },
70
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
72
};
71
- * case sets InvalidOp and returns the input value 'c'
73
72
- */
74
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
73
- rule = float_infzeronan_dnan_never;
75
{ .name = "VSTTBR_EL2", .state = ARM_CP_STATE_AA64,
74
- }
76
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 0,
75
-#elif defined(TARGET_SPARC) || \
77
.access = PL2_RW, .accessfn = sel2_access,
76
+#if defined(TARGET_SPARC) || \
78
+ .nv2_redirect_offset = 0x30,
77
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
79
.fieldoffset = offsetof(CPUARMState, cp15.vsttbr_el2) },
78
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
80
{ .name = "VSTCR_EL2", .state = ARM_CP_STATE_AA64,
81
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 2,
82
.access = PL2_RW, .accessfn = sel2_access,
83
+ .nv2_redirect_offset = 0x48,
84
.fieldoffset = offsetof(CPUARMState, cp15.vstcr_el2) },
85
};
86
87
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo nv2_reginfo[] = {
88
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 2, .opc2 = 0,
89
.access = PL2_RW,
90
.writefn = vncr_write,
91
+ .nv2_redirect_offset = 0xb0,
92
.fieldoffset = offsetof(CPUARMState, cp15.vncr_el2) },
93
};
94
95
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
96
.opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
97
.access = PL2_RW, .resetvalue = cpu->midr,
98
.type = ARM_CP_EL3_NO_EL2_C_NZ,
99
+ .nv2_redirect_offset = 0x88,
100
.fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
101
{ .name = "VMPIDR", .state = ARM_CP_STATE_AA32,
102
.cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
103
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
104
.opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
105
.access = PL2_RW, .resetvalue = vmpidr_def,
106
.type = ARM_CP_EL3_NO_EL2_C_NZ,
107
+ .nv2_redirect_offset = 0x50,
108
.fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
109
};
110
/*
79
/*
111
--
80
--
112
2.34.1
81
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the SPARC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-10-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
23
cpu_exec_realizefn(cs, &local_err);
24
if (local_err != NULL) {
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_SPARC) || \
34
- defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
35
+#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
36
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
37
/*
38
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the xtensa target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-11-peter.maydell@linaro.org
7
---
8
target/xtensa/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 +-
10
2 files changed, 3 insertions(+), 1 deletion(-)
11
12
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/xtensa/cpu.c
15
+++ b/target/xtensa/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
17
reset_mmu(env);
18
cs->halted = env->runstall;
19
#endif
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
set_no_signaling_nans(!dfpu, &env->fp_status);
23
xtensa_use_first_nan(env, !dfpu);
24
}
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
34
+#if defined(TARGET_HPPA) || \
35
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
36
/*
37
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the x86 target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-12-peter.maydell@linaro.org
6
---
7
target/i386/tcg/fpu_helper.c | 7 +++++++
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 8 insertions(+), 1 deletion(-)
10
11
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/i386/tcg/fpu_helper.c
14
+++ b/target/i386/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->mmx_status);
18
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->sse_status);
19
+ /*
20
+ * Only SSE has multiply-add instructions. In the SDM Section 14.5.2
21
+ * "Fused-Multiply-ADD (FMA) Numeric Behavior" the NaN handling is
22
+ * specified -- for 0 * inf + NaN the input NaN is selected, and if
23
+ * there are multiple input NaNs they are selected in the order a, b, c.
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
26
}
27
28
static inline uint8_t save_exception_flags(CPUX86State *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
34
* Temporarily fall back to ifdef ladder
35
*/
36
#if defined(TARGET_HPPA) || \
37
- defined(TARGET_I386) || defined(TARGET_LOONGARCH)
38
+ defined(TARGET_LOONGARCH)
39
/*
40
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
41
* case sets InvalidOp and returns the input value 'c'
42
--
43
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the loongarch target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-13-peter.maydell@linaro.org
6
---
7
target/loongarch/tcg/fpu_helper.c | 5 +++++
8
fpu/softfloat-specialize.c.inc | 7 +------
9
2 files changed, 6 insertions(+), 6 deletions(-)
10
11
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/tcg/fpu_helper.c
14
+++ b/target/loongarch/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
16
&env->fp_status);
17
set_flush_to_zero(0, &env->fp_status);
18
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
19
+ /*
20
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
21
+ * case sets InvalidOp and returns the input value 'c'
22
+ */
23
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
}
25
26
int ieee_ex_to_loongarch(int xcpt)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
index XXXXXXX..XXXXXXX 100644
29
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
32
/*
33
* Temporarily fall back to ifdef ladder
34
*/
35
-#if defined(TARGET_HPPA) || \
36
- defined(TARGET_LOONGARCH)
37
- /*
38
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
- * case sets InvalidOp and returns the input value 'c'
40
- */
41
+#if defined(TARGET_HPPA)
42
rule = float_infzeronan_dnan_never;
43
#endif
44
}
45
--
46
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the HPPA target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
As this is the last target to be converted to explicitly setting
5
the rule, we can remove the fallback code in pickNaNMulAdd()
6
entirely.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20241202131347.498124-14-peter.maydell@linaro.org
11
---
12
target/hppa/fpu_helper.c | 2 ++
13
fpu/softfloat-specialize.c.inc | 13 +------------
14
2 files changed, 3 insertions(+), 12 deletions(-)
15
16
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/hppa/fpu_helper.c
19
+++ b/target/hppa/fpu_helper.c
20
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
21
* HPPA does note implement a CPU reset method at all...
22
*/
23
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
24
+ /* For inf * 0 + NaN, return the input NaN */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
}
27
28
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
34
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
bool infzero, float_status *status)
36
{
37
- FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
38
-
39
/*
40
* We guarantee not to require the target to tell us how to
41
* pick a NaN if we're always returning the default NaN.
42
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
43
*/
44
assert(!status->default_nan_mode);
45
46
- if (rule == float_infzeronan_none) {
47
- /*
48
- * Temporarily fall back to ifdef ladder
49
- */
50
-#if defined(TARGET_HPPA)
51
- rule = float_infzeronan_dnan_never;
52
-#endif
53
- }
54
-
55
if (infzero) {
56
/*
57
* Inf * 0 + NaN -- some implementations return the default NaN here,
58
* and some return the input NaN.
59
*/
60
- switch (rule) {
61
+ switch (status->float_infzeronan_rule) {
62
case float_infzeronan_dnan_never:
63
return 2;
64
case float_infzeronan_dnan_always:
65
--
66
2.34.1
diff view generated by jsdifflib
New patch
1
The new implementation of pickNaNMulAdd() will find it convenient
2
to know whether at least one of the three arguments to the muladd
3
was a signaling NaN. We already calculate that in the caller,
4
so pass it in as a new bool have_snan.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-15-peter.maydell@linaro.org
9
---
10
fpu/softfloat-parts.c.inc | 5 +++--
11
fpu/softfloat-specialize.c.inc | 2 +-
12
2 files changed, 4 insertions(+), 3 deletions(-)
13
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat-parts.c.inc
17
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
19
{
20
int which;
21
bool infzero = (ab_mask == float_cmask_infzero);
22
+ bool have_snan = (abc_mask & float_cmask_snan);
23
24
- if (unlikely(abc_mask & float_cmask_snan)) {
25
+ if (unlikely(have_snan)) {
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
27
}
28
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
if (s->default_nan_mode) {
31
which = 3;
32
} else {
33
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
35
}
36
37
if (which == 3) {
38
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
39
index XXXXXXX..XXXXXXX 100644
40
--- a/fpu/softfloat-specialize.c.inc
41
+++ b/fpu/softfloat-specialize.c.inc
42
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
43
| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
44
*----------------------------------------------------------------------------*/
45
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
46
- bool infzero, float_status *status)
47
+ bool infzero, bool have_snan, float_status *status)
48
{
49
/*
50
* We guarantee not to require the target to tell us how to
51
--
52
2.34.1
diff view generated by jsdifflib
1
FEAT_NV2 requires that when HCR_EL2.{NV,NV2} == 0b11 then accesses by
1
IEEE 758 does not define a fixed rule for which NaN to pick as the
2
EL1 to certain system registers are redirected to RAM. The full list
2
result if both operands of a 3-operand fused multiply-add operation
3
of affected registers is in the table in rule R_CSRPQ in the Arm ARM.
3
are NaNs. As a result different architectures have ended up with
4
The registers may be normally accessible at EL1 (like ACTLR_EL1), or
4
different rules for propagating NaNs.
5
normally UNDEF at EL1 (like HCR_EL2). Some registers redirect to RAM
5
6
only when HCR_EL2.NV1 is 0, and some only when HCR_EL2.NV1 is 1;
6
QEMU currently hardcodes the NaN propagation logic into the binary
7
others trap in both cases.
7
because pickNaNMulAdd() has an ifdef ladder for different targets.
8
8
We want to make the propagation rule instead be selectable at
9
Add the infrastructure for identifying which registers should be
9
runtime, because:
10
redirected and turning them into memory accesses.
10
* this will let us have multiple targets in one QEMU binary
11
11
* the Arm FEAT_AFP architectural feature includes letting
12
This code does not set the correct syndrome or arrange for the
12
the guest select a NaN propagation rule at runtime
13
exception to be taken to the correct target EL if the access via
13
14
VNCR_EL2 faults; we will do that in the next commit.
14
In this commit we add an enum for the propagation rule, the field in
15
15
float_status, and the corresponding getters and setters. We change
16
Subsequent commits will mark up the relevant regdefs to set their
16
pickNaNMulAdd to honour this, but because all targets still leave
17
nv2_redirect_offset, and if relevant one of the two flags which
17
this field at its default 0 value, the fallback logic will pick the
18
indicates that the redirect happens only for a particular value of
18
rule type with the old ifdef ladder.
19
HCR_EL2.NV1.
19
20
It's valid not to set a propagation rule if default_nan_mode is
21
enabled, because in that case there's no need to pick a NaN; all the
22
callers of pickNaNMulAdd() catch this case and skip calling it.
20
23
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Tested-by: Miguel Luis <miguel.luis@oracle.com>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20241202131347.498124-16-peter.maydell@linaro.org
24
---
27
---
25
target/arm/cpregs.h | 12 ++++++++
28
include/fpu/softfloat-helpers.h | 11 +++
26
target/arm/cpu.h | 4 +++
29
include/fpu/softfloat-types.h | 55 +++++++++++
27
target/arm/tcg/translate.h | 6 ++++
30
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
28
target/arm/tcg/hflags.c | 6 ++++
31
3 files changed, 107 insertions(+), 126 deletions(-)
29
target/arm/tcg/translate-a64.c | 56 ++++++++++++++++++++++++++++++++++
32
30
5 files changed, 84 insertions(+)
33
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
31
32
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
33
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/cpregs.h
35
--- a/include/fpu/softfloat-helpers.h
35
+++ b/target/arm/cpregs.h
36
+++ b/include/fpu/softfloat-helpers.h
36
@@ -XXX,XX +XXX,XX @@ typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
37
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
37
38
status->float_2nan_prop_rule = rule;
38
#define CP_ANY 0xff
39
}
39
40
40
+/* Flags in the high bits of nv2_redirect_offset */
41
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
41
+#define NV2_REDIR_NV1 0x4000 /* Only redirect when HCR_EL2.NV1 == 1 */
42
+ float_status *status)
42
+#define NV2_REDIR_NO_NV1 0x8000 /* Only redirect when HCR_EL2.NV1 == 0 */
43
+{
43
+#define NV2_REDIR_FLAG_MASK 0xc000
44
+ status->float_3nan_prop_rule = rule;
44
+
45
+}
45
/* Definition of an ARM coprocessor register */
46
+
46
struct ARMCPRegInfo {
47
static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
47
/* Name of register (useful mainly for debugging, need not be unique) */
48
float_status *status)
48
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
49
{
49
* value encodes both the trap register and bit within it.
50
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
50
*/
51
return status->float_2nan_prop_rule;
51
FGTBit fgt;
52
}
52
+
53
53
+ /*
54
+static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
54
+ * Offset from VNCR_EL2 when FEAT_NV2 redirects access to memory;
55
+{
55
+ * may include an NV2_REDIR_* flag.
56
+ return status->float_3nan_prop_rule;
56
+ */
57
+}
57
+ uint32_t nv2_redirect_offset;
58
+
59
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
60
{
61
return status->float_infzeronan_rule;
62
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
63
index XXXXXXX..XXXXXXX 100644
64
--- a/include/fpu/softfloat-types.h
65
+++ b/include/fpu/softfloat-types.h
66
@@ -XXX,XX +XXX,XX @@ this code that are retained.
67
#ifndef SOFTFLOAT_TYPES_H
68
#define SOFTFLOAT_TYPES_H
69
70
+#include "hw/registerfields.h"
71
+
72
/*
73
* Software IEC/IEEE floating-point types.
74
*/
75
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
76
float_2nan_prop_x87,
77
} Float2NaNPropRule;
78
79
+/*
80
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
81
+ * architectures have different rules for which input NaN is
82
+ * propagated to the output when there is more than one NaN on the
83
+ * input.
84
+ *
85
+ * If default_nan_mode is enabled then it is valid not to set a NaN
86
+ * propagation rule, because the softfloat code guarantees not to try
87
+ * to pick a NaN to propagate in default NaN mode. When not in
88
+ * default-NaN mode, it is an error for the target not to set the rule
89
+ * in float_status if it uses a muladd, and we will assert if we need
90
+ * to handle an input NaN and no rule was selected.
91
+ *
92
+ * The naming scheme for Float3NaNPropRule values is:
93
+ * float_3nan_prop_s_abc:
94
+ * = "Prefer SNaN over QNaN, then operand A over B over C"
95
+ * float_3nan_prop_abc:
96
+ * = "Prefer A over B over C regardless of SNaN vs QNAN"
97
+ *
98
+ * For QEMU, the multiply-add operation is A * B + C.
99
+ */
100
+
101
+/*
102
+ * We set the Float3NaNPropRule enum values up so we can select the
103
+ * right value in pickNaNMulAdd in a data driven way.
104
+ */
105
+FIELD(3NAN, 1ST, 0, 2) /* which operand is most preferred ? */
106
+FIELD(3NAN, 2ND, 2, 2) /* which operand is next most preferred ? */
107
+FIELD(3NAN, 3RD, 4, 2) /* which operand is least preferred ? */
108
+FIELD(3NAN, SNAN, 6, 1) /* do we prefer SNaN over QNaN ? */
109
+
110
+#define PROPRULE(X, Y, Z) \
111
+ ((X << R_3NAN_1ST_SHIFT) | (Y << R_3NAN_2ND_SHIFT) | (Z << R_3NAN_3RD_SHIFT))
112
+
113
+typedef enum __attribute__((__packed__)) {
114
+ float_3nan_prop_none = 0, /* No propagation rule specified */
115
+ float_3nan_prop_abc = PROPRULE(0, 1, 2),
116
+ float_3nan_prop_acb = PROPRULE(0, 2, 1),
117
+ float_3nan_prop_bac = PROPRULE(1, 0, 2),
118
+ float_3nan_prop_bca = PROPRULE(1, 2, 0),
119
+ float_3nan_prop_cab = PROPRULE(2, 0, 1),
120
+ float_3nan_prop_cba = PROPRULE(2, 1, 0),
121
+ float_3nan_prop_s_abc = float_3nan_prop_abc | R_3NAN_SNAN_MASK,
122
+ float_3nan_prop_s_acb = float_3nan_prop_acb | R_3NAN_SNAN_MASK,
123
+ float_3nan_prop_s_bac = float_3nan_prop_bac | R_3NAN_SNAN_MASK,
124
+ float_3nan_prop_s_bca = float_3nan_prop_bca | R_3NAN_SNAN_MASK,
125
+ float_3nan_prop_s_cab = float_3nan_prop_cab | R_3NAN_SNAN_MASK,
126
+ float_3nan_prop_s_cba = float_3nan_prop_cba | R_3NAN_SNAN_MASK,
127
+} Float3NaNPropRule;
128
+
129
+#undef PROPRULE
130
+
131
/*
132
* Rule for result of fused multiply-add 0 * Inf + NaN.
133
* This must be a NaN, but implementations differ on whether this
134
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
135
FloatRoundMode float_rounding_mode;
136
FloatX80RoundPrec floatx80_rounding_precision;
137
Float2NaNPropRule float_2nan_prop_rule;
138
+ Float3NaNPropRule float_3nan_prop_rule;
139
FloatInfZeroNaNRule float_infzeronan_rule;
140
bool tininess_before_rounding;
141
/* should denormalised results go to zero and set the inexact flag? */
142
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
143
index XXXXXXX..XXXXXXX 100644
144
--- a/fpu/softfloat-specialize.c.inc
145
+++ b/fpu/softfloat-specialize.c.inc
146
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
147
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
148
bool infzero, bool have_snan, float_status *status)
149
{
150
+ FloatClass cls[3] = { a_cls, b_cls, c_cls };
151
+ Float3NaNPropRule rule = status->float_3nan_prop_rule;
152
+ int which;
58
+
153
+
59
/*
154
/*
60
* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
155
* We guarantee not to require the target to tell us how to
61
* this register was defined: can be used to hand data through to the
156
* pick a NaN if we're always returning the default NaN.
62
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
157
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/arm/cpu.h
65
+++ b/target/arm/cpu.h
66
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, ATA0, 31, 1)
67
FIELD(TBFLAG_A64, NV, 32, 1)
68
FIELD(TBFLAG_A64, NV1, 33, 1)
69
FIELD(TBFLAG_A64, NV2, 34, 1)
70
+/* Set if FEAT_NV2 RAM accesses use the EL2&0 translation regime */
71
+FIELD(TBFLAG_A64, NV2_MEM_E20, 35, 1)
72
+/* Set if FEAT_NV2 RAM accesses are big-endian */
73
+FIELD(TBFLAG_A64, NV2_MEM_BE, 36, 1)
74
75
/*
76
* Helpers for using the above. Note that only the A64 accessors use
77
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/tcg/translate.h
80
+++ b/target/arm/tcg/translate.h
81
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
82
bool nv1;
83
/* True if NV enabled and HCR_EL2.NV2 is set */
84
bool nv2;
85
+ /* True if NV2 enabled and NV2 RAM accesses use EL2&0 translation regime */
86
+ bool nv2_mem_e20;
87
+ /* True if NV2 enabled and NV2 RAM accesses are big-endian */
88
+ bool nv2_mem_be;
89
/*
90
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
91
* < 0, set by the current instruction.
92
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
93
int c15_cpar;
94
/* TCG op of the current insn_start. */
95
TCGOp *insn_start;
96
+ /* Offset from VNCR_EL2 when FEAT_NV2 redirects this reg to memory */
97
+ uint32_t nv2_redirect_offset;
98
} DisasContext;
99
100
typedef struct DisasCompare {
101
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/arm/tcg/hflags.c
104
+++ b/target/arm/tcg/hflags.c
105
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
106
}
107
if (hcr & HCR_NV2) {
108
DP_TBFLAG_A64(flags, NV2, 1);
109
+ if (hcr & HCR_E2H) {
110
+ DP_TBFLAG_A64(flags, NV2_MEM_E20, 1);
111
+ }
112
+ if (env->cp15.sctlr_el[2] & SCTLR_EE) {
113
+ DP_TBFLAG_A64(flags, NV2_MEM_BE, 1);
114
+ }
115
}
158
}
116
}
159
}
117
160
118
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
161
+ if (rule == float_3nan_prop_none) {
119
index XXXXXXX..XXXXXXX 100644
162
#if defined(TARGET_ARM)
120
--- a/target/arm/tcg/translate-a64.c
163
-
121
+++ b/target/arm/tcg/translate-a64.c
164
- /* This looks different from the ARM ARM pseudocode, because the ARM ARM
122
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
165
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
123
bool nv_trap_to_el2 = false;
166
- */
124
bool nv_redirect_reg = false;
167
- if (is_snan(c_cls)) {
125
bool skip_fp_access_checks = false;
168
- return 2;
126
+ bool nv2_mem_redirect = false;
169
- } else if (is_snan(a_cls)) {
127
TCGv_ptr tcg_ri = NULL;
170
- return 0;
128
TCGv_i64 tcg_rt;
171
- } else if (is_snan(b_cls)) {
129
uint32_t syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
172
- return 1;
130
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
173
- } else if (is_qnan(c_cls)) {
131
return;
174
- return 2;
132
}
175
- } else if (is_qnan(a_cls)) {
133
176
- return 0;
134
+ if (s->nv2 && ri->nv2_redirect_offset) {
177
- } else {
178
- return 1;
179
- }
135
+ /*
180
+ /*
136
+ * Some registers always redirect to memory; some only do so if
181
+ * This looks different from the ARM ARM pseudocode, because the ARM ARM
137
+ * HCR_EL2.NV1 is 0, and some only if NV1 is 1 (these come in
182
+ * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
138
+ * pairs which share an offset; see the table in R_CSRPQ).
139
+ */
183
+ */
140
+ if (ri->nv2_redirect_offset & NV2_REDIR_NV1) {
184
+ rule = float_3nan_prop_s_cab;
141
+ nv2_mem_redirect = s->nv1;
185
#elif defined(TARGET_MIPS)
142
+ } else if (ri->nv2_redirect_offset & NV2_REDIR_NO_NV1) {
186
- if (snan_bit_is_one(status)) {
143
+ nv2_mem_redirect = !s->nv1;
187
- /* Prefer sNaN over qNaN, in the a, b, c order. */
144
+ } else {
188
- if (is_snan(a_cls)) {
145
+ nv2_mem_redirect = true;
189
- return 0;
146
+ }
190
- } else if (is_snan(b_cls)) {
191
- return 1;
192
- } else if (is_snan(c_cls)) {
193
- return 2;
194
- } else if (is_qnan(a_cls)) {
195
- return 0;
196
- } else if (is_qnan(b_cls)) {
197
- return 1;
198
+ if (snan_bit_is_one(status)) {
199
+ rule = float_3nan_prop_s_abc;
200
} else {
201
- return 2;
202
+ rule = float_3nan_prop_s_cab;
203
}
204
- } else {
205
- /* Prefer sNaN over qNaN, in the c, a, b order. */
206
- if (is_snan(c_cls)) {
207
- return 2;
208
- } else if (is_snan(a_cls)) {
209
- return 0;
210
- } else if (is_snan(b_cls)) {
211
- return 1;
212
- } else if (is_qnan(c_cls)) {
213
- return 2;
214
- } else if (is_qnan(a_cls)) {
215
- return 0;
216
- } else {
217
- return 1;
218
- }
219
- }
220
#elif defined(TARGET_LOONGARCH64)
221
- /* Prefer sNaN over qNaN, in the c, a, b order. */
222
- if (is_snan(c_cls)) {
223
- return 2;
224
- } else if (is_snan(a_cls)) {
225
- return 0;
226
- } else if (is_snan(b_cls)) {
227
- return 1;
228
- } else if (is_qnan(c_cls)) {
229
- return 2;
230
- } else if (is_qnan(a_cls)) {
231
- return 0;
232
- } else {
233
- return 1;
234
- }
235
+ rule = float_3nan_prop_s_cab;
236
#elif defined(TARGET_PPC)
237
- /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
238
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
239
- */
240
- if (is_nan(a_cls)) {
241
- return 0;
242
- } else if (is_nan(c_cls)) {
243
- return 2;
244
- } else {
245
- return 1;
246
- }
247
+ /*
248
+ * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
249
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
250
+ */
251
+ rule = float_3nan_prop_acb;
252
#elif defined(TARGET_S390X)
253
- if (is_snan(a_cls)) {
254
- return 0;
255
- } else if (is_snan(b_cls)) {
256
- return 1;
257
- } else if (is_snan(c_cls)) {
258
- return 2;
259
- } else if (is_qnan(a_cls)) {
260
- return 0;
261
- } else if (is_qnan(b_cls)) {
262
- return 1;
263
- } else {
264
- return 2;
265
- }
266
+ rule = float_3nan_prop_s_abc;
267
#elif defined(TARGET_SPARC)
268
- /* Prefer SNaN over QNaN, order C, B, A. */
269
- if (is_snan(c_cls)) {
270
- return 2;
271
- } else if (is_snan(b_cls)) {
272
- return 1;
273
- } else if (is_snan(a_cls)) {
274
- return 0;
275
- } else if (is_qnan(c_cls)) {
276
- return 2;
277
- } else if (is_qnan(b_cls)) {
278
- return 1;
279
- } else {
280
- return 0;
281
- }
282
+ rule = float_3nan_prop_s_cba;
283
#elif defined(TARGET_XTENSA)
284
- /*
285
- * For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
286
- * an input NaN if we have one (ie c).
287
- */
288
- if (status->use_first_nan) {
289
- if (is_nan(a_cls)) {
290
- return 0;
291
- } else if (is_nan(b_cls)) {
292
- return 1;
293
+ if (status->use_first_nan) {
294
+ rule = float_3nan_prop_abc;
295
} else {
296
- return 2;
297
+ rule = float_3nan_prop_cba;
298
}
299
- } else {
300
- if (is_nan(c_cls)) {
301
- return 2;
302
- } else if (is_nan(b_cls)) {
303
- return 1;
304
- } else {
305
- return 0;
306
- }
307
- }
308
#else
309
- /* A default implementation: prefer a to b to c.
310
- * This is unlikely to actually match any real implementation.
311
- */
312
- if (is_nan(a_cls)) {
313
- return 0;
314
- } else if (is_nan(b_cls)) {
315
- return 1;
316
- } else {
317
- return 2;
318
- }
319
+ rule = float_3nan_prop_abc;
320
#endif
147
+ }
321
+ }
148
+
322
+
149
/* Check access permissions */
323
+ assert(rule != float_3nan_prop_none);
150
if (!cp_access_ok(s->current_el, ri, isread)) {
324
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
151
/*
325
+ /* We have at least one SNaN input and should prefer it */
152
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
326
+ do {
153
* the EL2 register's accessfn.
327
+ which = rule & R_3NAN_1ST_MASK;
154
*/
328
+ rule >>= R_3NAN_1ST_LENGTH;
155
nv_redirect_reg = true;
329
+ } while (!is_snan(cls[which]));
156
+ assert(!nv2_mem_redirect);
330
+ } else {
157
+ } else if (nv2_mem_redirect) {
331
+ do {
158
+ /*
332
+ which = rule & R_3NAN_1ST_MASK;
159
+ * NV2 redirect-to-memory takes precedence over trap to EL2 or
333
+ rule >>= R_3NAN_1ST_LENGTH;
160
+ * UNDEF to EL1.
334
+ } while (!is_nan(cls[which]));
161
+ */
162
} else if (s->nv && arm_cpreg_traps_in_nv(ri)) {
163
/*
164
* This register / instruction exists and is an EL2 register, so
165
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
166
assert(!(ri->type & ARM_CP_RAISES_EXC));
167
}
168
169
+ if (nv2_mem_redirect) {
170
+ /*
171
+ * This system register is being redirected into an EL2 memory access.
172
+ * This means it is not an IO operation, doesn't change hflags,
173
+ * and need not end the TB, because it has no side effects.
174
+ *
175
+ * The access is 64-bit single copy atomic, guaranteed aligned because
176
+ * of the definition of VCNR_EL2. Its endianness depends on
177
+ * SCTLR_EL2.EE, not on the data endianness of EL1.
178
+ * It is done under either the EL2 translation regime or the EL2&0
179
+ * translation regime, depending on HCR_EL2.E2H. It behaves as if
180
+ * PSTATE.PAN is 0.
181
+ */
182
+ TCGv_i64 ptr = tcg_temp_new_i64();
183
+ MemOp mop = MO_64 | MO_ALIGN | MO_ATOM_IFALIGN;
184
+ ARMMMUIdx armmemidx = s->nv2_mem_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_E2;
185
+ int memidx = arm_to_core_mmu_idx(armmemidx);
186
+
187
+ mop |= (s->nv2_mem_be ? MO_BE : MO_LE);
188
+
189
+ tcg_gen_ld_i64(ptr, tcg_env, offsetof(CPUARMState, cp15.vncr_el2));
190
+ tcg_gen_addi_i64(ptr, ptr,
191
+ (ri->nv2_redirect_offset & ~NV2_REDIR_FLAG_MASK));
192
+ tcg_rt = cpu_reg(s, rt);
193
+ if (isread) {
194
+ tcg_gen_qemu_ld_i64(tcg_rt, ptr, memidx, mop);
195
+ } else {
196
+ tcg_gen_qemu_st_i64(tcg_rt, ptr, memidx, mop);
197
+ }
198
+ return;
199
+ }
335
+ }
200
+
336
+ return which;
201
/* Handle special cases first */
337
}
202
switch (ri->type & ARM_CP_SPECIAL_MASK) {
338
203
case 0:
339
/*----------------------------------------------------------------------------
204
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
205
dc->nv = EX_TBFLAG_A64(tb_flags, NV);
206
dc->nv1 = EX_TBFLAG_A64(tb_flags, NV1);
207
dc->nv2 = EX_TBFLAG_A64(tb_flags, NV2);
208
+ dc->nv2_mem_e20 = EX_TBFLAG_A64(tb_flags, NV2_MEM_E20);
209
+ dc->nv2_mem_be = EX_TBFLAG_A64(tb_flags, NV2_MEM_BE);
210
dc->vec_len = 0;
211
dc->vec_stride = 0;
212
dc->cp_regs = arm_cpu->cp_regs;
213
--
340
--
214
2.34.1
341
2.34.1
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for propagating NaNs in
2
the muladd case. In meson.build we put -DTARGET_ARM in fpcflags, and
3
so we should select here the Arm rule of float_3nan_prop_s_cab.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-17-peter.maydell@linaro.org
8
---
9
tests/fp/fp-bench.c | 1 +
10
tests/fp/fp-test.c | 1 +
11
2 files changed, 2 insertions(+)
12
13
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/fp/fp-bench.c
16
+++ b/tests/fp/fp-bench.c
17
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
18
* doesn't specify match those used by the Arm architecture.
19
*/
20
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
22
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
23
24
f = bench_funcs[operation][precision];
25
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/fp/fp-test.c
28
+++ b/tests/fp/fp-test.c
29
@@ -XXX,XX +XXX,XX @@ void run_test(void)
30
* doesn't specify match those used by the Arm architecture.
31
*/
32
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
33
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
34
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
35
36
genCases_setLevel(test_level);
37
--
38
2.34.1
diff view generated by jsdifflib
1
Enable FEAT_NV2 on the 'max' CPU, and stop filtering it out for
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
the Neoverse N2 and Neoverse V1 CPUs.
2
ifdef from pickNaNMulAdd().
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Miguel Luis <miguel.luis@oracle.com>
6
Message-id: 20241202131347.498124-18-peter.maydell@linaro.org
7
---
7
---
8
docs/system/arm/emulation.rst | 1 +
8
target/arm/cpu.c | 5 +++++
9
target/arm/cpu.c | 5 -----
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
target/arm/tcg/cpu64.c | 2 +-
10
2 files changed, 6 insertions(+), 7 deletions(-)
11
3 files changed, 2 insertions(+), 6 deletions(-)
12
11
13
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/system/arm/emulation.rst
16
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
- FEAT_MTE2 (Memory Tagging Extension)
19
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
20
- FEAT_NV (Nested Virtualization)
21
+- FEAT_NV2 (Enhanced nested virtualization support)
22
- FEAT_PACIMP (Pointer authentication - IMPLEMENTATION DEFINED algorithm)
23
- FEAT_PACQARMA3 (Pointer authentication - QARMA3 algorithm)
24
- FEAT_PACQARMA5 (Pointer authentication - QARMA5 algorithm)
25
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
26
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.c
14
--- a/target/arm/cpu.c
28
+++ b/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
29
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
30
/* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */
17
* * tininess-before-rounding
31
cpu->isar.id_aa64pfr0 =
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
32
FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, MPAM, 0);
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
33
- /* FEAT_NV2 (Enhanced Nested Virtualization support) */
20
+ * * 3-input NaN propagation prefers SNaN over QNaN, and then
34
- if (FIELD_EX64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV) > 1) {
21
+ * operand C over A over B (see FPProcessNaNs3() pseudocode,
35
- cpu->isar.id_aa64mmfr2 =
22
+ * but note that for QEMU muladd is a * b + c, whereas for
36
- FIELD_DP64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV, 1);
23
+ * the pseudocode function the arguments are in the order c, a, b.
37
- }
24
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
25
* and the input NaN if it is signalling
26
*/
27
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
28
{
29
set_float_detect_tininess(float_tininess_before_rounding, s);
30
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
31
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
32
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
33
}
34
35
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
36
index XXXXXXX..XXXXXXX 100644
37
--- a/fpu/softfloat-specialize.c.inc
38
+++ b/fpu/softfloat-specialize.c.inc
39
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
38
}
40
}
39
41
40
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
42
if (rule == float_3nan_prop_none) {
41
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
43
-#if defined(TARGET_ARM)
42
index XXXXXXX..XXXXXXX 100644
44
- /*
43
--- a/target/arm/tcg/cpu64.c
45
- * This looks different from the ARM ARM pseudocode, because the ARM ARM
44
+++ b/target/arm/tcg/cpu64.c
46
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
45
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
47
- */
46
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
48
- rule = float_3nan_prop_s_cab;
47
t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */
49
-#elif defined(TARGET_MIPS)
48
t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
50
+#if defined(TARGET_MIPS)
49
- t = FIELD_DP64(t, ID_AA64MMFR2, NV, 1); /* FEAT_NV */
51
if (snan_bit_is_one(status)) {
50
+ t = FIELD_DP64(t, ID_AA64MMFR2, NV, 2); /* FEAT_NV2 */
52
rule = float_3nan_prop_s_abc;
51
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
53
} else {
52
t = FIELD_DP64(t, ID_AA64MMFR2, AT, 1); /* FEAT_LSE2 */
53
t = FIELD_DP64(t, ID_AA64MMFR2, IDS, 1); /* FEAT_IDST */
54
--
54
--
55
2.34.1
55
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for loongarch, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-19-peter.maydell@linaro.org
7
---
8
target/loongarch/tcg/fpu_helper.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/loongarch/tcg/fpu_helper.c
15
+++ b/target/loongarch/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
17
* case sets InvalidOp and returns the input value 'c'
18
*/
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
21
}
22
23
int ieee_ex_to_loongarch(int xcpt)
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_LOONGARCH64)
33
- rule = float_3nan_prop_s_cab;
34
#elif defined(TARGET_PPC)
35
/*
36
* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for PPC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-20-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 8 ++++++++
9
fpu/softfloat-specialize.c.inc | 6 ------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * NaN propagation for fused multiply-add:
22
+ * if fRA is a NaN return it; otherwise if fRB is a NaN return it;
23
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
24
+ * whereas QEMU labels the operands as (a * b) + c.
25
+ */
26
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->fp_status);
27
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->vec_status);
28
/*
29
* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
30
* to return an input NaN if we have one (ie c) rather than generating
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
} else {
37
rule = float_3nan_prop_s_cab;
38
}
39
-#elif defined(TARGET_PPC)
40
- /*
41
- * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
42
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
43
- */
44
- rule = float_3nan_prop_acb;
45
#elif defined(TARGET_S390X)
46
rule = float_3nan_prop_s_abc;
47
#elif defined(TARGET_SPARC)
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for s390x, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-21-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
21
set_float_infzeronan_rule(float_infzeronan_dnan_always,
22
&env->fpu_status);
23
/* fall through */
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_S390X)
33
- rule = float_3nan_prop_s_abc;
34
#elif defined(TARGET_SPARC)
35
rule = float_3nan_prop_s_cba;
36
#elif defined(TARGET_XTENSA)
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for SPARC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-22-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For fused-multiply add, prefer SNaN over QNaN, then C->B->A */
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
22
/* For inf * 0 + NaN, return the input NaN */
23
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
} else {
31
rule = float_3nan_prop_s_cab;
32
}
33
-#elif defined(TARGET_SPARC)
34
- rule = float_3nan_prop_s_cba;
35
#elif defined(TARGET_XTENSA)
36
if (status->use_first_nan) {
37
rule = float_3nan_prop_abc;
38
--
39
2.34.1
diff view generated by jsdifflib
1
FEAT_NV2 defines another new bit in HCR_EL2: NV2. When the
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
feature is enabled, allow this bit to be written in HCR_EL2.
2
ifdef from pickNaNMulAdd().
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Miguel Luis <miguel.luis@oracle.com>
6
Message-id: 20241202131347.498124-23-peter.maydell@linaro.org
7
---
7
---
8
target/arm/cpu-features.h | 5 +++++
8
target/mips/fpu_helper.h | 4 ++++
9
target/arm/helper.c | 3 +++
9
target/mips/msa.c | 3 +++
10
2 files changed, 8 insertions(+)
10
fpu/softfloat-specialize.c.inc | 8 +-------
11
3 files changed, 8 insertions(+), 7 deletions(-)
11
12
12
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu-features.h
15
--- a/target/mips/fpu_helper.h
15
+++ b/target/arm/cpu-features.h
16
+++ b/target/mips/fpu_helper.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_nv(const ARMISARegisters *id)
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
17
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, NV) != 0;
18
{
19
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
20
FloatInfZeroNaNRule izn_rule;
21
+ Float3NaNPropRule nan3_rule;
22
23
/*
24
* With nan2008, SNaNs are silenced in the usual way.
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
26
*/
27
izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
28
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
29
+ nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
30
+ set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
31
+
18
}
32
}
19
33
20
+static inline bool isar_feature_aa64_nv2(const ARMISARegisters *id)
34
static inline void restore_fp_status(CPUMIPSState *env)
21
+{
35
diff --git a/target/mips/msa.c b/target/mips/msa.c
22
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, NV) >= 2;
36
index XXXXXXX..XXXXXXX 100644
23
+}
37
--- a/target/mips/msa.c
38
+++ b/target/mips/msa.c
39
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
40
set_float_2nan_prop_rule(float_2nan_prop_s_ab,
41
&env->active_tc.msa_fp_status);
42
43
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab,
44
+ &env->active_tc.msa_fp_status);
24
+
45
+
25
static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
46
/* clear float_status exception flags */
26
{
47
set_float_exception_flags(0, &env->active_tc.msa_fp_status);
27
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
48
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
49
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
29
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/helper.c
51
--- a/fpu/softfloat-specialize.c.inc
31
+++ b/target/arm/helper.c
52
+++ b/fpu/softfloat-specialize.c.inc
32
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
53
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
33
if (cpu_isar_feature(aa64_nv, cpu)) {
34
valid_mask |= HCR_NV | HCR_NV1 | HCR_AT;
35
}
36
+ if (cpu_isar_feature(aa64_nv2, cpu)) {
37
+ valid_mask |= HCR_NV2;
38
+ }
39
}
54
}
40
55
41
if (cpu_isar_feature(any_evt, cpu)) {
56
if (rule == float_3nan_prop_none) {
57
-#if defined(TARGET_MIPS)
58
- if (snan_bit_is_one(status)) {
59
- rule = float_3nan_prop_s_abc;
60
- } else {
61
- rule = float_3nan_prop_s_cab;
62
- }
63
-#elif defined(TARGET_XTENSA)
64
+#if defined(TARGET_XTENSA)
65
if (status->use_first_nan) {
66
rule = float_3nan_prop_abc;
67
} else {
42
--
68
--
43
2.34.1
69
2.34.1
diff view generated by jsdifflib
1
For FEAT_NV, accesses to system registers and instructions from EL1
1
Set the Float3NaNPropRule explicitly for xtensa, and remove the
2
which would normally UNDEF there but which work in EL2 need to
2
ifdef from pickNaNMulAdd().
3
instead be trapped to EL2. Detect this both for "we know this will
4
UNDEF at translate time" and "we found this UNDEFs at runtime", and
5
make the affected registers trap to EL2 instead.
6
7
The Arm ARM defines the set of registers that should trap in terms
8
of their names; for our implementation this would be both awkward
9
and inefficent as a test, so we instead trap based on the opc1
10
field of the sysreg. The regularity of the architectural choice
11
of encodings for sysregs means that in practice this captures
12
exactly the correct set of registers.
13
14
Regardless of how we try to define the registers this trapping
15
applies to, there's going to be a certain possibility of breakage
16
if new architectural features introduce new registers that don't
17
follow the current rules (FEAT_MEC is one example already visible
18
in the released sysreg XML, though not yet in the Arm ARM). This
19
approach seems to me to be straightforward and likely to require
20
a minimum of manual overrides.
21
3
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Tested-by: Miguel Luis <miguel.luis@oracle.com>
6
Message-id: 20241202131347.498124-24-peter.maydell@linaro.org
25
---
7
---
26
target/arm/cpregs.h | 34 +++++++++++++++++++++++
8
target/xtensa/fpu_helper.c | 2 ++
27
target/arm/cpu.h | 1 +
9
fpu/softfloat-specialize.c.inc | 8 --------
28
target/arm/tcg/translate.h | 2 ++
10
2 files changed, 2 insertions(+), 8 deletions(-)
29
target/arm/tcg/hflags.c | 1 +
30
target/arm/tcg/translate-a64.c | 49 +++++++++++++++++++++++++++-------
31
5 files changed, 77 insertions(+), 10 deletions(-)
32
11
33
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
12
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
34
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/cpregs.h
14
--- a/target/xtensa/fpu_helper.c
36
+++ b/target/arm/cpregs.h
15
+++ b/target/xtensa/fpu_helper.c
37
@@ -XXX,XX +XXX,XX @@ void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
16
@@ -XXX,XX +XXX,XX @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
38
17
set_use_first_nan(use_first, &env->fp_status);
39
CPAccessResult access_tvm_trvm(CPUARMState *, const ARMCPRegInfo *, bool);
18
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
40
19
&env->fp_status);
41
+/**
20
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
42
+ * arm_cpreg_trap_in_nv: Return true if cpreg traps in nested virtualization
21
+ &env->fp_status);
43
+ *
22
}
44
+ * Return true if this cpreg is one which should be trapped to EL2 if
23
45
+ * it is executed at EL1 when nested virtualization is enabled via HCR_EL2.NV.
24
void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
46
+ */
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
47
+static inline bool arm_cpreg_traps_in_nv(const ARMCPRegInfo *ri)
48
+{
49
+ /*
50
+ * The Arm ARM defines the registers to be trapped in terms of
51
+ * their names (I_TZTZL). However the underlying principle is "if
52
+ * it would UNDEF at EL1 but work at EL2 then it should trap", and
53
+ * the way the encoding of sysregs and system instructions is done
54
+ * means that the right set of registers is exactly those where
55
+ * the opc1 field is 4 or 5. (You can see this also in the assert
56
+ * we do that the opc1 field and the permissions mask line up in
57
+ * define_one_arm_cp_reg_with_opaque().)
58
+ * Checking the opc1 field is easier for us and avoids the problem
59
+ * that we do not consistently use the right architectural names
60
+ * for all sysregs, since we treat the name field as largely for debug.
61
+ *
62
+ * However we do this check, it is going to be at least potentially
63
+ * fragile to future new sysregs, but this seems the least likely
64
+ * to break.
65
+ *
66
+ * In particular, note that the released sysreg XML defines that
67
+ * the FEAT_MEC sysregs and instructions do not follow this FEAT_NV
68
+ * trapping rule, so we will need to add an ARM_CP_* flag to indicate
69
+ * "register does not trap on NV" to handle those if/when we implement
70
+ * FEAT_MEC.
71
+ */
72
+ return ri->opc1 == 4 || ri->opc1 == 5;
73
+}
74
+
75
#endif /* TARGET_ARM_CPREGS_H */
76
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
77
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/cpu.h
27
--- a/fpu/softfloat-specialize.c.inc
79
+++ b/target/arm/cpu.h
28
+++ b/fpu/softfloat-specialize.c.inc
80
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, SME_TRAP_NONSTREAMING, 28, 1)
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
81
FIELD(TBFLAG_A64, TRAP_ERET, 29, 1)
82
FIELD(TBFLAG_A64, NAA, 30, 1)
83
FIELD(TBFLAG_A64, ATA0, 31, 1)
84
+FIELD(TBFLAG_A64, NV, 32, 1)
85
86
/*
87
* Helpers for using the above. Note that only the A64 accessors use
88
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/tcg/translate.h
91
+++ b/target/arm/tcg/translate.h
92
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
93
bool trap_eret;
94
/* True if FEAT_LSE2 SCTLR_ELx.nAA is set */
95
bool naa;
96
+ /* True if FEAT_NV HCR_EL2.NV is enabled */
97
+ bool nv;
98
/*
99
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
100
* < 0, set by the current instruction.
101
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/arm/tcg/hflags.c
104
+++ b/target/arm/tcg/hflags.c
105
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
106
*/
107
if (el == 1 && (hcr & HCR_NV)) {
108
DP_TBFLAG_A64(flags, TRAP_ERET, 1);
109
+ DP_TBFLAG_A64(flags, NV, 1);
110
}
30
}
111
31
112
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
32
if (rule == float_3nan_prop_none) {
113
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
33
-#if defined(TARGET_XTENSA)
114
index XXXXXXX..XXXXXXX 100644
34
- if (status->use_first_nan) {
115
--- a/target/arm/tcg/translate-a64.c
35
- rule = float_3nan_prop_abc;
116
+++ b/target/arm/tcg/translate-a64.c
36
- } else {
117
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
37
- rule = float_3nan_prop_cba;
118
crn, crm, op0, op1, op2);
38
- }
119
const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
39
-#else
120
bool need_exit_tb = false;
40
rule = float_3nan_prop_abc;
121
+ bool nv_trap_to_el2 = false;
41
-#endif
122
+ bool skip_fp_access_checks = false;
123
TCGv_ptr tcg_ri = NULL;
124
TCGv_i64 tcg_rt;
125
- uint32_t syndrome;
126
+ uint32_t syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
127
128
if (crn == 11 || crn == 15) {
129
/*
130
* Check for TIDCP trap, which must take precedence over
131
* the UNDEF for "no such register" etc.
132
*/
133
- syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
134
switch (s->current_el) {
135
case 0:
136
if (dc_isar_feature(aa64_tidcp1, s)) {
137
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
138
139
/* Check access permissions */
140
if (!cp_access_ok(s->current_el, ri, isread)) {
141
- gen_sysreg_undef(s, isread, op0, op1, op2, crn, crm, rt);
142
- return;
143
+ /*
144
+ * FEAT_NV/NV2 handling does not do the usual FP access checks
145
+ * for registers only accessible at EL2 (though it *does* do them
146
+ * for registers accessible at EL1).
147
+ */
148
+ skip_fp_access_checks = true;
149
+ if (s->nv && arm_cpreg_traps_in_nv(ri)) {
150
+ /*
151
+ * This register / instruction exists and is an EL2 register, so
152
+ * we must trap to EL2 if accessed in nested virtualization EL1
153
+ * instead of UNDEFing. We'll do that after the usual access checks.
154
+ * (This makes a difference only for a couple of registers like
155
+ * VSTTBR_EL2 where the "UNDEF if NonSecure" should take priority
156
+ * over the trap-to-EL2. Most trapped-by-FEAT_NV registers have
157
+ * an accessfn which does nothing when called from EL1, because
158
+ * the trap-to-EL3 controls which would apply to that register
159
+ * at EL2 don't take priority over the FEAT_NV trap-to-EL2.)
160
+ */
161
+ nv_trap_to_el2 = true;
162
+ } else {
163
+ gen_sysreg_undef(s, isread, op0, op1, op2, crn, crm, rt);
164
+ return;
165
+ }
166
}
42
}
167
43
168
if (ri->accessfn || (ri->fgt && s->fgt_active)) {
44
assert(rule != float_3nan_prop_none);
169
/* Emit code to perform further access permissions checks at
170
* runtime; this may result in an exception.
171
*/
172
- syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
173
gen_a64_update_pc(s, 0);
174
tcg_ri = tcg_temp_new_ptr();
175
gen_helper_access_check_cp_reg(tcg_ri, tcg_env,
176
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
177
gen_a64_update_pc(s, 0);
178
}
179
180
- if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
181
- return;
182
- } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
183
- return;
184
- } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
185
+ if (!skip_fp_access_checks) {
186
+ if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
187
+ return;
188
+ } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
189
+ return;
190
+ } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
191
+ return;
192
+ }
193
+ }
194
+
195
+ if (nv_trap_to_el2) {
196
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
197
return;
198
}
199
200
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
201
dc->pstate_za = EX_TBFLAG_A64(tb_flags, PSTATE_ZA);
202
dc->sme_trap_nonstreaming = EX_TBFLAG_A64(tb_flags, SME_TRAP_NONSTREAMING);
203
dc->naa = EX_TBFLAG_A64(tb_flags, NAA);
204
+ dc->nv = EX_TBFLAG_A64(tb_flags, NV);
205
dc->vec_len = 0;
206
dc->vec_stride = 0;
207
dc->cp_regs = arm_cpu->cp_regs;
208
--
45
--
209
2.34.1
46
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for i386. We had no
2
i386-specific behaviour in the old ifdef ladder, so we were using the
3
default "prefer a then b then c" fallback; this is actually the
4
correct per-the-spec handling for i386.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-25-peter.maydell@linaro.org
9
---
10
target/i386/tcg/fpu_helper.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/i386/tcg/fpu_helper.c
16
+++ b/target/i386/tcg/fpu_helper.c
17
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
18
* there are multiple input NaNs they are selected in the order a, b, c.
19
*/
20
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
22
}
23
24
static inline uint8_t save_exception_flags(CPUX86State *env)
25
--
26
2.34.1
diff view generated by jsdifflib
1
When FEAT_NV is turned on via the HCR_EL2.NV bit, ERET instructions
1
Set the Float3NaNPropRule explicitly for HPPA, and remove the
2
are trapped, with the same syndrome information as for the existing
2
ifdef from pickNaNMulAdd().
3
FEAT_FGT fine-grained trap (in the pseudocode this is handled in
4
AArch64.CheckForEretTrap()).
5
3
6
Rename the DisasContext and tbflag bits to reflect that they are
4
HPPA is the only target that was using the default branch of the
7
no longer exclusively for FGT traps, and set the tbflag bit when
5
ifdef ladder (other targets either do not use muladd or set
8
FEAT_NV is enabled as well as when the FGT is enabled.
6
default_nan_mode), so we can remove the ifdef fallback entirely now
7
(allowing the "rule not set" case to fall into the default of the
8
switch statement and assert).
9
10
We add a TODO note that the HPPA rule is probably wrong; this is
11
not a behavioural change for this refactoring.
9
12
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Tested-by: Miguel Luis <miguel.luis@oracle.com>
15
Message-id: 20241202131347.498124-26-peter.maydell@linaro.org
13
---
16
---
14
target/arm/cpu.h | 2 +-
17
target/hppa/fpu_helper.c | 8 ++++++++
15
target/arm/tcg/translate.h | 4 ++--
18
fpu/softfloat-specialize.c.inc | 4 ----
16
target/arm/tcg/hflags.c | 11 ++++++++++-
19
2 files changed, 8 insertions(+), 4 deletions(-)
17
target/arm/tcg/translate-a64.c | 6 +++---
18
4 files changed, 16 insertions(+), 7 deletions(-)
19
20
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
23
--- a/target/hppa/fpu_helper.c
23
+++ b/target/arm/cpu.h
24
+++ b/target/hppa/fpu_helper.c
24
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
25
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
25
FIELD(TBFLAG_A64, SVL, 24, 4)
26
* HPPA does note implement a CPU reset method at all...
26
/* Indicates that SME Streaming mode is active, and SMCR_ELx.FA64 is not. */
27
*/
27
FIELD(TBFLAG_A64, SME_TRAP_NONSTREAMING, 28, 1)
28
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
28
-FIELD(TBFLAG_A64, FGT_ERET, 29, 1)
29
+ /*
29
+FIELD(TBFLAG_A64, TRAP_ERET, 29, 1)
30
+ * TODO: The HPPA architecture reference only documents its NaN
30
FIELD(TBFLAG_A64, NAA, 30, 1)
31
+ * propagation rule for 2-operand operations. Testing on real hardware
31
FIELD(TBFLAG_A64, ATA0, 31, 1)
32
+ * might be necessary to confirm whether this order for muladd is correct.
32
33
+ * Not preferring the SNaN is almost certainly incorrect as it diverges
33
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
34
+ * from the documented rules for 2-operand operations.
35
+ */
36
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
37
/* For inf * 0 + NaN, return the input NaN */
38
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
39
}
40
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
34
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/tcg/translate.h
42
--- a/fpu/softfloat-specialize.c.inc
36
+++ b/target/arm/tcg/translate.h
43
+++ b/fpu/softfloat-specialize.c.inc
37
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
44
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
38
bool mve_no_pred;
39
/* True if fine-grained traps are active */
40
bool fgt_active;
41
- /* True if fine-grained trap on ERET is enabled */
42
- bool fgt_eret;
43
/* True if fine-grained trap on SVC is enabled */
44
bool fgt_svc;
45
+ /* True if a trap on ERET is enabled (FGT or NV) */
46
+ bool trap_eret;
47
/* True if FEAT_LSE2 SCTLR_ELx.nAA is set */
48
bool naa;
49
/*
50
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/tcg/hflags.c
53
+++ b/target/arm/tcg/hflags.c
54
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
55
CPUARMTBFlags flags = {};
56
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
57
uint64_t tcr = regime_tcr(env, mmu_idx);
58
+ uint64_t hcr = arm_hcr_el2_eff(env);
59
uint64_t sctlr;
60
int tbii, tbid;
61
62
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
63
if (arm_fgt_active(env, el)) {
64
DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1);
65
if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) {
66
- DP_TBFLAG_A64(flags, FGT_ERET, 1);
67
+ DP_TBFLAG_A64(flags, TRAP_ERET, 1);
68
}
69
if (fgt_svc(env, el)) {
70
DP_TBFLAG_ANY(flags, FGT_SVC, 1);
71
}
45
}
72
}
46
}
73
47
74
+ /*
48
- if (rule == float_3nan_prop_none) {
75
+ * ERET can also be trapped for FEAT_NV. arm_hcr_el2_eff() takes care
49
- rule = float_3nan_prop_abc;
76
+ * of "is EL2 enabled" and the NV bit can only be set if FEAT_NV is present.
50
- }
77
+ */
51
-
78
+ if (el == 1 && (hcr & HCR_NV)) {
52
assert(rule != float_3nan_prop_none);
79
+ DP_TBFLAG_A64(flags, TRAP_ERET, 1);
53
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
80
+ }
54
/* We have at least one SNaN input and should prefer it */
81
+
82
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
83
/*
84
* Set MTE_ACTIVE if any access may be Checked, and leave clear
85
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/tcg/translate-a64.c
88
+++ b/target/arm/tcg/translate-a64.c
89
@@ -XXX,XX +XXX,XX @@ static bool trans_ERET(DisasContext *s, arg_ERET *a)
90
if (s->current_el == 0) {
91
return false;
92
}
93
- if (s->fgt_eret) {
94
+ if (s->trap_eret) {
95
gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(0), 2);
96
return true;
97
}
98
@@ -XXX,XX +XXX,XX @@ static bool trans_ERETA(DisasContext *s, arg_reta *a)
99
return false;
100
}
101
/* The FGT trap takes precedence over an auth trap. */
102
- if (s->fgt_eret) {
103
+ if (s->trap_eret) {
104
gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(a->m ? 3 : 2), 2);
105
return true;
106
}
107
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
108
dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
109
dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
110
dc->fgt_svc = EX_TBFLAG_ANY(tb_flags, FGT_SVC);
111
- dc->fgt_eret = EX_TBFLAG_A64(tb_flags, FGT_ERET);
112
+ dc->trap_eret = EX_TBFLAG_A64(tb_flags, TRAP_ERET);
113
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
114
dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
115
dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
116
--
55
--
117
2.34.1
56
2.34.1
diff view generated by jsdifflib
New patch
1
The use_first_nan field in float_status was an xtensa-specific way to
2
select at runtime from two different NaN propagation rules. Now that
3
xtensa is using the target-agnostic NaN propagation rule selection
4
that we've just added, we can remove use_first_nan, because there is
5
no longer any code that reads it.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20241202131347.498124-27-peter.maydell@linaro.org
10
---
11
include/fpu/softfloat-helpers.h | 5 -----
12
include/fpu/softfloat-types.h | 1 -
13
target/xtensa/fpu_helper.c | 1 -
14
3 files changed, 7 deletions(-)
15
16
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/fpu/softfloat-helpers.h
19
+++ b/include/fpu/softfloat-helpers.h
20
@@ -XXX,XX +XXX,XX @@ static inline void set_snan_bit_is_one(bool val, float_status *status)
21
status->snan_bit_is_one = val;
22
}
23
24
-static inline void set_use_first_nan(bool val, float_status *status)
25
-{
26
- status->use_first_nan = val;
27
-}
28
-
29
static inline void set_no_signaling_nans(bool val, float_status *status)
30
{
31
status->no_signaling_nans = val;
32
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/fpu/softfloat-types.h
35
+++ b/include/fpu/softfloat-types.h
36
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
37
* softfloat-specialize.inc.c)
38
*/
39
bool snan_bit_is_one;
40
- bool use_first_nan;
41
bool no_signaling_nans;
42
/* should overflowed results subtract re_bias to its exponent? */
43
bool rebias_overflow;
44
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/xtensa/fpu_helper.c
47
+++ b/target/xtensa/fpu_helper.c
48
@@ -XXX,XX +XXX,XX @@ static const struct {
49
50
void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
51
{
52
- set_use_first_nan(use_first, &env->fp_status);
53
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
54
&env->fp_status);
55
set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
56
--
57
2.34.1
diff view generated by jsdifflib
New patch
1
Currently m68k_cpu_reset_hold() calls floatx80_default_nan(NULL)
2
to get the NaN bit pattern to reset the FPU registers. This
3
works because it happens that our implementation of
4
floatx80_default_nan() doesn't actually look at the float_status
5
pointer except for TARGET_MIPS. However, this isn't guaranteed,
6
and to be able to remove the ifdef in floatx80_default_nan()
7
we're going to need a real float_status here.
1
8
9
Rearrange m68k_cpu_reset_hold() so that we initialize env->fp_status
10
earlier, and thus can pass it to floatx80_default_nan().
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20241202131347.498124-28-peter.maydell@linaro.org
15
---
16
target/m68k/cpu.c | 12 +++++++-----
17
1 file changed, 7 insertions(+), 5 deletions(-)
18
19
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/m68k/cpu.c
22
+++ b/target/m68k/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
24
CPUState *cs = CPU(obj);
25
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(obj);
26
CPUM68KState *env = cpu_env(cs);
27
- floatx80 nan = floatx80_default_nan(NULL);
28
+ floatx80 nan;
29
int i;
30
31
if (mcc->parent_phases.hold) {
32
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
33
#else
34
cpu_m68k_set_sr(env, SR_S | SR_I);
35
#endif
36
- for (i = 0; i < 8; i++) {
37
- env->fregs[i].d = nan;
38
- }
39
- cpu_m68k_set_fpcr(env, 0);
40
/*
41
* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
42
* 3.4 FLOATING-POINT INSTRUCTION DETAILS
43
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
44
* preceding paragraph for nonsignaling NaNs.
45
*/
46
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
47
+
48
+ nan = floatx80_default_nan(&env->fp_status);
49
+ for (i = 0; i < 8; i++) {
50
+ env->fregs[i].d = nan;
51
+ }
52
+ cpu_m68k_set_fpcr(env, 0);
53
env->fpsr = 0;
54
55
/* TODO: We should set PC from the interrupt vector. */
56
--
57
2.34.1
diff view generated by jsdifflib
New patch
1
We create our 128-bit default NaN by calling parts64_default_nan()
2
and then adjusting the result. We can do the same trick for creating
3
the floatx80 default NaN, which lets us drop a target ifdef.
1
4
5
floatx80 is used only by:
6
i386
7
m68k
8
arm nwfpe old floating-point emulation emulation support
9
(which is essentially dead, especially the parts involving floatx80)
10
PPC (only in the xsrqpxp instruction, which just rounds an input
11
value by converting to floatx80 and back, so will never generate
12
the default NaN)
13
14
The floatx80 default NaN as currently implemented is:
15
m68k: sign = 0, exp = 1...1, int = 1, frac = 1....1
16
i386: sign = 1, exp = 1...1, int = 1, frac = 10...0
17
18
These are the same as the parts64_default_nan for these architectures.
19
20
This is technically a possible behaviour change for arm linux-user
21
nwfpe emulation emulation, because the default NaN will now have the
22
sign bit clear. But we were already generating a different floatx80
23
default NaN from the real kernel emulation we are supposedly
24
following, which appears to use an all-bits-1 value:
25
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L267
26
27
This won't affect the only "real" use of the nwfpe emulation, which
28
is ancient binaries that used it as part of the old floating point
29
calling convention; that only uses loads and stores of 32 and 64 bit
30
floats, not any of the floatx80 behaviour the original hardware had.
31
We also get the nwfpe float64 default NaN value wrong:
32
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L166
33
so if we ever cared about this obscure corner the right fix would be
34
to correct that so nwfpe used its own default-NaN setting rather
35
than the Arm VFP one.
36
37
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
38
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
39
Message-id: 20241202131347.498124-29-peter.maydell@linaro.org
40
---
41
fpu/softfloat-specialize.c.inc | 20 ++++++++++----------
42
1 file changed, 10 insertions(+), 10 deletions(-)
43
44
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
45
index XXXXXXX..XXXXXXX 100644
46
--- a/fpu/softfloat-specialize.c.inc
47
+++ b/fpu/softfloat-specialize.c.inc
48
@@ -XXX,XX +XXX,XX @@ static void parts128_silence_nan(FloatParts128 *p, float_status *status)
49
floatx80 floatx80_default_nan(float_status *status)
50
{
51
floatx80 r;
52
+ /*
53
+ * Extrapolate from the choices made by parts64_default_nan to fill
54
+ * in the floatx80 format. We assume that floatx80's explicit
55
+ * integer bit is always set (this is true for i386 and m68k,
56
+ * which are the only real users of this format).
57
+ */
58
+ FloatParts64 p64;
59
+ parts64_default_nan(&p64, status);
60
61
- /* None of the targets that have snan_bit_is_one use floatx80. */
62
- assert(!snan_bit_is_one(status));
63
-#if defined(TARGET_M68K)
64
- r.low = UINT64_C(0xFFFFFFFFFFFFFFFF);
65
- r.high = 0x7FFF;
66
-#else
67
- /* X86 */
68
- r.low = UINT64_C(0xC000000000000000);
69
- r.high = 0xFFFF;
70
-#endif
71
+ r.high = 0x7FFF | (p64.sign << 15);
72
+ r.low = (1ULL << DECOMPOSED_BINARY_POINT) | p64.frac;
73
return r;
74
}
75
76
--
77
2.34.1
diff view generated by jsdifflib
New patch
1
In target/loongarch's helper_fclass_s() and helper_fclass_d() we pass
2
a zero-initialized float_status struct to float32_is_quiet_nan() and
3
float64_is_quiet_nan(), with the cryptic comment "for
4
snan_bit_is_one".
1
5
6
This pattern appears to have been copied from target/riscv, where it
7
is used because the functions there do not have ready access to the
8
CPU state struct. The comment presumably refers to the fact that the
9
main reason the is_quiet_nan() functions want the float_state is
10
because they want to know about the snan_bit_is_one config.
11
12
In the loongarch helpers, though, we have the CPU state struct
13
to hand. Use the usual env->fp_status here. This avoids our needing
14
to track that we need to update the initializer of the local
15
float_status structs when the core softfloat code adds new
16
options for targets to configure their behaviour.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20241202131347.498124-30-peter.maydell@linaro.org
21
---
22
target/loongarch/tcg/fpu_helper.c | 6 ++----
23
1 file changed, 2 insertions(+), 4 deletions(-)
24
25
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/loongarch/tcg/fpu_helper.c
28
+++ b/target/loongarch/tcg/fpu_helper.c
29
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
30
} else if (float32_is_zero_or_denormal(f)) {
31
return sign ? 1 << 4 : 1 << 8;
32
} else if (float32_is_any_nan(f)) {
33
- float_status s = { }; /* for snan_bit_is_one */
34
- return float32_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
35
+ return float32_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
36
} else {
37
return sign ? 1 << 3 : 1 << 7;
38
}
39
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
40
} else if (float64_is_zero_or_denormal(f)) {
41
return sign ? 1 << 4 : 1 << 8;
42
} else if (float64_is_any_nan(f)) {
43
- float_status s = { }; /* for snan_bit_is_one */
44
- return float64_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
45
+ return float64_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
46
} else {
47
return sign ? 1 << 3 : 1 << 7;
48
}
49
--
50
2.34.1
diff view generated by jsdifflib
New patch
1
In the frem helper, we have a local float_status because we want to
2
execute the floatx80_div() with a custom rounding mode. Instead of
3
zero-initializing the local float_status and then having to set it up
4
with the m68k standard behaviour (including the NaN propagation rule
5
and copying the rounding precision from env->fp_status), initialize
6
it as a complete copy of env->fp_status. This will avoid our having
7
to add new code in this function for every new config knob we add
8
to fp_status.
1
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-31-peter.maydell@linaro.org
13
---
14
target/m68k/fpu_helper.c | 6 ++----
15
1 file changed, 2 insertions(+), 4 deletions(-)
16
17
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/m68k/fpu_helper.c
20
+++ b/target/m68k/fpu_helper.c
21
@@ -XXX,XX +XXX,XX @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
22
23
fp_rem = floatx80_rem(val1->d, val0->d, &env->fp_status);
24
if (!floatx80_is_any_nan(fp_rem)) {
25
- float_status fp_status = { };
26
+ /* Use local temporary fp_status to set different rounding mode */
27
+ float_status fp_status = env->fp_status;
28
uint32_t quotient;
29
int sign;
30
31
/* Calculate quotient directly using round to nearest mode */
32
- set_float_2nan_prop_rule(float_2nan_prop_ab, &fp_status);
33
set_float_rounding_mode(float_round_nearest_even, &fp_status);
34
- set_floatx80_rounding_precision(
35
- get_floatx80_rounding_precision(&env->fp_status), &fp_status);
36
fp_quot.d = floatx80_div(val1->d, val0->d, &fp_status);
37
38
sign = extractFloatx80Sign(fp_quot.d);
39
--
40
2.34.1
diff view generated by jsdifflib
1
FEAT_NV requires (per I_JKLJK) that when HCR_EL2.{NV,NV1} is {1,1} the
1
In cf_fpu_gdb_get_reg() and cf_fpu_gdb_set_reg() we do the conversion
2
unprivileged-access instructions LDTR, STTR etc behave as normal
2
from float64 to floatx80 using a scratch float_status, because we
3
loads and stores. Implement the check that handles this.
3
don't want the conversion to affect the CPU's floating point exception
4
status. Currently we use a zero-initialized float_status. This will
5
get steadily more awkward as we add config knobs to float_status
6
that the target must initialize. Avoid having to add any of that
7
configuration here by instead initializing our local float_status
8
from the env->fp_status.
4
9
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
12
Message-id: 20241202131347.498124-32-peter.maydell@linaro.org
8
---
13
---
9
target/arm/tcg/hflags.c | 6 ++++--
14
target/m68k/helper.c | 6 ++++--
10
1 file changed, 4 insertions(+), 2 deletions(-)
15
1 file changed, 4 insertions(+), 2 deletions(-)
11
16
12
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
17
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/hflags.c
19
--- a/target/m68k/helper.c
15
+++ b/target/arm/tcg/hflags.c
20
+++ b/target/m68k/helper.c
16
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
21
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
17
switch (mmu_idx) {
22
CPUM68KState *env = &cpu->env;
18
case ARMMMUIdx_E10_1:
23
19
case ARMMMUIdx_E10_1_PAN:
24
if (n < 8) {
20
- /* TODO: ARMv8.3-NV */
25
- float_status s = {};
21
- DP_TBFLAG_A64(flags, UNPRIV, 1);
26
+ /* Use scratch float_status so any exceptions don't change CPU state */
22
+ /* FEAT_NV: NV,NV1 == 1,1 means we don't do UNPRIV accesses */
27
+ float_status s = env->fp_status;
23
+ if ((hcr & (HCR_NV | HCR_NV1)) != (HCR_NV | HCR_NV1)) {
28
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
24
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
29
}
25
+ }
30
switch (n) {
26
break;
31
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
27
case ARMMMUIdx_E20_2:
32
CPUM68KState *env = &cpu->env;
28
case ARMMMUIdx_E20_2_PAN:
33
34
if (n < 8) {
35
- float_status s = {};
36
+ /* Use scratch float_status so any exceptions don't change CPU state */
37
+ float_status s = env->fp_status;
38
env->fregs[n].d = float64_to_floatx80(ldq_be_p(mem_buf), &s);
39
return 8;
40
}
29
--
41
--
30
2.34.1
42
2.34.1
diff view generated by jsdifflib
1
When HCR_EL2.{NV,NV1} is {1,1} we must trap five extra registers to
1
In the helper functions flcmps and flcmpd we use a scratch float_status
2
EL2: VBAR_EL1, ELR_EL1, SPSR_EL1, SCXTNUM_EL1 and TFSR_EL1.
2
so that we don't change the CPU state if the comparison raises any
3
Implement these traps.
3
floating point exception flags. Instead of zero-initializing this
4
scratch float_status, initialize it as a copy of env->fp_status. This
5
avoids the need to explicitly initialize settings like the NaN
6
propagation rule or others we might add to softfloat in future.
4
7
5
This trap does not apply when FEAT_NV2 is implemented and enabled;
8
To do this we need to pass the CPU env pointer in to the helper.
6
include the check that HCR_EL2.NV2 is 0 here, to save us having
7
to come back and add it later.
8
9
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Miguel Luis <miguel.luis@oracle.com>
12
Message-id: 20241202131347.498124-33-peter.maydell@linaro.org
12
---
13
---
13
target/arm/helper.c | 45 +++++++++++++++++++++++++++++++++++++++++----
14
target/sparc/helper.h | 4 ++--
14
1 file changed, 41 insertions(+), 4 deletions(-)
15
target/sparc/fop_helper.c | 8 ++++----
16
target/sparc/translate.c | 4 ++--
17
3 files changed, 8 insertions(+), 8 deletions(-)
15
18
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
21
--- a/target/sparc/helper.h
19
+++ b/target/arm/helper.c
22
+++ b/target/sparc/helper.h
20
@@ -XXX,XX +XXX,XX @@ static void mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
21
}
24
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
25
DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
26
DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
27
-DEF_HELPER_FLAGS_2(flcmps, TCG_CALL_NO_RWG_SE, i32, f32, f32)
28
-DEF_HELPER_FLAGS_2(flcmpd, TCG_CALL_NO_RWG_SE, i32, f64, f64)
29
+DEF_HELPER_FLAGS_3(flcmps, TCG_CALL_NO_RWG_SE, i32, env, f32, f32)
30
+DEF_HELPER_FLAGS_3(flcmpd, TCG_CALL_NO_RWG_SE, i32, env, f64, f64)
31
DEF_HELPER_2(raise_exception, noreturn, env, int)
32
33
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
34
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/sparc/fop_helper.c
37
+++ b/target/sparc/fop_helper.c
38
@@ -XXX,XX +XXX,XX @@ uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
39
return finish_fcmp(env, r, GETPC());
22
}
40
}
23
41
24
+static CPAccessResult access_nv1(CPUARMState *env, const ARMCPRegInfo *ri,
42
-uint32_t helper_flcmps(float32 src1, float32 src2)
25
+ bool isread)
43
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
26
+{
44
{
27
+ if (arm_current_el(env) == 1) {
28
+ uint64_t hcr_nv = arm_hcr_el2_eff(env) & (HCR_NV | HCR_NV1 | HCR_NV2);
29
+
30
+ if (hcr_nv == (HCR_NV | HCR_NV1)) {
31
+ return CP_ACCESS_TRAP_EL2;
32
+ }
33
+ }
34
+ return CP_ACCESS_OK;
35
+}
36
+
37
#ifdef CONFIG_USER_ONLY
38
/*
39
* `IC IVAU` is handled to improve compatibility with JITs that dual-map their
40
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
41
{ .name = "ELR_EL1", .state = ARM_CP_STATE_AA64,
42
.type = ARM_CP_ALIAS,
43
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1,
44
- .access = PL1_RW,
45
+ .access = PL1_RW, .accessfn = access_nv1,
46
.fieldoffset = offsetof(CPUARMState, elr_el[1]) },
47
{ .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
48
.type = ARM_CP_ALIAS,
49
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
50
- .access = PL1_RW,
51
+ .access = PL1_RW, .accessfn = access_nv1,
52
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
53
/*
45
/*
54
* We rely on the access checks not allowing the guest to write to the
46
* FLCMP never raises an exception nor modifies any FSR fields.
55
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_mte(CPUARMState *env, const ARMCPRegInfo *ri,
47
* Perform the comparison with a dummy fp environment.
56
return CP_ACCESS_OK;
48
*/
49
- float_status discard = { };
50
+ float_status discard = env->fp_status;
51
FloatRelation r;
52
53
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
54
@@ -XXX,XX +XXX,XX @@ uint32_t helper_flcmps(float32 src1, float32 src2)
55
g_assert_not_reached();
57
}
56
}
58
57
59
+static CPAccessResult access_tfsr_el1(CPUARMState *env, const ARMCPRegInfo *ri,
58
-uint32_t helper_flcmpd(float64 src1, float64 src2)
60
+ bool isread)
59
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
61
+{
62
+ CPAccessResult nv1 = access_nv1(env, ri, isread);
63
+
64
+ if (nv1 != CP_ACCESS_OK) {
65
+ return nv1;
66
+ }
67
+ return access_mte(env, ri, isread);
68
+}
69
+
70
static CPAccessResult access_tfsr_el2(CPUARMState *env, const ARMCPRegInfo *ri,
71
bool isread)
72
{
60
{
73
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
61
- float_status discard = { };
74
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[0]) },
62
+ float_status discard = env->fp_status;
75
{ .name = "TFSR_EL1", .state = ARM_CP_STATE_AA64,
63
FloatRelation r;
76
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 0,
64
77
- .access = PL1_RW, .accessfn = access_mte,
65
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
78
+ .access = PL1_RW, .accessfn = access_tfsr_el1,
66
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
79
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
67
index XXXXXXX..XXXXXXX 100644
80
{ .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
68
--- a/target/sparc/translate.c
81
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 6, .opc2 = 0,
69
+++ b/target/sparc/translate.c
82
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_scxtnum(CPUARMState *env, const ARMCPRegInfo *ri,
70
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPs(DisasContext *dc, arg_FLCMPs *a)
83
return CP_ACCESS_OK;
71
72
src1 = gen_load_fpr_F(dc, a->rs1);
73
src2 = gen_load_fpr_F(dc, a->rs2);
74
- gen_helper_flcmps(cpu_fcc[a->cc], src1, src2);
75
+ gen_helper_flcmps(cpu_fcc[a->cc], tcg_env, src1, src2);
76
return advance_pc(dc);
84
}
77
}
85
78
86
+static CPAccessResult access_scxtnum_el1(CPUARMState *env,
79
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPd(DisasContext *dc, arg_FLCMPd *a)
87
+ const ARMCPRegInfo *ri,
80
88
+ bool isread)
81
src1 = gen_load_fpr_D(dc, a->rs1);
89
+{
82
src2 = gen_load_fpr_D(dc, a->rs2);
90
+ CPAccessResult nv1 = access_nv1(env, ri, isread);
83
- gen_helper_flcmpd(cpu_fcc[a->cc], src1, src2);
91
+
84
+ gen_helper_flcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
92
+ if (nv1 != CP_ACCESS_OK) {
85
return advance_pc(dc);
93
+ return nv1;
86
}
94
+ }
87
95
+ return access_scxtnum(env, ri, isread);
96
+}
97
+
98
static const ARMCPRegInfo scxtnum_reginfo[] = {
99
{ .name = "SCXTNUM_EL0", .state = ARM_CP_STATE_AA64,
100
.opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 7,
101
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo scxtnum_reginfo[] = {
102
.fieldoffset = offsetof(CPUARMState, scxtnum_el[0]) },
103
{ .name = "SCXTNUM_EL1", .state = ARM_CP_STATE_AA64,
104
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 7,
105
- .access = PL1_RW, .accessfn = access_scxtnum,
106
+ .access = PL1_RW, .accessfn = access_scxtnum_el1,
107
.fgt = FGT_SCXTNUM_EL1,
108
.fieldoffset = offsetof(CPUARMState, scxtnum_el[1]) },
109
{ .name = "SCXTNUM_EL2", .state = ARM_CP_STATE_AA64,
110
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
111
{ .name = "VBAR", .state = ARM_CP_STATE_BOTH,
112
.opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
113
.access = PL1_RW, .writefn = vbar_write,
114
+ .accessfn = access_nv1,
115
.fgt = FGT_VBAR_EL1,
116
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
117
offsetof(CPUARMState, cp15.vbar_ns) },
118
--
88
--
119
2.34.1
89
2.34.1
diff view generated by jsdifflib
1
Mark up the cpreginfo structs for the GIC CPU registers to indicate
1
In the helper_compute_fprf functions, we pass a dummy float_status
2
the offsets from VNCR_EL2, as defined in table D8-66 in rule R_CSRPQ
2
in to the is_signaling_nan() function. This is unnecessary, because
3
in the Arm ARM.
3
we have convenient access to the CPU env pointer here and that
4
is already set up with the correct values for the snan_bit_is_one
5
and no_signaling_nans config settings. is_signaling_nan() doesn't
6
ever update the fp_status with any exception flags, so there is
7
no reason not to use env->fp_status here.
8
9
Use env->fp_status instead of the dummy fp_status.
4
10
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
13
Message-id: 20241202131347.498124-34-peter.maydell@linaro.org
8
---
14
---
9
hw/intc/arm_gicv3_cpuif.c | 11 +++++++++++
15
target/ppc/fpu_helper.c | 3 +--
10
1 file changed, 11 insertions(+)
16
1 file changed, 1 insertion(+), 2 deletions(-)
11
17
12
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
18
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/arm_gicv3_cpuif.c
20
--- a/target/ppc/fpu_helper.c
15
+++ b/hw/intc/arm_gicv3_cpuif.c
21
+++ b/target/ppc/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
22
@@ -XXX,XX +XXX,XX @@ void helper_compute_fprf_##tp(CPUPPCState *env, tp arg) \
17
{ .name = "ICH_AP0R0_EL2", .state = ARM_CP_STATE_BOTH,
23
} else if (tp##_is_infinity(arg)) { \
18
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 0,
24
fprf = neg ? 0x09 << FPSCR_FPRF : 0x05 << FPSCR_FPRF; \
19
.type = ARM_CP_IO | ARM_CP_NO_RAW,
25
} else { \
20
+ .nv2_redirect_offset = 0x480,
26
- float_status dummy = { }; /* snan_bit_is_one = 0 */ \
21
.access = PL2_RW,
27
- if (tp##_is_signaling_nan(arg, &dummy)) { \
22
.readfn = ich_ap_read,
28
+ if (tp##_is_signaling_nan(arg, &env->fp_status)) { \
23
.writefn = ich_ap_write,
29
fprf = 0x00 << FPSCR_FPRF; \
24
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
30
} else { \
25
{ .name = "ICH_AP1R0_EL2", .state = ARM_CP_STATE_BOTH,
31
fprf = 0x11 << FPSCR_FPRF; \
26
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 0,
27
.type = ARM_CP_IO | ARM_CP_NO_RAW,
28
+ .nv2_redirect_offset = 0x4a0,
29
.access = PL2_RW,
30
.readfn = ich_ap_read,
31
.writefn = ich_ap_write,
32
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
33
{ .name = "ICH_HCR_EL2", .state = ARM_CP_STATE_BOTH,
34
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 0,
35
.type = ARM_CP_IO | ARM_CP_NO_RAW,
36
+ .nv2_redirect_offset = 0x4c0,
37
.access = PL2_RW,
38
.readfn = ich_hcr_read,
39
.writefn = ich_hcr_write,
40
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
41
{ .name = "ICH_VMCR_EL2", .state = ARM_CP_STATE_BOTH,
42
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 7,
43
.type = ARM_CP_IO | ARM_CP_NO_RAW,
44
+ .nv2_redirect_offset = 0x4c8,
45
.access = PL2_RW,
46
.readfn = ich_vmcr_read,
47
.writefn = ich_vmcr_write,
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr1_reginfo[] = {
49
{ .name = "ICH_AP0R1_EL2", .state = ARM_CP_STATE_BOTH,
50
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 1,
51
.type = ARM_CP_IO | ARM_CP_NO_RAW,
52
+ .nv2_redirect_offset = 0x488,
53
.access = PL2_RW,
54
.readfn = ich_ap_read,
55
.writefn = ich_ap_write,
56
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr1_reginfo[] = {
57
{ .name = "ICH_AP1R1_EL2", .state = ARM_CP_STATE_BOTH,
58
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 1,
59
.type = ARM_CP_IO | ARM_CP_NO_RAW,
60
+ .nv2_redirect_offset = 0x4a8,
61
.access = PL2_RW,
62
.readfn = ich_ap_read,
63
.writefn = ich_ap_write,
64
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
65
{ .name = "ICH_AP0R2_EL2", .state = ARM_CP_STATE_BOTH,
66
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 2,
67
.type = ARM_CP_IO | ARM_CP_NO_RAW,
68
+ .nv2_redirect_offset = 0x490,
69
.access = PL2_RW,
70
.readfn = ich_ap_read,
71
.writefn = ich_ap_write,
72
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
73
{ .name = "ICH_AP0R3_EL2", .state = ARM_CP_STATE_BOTH,
74
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 3,
75
.type = ARM_CP_IO | ARM_CP_NO_RAW,
76
+ .nv2_redirect_offset = 0x498,
77
.access = PL2_RW,
78
.readfn = ich_ap_read,
79
.writefn = ich_ap_write,
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
81
{ .name = "ICH_AP1R2_EL2", .state = ARM_CP_STATE_BOTH,
82
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 2,
83
.type = ARM_CP_IO | ARM_CP_NO_RAW,
84
+ .nv2_redirect_offset = 0x4b0,
85
.access = PL2_RW,
86
.readfn = ich_ap_read,
87
.writefn = ich_ap_write,
88
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
89
{ .name = "ICH_AP1R3_EL2", .state = ARM_CP_STATE_BOTH,
90
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 3,
91
.type = ARM_CP_IO | ARM_CP_NO_RAW,
92
+ .nv2_redirect_offset = 0x4b8,
93
.access = PL2_RW,
94
.readfn = ich_ap_read,
95
.writefn = ich_ap_write,
96
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
97
.opc0 = 3, .opc1 = 4, .crn = 12,
98
.crm = 12 + (j >> 3), .opc2 = j & 7,
99
.type = ARM_CP_IO | ARM_CP_NO_RAW,
100
+ .nv2_redirect_offset = 0x400 + 8 * j,
101
.access = PL2_RW,
102
.readfn = ich_lr_read,
103
.writefn = ich_lr_write,
104
--
32
--
105
2.34.1
33
2.34.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
QDev objects created with qdev_new() need to manually add
3
Now that float_status has a bunch of fp parameters,
4
their parent relationship with object_property_add_child().
4
it is easier to copy an existing structure than create
5
one from scratch. Begin by copying the structure that
6
corresponds to the FPSR and make only the adjustments
7
required for BFloat16 semantics.
5
8
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20240104141159.53883-1-philmd@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20241203203949.483774-2-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
hw/arm/msf2-som.c | 1 +
15
target/arm/tcg/vec_helper.c | 20 +++++++-------------
12
hw/arm/netduino2.c | 1 +
16
1 file changed, 7 insertions(+), 13 deletions(-)
13
hw/arm/netduinoplus2.c | 1 +
14
hw/arm/olimex-stm32-h405.c | 1 +
15
hw/arm/stm32vldiscovery.c | 1 +
16
5 files changed, 5 insertions(+)
17
17
18
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
18
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/msf2-som.c
20
--- a/target/arm/tcg/vec_helper.c
21
+++ b/hw/arm/msf2-som.c
21
+++ b/target/arm/tcg/vec_helper.c
22
@@ -XXX,XX +XXX,XX @@ static void emcraft_sf2_s2s010_init(MachineState *machine)
22
@@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
23
memory_region_add_subregion(sysmem, DDR_BASE_ADDRESS, ddr);
23
* no effect on AArch32 instructions.
24
24
*/
25
dev = qdev_new(TYPE_MSF2_SOC);
25
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
26
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
26
- *statusp = (float_status){
27
qdev_prop_set_string(dev, "part-name", "M2S010");
27
- .tininess_before_rounding = float_tininess_before_rounding,
28
qdev_prop_set_string(dev, "cpu-type", mc->default_cpu_type);
28
- .float_rounding_mode = float_round_to_odd_inf,
29
29
- .flush_to_zero = true,
30
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
30
- .flush_inputs_to_zero = true,
31
index XXXXXXX..XXXXXXX 100644
31
- .default_nan_mode = true,
32
--- a/hw/arm/netduino2.c
32
- };
33
+++ b/hw/arm/netduino2.c
33
+
34
@@ -XXX,XX +XXX,XX @@ static void netduino2_init(MachineState *machine)
34
+ *statusp = env->vfp.fp_status;
35
clock_set_hz(sysclk, SYSCLK_FRQ);
35
+ set_default_nan_mode(true, statusp);
36
36
37
dev = qdev_new(TYPE_STM32F205_SOC);
37
if (ebf) {
38
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
38
- float_status *fpst = &env->vfp.fp_status;
39
qdev_connect_clock_in(dev, "sysclk", sysclk);
39
- set_flush_to_zero(get_flush_to_zero(fpst), statusp);
40
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
40
- set_flush_inputs_to_zero(get_flush_inputs_to_zero(fpst), statusp);
41
41
- set_float_rounding_mode(get_float_rounding_mode(fpst), statusp);
42
diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
42
-
43
index XXXXXXX..XXXXXXX 100644
43
/* EBF=1 needs to do a step with round-to-odd semantics */
44
--- a/hw/arm/netduinoplus2.c
44
*oddstatusp = *statusp;
45
+++ b/hw/arm/netduinoplus2.c
45
set_float_rounding_mode(float_round_to_odd, oddstatusp);
46
@@ -XXX,XX +XXX,XX @@ static void netduinoplus2_init(MachineState *machine)
46
+ } else {
47
clock_set_hz(sysclk, SYSCLK_FRQ);
47
+ set_flush_to_zero(true, statusp);
48
48
+ set_flush_inputs_to_zero(true, statusp);
49
dev = qdev_new(TYPE_STM32F405_SOC);
49
+ set_float_rounding_mode(float_round_to_odd_inf, statusp);
50
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
50
}
51
qdev_connect_clock_in(dev, "sysclk", sysclk);
51
-
52
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
52
return ebf;
53
53
}
54
diff --git a/hw/arm/olimex-stm32-h405.c b/hw/arm/olimex-stm32-h405.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/olimex-stm32-h405.c
57
+++ b/hw/arm/olimex-stm32-h405.c
58
@@ -XXX,XX +XXX,XX @@ static void olimex_stm32_h405_init(MachineState *machine)
59
clock_set_hz(sysclk, SYSCLK_FRQ);
60
61
dev = qdev_new(TYPE_STM32F405_SOC);
62
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
63
qdev_connect_clock_in(dev, "sysclk", sysclk);
64
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
65
66
diff --git a/hw/arm/stm32vldiscovery.c b/hw/arm/stm32vldiscovery.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/stm32vldiscovery.c
69
+++ b/hw/arm/stm32vldiscovery.c
70
@@ -XXX,XX +XXX,XX @@ static void stm32vldiscovery_init(MachineState *machine)
71
clock_set_hz(sysclk, SYSCLK_FRQ);
72
73
dev = qdev_new(TYPE_STM32F100_SOC);
74
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
75
qdev_connect_clock_in(dev, "sysclk", sysclk);
76
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
77
54
78
--
55
--
79
2.34.1
56
2.34.1
80
57
81
58
diff view generated by jsdifflib
1
FEAT_NV and FEAT_NV2 will allow EL1 to attempt to access cpregs that
1
Currently we hardcode the default NaN value in parts64_default_nan()
2
only exist at EL2. This means we're going to want to run their
2
using a compile-time ifdef ladder. This is awkward for two cases:
3
accessfns when the CPU is at EL1. In almost all cases, the behaviour
3
* for single-QEMU-binary we can't hard-code target-specifics like this
4
we want is "the accessfn returns OK if at EL1".
4
* for Arm FEAT_AFP the default NaN value depends on FPCR.AH
5
(specifically the sign bit is different)
5
6
6
Mostly the accessfn already does the right thing; in a few cases we
7
Add a field to float_status to specify the default NaN value; fall
7
need to explicitly check that the EL is not 1 before applying various
8
back to the old ifdef behaviour if these are not set.
8
trap controls, or split out an accessfn used both for an _EL1 and an
9
_EL2 register into two so we can handle the FEAT_NV case correctly
10
for the _EL2 register.
11
9
12
There are two registers where we want the accessfn to trap for
10
The default NaN value is specified by setting a uint8_t to a
13
a FEAT_NV EL1 access: VSTTBR_EL2 and VSTCR_EL2 should UNDEF
11
pattern corresponding to the sign and upper fraction parts of
14
an access from NonSecure EL1, not trap to EL2 under FEAT_NV.
12
the NaN; the lower bits of the fraction are set from bit 0 of
15
The way we have written sel2_access() already results in this
13
the pattern.
16
behaviour.
17
18
We can identify the registers we care about here because they
19
all have opc1 == 4 or 5.
20
14
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Tested-by: Miguel Luis <miguel.luis@oracle.com>
17
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
24
---
18
---
25
target/arm/debug_helper.c | 12 +++++++-
19
include/fpu/softfloat-helpers.h | 11 +++++++
26
target/arm/helper.c | 65 ++++++++++++++++++++++++++++++++++-----
20
include/fpu/softfloat-types.h | 10 ++++++
27
2 files changed, 69 insertions(+), 8 deletions(-)
21
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
22
3 files changed, 54 insertions(+), 22 deletions(-)
28
23
29
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
24
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
30
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/debug_helper.c
26
--- a/include/fpu/softfloat-helpers.h
32
+++ b/target/arm/debug_helper.c
27
+++ b/include/fpu/softfloat-helpers.h
33
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
28
@@ -XXX,XX +XXX,XX @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
34
return CP_ACCESS_OK;
29
status->float_infzeronan_rule = rule;
35
}
30
}
36
31
37
+static CPAccessResult access_dbgvcr32(CPUARMState *env, const ARMCPRegInfo *ri,
32
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
38
+ bool isread)
33
+ float_status *status)
39
+{
34
+{
40
+ /* MCDR_EL3.TDMA doesn't apply for FEAT_NV traps */
35
+ status->default_nan_pattern = dnan_pattern;
41
+ if (arm_current_el(env) == 2 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
42
+ return CP_ACCESS_TRAP_EL3;
43
+ }
44
+ return CP_ACCESS_OK;
45
+}
36
+}
46
+
37
+
47
/*
38
static inline void set_flush_to_zero(bool val, float_status *status)
48
* Check for traps to Debug Comms Channel registers. If FEAT_FGT
49
* is implemented then these are controlled by MDCR_EL2.TDCC for
50
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_aa32_el1_reginfo[] = {
51
*/
52
{ .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
53
.opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
54
- .access = PL2_RW, .accessfn = access_tda,
55
+ .access = PL2_RW, .accessfn = access_dbgvcr32,
56
.type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
57
};
58
59
diff --git a/target/arm/helper.c b/target/arm/helper.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/helper.c
62
+++ b/target/arm/helper.c
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
64
static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
65
bool isread)
66
{
39
{
67
+ if (arm_current_el(env) == 1) {
40
status->flush_to_zero = val;
68
+ /* This must be a FEAT_NV access */
41
@@ -XXX,XX +XXX,XX @@ static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status
69
+ /* TODO: FEAT_ECV will need to check CNTHCTL_EL2 here */
42
return status->float_infzeronan_rule;
70
+ return CP_ACCESS_OK;
71
+ }
72
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
73
return CP_ACCESS_TRAP;
74
}
75
@@ -XXX,XX +XXX,XX @@ static void hcrx_write(CPUARMState *env, const ARMCPRegInfo *ri,
76
static CPAccessResult access_hxen(CPUARMState *env, const ARMCPRegInfo *ri,
77
bool isread)
78
{
79
- if (arm_current_el(env) < 3
80
+ if (arm_current_el(env) == 2
81
&& arm_feature(env, ARM_FEATURE_EL3)
82
&& !(env->cp15.scr_el3 & SCR_HXEN)) {
83
return CP_ACCESS_TRAP_EL3;
84
@@ -XXX,XX +XXX,XX @@ static CPAccessResult el2_e2h_e12_access(CPUARMState *env,
85
const ARMCPRegInfo *ri,
86
bool isread)
87
{
88
+ if (arm_current_el(env) == 1) {
89
+ /*
90
+ * This must be a FEAT_NV access (will either trap or redirect
91
+ * to memory). None of the registers with _EL12 aliases want to
92
+ * apply their trap controls for this kind of access, so don't
93
+ * call the orig_accessfn or do the "UNDEF when E2H is 0" check.
94
+ */
95
+ return CP_ACCESS_OK;
96
+ }
97
/* FOO_EL12 aliases only exist when E2H is 1; otherwise they UNDEF */
98
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
99
return CP_ACCESS_TRAP_UNCATEGORIZED;
100
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tpidr2(CPUARMState *env, const ARMCPRegInfo *ri,
101
return CP_ACCESS_OK;
102
}
43
}
103
44
104
-static CPAccessResult access_esm(CPUARMState *env, const ARMCPRegInfo *ri,
45
+static inline uint8_t get_float_default_nan_pattern(float_status *status)
105
- bool isread)
106
+static CPAccessResult access_smprimap(CPUARMState *env, const ARMCPRegInfo *ri,
107
+ bool isread)
108
+{
46
+{
109
+ /* If EL1 this is a FEAT_NV access and CPTR_EL3.ESM doesn't apply */
47
+ return status->default_nan_pattern;
110
+ if (arm_current_el(env) == 2
111
+ && arm_feature(env, ARM_FEATURE_EL3)
112
+ && !FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, ESM)) {
113
+ return CP_ACCESS_TRAP_EL3;
114
+ }
115
+ return CP_ACCESS_OK;
116
+}
48
+}
117
+
49
+
118
+static CPAccessResult access_smpri(CPUARMState *env, const ARMCPRegInfo *ri,
50
static inline bool get_flush_to_zero(float_status *status)
119
+ bool isread)
120
{
51
{
121
- /* TODO: FEAT_FGT for SMPRI_EL1 but not SMPRIMAP_EL2 */
52
return status->flush_to_zero;
122
if (arm_current_el(env) < 3
53
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
123
&& arm_feature(env, ARM_FEATURE_EL3)
54
index XXXXXXX..XXXXXXX 100644
124
&& !FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, ESM)) {
55
--- a/include/fpu/softfloat-types.h
125
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
56
+++ b/include/fpu/softfloat-types.h
126
*/
57
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
127
{ .name = "SMPRI_EL1", .state = ARM_CP_STATE_AA64,
58
/* should denormalised inputs go to zero and set the input_denormal flag? */
128
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 4,
59
bool flush_inputs_to_zero;
129
- .access = PL1_RW, .accessfn = access_esm,
60
bool default_nan_mode;
130
+ .access = PL1_RW, .accessfn = access_smpri,
61
+ /*
131
.fgt = FGT_NSMPRI_EL1,
62
+ * The pattern to use for the default NaN. Here the high bit specifies
132
.type = ARM_CP_CONST, .resetvalue = 0 },
63
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
133
{ .name = "SMPRIMAP_EL2", .state = ARM_CP_STATE_AA64,
64
+ * fractional part. The low bits of the fractional part are copies of bit 0.
134
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 5,
65
+ * The exponent of the default NaN is (as for any NaN) always all 1s.
135
- .access = PL2_RW, .accessfn = access_esm,
66
+ * Note that a value of 0 here is not a valid NaN. The target must set
136
+ .access = PL2_RW, .accessfn = access_smprimap,
67
+ * this to the correct non-zero value, or we will assert when trying to
137
.type = ARM_CP_CONST, .resetvalue = 0 },
68
+ * create a default NaN.
138
};
69
+ */
139
70
+ uint8_t default_nan_pattern;
140
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_mte(CPUARMState *env, const ARMCPRegInfo *ri,
71
/*
141
bool isread)
72
* The flags below are not used on all specializations and may
73
* constant fold away (see snan_bit_is_one()/no_signalling_nans() in
74
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
75
index XXXXXXX..XXXXXXX 100644
76
--- a/fpu/softfloat-specialize.c.inc
77
+++ b/fpu/softfloat-specialize.c.inc
78
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
142
{
79
{
143
int el = arm_current_el(env);
80
bool sign = 0;
144
+ if (el < 2 && arm_is_el2_enabled(env)) {
81
uint64_t frac;
145
+ uint64_t hcr = arm_hcr_el2_eff(env);
82
+ uint8_t dnan_pattern = status->default_nan_pattern;
146
+ if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
83
147
+ return CP_ACCESS_TRAP_EL2;
84
+ if (dnan_pattern == 0) {
85
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
86
- /* !snan_bit_is_one, set all bits */
87
- frac = (1ULL << DECOMPOSED_BINARY_POINT) - 1;
88
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
89
+ /* Sign bit clear, all frac bits set */
90
+ dnan_pattern = 0b01111111;
91
+#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
92
|| defined(TARGET_MICROBLAZE)
93
- /* !snan_bit_is_one, set sign and msb */
94
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
95
- sign = 1;
96
+ /* Sign bit set, most significant frac bit set */
97
+ dnan_pattern = 0b11000000;
98
#elif defined(TARGET_HPPA)
99
- /* snan_bit_is_one, set msb-1. */
100
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 2);
101
+ /* Sign bit clear, msb-1 frac bit set */
102
+ dnan_pattern = 0b00100000;
103
#elif defined(TARGET_HEXAGON)
104
- sign = 1;
105
- frac = ~0ULL;
106
+ /* Sign bit set, all frac bits set. */
107
+ dnan_pattern = 0b11111111;
108
#else
109
- /*
110
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
111
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
112
- * do not have floating-point.
113
- */
114
- if (snan_bit_is_one(status)) {
115
- /* set all bits other than msb */
116
- frac = (1ULL << (DECOMPOSED_BINARY_POINT - 1)) - 1;
117
- } else {
118
- /* set msb */
119
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
120
- }
121
+ /*
122
+ * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
123
+ * S390, SH4, TriCore, and Xtensa. Our other supported targets
124
+ * do not have floating-point.
125
+ */
126
+ if (snan_bit_is_one(status)) {
127
+ /* sign bit clear, set all frac bits other than msb */
128
+ dnan_pattern = 0b00111111;
129
+ } else {
130
+ /* sign bit clear, set frac msb */
131
+ dnan_pattern = 0b01000000;
148
+ }
132
+ }
133
#endif
149
+ }
134
+ }
150
+ if (el < 3 &&
135
+ assert(dnan_pattern != 0);
151
+ arm_feature(env, ARM_FEATURE_EL3) &&
136
+
152
+ !(env->cp15.scr_el3 & SCR_ATA)) {
137
+ sign = dnan_pattern >> 7;
153
+ return CP_ACCESS_TRAP_EL3;
154
+ }
155
+ return CP_ACCESS_OK;
156
+}
157
158
+static CPAccessResult access_tfsr_el2(CPUARMState *env, const ARMCPRegInfo *ri,
159
+ bool isread)
160
+{
161
+ /*
138
+ /*
162
+ * TFSR_EL2: similar to generic access_mte(), but we need to
139
+ * Place default_nan_pattern [6:0] into bits [62:56],
163
+ * account for FEAT_NV. At EL1 this must be a FEAT_NV access;
140
+ * and replecate bit [0] down into [55:0]
164
+ * we will trap to EL2 and the HCR/SCR traps do not apply.
165
+ */
141
+ */
166
+ int el = arm_current_el(env);
142
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
167
+
143
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
168
+ if (el == 1) {
144
169
+ return CP_ACCESS_OK;
145
*p = (FloatParts64) {
170
+ }
146
.cls = float_class_qnan,
171
if (el < 2 && arm_is_el2_enabled(env)) {
172
uint64_t hcr = arm_hcr_el2_eff(env);
173
if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
174
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
175
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
176
{ .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
177
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 6, .opc2 = 0,
178
- .access = PL2_RW, .accessfn = access_mte,
179
+ .access = PL2_RW, .accessfn = access_tfsr_el2,
180
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[2]) },
181
{ .name = "TFSR_EL3", .state = ARM_CP_STATE_AA64,
182
.opc0 = 3, .opc1 = 6, .crn = 5, .crm = 6, .opc2 = 0,
183
--
147
--
184
2.34.1
148
2.34.1
diff view generated by jsdifflib
1
Mark up the cpreginfo structs to indicate offsets for system
1
Set the default NaN pattern explicitly for the tests/fp code.
2
registers from VNCR_EL2, as defined in table D8-66 in rule R_CSRPQ in
3
the Arm ARM. This covers all the remaining offsets at 0x200 and
4
above, except for the GIC ICH_* registers.
5
6
(Note that because we don't implement FEAT_SPE, FEAT_TRF,
7
FEAT_MPAM, FEAT_BRBE or FEAT_AMUv1p1 we don't implement any
8
of the registers that use offsets at 0x800 and above.)
9
2
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Tested-by: Miguel Luis <miguel.luis@oracle.com>
5
Message-id: 20241202131347.498124-36-peter.maydell@linaro.org
13
---
6
---
14
target/arm/helper.c | 8 ++++++++
7
tests/fp/fp-bench.c | 1 +
15
1 file changed, 8 insertions(+)
8
tests/fp/fp-test-log2.c | 1 +
9
tests/fp/fp-test.c | 1 +
10
3 files changed, 3 insertions(+)
16
11
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
14
--- a/tests/fp/fp-bench.c
20
+++ b/target/arm/helper.c
15
+++ b/tests/fp/fp-bench.c
21
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
16
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
22
.opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
17
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
23
.access = PL1_RW, .accessfn = access_tvm_trvm,
18
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
24
.fgt = FGT_FAR_EL1,
19
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
25
+ .nv2_redirect_offset = 0x220 | NV2_REDIR_NV1,
20
+ set_float_default_nan_pattern(0b01000000, &soft_status);
26
.fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
21
27
.resetvalue = 0, },
22
f = bench_funcs[operation][precision];
28
};
23
g_assert(f);
29
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
24
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c
30
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
25
index XXXXXXX..XXXXXXX 100644
31
.access = PL1_RW, .accessfn = access_tvm_trvm,
26
--- a/tests/fp/fp-test-log2.c
32
.fgt = FGT_TTBR0_EL1,
27
+++ b/tests/fp/fp-test-log2.c
33
+ .nv2_redirect_offset = 0x200 | NV2_REDIR_NV1,
28
@@ -XXX,XX +XXX,XX @@ int main(int ac, char **av)
34
.writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
29
int i;
35
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
30
36
offsetof(CPUARMState, cp15.ttbr0_ns) } },
31
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
37
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
32
+ set_float_default_nan_pattern(0b01000000, &qsf);
38
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
33
set_float_rounding_mode(float_round_nearest_even, &qsf);
39
.access = PL1_RW, .accessfn = access_tvm_trvm,
34
40
.fgt = FGT_TTBR1_EL1,
35
test.d = 0.0;
41
+ .nv2_redirect_offset = 0x210 | NV2_REDIR_NV1,
36
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
42
.writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
37
index XXXXXXX..XXXXXXX 100644
43
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
38
--- a/tests/fp/fp-test.c
44
offsetof(CPUARMState, cp15.ttbr1_ns) } },
39
+++ b/tests/fp/fp-test.c
45
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
40
@@ -XXX,XX +XXX,XX @@ void run_test(void)
46
.type = ARM_CP_ALIAS,
41
*/
47
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1,
42
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
48
.access = PL1_RW, .accessfn = access_nv1,
43
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
49
+ .nv2_redirect_offset = 0x230 | NV2_REDIR_NV1,
44
+ set_float_default_nan_pattern(0b01000000, &qsf);
50
.fieldoffset = offsetof(CPUARMState, elr_el[1]) },
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
51
{ .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
46
52
.type = ARM_CP_ALIAS,
47
genCases_setLevel(test_level);
53
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
54
.fieldoffset = offsetof(CPUARMState, sp_el[0]) },
55
{ .name = "SP_EL1", .state = ARM_CP_STATE_AA64,
56
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 1, .opc2 = 0,
57
+ .nv2_redirect_offset = 0x240,
58
.access = PL2_RW, .type = ARM_CP_ALIAS | ARM_CP_EL3_NO_EL2_KEEP,
59
.fieldoffset = offsetof(CPUARMState, sp_el[1]) },
60
{ .name = "SPSel", .state = ARM_CP_STATE_AA64,
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo minimal_ras_reginfo[] = {
62
.type = ARM_CP_CONST, .resetvalue = 0 },
63
{ .name = "VDISR_EL2", .state = ARM_CP_STATE_BOTH,
64
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 1, .opc2 = 1,
65
+ .nv2_redirect_offset = 0x500,
66
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.vdisr_el2) },
67
{ .name = "VSESR_EL2", .state = ARM_CP_STATE_BOTH,
68
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 3,
69
+ .nv2_redirect_offset = 0x508,
70
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.vsesr_el2) },
71
};
72
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
74
.access = PL1_RW, .writefn = vbar_write,
75
.accessfn = access_nv1,
76
.fgt = FGT_VBAR_EL1,
77
+ .nv2_redirect_offset = 0x250 | NV2_REDIR_NV1,
78
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
79
offsetof(CPUARMState, cp15.vbar_ns) },
80
.resetvalue = 0 },
81
--
48
--
82
2.34.1
49
2.34.1
diff view generated by jsdifflib
1
Mark up the cpreginfo structs to indicate offsets for system
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
registers from VNCR_EL2, as defined in table D8-66 in rule R_CSRPQ in
2
parts64_default_nan().
3
the Arm ARM. This commit covers offsets 0x168 to 0x1f8.
4
3
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
6
Message-id: 20241202131347.498124-37-peter.maydell@linaro.org
8
---
7
---
9
target/arm/helper.c | 18 ++++++++++++++++++
8
target/microblaze/cpu.c | 2 ++
10
1 file changed, 18 insertions(+)
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
14
--- a/target/microblaze/cpu.c
15
+++ b/target/arm/helper.c
15
+++ b/target/microblaze/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
16
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_reset_hold(Object *obj, ResetType type)
17
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 1,
17
* this architecture.
18
.type = ARM_CP_IO, .access = PL0_RW,
18
*/
19
.accessfn = gt_ptimer_access,
19
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
20
+ .nv2_redirect_offset = 0x180 | NV2_REDIR_NV1,
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
.resetvalue = 0,
22
23
.readfn = gt_phys_redir_ctl_read, .raw_readfn = raw_read,
23
#if defined(CONFIG_USER_ONLY)
24
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
24
/* start in user mode with interrupts enabled. */
25
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 1,
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
.type = ARM_CP_IO, .access = PL0_RW,
26
index XXXXXXX..XXXXXXX 100644
27
.accessfn = gt_vtimer_access,
27
--- a/fpu/softfloat-specialize.c.inc
28
+ .nv2_redirect_offset = 0x170 | NV2_REDIR_NV1,
28
+++ b/fpu/softfloat-specialize.c.inc
29
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
.resetvalue = 0,
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
.readfn = gt_virt_redir_ctl_read, .raw_readfn = raw_read,
31
/* Sign bit clear, all frac bits set */
32
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
32
dnan_pattern = 0b01111111;
33
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 2,
33
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
34
.access = PL0_RW,
34
- || defined(TARGET_MICROBLAZE)
35
.type = ARM_CP_IO,
35
+#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
+ .nv2_redirect_offset = 0x178 | NV2_REDIR_NV1,
36
/* Sign bit set, most significant frac bit set */
37
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
37
dnan_pattern = 0b11000000;
38
.resetvalue = 0, .accessfn = gt_ptimer_access,
38
#elif defined(TARGET_HPPA)
39
.readfn = gt_phys_redir_cval_read, .raw_readfn = raw_read,
40
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
41
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 2,
42
.access = PL0_RW,
43
.type = ARM_CP_IO,
44
+ .nv2_redirect_offset = 0x168 | NV2_REDIR_NV1,
45
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
46
.resetvalue = 0, .accessfn = gt_vtimer_access,
47
.readfn = gt_virt_redir_cval_read, .raw_readfn = raw_read,
48
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
49
static const ARMCPRegInfo zcr_reginfo[] = {
50
{ .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
51
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
52
+ .nv2_redirect_offset = 0x1e0 | NV2_REDIR_NV1,
53
.access = PL1_RW, .type = ARM_CP_SVE,
54
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
55
.writefn = zcr_write, .raw_writefn = raw_write },
56
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
57
.writefn = svcr_write, .raw_writefn = raw_write },
58
{ .name = "SMCR_EL1", .state = ARM_CP_STATE_AA64,
59
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 6,
60
+ .nv2_redirect_offset = 0x1f0 | NV2_REDIR_NV1,
61
.access = PL1_RW, .type = ARM_CP_SME,
62
.fieldoffset = offsetof(CPUARMState, vfp.smcr_el[1]),
63
.writefn = smcr_write, .raw_writefn = raw_write },
64
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
65
.type = ARM_CP_CONST, .resetvalue = 0 },
66
{ .name = "SMPRIMAP_EL2", .state = ARM_CP_STATE_AA64,
67
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 5,
68
+ .nv2_redirect_offset = 0x1f8,
69
.access = PL2_RW, .accessfn = access_smprimap,
70
.type = ARM_CP_CONST, .resetvalue = 0 },
71
};
72
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
73
{ .name = "TFSR_EL1", .state = ARM_CP_STATE_AA64,
74
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 0,
75
.access = PL1_RW, .accessfn = access_tfsr_el1,
76
+ .nv2_redirect_offset = 0x190 | NV2_REDIR_NV1,
77
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
78
{ .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
79
.type = ARM_CP_NV2_REDIRECT,
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo scxtnum_reginfo[] = {
81
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 7,
82
.access = PL1_RW, .accessfn = access_scxtnum_el1,
83
.fgt = FGT_SCXTNUM_EL1,
84
+ .nv2_redirect_offset = 0x188 | NV2_REDIR_NV1,
85
.fieldoffset = offsetof(CPUARMState, scxtnum_el[1]) },
86
{ .name = "SCXTNUM_EL2", .state = ARM_CP_STATE_AA64,
87
.opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 7,
88
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_fgt(CPUARMState *env, const ARMCPRegInfo *ri,
89
static const ARMCPRegInfo fgt_reginfo[] = {
90
{ .name = "HFGRTR_EL2", .state = ARM_CP_STATE_AA64,
91
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
92
+ .nv2_redirect_offset = 0x1b8,
93
.access = PL2_RW, .accessfn = access_fgt,
94
.fieldoffset = offsetof(CPUARMState, cp15.fgt_read[FGTREG_HFGRTR]) },
95
{ .name = "HFGWTR_EL2", .state = ARM_CP_STATE_AA64,
96
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 5,
97
+ .nv2_redirect_offset = 0x1c0,
98
.access = PL2_RW, .accessfn = access_fgt,
99
.fieldoffset = offsetof(CPUARMState, cp15.fgt_write[FGTREG_HFGWTR]) },
100
{ .name = "HDFGRTR_EL2", .state = ARM_CP_STATE_AA64,
101
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 1, .opc2 = 4,
102
+ .nv2_redirect_offset = 0x1d0,
103
.access = PL2_RW, .accessfn = access_fgt,
104
.fieldoffset = offsetof(CPUARMState, cp15.fgt_read[FGTREG_HDFGRTR]) },
105
{ .name = "HDFGWTR_EL2", .state = ARM_CP_STATE_AA64,
106
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 1, .opc2 = 5,
107
+ .nv2_redirect_offset = 0x1d8,
108
.access = PL2_RW, .accessfn = access_fgt,
109
.fieldoffset = offsetof(CPUARMState, cp15.fgt_write[FGTREG_HDFGWTR]) },
110
{ .name = "HFGITR_EL2", .state = ARM_CP_STATE_AA64,
111
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 6,
112
+ .nv2_redirect_offset = 0x1c8,
113
.access = PL2_RW, .accessfn = access_fgt,
114
.fieldoffset = offsetof(CPUARMState, cp15.fgt_exec[FGTREG_HFGITR]) },
115
};
116
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
117
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 1,
118
.type = ARM_CP_IO | ARM_CP_ALIAS,
119
.access = PL2_RW, .accessfn = e2h_access,
120
+ .nv2_redirect_offset = 0x180 | NV2_REDIR_NO_NV1,
121
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
122
.writefn = gt_phys_ctl_write, .raw_writefn = raw_write },
123
{ .name = "CNTV_CTL_EL02", .state = ARM_CP_STATE_AA64,
124
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 1,
125
.type = ARM_CP_IO | ARM_CP_ALIAS,
126
.access = PL2_RW, .accessfn = e2h_access,
127
+ .nv2_redirect_offset = 0x170 | NV2_REDIR_NO_NV1,
128
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
129
.writefn = gt_virt_ctl_write, .raw_writefn = raw_write },
130
{ .name = "CNTP_TVAL_EL02", .state = ARM_CP_STATE_AA64,
131
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
132
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 2,
133
.type = ARM_CP_IO | ARM_CP_ALIAS,
134
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
135
+ .nv2_redirect_offset = 0x178 | NV2_REDIR_NO_NV1,
136
.access = PL2_RW, .accessfn = e2h_access,
137
.writefn = gt_phys_cval_write, .raw_writefn = raw_write },
138
{ .name = "CNTV_CVAL_EL02", .state = ARM_CP_STATE_AA64,
139
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 2,
140
.type = ARM_CP_IO | ARM_CP_ALIAS,
141
+ .nv2_redirect_offset = 0x168 | NV2_REDIR_NO_NV1,
142
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
143
.access = PL2_RW, .accessfn = e2h_access,
144
.writefn = gt_virt_cval_write, .raw_writefn = raw_write },
145
--
39
--
146
2.34.1
40
2.34.1
diff view generated by jsdifflib
1
Mark up the cpreginfo structs to indicate offsets for system
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
registers from VNCR_EL2, as defined in table D8-66 in rule R_CSRPQ in
2
parts64_default_nan().
3
the Arm ARM. This commit covers offsets 0x100 to 0x160.
4
5
Many (but not all) of the registers in this range have _EL12 aliases,
6
and the slot in memory is shared between the _EL12 version of the
7
register and the _EL1 version. Where we programmatically generate
8
the regdef for the _EL12 register, arrange that its
9
nv2_redirect_offset is set up correctly to do this.
10
3
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Miguel Luis <miguel.luis@oracle.com>
6
Message-id: 20241202131347.498124-38-peter.maydell@linaro.org
14
---
7
---
15
target/arm/debug_helper.c | 1 +
8
target/i386/tcg/fpu_helper.c | 4 ++++
16
target/arm/helper.c | 22 ++++++++++++++++++++++
9
fpu/softfloat-specialize.c.inc | 3 ---
17
2 files changed, 23 insertions(+)
10
2 files changed, 4 insertions(+), 3 deletions(-)
18
11
19
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
12
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/debug_helper.c
14
--- a/target/i386/tcg/fpu_helper.c
22
+++ b/target/arm/debug_helper.c
15
+++ b/target/i386/tcg/fpu_helper.c
23
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
16
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
24
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
17
*/
25
.access = PL1_RW, .accessfn = access_tda,
18
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
26
.fgt = FGT_MDSCR_EL1,
19
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
27
+ .nv2_redirect_offset = 0x158,
20
+ /* Default NaN: sign bit set, most significant frac bit set */
28
.fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
29
.resetvalue = 0 },
22
+ set_float_default_nan_pattern(0b11000000, &env->mmx_status);
30
/*
23
+ set_float_default_nan_pattern(0b11000000, &env->sse_status);
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
}
25
26
static inline uint8_t save_exception_flags(CPUX86State *env)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
29
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/target/arm/helper.c
30
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
31
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
36
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
32
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
37
.access = PL1_RW, .accessfn = access_tvm_trvm,
33
/* Sign bit clear, all frac bits set */
38
.fgt = FGT_CONTEXTIDR_EL1,
34
dnan_pattern = 0b01111111;
39
+ .nv2_redirect_offset = 0x108 | NV2_REDIR_NV1,
35
-#elif defined(TARGET_I386) || defined(TARGET_X86_64)
40
.secure = ARM_CP_SECSTATE_NS,
36
- /* Sign bit set, most significant frac bit set */
41
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]),
37
- dnan_pattern = 0b11000000;
42
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
38
#elif defined(TARGET_HPPA)
43
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
39
/* Sign bit clear, msb-1 frac bit set */
44
{ .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
40
dnan_pattern = 0b00100000;
45
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
46
.fgt = FGT_CPACR_EL1,
47
+ .nv2_redirect_offset = 0x100 | NV2_REDIR_NV1,
48
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
49
.resetfn = cpacr_reset, .writefn = cpacr_write, .readfn = cpacr_read },
50
};
51
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
52
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0,
53
.access = PL1_RW, .accessfn = access_tvm_trvm,
54
.fgt = FGT_AFSR0_EL1,
55
+ .nv2_redirect_offset = 0x128 | NV2_REDIR_NV1,
56
.type = ARM_CP_CONST, .resetvalue = 0 },
57
{ .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH,
58
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
59
.access = PL1_RW, .accessfn = access_tvm_trvm,
60
.fgt = FGT_AFSR1_EL1,
61
+ .nv2_redirect_offset = 0x130 | NV2_REDIR_NV1,
62
.type = ARM_CP_CONST, .resetvalue = 0 },
63
/*
64
* MAIR can just read-as-written because we don't implement caches
65
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
66
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
67
.access = PL1_RW, .accessfn = access_tvm_trvm,
68
.fgt = FGT_MAIR_EL1,
69
+ .nv2_redirect_offset = 0x140 | NV2_REDIR_NV1,
70
.fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
71
.resetvalue = 0 },
72
{ .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64,
73
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
74
.opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
75
.access = PL1_RW, .accessfn = access_tvm_trvm,
76
.fgt = FGT_ESR_EL1,
77
+ .nv2_redirect_offset = 0x138 | NV2_REDIR_NV1,
78
.fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
79
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
80
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
81
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
82
.opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
83
.access = PL1_RW, .accessfn = access_tvm_trvm,
84
.fgt = FGT_TCR_EL1,
85
+ .nv2_redirect_offset = 0x120 | NV2_REDIR_NV1,
86
.writefn = vmsa_tcr_el12_write,
87
.raw_writefn = raw_write,
88
.resetvalue = 0,
89
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
90
.opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
91
.access = PL1_RW, .accessfn = access_tvm_trvm,
92
.fgt = FGT_AMAIR_EL1,
93
+ .nv2_redirect_offset = 0x148 | NV2_REDIR_NV1,
94
.type = ARM_CP_CONST, .resetvalue = 0 },
95
/* AMAIR1 is mapped to AMAIR_EL1[63:32] */
96
{ .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
97
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
98
.type = ARM_CP_ALIAS,
99
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
100
.access = PL1_RW, .accessfn = access_nv1,
101
+ .nv2_redirect_offset = 0x160 | NV2_REDIR_NV1,
102
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
103
/*
104
* We rely on the access checks not allowing the guest to write to the
105
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
106
new_reg->writefn = el2_e2h_e12_write;
107
new_reg->accessfn = el2_e2h_e12_access;
108
109
+ /*
110
+ * If the _EL1 register is redirected to memory by FEAT_NV2,
111
+ * then it shares the offset with the _EL12 register,
112
+ * and which one is redirected depends on HCR_EL2.NV1.
113
+ */
114
+ if (new_reg->nv2_redirect_offset) {
115
+ assert(new_reg->nv2_redirect_offset & NV2_REDIR_NV1);
116
+ new_reg->nv2_redirect_offset &= ~NV2_REDIR_NV1;
117
+ new_reg->nv2_redirect_offset |= NV2_REDIR_NO_NV1;
118
+ }
119
+
120
ok = g_hash_table_insert(cpu->cp_regs,
121
(gpointer)(uintptr_t)a->new_key, new_reg);
122
g_assert(ok);
123
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
124
{ .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH,
125
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1,
126
.access = PL1_RW, .accessfn = access_tacr,
127
+ .nv2_redirect_offset = 0x118,
128
.type = ARM_CP_CONST, .resetvalue = cpu->reset_auxcr },
129
{ .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH,
130
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1,
131
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
132
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
133
.access = PL1_RW, .accessfn = access_tvm_trvm,
134
.fgt = FGT_SCTLR_EL1,
135
+ .nv2_redirect_offset = 0x110 | NV2_REDIR_NV1,
136
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
137
offsetof(CPUARMState, cp15.sctlr_ns) },
138
.writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
139
--
41
--
140
2.34.1
42
2.34.1
diff view generated by jsdifflib
1
Under FEAT_NV2, when HCR_EL2.{NV,NV2} == 0b11 at EL1, accesses to the
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
registers SPSR_EL2, ELR_EL2, ESR_EL2, FAR_EL2 and TFSR_EL2 (which
2
parts64_default_nan().
3
would UNDEF without FEAT_NV or FEAT_NV2) should instead access the
4
equivalent EL1 registers SPSR_EL1, ELR_EL1, ESR_EL1, FAR_EL1 and
5
TFSR_EL1.
6
7
Because there are only five registers involved and the encoding for
8
the EL1 register is identical to that of the EL2 register except
9
that opc1 is 0, we handle this by finding the EL1 register in the
10
hash table and using it instead.
11
12
Note that traps that apply to direct accesses to the EL1 register,
13
such as active fine-grained traps or other trap bits, do not trigger
14
when it is accessed via the EL2 encoding in this way. However, some
15
traps that are defined by the EL2 register may apply. We therefore
16
call the EL2 register's accessfn first. The only one of the five
17
which has such traps is TFSR_EL2: make sure its accessfn correctly
18
handles both FEAT_NV (where we trap to EL2 without checking ATA bits)
19
and FEAT_NV2 (where we check ATA bits and then redirect to TFSR_EL1).
20
21
(We don't need the NV1 tbflag bit until the next patch, but we
22
introduce it here to avoid putting the NV, NV1, NV2 bits in an
23
odd order.)
24
3
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Tested-by: Miguel Luis <miguel.luis@oracle.com>
6
Message-id: 20241202131347.498124-39-peter.maydell@linaro.org
28
---
7
---
29
target/arm/cpregs.h | 5 +++++
8
target/hppa/fpu_helper.c | 2 ++
30
target/arm/cpu.h | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 ---
31
target/arm/tcg/translate.h | 4 ++++
10
2 files changed, 2 insertions(+), 3 deletions(-)
32
target/arm/helper.c | 13 +++++++++----
33
target/arm/tcg/hflags.c | 6 ++++++
34
target/arm/tcg/translate-a64.c | 33 ++++++++++++++++++++++++++++++++-
35
6 files changed, 58 insertions(+), 5 deletions(-)
36
11
37
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
12
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
38
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/cpregs.h
14
--- a/target/hppa/fpu_helper.c
40
+++ b/target/arm/cpregs.h
15
+++ b/target/hppa/fpu_helper.c
41
@@ -XXX,XX +XXX,XX @@ enum {
16
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
42
* ARM pseudocode function CheckSMEAccess().
17
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
43
*/
18
/* For inf * 0 + NaN, return the input NaN */
44
ARM_CP_SME = 1 << 19,
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
45
+ /*
20
+ /* Default NaN: sign bit clear, msb-1 frac bit set */
46
+ * Flag: one of the four EL2 registers which redirect to the
21
+ set_float_default_nan_pattern(0b00100000, &env->fp_status);
47
+ * equivalent EL1 register when FEAT_NV2 is enabled.
22
}
48
+ */
23
49
+ ARM_CP_NV2_REDIRECT = 1 << 20,
24
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
50
};
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
51
52
/*
53
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
54
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/cpu.h
27
--- a/fpu/softfloat-specialize.c.inc
56
+++ b/target/arm/cpu.h
28
+++ b/fpu/softfloat-specialize.c.inc
57
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, TRAP_ERET, 29, 1)
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
58
FIELD(TBFLAG_A64, NAA, 30, 1)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
59
FIELD(TBFLAG_A64, ATA0, 31, 1)
31
/* Sign bit clear, all frac bits set */
60
FIELD(TBFLAG_A64, NV, 32, 1)
32
dnan_pattern = 0b01111111;
61
+FIELD(TBFLAG_A64, NV1, 33, 1)
33
-#elif defined(TARGET_HPPA)
62
+FIELD(TBFLAG_A64, NV2, 34, 1)
34
- /* Sign bit clear, msb-1 frac bit set */
63
35
- dnan_pattern = 0b00100000;
64
/*
36
#elif defined(TARGET_HEXAGON)
65
* Helpers for using the above. Note that only the A64 accessors use
37
/* Sign bit set, all frac bits set. */
66
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
38
dnan_pattern = 0b11111111;
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/tcg/translate.h
69
+++ b/target/arm/tcg/translate.h
70
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
71
bool naa;
72
/* True if FEAT_NV HCR_EL2.NV is enabled */
73
bool nv;
74
+ /* True if NV enabled and HCR_EL2.NV1 is set */
75
+ bool nv1;
76
+ /* True if NV enabled and HCR_EL2.NV2 is set */
77
+ bool nv2;
78
/*
79
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
80
* < 0, set by the current instruction.
81
diff --git a/target/arm/helper.c b/target/arm/helper.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/helper.c
84
+++ b/target/arm/helper.c
85
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
86
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
87
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
88
{ .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
89
- .type = ARM_CP_ALIAS,
90
+ .type = ARM_CP_ALIAS | ARM_CP_NV2_REDIRECT,
91
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
92
.access = PL2_RW,
93
.fieldoffset = offsetof(CPUARMState, elr_el[2]) },
94
{ .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
95
+ .type = ARM_CP_NV2_REDIRECT,
96
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
97
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
98
{ .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
99
+ .type = ARM_CP_NV2_REDIRECT,
100
.opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
101
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) },
102
{ .name = "HIFAR", .state = ARM_CP_STATE_AA32,
103
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
104
.access = PL2_RW,
105
.fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[2]) },
106
{ .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
107
- .type = ARM_CP_ALIAS,
108
+ .type = ARM_CP_ALIAS | ARM_CP_NV2_REDIRECT,
109
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
110
.access = PL2_RW,
111
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
112
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tfsr_el2(CPUARMState *env, const ARMCPRegInfo *ri,
113
/*
114
* TFSR_EL2: similar to generic access_mte(), but we need to
115
* account for FEAT_NV. At EL1 this must be a FEAT_NV access;
116
- * we will trap to EL2 and the HCR/SCR traps do not apply.
117
+ * if NV2 is enabled then we will redirect this to TFSR_EL1
118
+ * after doing the HCR and SCR ATA traps; otherwise this will
119
+ * be a trap to EL2 and the HCR/SCR traps do not apply.
120
*/
121
int el = arm_current_el(env);
122
123
- if (el == 1) {
124
+ if (el == 1 && (arm_hcr_el2_eff(env) & HCR_NV2)) {
125
return CP_ACCESS_OK;
126
}
127
if (el < 2 && arm_is_el2_enabled(env)) {
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
129
.access = PL1_RW, .accessfn = access_tfsr_el1,
130
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
131
{ .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
132
+ .type = ARM_CP_NV2_REDIRECT,
133
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 6, .opc2 = 0,
134
.access = PL2_RW, .accessfn = access_tfsr_el2,
135
.fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[2]) },
136
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/tcg/hflags.c
139
+++ b/target/arm/tcg/hflags.c
140
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
141
if (el == 1 && (hcr & HCR_NV)) {
142
DP_TBFLAG_A64(flags, TRAP_ERET, 1);
143
DP_TBFLAG_A64(flags, NV, 1);
144
+ if (hcr & HCR_NV1) {
145
+ DP_TBFLAG_A64(flags, NV1, 1);
146
+ }
147
+ if (hcr & HCR_NV2) {
148
+ DP_TBFLAG_A64(flags, NV2, 1);
149
+ }
150
}
151
152
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
153
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/target/arm/tcg/translate-a64.c
156
+++ b/target/arm/tcg/translate-a64.c
157
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
158
const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
159
bool need_exit_tb = false;
160
bool nv_trap_to_el2 = false;
161
+ bool nv_redirect_reg = false;
162
bool skip_fp_access_checks = false;
163
TCGv_ptr tcg_ri = NULL;
164
TCGv_i64 tcg_rt;
165
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
166
* for registers accessible at EL1).
167
*/
168
skip_fp_access_checks = true;
169
- if (s->nv && arm_cpreg_traps_in_nv(ri)) {
170
+ if (s->nv2 && (ri->type & ARM_CP_NV2_REDIRECT)) {
171
+ /*
172
+ * This is one of the few EL2 registers which should redirect
173
+ * to the equivalent EL1 register. We do that after running
174
+ * the EL2 register's accessfn.
175
+ */
176
+ nv_redirect_reg = true;
177
+ } else if (s->nv && arm_cpreg_traps_in_nv(ri)) {
178
/*
179
* This register / instruction exists and is an EL2 register, so
180
* we must trap to EL2 if accessed in nested virtualization EL1
181
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
182
return;
183
}
184
185
+ if (nv_redirect_reg) {
186
+ /*
187
+ * FEAT_NV2 redirection of an EL2 register to an EL1 register.
188
+ * Conveniently in all cases the encoding of the EL1 register is
189
+ * identical to the EL2 register except that opc1 is 0.
190
+ * Get the reginfo for the EL1 register to use for the actual access.
191
+ * We don't use the EL1 register's access function, and
192
+ * fine-grained-traps on EL1 also do not apply here.
193
+ */
194
+ key = ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
195
+ crn, crm, op0, 0, op2);
196
+ ri = get_arm_cp_reginfo(s->cp_regs, key);
197
+ assert(ri);
198
+ assert(cp_access_ok(s->current_el, ri, isread));
199
+ /*
200
+ * We might not have done an update_pc earlier, so check we don't
201
+ * need it. We could support this in future if necessary.
202
+ */
203
+ assert(!(ri->type & ARM_CP_RAISES_EXC));
204
+ }
205
+
206
/* Handle special cases first */
207
switch (ri->type & ARM_CP_SPECIAL_MASK) {
208
case 0:
209
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
210
dc->sme_trap_nonstreaming = EX_TBFLAG_A64(tb_flags, SME_TRAP_NONSTREAMING);
211
dc->naa = EX_TBFLAG_A64(tb_flags, NAA);
212
dc->nv = EX_TBFLAG_A64(tb_flags, NV);
213
+ dc->nv1 = EX_TBFLAG_A64(tb_flags, NV1);
214
+ dc->nv2 = EX_TBFLAG_A64(tb_flags, NV2);
215
dc->vec_len = 0;
216
dc->vec_stride = 0;
217
dc->cp_regs = arm_cpu->cp_regs;
218
--
39
--
219
2.34.1
40
2.34.1
diff view generated by jsdifflib
1
With FEAT_NV2, the condition for when SPSR_EL1.M should report that
1
Set the default NaN pattern explicitly for the alpha target.
2
an exception was taken from EL2 changes.
3
2
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Miguel Luis <miguel.luis@oracle.com>
5
Message-id: 20241202131347.498124-40-peter.maydell@linaro.org
7
---
6
---
8
target/arm/helper.c | 16 ++++++++++++----
7
target/alpha/cpu.c | 2 ++
9
1 file changed, 12 insertions(+), 4 deletions(-)
8
1 file changed, 2 insertions(+)
10
9
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
10
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
12
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
12
--- a/target/alpha/cpu.c
14
+++ b/target/arm/helper.c
13
+++ b/target/alpha/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
14
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_initfn(Object *obj)
16
aarch64_save_sp(env, arm_current_el(env));
15
* operand in Fa. That is float_2nan_prop_ba.
17
env->elr_el[new_el] = env->pc;
16
*/
18
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
19
- if (cur_el == 1 && new_el == 1 &&
18
+ /* Default NaN: sign bit clear, msb frac bit set */
20
- ((arm_hcr_el2_eff(env) & (HCR_NV | HCR_NV1)) == HCR_NV)) {
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
21
- /* I_ZJRNN: report EL2 in the SPSR by setting M[3:2] to 0b10 */
20
#if defined(CONFIG_USER_ONLY)
22
- old_mode = deposit32(old_mode, 2, 2, 2);
21
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
23
+ if (cur_el == 1 && new_el == 1) {
22
cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD
24
+ uint64_t hcr = arm_hcr_el2_eff(env);
25
+ if ((hcr & (HCR_NV | HCR_NV1 | HCR_NV2)) == HCR_NV ||
26
+ (hcr & (HCR_NV | HCR_NV2)) == (HCR_NV | HCR_NV2)) {
27
+ /*
28
+ * FEAT_NV, FEAT_NV2 may need to report EL2 in the SPSR
29
+ * by setting M[3:2] to 0b10.
30
+ * If NV2 is disabled, change SPSR when NV,NV1 == 1,0 (I_ZJRNN)
31
+ * If NV2 is enabled, change SPSR when NV is 1 (I_DBTLM)
32
+ */
33
+ old_mode = deposit32(old_mode, 2, 2, 2);
34
+ }
35
}
36
} else {
37
old_mode = cpsr_read_for_spsr_elx(env);
38
--
23
--
39
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
Enable FEAT_NV on the 'max' CPU, and stop filtering it out for the
1
Set the default NaN pattern explicitly for the arm target.
2
Neoverse N2 and Neoverse V1 CPUs. We continue to downgrade FEAT_NV2
2
This includes setting it for the old linux-user nwfpe emulation.
3
support to FEAT_NV for the latter two CPU types.
3
For nwfpe, our default doesn't match the real kernel, but we
4
avoid making a behaviour change in this commit.
4
5
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
8
Message-id: 20241202131347.498124-41-peter.maydell@linaro.org
8
---
9
---
9
docs/system/arm/emulation.rst | 1 +
10
linux-user/arm/nwfpe/fpa11.c | 5 +++++
10
target/arm/cpu.c | 8 +++++---
11
target/arm/cpu.c | 2 ++
11
target/arm/tcg/cpu64.c | 1 +
12
2 files changed, 7 insertions(+)
12
3 files changed, 7 insertions(+), 3 deletions(-)
13
13
14
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/emulation.rst
16
--- a/linux-user/arm/nwfpe/fpa11.c
17
+++ b/docs/system/arm/emulation.rst
17
+++ b/linux-user/arm/nwfpe/fpa11.c
18
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
@@ -XXX,XX +XXX,XX @@ void resetFPA11(void)
19
- FEAT_MTE (Memory Tagging Extension)
19
* this late date.
20
- FEAT_MTE2 (Memory Tagging Extension)
20
*/
21
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
21
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
22
+- FEAT_NV (Nested Virtualization)
22
+ /*
23
- FEAT_PACIMP (Pointer authentication - IMPLEMENTATION DEFINED algorithm)
23
+ * Use the same default NaN value as Arm VFP. This doesn't match
24
- FEAT_PACQARMA3 (Pointer authentication - QARMA3 algorithm)
24
+ * the Linux kernel's nwfpe emulation, which uses an all-1s value.
25
- FEAT_PACQARMA5 (Pointer authentication - QARMA5 algorithm)
25
+ */
26
+ set_float_default_nan_pattern(0b01000000, &fpa11->fp_status);
27
}
28
29
void SetRoundingMode(const unsigned int opcode)
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
30
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
27
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu.c
32
--- a/target/arm/cpu.c
29
+++ b/target/arm/cpu.c
33
+++ b/target/arm/cpu.c
30
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
34
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
31
/* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */
35
* the pseudocode function the arguments are in the order c, a, b.
32
cpu->isar.id_aa64pfr0 =
36
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
33
FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, MPAM, 0);
37
* and the input NaN if it is signalling
34
- /* FEAT_NV (Nested Virtualization) */
38
+ * * Default NaN has sign bit clear, msb frac bit set
35
- cpu->isar.id_aa64mmfr2 =
39
*/
36
- FIELD_DP64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV, 0);
40
static void arm_set_default_fp_behaviours(float_status *s)
37
+ /* FEAT_NV2 (Enhanced Nested Virtualization support) */
41
{
38
+ if (FIELD_EX64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV) > 1) {
42
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
39
+ cpu->isar.id_aa64mmfr2 =
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
40
+ FIELD_DP64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV, 1);
44
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
41
+ }
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
42
}
46
+ set_float_default_nan_pattern(0b01000000, s);
43
47
}
44
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
48
45
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
49
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/tcg/cpu64.c
48
+++ b/target/arm/tcg/cpu64.c
49
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
50
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
51
t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */
52
t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
53
+ t = FIELD_DP64(t, ID_AA64MMFR2, NV, 1); /* FEAT_NV */
54
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
55
t = FIELD_DP64(t, ID_AA64MMFR2, AT, 1); /* FEAT_LSE2 */
56
t = FIELD_DP64(t, ID_AA64MMFR2, IDS, 1); /* FEAT_IDST */
57
--
50
--
58
2.34.1
51
2.34.1
diff view generated by jsdifflib
1
If FEAT_NV2 redirects a system register access to a memory offset
1
Set the default NaN pattern explicitly for loongarch.
2
from VNCR_EL2, that access might fault. In this case we need to
3
report the correct syndrome information:
4
* Data Abort, from same-EL
5
* no ISS information
6
* the VNCR bit (bit 13) is set
7
8
and the exception must be taken to EL2.
9
10
Save an appropriate syndrome template when generating code; we can
11
then use that to:
12
* select the right target EL
13
* reconstitute a correct final syndrome for the data abort
14
* report the right syndrome if we take a FEAT_RME granule protection
15
fault on the VNCR-based write
16
17
Note that because VNCR is bit 13, we must start keeping bit 13 in
18
template syndromes, by adjusting ARM_INSN_START_WORD2_SHIFT.
19
2
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Tested-by: Miguel Luis <miguel.luis@oracle.com>
5
Message-id: 20241202131347.498124-42-peter.maydell@linaro.org
23
---
6
---
24
target/arm/cpu.h | 4 ++--
7
target/loongarch/tcg/fpu_helper.c | 2 ++
25
target/arm/syndrome.h | 20 ++++++++++++++++----
8
1 file changed, 2 insertions(+)
26
target/arm/tcg/tlb_helper.c | 27 +++++++++++++++++++++++++--
27
target/arm/tcg/translate-a64.c | 4 ++++
28
4 files changed, 47 insertions(+), 8 deletions(-)
29
9
30
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
10
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
31
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu.h
12
--- a/target/loongarch/tcg/fpu_helper.c
33
+++ b/target/arm/cpu.h
13
+++ b/target/loongarch/tcg/fpu_helper.c
34
@@ -XXX,XX +XXX,XX @@ enum {
14
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
35
#define TARGET_INSN_START_EXTRA_WORDS 2
15
*/
36
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
37
/* The 2nd extra word holding syndrome info for data aborts does not use
17
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
38
- * the upper 6 bits nor the lower 14 bits. We mask and shift it down to
18
+ /* Default NaN: sign bit clear, msb frac bit set */
39
+ * the upper 6 bits nor the lower 13 bits. We mask and shift it down to
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
40
* help the sleb128 encoder do a better job.
41
* When restoring the CPU state, we shift it back up.
42
*/
43
#define ARM_INSN_START_WORD2_MASK ((1 << 26) - 1)
44
-#define ARM_INSN_START_WORD2_SHIFT 14
45
+#define ARM_INSN_START_WORD2_SHIFT 13
46
47
/* We currently assume float and double are IEEE single and double
48
precision respectively.
49
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/syndrome.h
52
+++ b/target/arm/syndrome.h
53
@@ -XXX,XX +XXX,XX @@ typedef enum {
54
#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
55
#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
56
57
+/* In the Data Abort syndrome */
58
+#define ARM_EL_VNCR (1 << 13)
59
+
60
static inline uint32_t syn_get_ec(uint32_t syn)
61
{
62
return syn >> ARM_EL_EC_SHIFT;
63
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
64
(cv << 24) | (cond << 20) | rm;
65
}
20
}
66
21
67
-static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc,
22
int ieee_ex_to_loongarch(int xcpt)
68
+static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc, int vncr,
69
int cm, int s1ptw, int wnr, int fsc)
70
{
71
- /* TODO: FEAT_NV2 adds VNCR */
72
return (EC_GPC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (s2ptw << 21)
73
- | (ind << 20) | (gpcsc << 14) | (cm << 8) | (s1ptw << 7)
74
- | (wnr << 6) | fsc;
75
+ | (ind << 20) | (gpcsc << 14) | (vncr << 13) | (cm << 8)
76
+ | (s1ptw << 7) | (wnr << 6) | fsc;
77
}
78
79
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
80
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_data_abort_with_iss(int same_el,
81
| (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
82
}
83
84
+/*
85
+ * Faults due to FEAT_NV2 VNCR_EL2-based accesses report as same-EL
86
+ * Data Aborts with the VNCR bit set.
87
+ */
88
+static inline uint32_t syn_data_abort_vncr(int ea, int wnr, int fsc)
89
+{
90
+ return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (1 << ARM_EL_EC_SHIFT)
91
+ | ARM_EL_IL | ARM_EL_VNCR | (wnr << 6) | fsc;
92
+}
93
+
94
static inline uint32_t syn_swstep(int same_el, int isv, int ex)
95
{
96
return (EC_SOFTWARESTEP << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
97
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/arm/tcg/tlb_helper.c
100
+++ b/target/arm/tcg/tlb_helper.c
101
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
102
* ST64BV, or ST64BV0 insns report syndrome info even for stage-1
103
* faults and regardless of the target EL.
104
*/
105
- if (!(template_syn & ARM_EL_ISV) || target_el != 2
106
+ if (template_syn & ARM_EL_VNCR) {
107
+ /*
108
+ * FEAT_NV2 faults on accesses via VNCR_EL2 are a special case:
109
+ * they are always reported as "same EL", even though we are going
110
+ * from EL1 to EL2.
111
+ */
112
+ assert(!fi->stage2);
113
+ syn = syn_data_abort_vncr(fi->ea, is_write, fsc);
114
+ } else if (!(template_syn & ARM_EL_ISV) || target_el != 2
115
|| fi->s1ptw || !fi->stage2) {
116
syn = syn_data_abort_no_iss(same_el, 0,
117
fi->ea, 0, fi->s1ptw, is_write, fsc);
118
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
119
int current_el = arm_current_el(env);
120
bool same_el;
121
uint32_t syn, exc, fsr, fsc;
122
+ /*
123
+ * We know this must be a data or insn abort, and that
124
+ * env->exception.syndrome contains the template syndrome set
125
+ * up at translate time. So we can check only the VNCR bit
126
+ * (and indeed syndrome does not have the EC field in it,
127
+ * because we masked that out in disas_set_insn_syndrome())
128
+ */
129
+ bool is_vncr = (mmu_idx != MMU_INST_FETCH) &&
130
+ (env->exception.syndrome & ARM_EL_VNCR);
131
+
132
+ if (is_vncr) {
133
+ /* FEAT_NV2 faults on accesses via VNCR_EL2 go to EL2 */
134
+ target_el = 2;
135
+ }
136
137
if (report_as_gpc_exception(cpu, current_el, fi)) {
138
target_el = 3;
139
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
140
141
syn = syn_gpc(fi->stage2 && fi->type == ARMFault_GPCFOnWalk,
142
access_type == MMU_INST_FETCH,
143
- encode_gpcsc(fi), 0, fi->s1ptw,
144
+ encode_gpcsc(fi), is_vncr,
145
+ 0, fi->s1ptw,
146
access_type == MMU_DATA_STORE, fsc);
147
148
env->cp15.mfar_el3 = fi->paddr;
149
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/tcg/translate-a64.c
152
+++ b/target/arm/tcg/translate-a64.c
153
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
154
MemOp mop = MO_64 | MO_ALIGN | MO_ATOM_IFALIGN;
155
ARMMMUIdx armmemidx = s->nv2_mem_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_E2;
156
int memidx = arm_to_core_mmu_idx(armmemidx);
157
+ uint32_t syn;
158
159
mop |= (s->nv2_mem_be ? MO_BE : MO_LE);
160
161
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
162
tcg_gen_addi_i64(ptr, ptr,
163
(ri->nv2_redirect_offset & ~NV2_REDIR_FLAG_MASK));
164
tcg_rt = cpu_reg(s, rt);
165
+
166
+ syn = syn_data_abort_vncr(0, !isread, 0);
167
+ disas_set_insn_syndrome(s, syn);
168
if (isread) {
169
tcg_gen_qemu_ld_i64(tcg_rt, ptr, memidx, mop);
170
} else {
171
--
23
--
172
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
For FEAT_NV2, a new system register VNCR_EL2 holds the base
1
Set the default NaN pattern explicitly for m68k.
2
address of the memory which nested-guest system register
3
accesses are redirected to. Implement this register.
4
2
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
5
Message-id: 20241202131347.498124-43-peter.maydell@linaro.org
8
---
6
---
9
target/arm/cpu.h | 3 +++
7
target/m68k/cpu.c | 2 ++
10
target/arm/helper.c | 26 ++++++++++++++++++++++++++
8
fpu/softfloat-specialize.c.inc | 2 +-
11
2 files changed, 29 insertions(+)
9
2 files changed, 3 insertions(+), 1 deletion(-)
12
10
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
11
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
13
--- a/target/m68k/cpu.c
16
+++ b/target/arm/cpu.h
14
+++ b/target/m68k/cpu.c
17
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
15
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
18
uint64_t gpccr_el3;
16
* preceding paragraph for nonsignaling NaNs.
19
uint64_t gptbr_el3;
17
*/
20
uint64_t mfar_el3;
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
21
+
19
+ /* Default NaN: sign bit clear, all frac bits set */
22
+ /* NV2 register */
20
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
23
+ uint64_t vncr_el2;
21
24
} cp15;
22
nan = floatx80_default_nan(&env->fp_status);
25
23
for (i = 0; i < 8; i++) {
26
struct {
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
27
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/helper.c
26
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/target/arm/helper.c
27
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo fgt_reginfo[] = {
28
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
32
.access = PL2_RW, .accessfn = access_fgt,
29
uint8_t dnan_pattern = status->default_nan_pattern;
33
.fieldoffset = offsetof(CPUARMState, cp15.fgt_exec[FGTREG_HFGITR]) },
30
34
};
31
if (dnan_pattern == 0) {
35
+
32
-#if defined(TARGET_SPARC) || defined(TARGET_M68K)
36
+static void vncr_write(CPUARMState *env, const ARMCPRegInfo *ri,
33
+#if defined(TARGET_SPARC)
37
+ uint64_t value)
34
/* Sign bit clear, all frac bits set */
38
+{
35
dnan_pattern = 0b01111111;
39
+ /*
36
#elif defined(TARGET_HEXAGON)
40
+ * Clear the RES0 bottom 12 bits; this means at runtime we can guarantee
41
+ * that VNCR_EL2 + offset is 64-bit aligned. We don't need to do anything
42
+ * about the RESS bits at the top -- we choose the "generate an EL2
43
+ * translation abort on use" CONSTRAINED UNPREDICTABLE option (i.e. let
44
+ * the ptw.c code detect the resulting invalid address).
45
+ */
46
+ env->cp15.vncr_el2 = value & ~0xfffULL;
47
+}
48
+
49
+static const ARMCPRegInfo nv2_reginfo[] = {
50
+ { .name = "VNCR_EL2", .state = ARM_CP_STATE_AA64,
51
+ .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 2, .opc2 = 0,
52
+ .access = PL2_RW,
53
+ .writefn = vncr_write,
54
+ .fieldoffset = offsetof(CPUARMState, cp15.vncr_el2) },
55
+};
56
+
57
#endif /* TARGET_AARCH64 */
58
59
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
60
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
61
define_arm_cp_regs(cpu, rme_mte_reginfo);
62
}
63
}
64
+
65
+ if (cpu_isar_feature(aa64_nv2, cpu)) {
66
+ define_arm_cp_regs(cpu, nv2_reginfo);
67
+ }
68
#endif
69
70
if (cpu_isar_feature(any_predinv, cpu)) {
71
--
37
--
72
2.34.1
38
2.34.1
diff view generated by jsdifflib
1
FEAT_NV requires that when HCR_EL2.{NV,NV1} == {1,1} the handling
1
Set the default NaN pattern explicitly for MIPS. Note that this
2
of some of the page table attribute bits changes for the EL1&0
2
is our only target which currently changes the default NaN
3
translation regime:
3
at runtime (which it was previously doing indirectly when it
4
4
changed the snan_bit_is_one setting).
5
* for block and page descriptors:
6
- bit [54] holds PXN, not UXN
7
- bit [53] is RES0, and the effective value of UXN is 0
8
- bit [6], AP[1], is treated as 0
9
* for table descriptors, when hierarchical permissions are enabled:
10
- bit [60] holds PXNTable, not UXNTable
11
- bit [59] is RES0
12
- bit [61], APTable[0] is treated as 0
13
14
Implement these changes to the page table attribute handling.
15
5
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Tested-by: Miguel Luis <miguel.luis@oracle.com>
8
Message-id: 20241202131347.498124-44-peter.maydell@linaro.org
19
---
9
---
20
target/arm/ptw.c | 21 +++++++++++++++++++++
10
target/mips/fpu_helper.h | 7 +++++++
21
1 file changed, 21 insertions(+)
11
target/mips/msa.c | 3 +++
12
2 files changed, 10 insertions(+)
22
13
23
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/ptw.c
16
--- a/target/mips/fpu_helper.h
26
+++ b/target/arm/ptw.c
17
+++ b/target/mips/fpu_helper.h
27
@@ -XXX,XX +XXX,XX @@ static bool lpae_block_desc_valid(ARMCPU *cpu, bool ds,
18
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
28
}
19
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
20
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
21
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
22
+ /*
23
+ * With nan2008, the default NaN value has the sign bit clear and the
24
+ * frac msb set; with the older mode, the sign bit is clear, and all
25
+ * frac bits except the msb are set.
26
+ */
27
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
28
+ &env->active_fpu.fp_status);
29
29
}
30
}
30
31
31
+static bool nv_nv1_enabled(CPUARMState *env, S1Translate *ptw)
32
diff --git a/target/mips/msa.c b/target/mips/msa.c
32
+{
33
index XXXXXXX..XXXXXXX 100644
33
+ uint64_t hcr = arm_hcr_el2_eff_secstate(env, ptw->in_space);
34
--- a/target/mips/msa.c
34
+ return (hcr & (HCR_NV | HCR_NV1)) == (HCR_NV | HCR_NV1);
35
+++ b/target/mips/msa.c
35
+}
36
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
36
+
37
/* Inf * 0 + NaN returns the input NaN */
37
/**
38
set_float_infzeronan_rule(float_infzeronan_dnan_never,
38
* get_phys_addr_lpae: perform one stage of page table walk, LPAE format
39
&env->active_tc.msa_fp_status);
39
*
40
+ /* Default NaN: sign bit clear, frac msb set */
40
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
41
+ set_float_default_nan_pattern(0b01000000,
41
xn = extract64(attrs, 54, 1);
42
+ &env->active_tc.msa_fp_status);
42
pxn = extract64(attrs, 53, 1);
43
}
43
44
+ if (el == 1 && nv_nv1_enabled(env, ptw)) {
45
+ /*
46
+ * With FEAT_NV, when HCR_EL2.{NV,NV1} == {1,1}, the block/page
47
+ * descriptor bit 54 holds PXN, 53 is RES0, and the effective value
48
+ * of UXN is 0. Similarly for bits 59 and 60 in table descriptors
49
+ * (which we have already folded into bits 53 and 54 of attrs).
50
+ * AP[1] (descriptor bit 6, our ap bit 0) is treated as 0.
51
+ * Similarly, APTable[0] from the table descriptor is treated as 0;
52
+ * we already folded this into AP[1] and squashing that to 0 does
53
+ * the right thing.
54
+ */
55
+ pxn = xn;
56
+ xn = 0;
57
+ ap &= ~1;
58
+ }
59
/*
60
* Note that we modified ptw->in_space earlier for NSTable, but
61
* result->f.attrs retains a copy of the original security space.
62
--
44
--
63
2.34.1
45
2.34.1
diff view generated by jsdifflib
1
For FEAT_NV, when HCR_EL2.{NV,NV1} is {1,1} PAN is always disabled
1
Set the default NaN pattern explicitly for openrisc.
2
even when the PSTATE.PAN bit is set. Implement this by having
3
arm_pan_enabled() return false in this situation.
4
2
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
5
Message-id: 20241202131347.498124-45-peter.maydell@linaro.org
8
---
6
---
9
target/arm/helper.c | 3 +++
7
target/openrisc/cpu.c | 2 ++
10
1 file changed, 3 insertions(+)
8
1 file changed, 2 insertions(+)
11
9
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
10
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
12
--- a/target/openrisc/cpu.c
15
+++ b/target/arm/helper.c
13
+++ b/target/openrisc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ void init_cpreg_list(ARMCPU *cpu)
14
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
17
static bool arm_pan_enabled(CPUARMState *env)
15
*/
18
{
16
set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
19
if (is_a64(env)) {
17
20
+ if ((arm_hcr_el2_eff(env) & (HCR_NV | HCR_NV1)) == (HCR_NV | HCR_NV1)) {
18
+ /* Default NaN: sign bit clear, frac msb set */
21
+ return false;
19
+ set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
22
+ }
20
23
return env->pstate & PSTATE_PAN;
21
#ifndef CONFIG_USER_ONLY
24
} else {
22
cpu->env.picmr = 0x00000000;
25
return env->uncached_cpsr & CPSR_PAN;
26
--
23
--
27
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
We already print various lines of information when we take an
1
Set the default NaN pattern explicitly for ppc.
2
exception, including the ELR and (if relevant) the FAR. Now
3
that FEAT_NV means that we might report something other than
4
the old PSTATE to the guest as the SPSR, it's worth logging
5
this as well.
6
2
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Miguel Luis <miguel.luis@oracle.com>
5
Message-id: 20241202131347.498124-46-peter.maydell@linaro.org
10
---
6
---
11
target/arm/helper.c | 1 +
7
target/ppc/cpu_init.c | 4 ++++
12
1 file changed, 1 insertion(+)
8
1 file changed, 4 insertions(+)
13
9
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
10
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
12
--- a/target/ppc/cpu_init.c
17
+++ b/target/arm/helper.c
13
+++ b/target/ppc/cpu_init.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
14
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
19
}
15
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
env->banked_spsr[aarch64_banked_spsr_index(new_el)] = old_mode;
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
21
17
22
+ qemu_log_mask(CPU_LOG_INT, "...with SPSR 0x%x\n", old_mode);
18
+ /* Default NaN: sign bit clear, set frac msb */
23
qemu_log_mask(CPU_LOG_INT, "...with ELR 0x%" PRIx64 "\n",
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
24
env->elr_el[new_el]);
20
+ set_float_default_nan_pattern(0b01000000, &env->vec_status);
21
+
22
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
23
ppc_spr_t *spr = &env->spr_cb[i];
25
24
26
--
25
--
27
2.34.1
26
2.34.1
diff view generated by jsdifflib
1
FEAT_NV requires that when HCR_EL2.{NV,NV1} == {1,0} and an exception
1
Set the default NaN pattern explicitly for sh4. Note that sh4
2
is taken from EL1 to EL1 then the reported EL in SPSR_EL1.M should be
2
is one of the only three targets (the others being HPPA and
3
EL2, not EL1. Implement this behaviour.
3
sometimes MIPS) that has snan_bit_is_one set.
4
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
7
Message-id: 20241202131347.498124-47-peter.maydell@linaro.org
8
---
8
---
9
target/arm/helper.c | 6 ++++++
9
target/sh4/cpu.c | 2 ++
10
1 file changed, 6 insertions(+)
10
1 file changed, 2 insertions(+)
11
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
14
--- a/target/sh4/cpu.c
15
+++ b/target/arm/helper.c
15
+++ b/target/sh4/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
16
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_reset_hold(Object *obj, ResetType type)
17
old_mode = pstate_read(env);
17
set_flush_to_zero(1, &env->fp_status);
18
aarch64_save_sp(env, arm_current_el(env));
18
#endif
19
env->elr_el[new_el] = env->pc;
19
set_default_nan_mode(1, &env->fp_status);
20
+
20
+ /* sign bit clear, set all frac bits other than msb */
21
+ if (cur_el == 1 && new_el == 1 &&
21
+ set_float_default_nan_pattern(0b00111111, &env->fp_status);
22
+ ((arm_hcr_el2_eff(env) & (HCR_NV | HCR_NV1)) == HCR_NV)) {
22
}
23
+ /* I_ZJRNN: report EL2 in the SPSR by setting M[3:2] to 0b10 */
23
24
+ old_mode = deposit32(old_mode, 2, 2, 2);
24
static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
25
+ }
26
} else {
27
old_mode = cpsr_read_for_spsr_elx(env);
28
env->elr_el[new_el] = env->regs[15];
29
--
25
--
30
2.34.1
26
2.34.1
diff view generated by jsdifflib
1
FEAT_NV requires that when HCR_EL2.NV is set reads of the CurrentEL
1
Set the default NaN pattern explicitly for rx.
2
register from EL1 always report EL2 rather than the real EL.
3
Implement this.
4
2
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
5
Message-id: 20241202131347.498124-48-peter.maydell@linaro.org
8
---
6
---
9
target/arm/tcg/translate-a64.c | 9 +++++++--
7
target/rx/cpu.c | 2 ++
10
1 file changed, 7 insertions(+), 2 deletions(-)
8
1 file changed, 2 insertions(+)
11
9
12
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
10
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/translate-a64.c
12
--- a/target/rx/cpu.c
15
+++ b/target/arm/tcg/translate-a64.c
13
+++ b/target/rx/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
14
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_reset_hold(Object *obj, ResetType type)
17
}
15
* then prefer dest over source", which is float_2nan_prop_s_ab.
18
return;
16
*/
19
case ARM_CP_CURRENTEL:
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
20
- /* Reads as current EL value from pstate, which is
18
+ /* Default NaN value: sign bit clear, set frac msb */
21
+ {
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
22
+ /*
20
}
23
+ * Reads as current EL value from pstate, which is
21
24
* guaranteed to be constant by the tb flags.
22
static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
25
+ * For nested virt we should report EL2.
26
*/
27
+ int el = s->nv ? 2 : s->current_el;
28
tcg_rt = cpu_reg(s, rt);
29
- tcg_gen_movi_i64(tcg_rt, s->current_el << 2);
30
+ tcg_gen_movi_i64(tcg_rt, el << 2);
31
return;
32
+ }
33
case ARM_CP_DC_ZVA:
34
/* Writes clear the aligned block of memory which rt points into. */
35
if (s->mte_active[0]) {
36
--
23
--
37
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
The TBFLAG_A64 TB flag bits go in flags2, which for AArch64 guests
1
Set the default NaN pattern explicitly for s390x.
2
we know is 64 bits. However at the moment we use FIELD_EX32() and
3
FIELD_DP32() to read and write these bits, which only works for
4
bits 0 to 31. Since we're about to add a flag that uses bit 32,
5
switch to FIELD_EX64() and FIELD_DP64() so that this will work.
6
2
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Miguel Luis <miguel.luis@oracle.com>
5
Message-id: 20241202131347.498124-49-peter.maydell@linaro.org
10
---
6
---
11
target/arm/cpu.h | 8 +++++---
7
target/s390x/cpu.c | 2 ++
12
1 file changed, 5 insertions(+), 3 deletions(-)
8
1 file changed, 2 insertions(+)
13
9
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
10
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
12
--- a/target/s390x/cpu.c
17
+++ b/target/arm/cpu.h
13
+++ b/target/s390x/cpu.c
18
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, NAA, 30, 1)
14
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
19
FIELD(TBFLAG_A64, ATA0, 31, 1)
15
set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
20
16
set_float_infzeronan_rule(float_infzeronan_dnan_always,
21
/*
17
&env->fpu_status);
22
- * Helpers for using the above.
18
+ /* Default NaN value: sign bit clear, frac msb set */
23
+ * Helpers for using the above. Note that only the A64 accessors use
19
+ set_float_default_nan_pattern(0b01000000, &env->fpu_status);
24
+ * FIELD_DP64() and FIELD_EX64(), because in the other cases the flags
20
/* fall through */
25
+ * word either is or might be 32 bits only.
21
case RESET_TYPE_S390_CPU_NORMAL:
26
*/
22
env->psw.mask &= ~PSW_MASK_RI;
27
#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
28
(DST.flags = FIELD_DP32(DST.flags, TBFLAG_ANY, WHICH, VAL))
29
#define DP_TBFLAG_A64(DST, WHICH, VAL) \
30
- (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A64, WHICH, VAL))
31
+ (DST.flags2 = FIELD_DP64(DST.flags2, TBFLAG_A64, WHICH, VAL))
32
#define DP_TBFLAG_A32(DST, WHICH, VAL) \
33
(DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A32, WHICH, VAL))
34
#define DP_TBFLAG_M32(DST, WHICH, VAL) \
35
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, ATA0, 31, 1)
36
(DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_AM32, WHICH, VAL))
37
38
#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_ANY, WHICH)
39
-#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A64, WHICH)
40
+#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX64(IN.flags2, TBFLAG_A64, WHICH)
41
#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A32, WHICH)
42
#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_M32, WHICH)
43
#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_AM32, WHICH)
44
--
23
--
45
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
The HCR_EL2.TSC trap for trapping EL1 execution of SMC instructions
1
Set the default NaN pattern explicitly for SPARC, and remove
2
has a behaviour change for FEAT_NV when EL3 is not implemented:
2
the ifdef from parts64_default_nan.
3
4
* in older architecture versions TSC was required to have no
5
effect (i.e. the SMC insn UNDEFs)
6
* with FEAT_NV, when HCR_EL2.NV == 1 the trap must apply
7
(i.e. SMC traps to EL2, as it already does in all cases when
8
EL3 is implemented)
9
* in newer architecture versions, the behaviour either without
10
FEAT_NV or with FEAT_NV and HCR_EL2.NV == 0 is relaxed to
11
an IMPDEF choice between UNDEF and trap-to-EL2 (i.e. it is
12
permitted to always honour HCR_EL2.TSC) for AArch64 only
13
14
Add the condition to honour the trap bit when HCR_EL2.NV == 1. We
15
leave the HCR_EL2.NV == 0 case with the existing (UNDEF) behaviour,
16
as our IMPDEF choice (both because it avoids a behaviour change
17
for older CPU models and because we'd have to distinguish AArch32
18
from AArch64 if we opted to trap to EL2).
19
3
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Tested-by: Miguel Luis <miguel.luis@oracle.com>
6
Message-id: 20241202131347.498124-50-peter.maydell@linaro.org
23
---
7
---
24
target/arm/tcg/op_helper.c | 16 +++++++++++++---
8
target/sparc/cpu.c | 2 ++
25
1 file changed, 13 insertions(+), 3 deletions(-)
9
fpu/softfloat-specialize.c.inc | 5 +----
10
2 files changed, 3 insertions(+), 4 deletions(-)
26
11
27
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
28
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/tcg/op_helper.c
14
--- a/target/sparc/cpu.c
30
+++ b/target/arm/tcg/op_helper.c
15
+++ b/target/sparc/cpu.c
31
@@ -XXX,XX +XXX,XX @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
32
*
17
set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
33
* Conduit SMC, valid call Trap to EL2 PSCI Call
18
/* For inf * 0 + NaN, return the input NaN */
34
* Conduit SMC, inval call Trap to EL2 Undef insn
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
35
- * Conduit not SMC Undef insn Undef insn
20
+ /* Default NaN value: sign bit clear, all frac bits set */
36
+ * Conduit not SMC Undef or trap[1] Undef insn
21
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
37
+ *
22
38
+ * [1] In this case:
23
cpu_exec_realizefn(cs, &local_err);
39
+ * - if HCR_EL2.NV == 1 we must trap to EL2
24
if (local_err != NULL) {
40
+ * - if HCR_EL2.NV == 0 then newer architecture revisions permit
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
41
+ * AArch64 (but not AArch32) to trap to EL2 as an IMPDEF choice
26
index XXXXXXX..XXXXXXX 100644
42
+ * - otherwise we must UNDEF
27
--- a/fpu/softfloat-specialize.c.inc
43
+ * We take the IMPDEF choice to always UNDEF if HCR_EL2.NV == 0.
28
+++ b/fpu/softfloat-specialize.c.inc
44
*/
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
45
30
uint8_t dnan_pattern = status->default_nan_pattern;
46
/* On ARMv8 with EL3 AArch64, SMD applies to both S and NS state.
31
47
@@ -XXX,XX +XXX,XX @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
32
if (dnan_pattern == 0) {
48
: smd_flag && !secure;
33
-#if defined(TARGET_SPARC)
49
34
- /* Sign bit clear, all frac bits set */
50
if (!arm_feature(env, ARM_FEATURE_EL3) &&
35
- dnan_pattern = 0b01111111;
51
+ !(arm_hcr_el2_eff(env) & HCR_NV) &&
36
-#elif defined(TARGET_HEXAGON)
52
cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
37
+#if defined(TARGET_HEXAGON)
53
- /* If we have no EL3 then SMC always UNDEFs and can't be
38
/* Sign bit set, all frac bits set. */
54
- * trapped to EL2. PSCI-via-SMC is a sort of ersatz EL3
39
dnan_pattern = 0b11111111;
55
+ /*
40
#else
56
+ * If we have no EL3 then traditionally SMC always UNDEFs and can't be
57
+ * trapped to EL2. For nested virtualization, SMC can be trapped to
58
+ * the outer hypervisor. PSCI-via-SMC is a sort of ersatz EL3
59
* firmware within QEMU, and we want an EL2 guest to be able
60
* to forbid its EL1 from making PSCI calls into QEMU's
61
* "firmware" via HCR.TSC, so for these purposes treat
62
--
41
--
63
2.34.1
42
2.34.1
diff view generated by jsdifflib
1
The alias registers like SCTLR_EL12 only exist when HCR_EL2.E2H
1
Set the default NaN pattern explicitly for xtensa.
2
is 1; they should UNDEF otherwise. We weren't implementing this.
3
Add an intercept of the accessfn for these aliases, and implement
4
the UNDEF check.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Miguel Luis <miguel.luis@oracle.com>
5
Message-id: 20241202131347.498124-51-peter.maydell@linaro.org
9
---
6
---
10
target/arm/cpregs.h | 3 ++-
7
target/xtensa/cpu.c | 2 ++
11
target/arm/helper.c | 16 ++++++++++++++++
8
1 file changed, 2 insertions(+)
12
2 files changed, 18 insertions(+), 1 deletion(-)
13
9
14
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
10
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpregs.h
12
--- a/target/xtensa/cpu.c
17
+++ b/target/arm/cpregs.h
13
+++ b/target/xtensa/cpu.c
18
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
14
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
19
CPResetFn *resetfn;
15
/* For inf * 0 + NaN, return the input NaN */
20
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
21
/*
17
set_no_signaling_nans(!dfpu, &env->fp_status);
22
- * "Original" writefn and readfn.
18
+ /* Default NaN value: sign bit clear, set frac msb */
23
+ * "Original" readfn, writefn, accessfn.
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
24
* For ARMv8.1-VHE register aliases, we overwrite the read/write
20
xtensa_use_first_nan(env, !dfpu);
25
* accessor functions of various EL1/EL0 to perform the runtime
26
* check for which sysreg should actually be modified, and then
27
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
28
*/
29
CPReadFn *orig_readfn;
30
CPWriteFn *orig_writefn;
31
+ CPAccessFn *orig_accessfn;
32
};
33
34
/*
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ static void el2_e2h_e12_write(CPUARMState *env, const ARMCPRegInfo *ri,
40
return ri->orig_writefn(env, ri->opaque, value);
41
}
21
}
42
22
43
+static CPAccessResult el2_e2h_e12_access(CPUARMState *env,
44
+ const ARMCPRegInfo *ri,
45
+ bool isread)
46
+{
47
+ /* FOO_EL12 aliases only exist when E2H is 1; otherwise they UNDEF */
48
+ if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
49
+ return CP_ACCESS_TRAP_UNCATEGORIZED;
50
+ }
51
+ if (ri->orig_accessfn) {
52
+ return ri->orig_accessfn(env, ri->opaque, isread);
53
+ }
54
+ return CP_ACCESS_OK;
55
+}
56
+
57
static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
58
{
59
struct E2HAlias {
60
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
61
new_reg->opaque = src_reg;
62
new_reg->orig_readfn = src_reg->readfn ?: raw_read;
63
new_reg->orig_writefn = src_reg->writefn ?: raw_write;
64
+ new_reg->orig_accessfn = src_reg->accessfn;
65
if (!new_reg->raw_readfn) {
66
new_reg->raw_readfn = raw_read;
67
}
68
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
69
}
70
new_reg->readfn = el2_e2h_e12_read;
71
new_reg->writefn = el2_e2h_e12_write;
72
+ new_reg->accessfn = el2_e2h_e12_access;
73
74
ok = g_hash_table_insert(cpu->cp_regs,
75
(gpointer)(uintptr_t)a->new_key, new_reg);
76
--
23
--
77
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
The FEAT_NV HCR_EL2.AT bit enables trapping of some address
1
Set the default NaN pattern explicitly for hexagon.
2
translation instructions from EL1 to EL2. Implement this behaviour.
2
Remove the ifdef from parts64_default_nan(); the only
3
remaining unconverted targets all use the default case.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Miguel Luis <miguel.luis@oracle.com>
7
Message-id: 20241202131347.498124-52-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper.c | 21 +++++++++++++++------
9
target/hexagon/cpu.c | 2 ++
9
1 file changed, 15 insertions(+), 6 deletions(-)
10
fpu/softfloat-specialize.c.inc | 5 -----
11
2 files changed, 2 insertions(+), 5 deletions(-)
10
12
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
15
--- a/target/hexagon/cpu.c
14
+++ b/target/arm/helper.c
16
+++ b/target/hexagon/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
17
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
16
return at_e012_access(env, ri, isread);
18
19
set_default_nan_mode(1, &env->fp_status);
20
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
21
+ /* Default NaN value: sign bit set, all frac bits set */
22
+ set_float_default_nan_pattern(0b11111111, &env->fp_status);
17
}
23
}
18
24
19
+static CPAccessResult at_s1e01_access(CPUARMState *env, const ARMCPRegInfo *ri,
25
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
20
+ bool isread)
26
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
21
+{
27
index XXXXXXX..XXXXXXX 100644
22
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_AT)) {
28
--- a/fpu/softfloat-specialize.c.inc
23
+ return CP_ACCESS_TRAP_EL2;
29
+++ b/fpu/softfloat-specialize.c.inc
24
+ }
30
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
25
+ return at_e012_access(env, ri, isread);
31
uint8_t dnan_pattern = status->default_nan_pattern;
26
+}
32
27
+
33
if (dnan_pattern == 0) {
28
static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
34
-#if defined(TARGET_HEXAGON)
29
uint64_t value)
35
- /* Sign bit set, all frac bits set. */
30
{
36
- dnan_pattern = 0b11111111;
31
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
37
-#else
32
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0,
38
/*
33
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
39
* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
34
.fgt = FGT_ATS1E1R,
40
* S390, SH4, TriCore, and Xtensa. Our other supported targets
35
- .accessfn = at_e012_access, .writefn = ats_write64 },
41
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
36
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
42
/* sign bit clear, set frac msb */
37
{ .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
43
dnan_pattern = 0b01000000;
38
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1,
44
}
39
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
45
-#endif
40
.fgt = FGT_ATS1E1W,
46
}
41
- .accessfn = at_e012_access, .writefn = ats_write64 },
47
assert(dnan_pattern != 0);
42
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
48
43
{ .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64,
44
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2,
45
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
46
.fgt = FGT_ATS1E0R,
47
- .accessfn = at_e012_access, .writefn = ats_write64 },
48
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
49
{ .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64,
50
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3,
51
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
52
.fgt = FGT_ATS1E0W,
53
- .accessfn = at_e012_access, .writefn = ats_write64 },
54
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
55
{ .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64,
56
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4,
57
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
58
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1e1_reginfo[] = {
59
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
60
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
61
.fgt = FGT_ATS1E1RP,
62
- .accessfn = at_e012_access, .writefn = ats_write64 },
63
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
64
{ .name = "AT_S1E1WP", .state = ARM_CP_STATE_AA64,
65
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
66
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
67
.fgt = FGT_ATS1E1WP,
68
- .accessfn = at_e012_access, .writefn = ats_write64 },
69
+ .accessfn = at_s1e01_access, .writefn = ats_write64 },
70
};
71
72
static const ARMCPRegInfo ats1cp_reginfo[] = {
73
--
49
--
74
2.34.1
50
2.34.1
diff view generated by jsdifflib
1
The hypervisor can deliver (virtual) LPIs to a guest by setting up a
1
Set the default NaN pattern explicitly for riscv.
2
list register to have an intid which is an LPI. The GIC has to treat
3
these a little differently to standard interrupt IDs, because LPIs
4
have no Active state, and so the guest will only EOI them, it will
5
not also deactivate them. So icv_eoir_write() must do two things:
6
2
7
* if the LPI ID is not in any list register, we drop the
8
priority but do not increment the EOI count
9
* if the LPI ID is in a list register, we immediately deactivate
10
it, regardless of the split-drop-and-deactivate control
11
12
This can be seen in the VirtualWriteEOIR0() and VirtualWriteEOIR1()
13
pseudocode in the GICv3 architecture specification.
14
15
Without this fix, potentially a hypervisor guest might stall because
16
LPIs get stuck in a bogus Active+Pending state.
17
18
Cc: qemu-stable@nongnu.org
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Tested-by: Miguel Luis <miguel.luis@oracle.com>
5
Message-id: 20241202131347.498124-53-peter.maydell@linaro.org
22
---
6
---
23
hw/intc/arm_gicv3_cpuif.c | 17 +++++++++++++----
7
target/riscv/cpu.c | 2 ++
24
1 file changed, 13 insertions(+), 4 deletions(-)
8
1 file changed, 2 insertions(+)
25
9
26
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
10
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
27
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/arm_gicv3_cpuif.c
12
--- a/target/riscv/cpu.c
29
+++ b/hw/intc/arm_gicv3_cpuif.c
13
+++ b/target/riscv/cpu.c
30
@@ -XXX,XX +XXX,XX @@ static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
14
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
31
idx = icv_find_active(cs, irq);
15
cs->exception_index = RISCV_EXCP_NONE;
32
16
env->load_res = -1;
33
if (idx < 0) {
17
set_default_nan_mode(1, &env->fp_status);
34
- /* No valid list register corresponding to EOI ID */
18
+ /* Default NaN value: sign bit clear, frac msb set */
35
- icv_increment_eoicount(cs);
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
36
+ /*
20
env->vill = true;
37
+ * No valid list register corresponding to EOI ID; if this is a vLPI
21
38
+ * not in the list regs then do nothing; otherwise increment EOI count
22
#ifndef CONFIG_USER_ONLY
39
+ */
40
+ if (irq < GICV3_LPI_INTID_START) {
41
+ icv_increment_eoicount(cs);
42
+ }
43
} else {
44
uint64_t lr = cs->ich_lr_el2[idx];
45
int thisgrp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;
46
int lr_gprio = ich_lr_prio(lr) & icv_gprio_mask(cs, grp);
47
48
if (thisgrp == grp && lr_gprio == dropprio) {
49
- if (!icv_eoi_split(env, cs)) {
50
- /* Priority drop and deactivate not split: deactivate irq now */
51
+ if (!icv_eoi_split(env, cs) || irq >= GICV3_LPI_INTID_START) {
52
+ /*
53
+ * Priority drop and deactivate not split: deactivate irq now.
54
+ * LPIs always get their active state cleared immediately
55
+ * because no separate deactivate is expected.
56
+ */
57
icv_deactivate_irq(cs, idx);
58
}
59
}
60
--
23
--
61
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
FEAT_NV defines three new bits in HCR_EL2: NV, NV1 and AT. When the
1
Set the default NaN pattern explicitly for tricore.
2
feature is enabled, allow these bits to be written, and flush the
3
TLBs for the bits which affect page table interpretation.
4
2
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Miguel Luis <miguel.luis@oracle.com>
5
Message-id: 20241202131347.498124-54-peter.maydell@linaro.org
8
---
6
---
9
target/arm/cpu-features.h | 5 +++++
7
target/tricore/helper.c | 2 ++
10
target/arm/helper.c | 6 +++++-
8
1 file changed, 2 insertions(+)
11
2 files changed, 10 insertions(+), 1 deletion(-)
12
9
13
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
10
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu-features.h
12
--- a/target/tricore/helper.c
16
+++ b/target/arm/cpu-features.h
13
+++ b/target/tricore/helper.c
17
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
14
@@ -XXX,XX +XXX,XX @@ void fpu_set_state(CPUTriCoreState *env)
18
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
15
set_flush_to_zero(1, &env->fp_status);
16
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
17
set_default_nan_mode(1, &env->fp_status);
18
+ /* Default NaN pattern: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
19
}
20
}
20
21
21
+static inline bool isar_feature_aa64_nv(const ARMISARegisters *id)
22
uint32_t psw_read(CPUTriCoreState *env)
22
+{
23
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, NV) != 0;
24
+}
25
+
26
static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
27
{
28
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
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 @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
34
if (cpu_isar_feature(aa64_rme, cpu)) {
35
valid_mask |= HCR_GPF;
36
}
37
+ if (cpu_isar_feature(aa64_nv, cpu)) {
38
+ valid_mask |= HCR_NV | HCR_NV1 | HCR_AT;
39
+ }
40
}
41
42
if (cpu_isar_feature(any_evt, cpu)) {
43
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
44
* HCR_DC disables stage1 and enables stage2 translation
45
* HCR_DCT enables tagging on (disabled) stage1 translation
46
* HCR_FWB changes the interpretation of stage2 descriptor bits
47
+ * HCR_NV and HCR_NV1 affect interpretation of descriptor bits
48
*/
49
if ((env->cp15.hcr_el2 ^ value) &
50
- (HCR_VM | HCR_PTW | HCR_DC | HCR_DCT | HCR_FWB)) {
51
+ (HCR_VM | HCR_PTW | HCR_DC | HCR_DCT | HCR_FWB | HCR_NV | HCR_NV1)) {
52
tlb_flush(CPU(cpu));
53
}
54
env->cp15.hcr_el2 = value;
55
--
23
--
56
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
The CTR_EL0 register has some bits which allow the implementation to
1
Now that all our targets have bene converted to explicitly specify
2
tell the guest that it does not need to do cache maintenance for
2
their pattern for the default NaN value we can remove the remaining
3
data-to-instruction coherence and instruction-to-data coherence.
3
fallback code in parts64_default_nan().
4
QEMU doesn't emulate caches and so our cache maintenance insns are
5
all NOPs.
6
7
We already have some models of specific CPUs where we set these bits
8
(e.g. the Neoverse V1), but the 'max' CPU still uses the settings it
9
inherits from Cortex-A57. Set the bits for 'max' as well, so the
10
guest doesn't need to do unnecessary work.
11
4
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Miguel Luis <miguel.luis@oracle.com>
7
Message-id: 20241202131347.498124-55-peter.maydell@linaro.org
15
---
8
---
16
target/arm/tcg/cpu64.c | 10 ++++++++++
9
fpu/softfloat-specialize.c.inc | 14 --------------
17
1 file changed, 10 insertions(+)
10
1 file changed, 14 deletions(-)
18
11
19
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
12
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/tcg/cpu64.c
14
--- a/fpu/softfloat-specialize.c.inc
22
+++ b/target/arm/tcg/cpu64.c
15
+++ b/fpu/softfloat-specialize.c.inc
23
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
16
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
24
u = FIELD_DP32(u, CLIDR_EL1, LOUU, 0);
17
uint64_t frac;
25
cpu->clidr = u;
18
uint8_t dnan_pattern = status->default_nan_pattern;
26
19
27
+ /*
20
- if (dnan_pattern == 0) {
28
+ * Set CTR_EL0.DIC and IDC to tell the guest it doesnt' need to
21
- /*
29
+ * do any cache maintenance for data-to-instruction or
22
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
30
+ * instruction-to-guest coherence. (Our cache ops are nops.)
23
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
31
+ */
24
- * do not have floating-point.
32
+ t = cpu->ctr;
25
- */
33
+ t = FIELD_DP64(t, CTR_EL0, IDC, 1);
26
- if (snan_bit_is_one(status)) {
34
+ t = FIELD_DP64(t, CTR_EL0, DIC, 1);
27
- /* sign bit clear, set all frac bits other than msb */
35
+ cpu->ctr = t;
28
- dnan_pattern = 0b00111111;
36
+
29
- } else {
37
t = cpu->isar.id_aa64isar0;
30
- /* sign bit clear, set frac msb */
38
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
31
- dnan_pattern = 0b01000000;
39
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
32
- }
33
- }
34
assert(dnan_pattern != 0);
35
36
sign = dnan_pattern >> 7;
40
--
37
--
41
2.34.1
38
2.34.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Inline pickNaNMulAdd into its only caller. This makes
4
one assert redundant with the immediately preceding IF.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-3-richard.henderson@linaro.org
9
[PMM: keep comment from old code in new location]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
13
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
14
2 files changed, 40 insertions(+), 55 deletions(-)
15
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
17
index XXXXXXX..XXXXXXX 100644
18
--- a/fpu/softfloat-parts.c.inc
19
+++ b/fpu/softfloat-parts.c.inc
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
21
}
22
23
if (s->default_nan_mode) {
24
+ /*
25
+ * We guarantee not to require the target to tell us how to
26
+ * pick a NaN if we're always returning the default NaN.
27
+ * But if we're not in default-NaN mode then the target must
28
+ * specify.
29
+ */
30
which = 3;
31
+ } else if (infzero) {
32
+ /*
33
+ * Inf * 0 + NaN -- some implementations return the
34
+ * default NaN here, and some return the input NaN.
35
+ */
36
+ switch (s->float_infzeronan_rule) {
37
+ case float_infzeronan_dnan_never:
38
+ which = 2;
39
+ break;
40
+ case float_infzeronan_dnan_always:
41
+ which = 3;
42
+ break;
43
+ case float_infzeronan_dnan_if_qnan:
44
+ which = is_qnan(c->cls) ? 3 : 2;
45
+ break;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
} else {
50
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
51
+ FloatClass cls[3] = { a->cls, b->cls, c->cls };
52
+ Float3NaNPropRule rule = s->float_3nan_prop_rule;
53
+
54
+ assert(rule != float_3nan_prop_none);
55
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
56
+ /* We have at least one SNaN input and should prefer it */
57
+ do {
58
+ which = rule & R_3NAN_1ST_MASK;
59
+ rule >>= R_3NAN_1ST_LENGTH;
60
+ } while (!is_snan(cls[which]));
61
+ } else {
62
+ do {
63
+ which = rule & R_3NAN_1ST_MASK;
64
+ rule >>= R_3NAN_1ST_LENGTH;
65
+ } while (!is_nan(cls[which]));
66
+ }
67
}
68
69
if (which == 3) {
70
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
71
index XXXXXXX..XXXXXXX 100644
72
--- a/fpu/softfloat-specialize.c.inc
73
+++ b/fpu/softfloat-specialize.c.inc
74
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
75
}
76
}
77
78
-/*----------------------------------------------------------------------------
79
-| Select which NaN to propagate for a three-input operation.
80
-| For the moment we assume that no CPU needs the 'larger significand'
81
-| information.
82
-| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
83
-*----------------------------------------------------------------------------*/
84
-static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
85
- bool infzero, bool have_snan, float_status *status)
86
-{
87
- FloatClass cls[3] = { a_cls, b_cls, c_cls };
88
- Float3NaNPropRule rule = status->float_3nan_prop_rule;
89
- int which;
90
-
91
- /*
92
- * We guarantee not to require the target to tell us how to
93
- * pick a NaN if we're always returning the default NaN.
94
- * But if we're not in default-NaN mode then the target must
95
- * specify.
96
- */
97
- assert(!status->default_nan_mode);
98
-
99
- if (infzero) {
100
- /*
101
- * Inf * 0 + NaN -- some implementations return the default NaN here,
102
- * and some return the input NaN.
103
- */
104
- switch (status->float_infzeronan_rule) {
105
- case float_infzeronan_dnan_never:
106
- return 2;
107
- case float_infzeronan_dnan_always:
108
- return 3;
109
- case float_infzeronan_dnan_if_qnan:
110
- return is_qnan(c_cls) ? 3 : 2;
111
- default:
112
- g_assert_not_reached();
113
- }
114
- }
115
-
116
- assert(rule != float_3nan_prop_none);
117
- if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
118
- /* We have at least one SNaN input and should prefer it */
119
- do {
120
- which = rule & R_3NAN_1ST_MASK;
121
- rule >>= R_3NAN_1ST_LENGTH;
122
- } while (!is_snan(cls[which]));
123
- } else {
124
- do {
125
- which = rule & R_3NAN_1ST_MASK;
126
- rule >>= R_3NAN_1ST_LENGTH;
127
- } while (!is_nan(cls[which]));
128
- }
129
- return which;
130
-}
131
-
132
/*----------------------------------------------------------------------------
133
| Returns 1 if the double-precision floating-point value `a' is a quiet
134
| NaN; otherwise returns 0.
135
--
136
2.34.1
137
138
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Remove "3" as a special case for which and simply
4
branch to return the desired value.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-4-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
12
1 file changed, 10 insertions(+), 10 deletions(-)
13
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat-parts.c.inc
17
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
19
* But if we're not in default-NaN mode then the target must
20
* specify.
21
*/
22
- which = 3;
23
+ goto default_nan;
24
} else if (infzero) {
25
/*
26
* Inf * 0 + NaN -- some implementations return the
27
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
28
*/
29
switch (s->float_infzeronan_rule) {
30
case float_infzeronan_dnan_never:
31
- which = 2;
32
break;
33
case float_infzeronan_dnan_always:
34
- which = 3;
35
- break;
36
+ goto default_nan;
37
case float_infzeronan_dnan_if_qnan:
38
- which = is_qnan(c->cls) ? 3 : 2;
39
+ if (is_qnan(c->cls)) {
40
+ goto default_nan;
41
+ }
42
break;
43
default:
44
g_assert_not_reached();
45
}
46
+ which = 2;
47
} else {
48
FloatClass cls[3] = { a->cls, b->cls, c->cls };
49
Float3NaNPropRule rule = s->float_3nan_prop_rule;
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
51
}
52
}
53
54
- if (which == 3) {
55
- parts_default_nan(a, s);
56
- return a;
57
- }
58
-
59
switch (which) {
60
case 0:
61
break;
62
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
63
parts_silence_nan(a, s);
64
}
65
return a;
66
+
67
+ default_nan:
68
+ parts_default_nan(a, s);
69
+ return a;
70
}
71
72
/*
73
--
74
2.34.1
75
76
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Assign the pointer return value to 'a' directly,
4
rather than going through an intermediary index.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
12
1 file changed, 10 insertions(+), 22 deletions(-)
13
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat-parts.c.inc
17
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
19
FloatPartsN *c, float_status *s,
20
int ab_mask, int abc_mask)
21
{
22
- int which;
23
bool infzero = (ab_mask == float_cmask_infzero);
24
bool have_snan = (abc_mask & float_cmask_snan);
25
+ FloatPartsN *ret;
26
27
if (unlikely(have_snan)) {
28
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
default:
31
g_assert_not_reached();
32
}
33
- which = 2;
34
+ ret = c;
35
} else {
36
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
37
+ FloatPartsN *val[3] = { a, b, c };
38
Float3NaNPropRule rule = s->float_3nan_prop_rule;
39
40
assert(rule != float_3nan_prop_none);
41
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
42
/* We have at least one SNaN input and should prefer it */
43
do {
44
- which = rule & R_3NAN_1ST_MASK;
45
+ ret = val[rule & R_3NAN_1ST_MASK];
46
rule >>= R_3NAN_1ST_LENGTH;
47
- } while (!is_snan(cls[which]));
48
+ } while (!is_snan(ret->cls));
49
} else {
50
do {
51
- which = rule & R_3NAN_1ST_MASK;
52
+ ret = val[rule & R_3NAN_1ST_MASK];
53
rule >>= R_3NAN_1ST_LENGTH;
54
- } while (!is_nan(cls[which]));
55
+ } while (!is_nan(ret->cls));
56
}
57
}
58
59
- switch (which) {
60
- case 0:
61
- break;
62
- case 1:
63
- a = b;
64
- break;
65
- case 2:
66
- a = c;
67
- break;
68
- default:
69
- g_assert_not_reached();
70
+ if (is_snan(ret->cls)) {
71
+ parts_silence_nan(ret, s);
72
}
73
- if (is_snan(a->cls)) {
74
- parts_silence_nan(a, s);
75
- }
76
- return a;
77
+ return ret;
78
79
default_nan:
80
parts_default_nan(a, s);
81
--
82
2.34.1
83
84
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
While all indices into val[] should be in [0-2], the mask
4
applied is two bits. To help static analysis see there is
5
no possibility of read beyond the end of the array, pad the
6
array to 4 entries, with the final being (implicitly) NULL.
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20241203203949.483774-6-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
fpu/softfloat-parts.c.inc | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
17
index XXXXXXX..XXXXXXX 100644
18
--- a/fpu/softfloat-parts.c.inc
19
+++ b/fpu/softfloat-parts.c.inc
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
21
}
22
ret = c;
23
} else {
24
- FloatPartsN *val[3] = { a, b, c };
25
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
26
Float3NaNPropRule rule = s->float_3nan_prop_rule;
27
28
assert(rule != float_3nan_prop_none);
29
--
30
2.34.1
31
32
diff view generated by jsdifflib
1
Currently the code in target/arm/helper.c mostly checks the PAN bits
1
From: Richard Henderson <richard.henderson@linaro.org>
2
in env->pstate or env->uncached_cpsr directly when it wants to know
3
if PAN is enabled, because in most callsites we know whether we are
4
in AArch64 or AArch32. We do have an arm_pan_enabled() function, but
5
we only use it in a few places where the code might run in either an
6
AArch32 or AArch64 context.
7
2
8
For FEAT_NV, when HCR_EL2.{NV,NV1} is {1,1} PAN is always disabled
3
This function is part of the public interface and
9
even when the PSTATE.PAN bit is set, the "is PAN enabled" test
4
is not "specialized" to any target in any way.
10
becomes more complicated. Make all places that check for PAN use
11
arm_pan_enabled(), so we have a place to put the FEAT_NV test.
12
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Tested-by: Miguel Luis <miguel.luis@oracle.com>
16
---
10
---
17
target/arm/helper.c | 22 +++++++++++-----------
11
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
18
1 file changed, 11 insertions(+), 11 deletions(-)
12
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
13
2 files changed, 52 insertions(+), 52 deletions(-)
19
14
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
17
--- a/fpu/softfloat.c
23
+++ b/target/arm/helper.c
18
+++ b/fpu/softfloat.c
24
@@ -XXX,XX +XXX,XX @@ void init_cpreg_list(ARMCPU *cpu)
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
25
g_list_free(keys);
20
*zExpPtr = 1 - shiftCount;
26
}
21
}
27
22
28
+static bool arm_pan_enabled(CPUARMState *env)
23
+/*----------------------------------------------------------------------------
24
+| Takes two extended double-precision floating-point values `a' and `b', one
25
+| of which is a NaN, and returns the appropriate NaN result. If either `a' or
26
+| `b' is a signaling NaN, the invalid exception is raised.
27
+*----------------------------------------------------------------------------*/
28
+
29
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
29
+{
30
+{
30
+ if (is_a64(env)) {
31
+ bool aIsLargerSignificand;
31
+ return env->pstate & PSTATE_PAN;
32
+ FloatClass a_cls, b_cls;
33
+
34
+ /* This is not complete, but is good enough for pickNaN. */
35
+ a_cls = (!floatx80_is_any_nan(a)
36
+ ? float_class_normal
37
+ : floatx80_is_signaling_nan(a, status)
38
+ ? float_class_snan
39
+ : float_class_qnan);
40
+ b_cls = (!floatx80_is_any_nan(b)
41
+ ? float_class_normal
42
+ : floatx80_is_signaling_nan(b, status)
43
+ ? float_class_snan
44
+ : float_class_qnan);
45
+
46
+ if (is_snan(a_cls) || is_snan(b_cls)) {
47
+ float_raise(float_flag_invalid, status);
48
+ }
49
+
50
+ if (status->default_nan_mode) {
51
+ return floatx80_default_nan(status);
52
+ }
53
+
54
+ if (a.low < b.low) {
55
+ aIsLargerSignificand = 0;
56
+ } else if (b.low < a.low) {
57
+ aIsLargerSignificand = 1;
32
+ } else {
58
+ } else {
33
+ return env->uncached_cpsr & CPSR_PAN;
59
+ aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
60
+ }
61
+
62
+ if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
63
+ if (is_snan(b_cls)) {
64
+ return floatx80_silence_nan(b, status);
65
+ }
66
+ return b;
67
+ } else {
68
+ if (is_snan(a_cls)) {
69
+ return floatx80_silence_nan(a, status);
70
+ }
71
+ return a;
34
+ }
72
+ }
35
+}
73
+}
36
+
74
+
37
/*
75
/*----------------------------------------------------------------------------
38
* Some registers are not accessible from AArch32 EL3 if SCR.NS == 0.
76
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
39
*/
77
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
40
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
78
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
41
g_assert(ss != ARMSS_Secure); /* ARMv8.4-SecEL2 is 64-bit only */
79
index XXXXXXX..XXXXXXX 100644
42
/* fall through */
80
--- a/fpu/softfloat-specialize.c.inc
43
case 1:
81
+++ b/fpu/softfloat-specialize.c.inc
44
- if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
82
@@ -XXX,XX +XXX,XX @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
45
+ if (ri->crm == 9 && arm_pan_enabled(env)) {
83
return a;
46
mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
47
} else {
48
mmu_idx = ARMMMUIdx_Stage1_E1;
49
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
50
case 0:
51
switch (ri->opc1) {
52
case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */
53
- if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) {
54
+ if (ri->crm == 9 && arm_pan_enabled(env)) {
55
mmu_idx = regime_e20 ?
56
ARMMMUIdx_E20_2_PAN : ARMMMUIdx_Stage1_E1_PAN;
57
} else {
58
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
59
}
84
}
60
#endif
85
61
86
-/*----------------------------------------------------------------------------
62
-static bool arm_pan_enabled(CPUARMState *env)
87
-| Takes two extended double-precision floating-point values `a' and `b', one
88
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
89
-| `b' is a signaling NaN, the invalid exception is raised.
90
-*----------------------------------------------------------------------------*/
91
-
92
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
63
-{
93
-{
64
- if (is_a64(env)) {
94
- bool aIsLargerSignificand;
65
- return env->pstate & PSTATE_PAN;
95
- FloatClass a_cls, b_cls;
96
-
97
- /* This is not complete, but is good enough for pickNaN. */
98
- a_cls = (!floatx80_is_any_nan(a)
99
- ? float_class_normal
100
- : floatx80_is_signaling_nan(a, status)
101
- ? float_class_snan
102
- : float_class_qnan);
103
- b_cls = (!floatx80_is_any_nan(b)
104
- ? float_class_normal
105
- : floatx80_is_signaling_nan(b, status)
106
- ? float_class_snan
107
- : float_class_qnan);
108
-
109
- if (is_snan(a_cls) || is_snan(b_cls)) {
110
- float_raise(float_flag_invalid, status);
111
- }
112
-
113
- if (status->default_nan_mode) {
114
- return floatx80_default_nan(status);
115
- }
116
-
117
- if (a.low < b.low) {
118
- aIsLargerSignificand = 0;
119
- } else if (b.low < a.low) {
120
- aIsLargerSignificand = 1;
66
- } else {
121
- } else {
67
- return env->uncached_cpsr & CPSR_PAN;
122
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
123
- }
124
-
125
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
126
- if (is_snan(b_cls)) {
127
- return floatx80_silence_nan(b, status);
128
- }
129
- return b;
130
- } else {
131
- if (is_snan(a_cls)) {
132
- return floatx80_silence_nan(a, status);
133
- }
134
- return a;
68
- }
135
- }
69
-}
136
-}
70
-
137
-
71
ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
138
/*----------------------------------------------------------------------------
72
{
139
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
73
ARMMMUIdx idx;
140
| NaN; otherwise returns 0.
74
--
141
--
75
2.34.1
142
2.34.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Unpacking and repacking the parts may be slightly more work
4
than we did before, but we get to reuse more code. For a
5
code path handling exceptional values, this is an improvement.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241203203949.483774-8-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
fpu/softfloat.c | 43 +++++--------------------------------------
13
1 file changed, 5 insertions(+), 38 deletions(-)
14
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/fpu/softfloat.c
18
+++ b/fpu/softfloat.c
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
20
21
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
22
{
23
- bool aIsLargerSignificand;
24
- FloatClass a_cls, b_cls;
25
+ FloatParts128 pa, pb, *pr;
26
27
- /* This is not complete, but is good enough for pickNaN. */
28
- a_cls = (!floatx80_is_any_nan(a)
29
- ? float_class_normal
30
- : floatx80_is_signaling_nan(a, status)
31
- ? float_class_snan
32
- : float_class_qnan);
33
- b_cls = (!floatx80_is_any_nan(b)
34
- ? float_class_normal
35
- : floatx80_is_signaling_nan(b, status)
36
- ? float_class_snan
37
- : float_class_qnan);
38
-
39
- if (is_snan(a_cls) || is_snan(b_cls)) {
40
- float_raise(float_flag_invalid, status);
41
- }
42
-
43
- if (status->default_nan_mode) {
44
+ if (!floatx80_unpack_canonical(&pa, a, status) ||
45
+ !floatx80_unpack_canonical(&pb, b, status)) {
46
return floatx80_default_nan(status);
47
}
48
49
- if (a.low < b.low) {
50
- aIsLargerSignificand = 0;
51
- } else if (b.low < a.low) {
52
- aIsLargerSignificand = 1;
53
- } else {
54
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
55
- }
56
-
57
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
58
- if (is_snan(b_cls)) {
59
- return floatx80_silence_nan(b, status);
60
- }
61
- return b;
62
- } else {
63
- if (is_snan(a_cls)) {
64
- return floatx80_silence_nan(a, status);
65
- }
66
- return a;
67
- }
68
+ pr = parts_pick_nan(&pa, &pb, status);
69
+ return floatx80_round_pack_canonical(pr, status);
70
}
71
72
/*----------------------------------------------------------------------------
73
--
74
2.34.1
diff view generated by jsdifflib
1
From: Samuel Tardieu <sam@rfc1149.net>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
A SoC will not have a direct access to the NVIC embedded in its ARM
3
Inline pickNaN into its only caller. This makes one assert
4
core. By aliasing the "num-prio-bits" property similarly to what is
4
redundant with the immediately preceding IF.
5
done for the "num-irq" one, a SoC can easily configure it on its
5
6
armv7m instance.
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
8
Signed-off-by: Samuel Tardieu <sam@rfc1149.net>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20240106181503.1746200-3-sam@rfc1149.net
8
Message-id: 20241203203949.483774-9-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
include/hw/arm/armv7m.h | 1 +
11
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
15
hw/arm/armv7m.c | 2 ++
12
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
16
2 files changed, 3 insertions(+)
13
2 files changed, 73 insertions(+), 105 deletions(-)
17
14
18
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
15
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/armv7m.h
17
--- a/fpu/softfloat-parts.c.inc
21
+++ b/include/hw/arm/armv7m.h
18
+++ b/fpu/softfloat-parts.c.inc
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MState, ARMV7M)
19
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
23
* a qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET).
20
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
24
* + Property "cpu-type": CPU type to instantiate
21
float_status *s)
25
* + Property "num-irq": number of external IRQ lines
22
{
26
+ * + Property "num-prio-bits": number of priority bits in the NVIC
23
+ int cmp, which;
27
* + Property "memory": MemoryRegion defining the physical address space
24
+
28
* that CPU accesses see. (The NVIC, bitbanding and other CPU-internal
25
if (is_snan(a->cls) || is_snan(b->cls)) {
29
* devices will be automatically layered on top of this view.)
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
30
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
27
}
28
29
if (s->default_nan_mode) {
30
parts_default_nan(a, s);
31
- } else {
32
- int cmp = frac_cmp(a, b);
33
- if (cmp == 0) {
34
- cmp = a->sign < b->sign;
35
- }
36
+ return a;
37
+ }
38
39
- if (pickNaN(a->cls, b->cls, cmp > 0, s)) {
40
- a = b;
41
- }
42
+ cmp = frac_cmp(a, b);
43
+ if (cmp == 0) {
44
+ cmp = a->sign < b->sign;
45
+ }
46
+
47
+ switch (s->float_2nan_prop_rule) {
48
+ case float_2nan_prop_s_ab:
49
if (is_snan(a->cls)) {
50
- parts_silence_nan(a, s);
51
+ which = 0;
52
+ } else if (is_snan(b->cls)) {
53
+ which = 1;
54
+ } else if (is_qnan(a->cls)) {
55
+ which = 0;
56
+ } else {
57
+ which = 1;
58
}
59
+ break;
60
+ case float_2nan_prop_s_ba:
61
+ if (is_snan(b->cls)) {
62
+ which = 1;
63
+ } else if (is_snan(a->cls)) {
64
+ which = 0;
65
+ } else if (is_qnan(b->cls)) {
66
+ which = 1;
67
+ } else {
68
+ which = 0;
69
+ }
70
+ break;
71
+ case float_2nan_prop_ab:
72
+ which = is_nan(a->cls) ? 0 : 1;
73
+ break;
74
+ case float_2nan_prop_ba:
75
+ which = is_nan(b->cls) ? 1 : 0;
76
+ break;
77
+ case float_2nan_prop_x87:
78
+ /*
79
+ * This implements x87 NaN propagation rules:
80
+ * SNaN + QNaN => return the QNaN
81
+ * two SNaNs => return the one with the larger significand, silenced
82
+ * two QNaNs => return the one with the larger significand
83
+ * SNaN and a non-NaN => return the SNaN, silenced
84
+ * QNaN and a non-NaN => return the QNaN
85
+ *
86
+ * If we get down to comparing significands and they are the same,
87
+ * return the NaN with the positive sign bit (if any).
88
+ */
89
+ if (is_snan(a->cls)) {
90
+ if (is_snan(b->cls)) {
91
+ which = cmp > 0 ? 0 : 1;
92
+ } else {
93
+ which = is_qnan(b->cls) ? 1 : 0;
94
+ }
95
+ } else if (is_qnan(a->cls)) {
96
+ if (is_snan(b->cls) || !is_qnan(b->cls)) {
97
+ which = 0;
98
+ } else {
99
+ which = cmp > 0 ? 0 : 1;
100
+ }
101
+ } else {
102
+ which = 1;
103
+ }
104
+ break;
105
+ default:
106
+ g_assert_not_reached();
107
+ }
108
+
109
+ if (which) {
110
+ a = b;
111
+ }
112
+ if (is_snan(a->cls)) {
113
+ parts_silence_nan(a, s);
114
}
115
return a;
116
}
117
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
31
index XXXXXXX..XXXXXXX 100644
118
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/armv7m.c
119
--- a/fpu/softfloat-specialize.c.inc
33
+++ b/hw/arm/armv7m.c
120
+++ b/fpu/softfloat-specialize.c.inc
34
@@ -XXX,XX +XXX,XX @@ static void armv7m_instance_init(Object *obj)
121
@@ -XXX,XX +XXX,XX @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
35
object_initialize_child(obj, "nvic", &s->nvic, TYPE_NVIC);
122
}
36
object_property_add_alias(obj, "num-irq",
123
}
37
OBJECT(&s->nvic), "num-irq");
124
38
+ object_property_add_alias(obj, "num-prio-bits",
125
-/*----------------------------------------------------------------------------
39
+ OBJECT(&s->nvic), "num-prio-bits");
126
-| Select which NaN to propagate for a two-input operation.
40
127
-| IEEE754 doesn't specify all the details of this, so the
41
object_initialize_child(obj, "systick-reg-ns", &s->systick[M_REG_NS],
128
-| algorithm is target-specific.
42
TYPE_SYSTICK);
129
-| The routine is passed various bits of information about the
130
-| two NaNs and should return 0 to select NaN a and 1 for NaN b.
131
-| Note that signalling NaNs are always squashed to quiet NaNs
132
-| by the caller, by calling floatXX_silence_nan() before
133
-| returning them.
134
-|
135
-| aIsLargerSignificand is only valid if both a and b are NaNs
136
-| of some kind, and is true if a has the larger significand,
137
-| or if both a and b have the same significand but a is
138
-| positive but b is negative. It is only needed for the x87
139
-| tie-break rule.
140
-*----------------------------------------------------------------------------*/
141
-
142
-static int pickNaN(FloatClass a_cls, FloatClass b_cls,
143
- bool aIsLargerSignificand, float_status *status)
144
-{
145
- /*
146
- * We guarantee not to require the target to tell us how to
147
- * pick a NaN if we're always returning the default NaN.
148
- * But if we're not in default-NaN mode then the target must
149
- * specify via set_float_2nan_prop_rule().
150
- */
151
- assert(!status->default_nan_mode);
152
-
153
- switch (status->float_2nan_prop_rule) {
154
- case float_2nan_prop_s_ab:
155
- if (is_snan(a_cls)) {
156
- return 0;
157
- } else if (is_snan(b_cls)) {
158
- return 1;
159
- } else if (is_qnan(a_cls)) {
160
- return 0;
161
- } else {
162
- return 1;
163
- }
164
- break;
165
- case float_2nan_prop_s_ba:
166
- if (is_snan(b_cls)) {
167
- return 1;
168
- } else if (is_snan(a_cls)) {
169
- return 0;
170
- } else if (is_qnan(b_cls)) {
171
- return 1;
172
- } else {
173
- return 0;
174
- }
175
- break;
176
- case float_2nan_prop_ab:
177
- if (is_nan(a_cls)) {
178
- return 0;
179
- } else {
180
- return 1;
181
- }
182
- break;
183
- case float_2nan_prop_ba:
184
- if (is_nan(b_cls)) {
185
- return 1;
186
- } else {
187
- return 0;
188
- }
189
- break;
190
- case float_2nan_prop_x87:
191
- /*
192
- * This implements x87 NaN propagation rules:
193
- * SNaN + QNaN => return the QNaN
194
- * two SNaNs => return the one with the larger significand, silenced
195
- * two QNaNs => return the one with the larger significand
196
- * SNaN and a non-NaN => return the SNaN, silenced
197
- * QNaN and a non-NaN => return the QNaN
198
- *
199
- * If we get down to comparing significands and they are the same,
200
- * return the NaN with the positive sign bit (if any).
201
- */
202
- if (is_snan(a_cls)) {
203
- if (is_snan(b_cls)) {
204
- return aIsLargerSignificand ? 0 : 1;
205
- }
206
- return is_qnan(b_cls) ? 1 : 0;
207
- } else if (is_qnan(a_cls)) {
208
- if (is_snan(b_cls) || !is_qnan(b_cls)) {
209
- return 0;
210
- } else {
211
- return aIsLargerSignificand ? 0 : 1;
212
- }
213
- } else {
214
- return 1;
215
- }
216
- default:
217
- g_assert_not_reached();
218
- }
219
-}
220
-
221
/*----------------------------------------------------------------------------
222
| Returns 1 if the double-precision floating-point value `a' is a quiet
223
| NaN; otherwise returns 0.
43
--
224
--
44
2.34.1
225
2.34.1
45
226
46
227
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Remember if there was an SNaN, and use that to simplify
4
float_2nan_prop_s_{ab,ba} to only the snan component.
5
Then, fall through to the corresponding
6
float_2nan_prop_{ab,ba} case to handle any remaining
7
nans, which must be quiet.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20241203203949.483774-10-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
15
1 file changed, 12 insertions(+), 20 deletions(-)
16
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
18
index XXXXXXX..XXXXXXX 100644
19
--- a/fpu/softfloat-parts.c.inc
20
+++ b/fpu/softfloat-parts.c.inc
21
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
22
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
23
float_status *s)
24
{
25
+ bool have_snan = false;
26
int cmp, which;
27
28
if (is_snan(a->cls) || is_snan(b->cls)) {
29
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
30
+ have_snan = true;
31
}
32
33
if (s->default_nan_mode) {
34
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
35
36
switch (s->float_2nan_prop_rule) {
37
case float_2nan_prop_s_ab:
38
- if (is_snan(a->cls)) {
39
- which = 0;
40
- } else if (is_snan(b->cls)) {
41
- which = 1;
42
- } else if (is_qnan(a->cls)) {
43
- which = 0;
44
- } else {
45
- which = 1;
46
+ if (have_snan) {
47
+ which = is_snan(a->cls) ? 0 : 1;
48
+ break;
49
}
50
- break;
51
- case float_2nan_prop_s_ba:
52
- if (is_snan(b->cls)) {
53
- which = 1;
54
- } else if (is_snan(a->cls)) {
55
- which = 0;
56
- } else if (is_qnan(b->cls)) {
57
- which = 1;
58
- } else {
59
- which = 0;
60
- }
61
- break;
62
+ /* fall through */
63
case float_2nan_prop_ab:
64
which = is_nan(a->cls) ? 0 : 1;
65
break;
66
+ case float_2nan_prop_s_ba:
67
+ if (have_snan) {
68
+ which = is_snan(b->cls) ? 1 : 0;
69
+ break;
70
+ }
71
+ /* fall through */
72
case float_2nan_prop_ba:
73
which = is_nan(b->cls) ? 1 : 0;
74
break;
75
--
76
2.34.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Move the fractional comparison to the end of the
4
float_2nan_prop_x87 case. This is not required for
5
any other 2nan propagation rule. Reorganize the
6
x87 case itself to break out of the switch when the
7
fractional comparison is not required.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
fpu/softfloat-parts.c.inc | 19 +++++++++----------
15
1 file changed, 9 insertions(+), 10 deletions(-)
16
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
18
index XXXXXXX..XXXXXXX 100644
19
--- a/fpu/softfloat-parts.c.inc
20
+++ b/fpu/softfloat-parts.c.inc
21
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
22
return a;
23
}
24
25
- cmp = frac_cmp(a, b);
26
- if (cmp == 0) {
27
- cmp = a->sign < b->sign;
28
- }
29
-
30
switch (s->float_2nan_prop_rule) {
31
case float_2nan_prop_s_ab:
32
if (have_snan) {
33
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
34
* return the NaN with the positive sign bit (if any).
35
*/
36
if (is_snan(a->cls)) {
37
- if (is_snan(b->cls)) {
38
- which = cmp > 0 ? 0 : 1;
39
- } else {
40
+ if (!is_snan(b->cls)) {
41
which = is_qnan(b->cls) ? 1 : 0;
42
+ break;
43
}
44
} else if (is_qnan(a->cls)) {
45
if (is_snan(b->cls) || !is_qnan(b->cls)) {
46
which = 0;
47
- } else {
48
- which = cmp > 0 ? 0 : 1;
49
+ break;
50
}
51
} else {
52
which = 1;
53
+ break;
54
}
55
+ cmp = frac_cmp(a, b);
56
+ if (cmp == 0) {
57
+ cmp = a->sign < b->sign;
58
+ }
59
+ which = cmp > 0 ? 0 : 1;
60
break;
61
default:
62
g_assert_not_reached();
63
--
64
2.34.1
diff view generated by jsdifflib
1
From: Nikita Ostrenkov <n.ostrenkov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Nikita Ostrenkov <n.ostrenkov@gmail.com>
3
Replace the "index" selecting between A and B with a result variable
4
of the proper type. This improves clarity within the function.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20231219105510.4907-1-n.ostrenkov@gmail.com
8
Message-id: 20241203203949.483774-12-richard.henderson@linaro.org
6
[PMM: fixed stray whitespace]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
hw/arm/fsl-imx6.c | 3 +++
11
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
10
hw/arm/Kconfig | 1 +
12
1 file changed, 13 insertions(+), 15 deletions(-)
11
2 files changed, 4 insertions(+)
12
13
13
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/fsl-imx6.c
16
--- a/fpu/softfloat-parts.c.inc
16
+++ b/hw/arm/fsl-imx6.c
17
+++ b/fpu/softfloat-parts.c.inc
17
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
18
qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_FIQ));
19
float_status *s)
20
{
21
bool have_snan = false;
22
- int cmp, which;
23
+ FloatPartsN *ret;
24
+ int cmp;
25
26
if (is_snan(a->cls) || is_snan(b->cls)) {
27
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
28
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
29
switch (s->float_2nan_prop_rule) {
30
case float_2nan_prop_s_ab:
31
if (have_snan) {
32
- which = is_snan(a->cls) ? 0 : 1;
33
+ ret = is_snan(a->cls) ? a : b;
34
break;
35
}
36
/* fall through */
37
case float_2nan_prop_ab:
38
- which = is_nan(a->cls) ? 0 : 1;
39
+ ret = is_nan(a->cls) ? a : b;
40
break;
41
case float_2nan_prop_s_ba:
42
if (have_snan) {
43
- which = is_snan(b->cls) ? 1 : 0;
44
+ ret = is_snan(b->cls) ? b : a;
45
break;
46
}
47
/* fall through */
48
case float_2nan_prop_ba:
49
- which = is_nan(b->cls) ? 1 : 0;
50
+ ret = is_nan(b->cls) ? b : a;
51
break;
52
case float_2nan_prop_x87:
53
/*
54
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
55
*/
56
if (is_snan(a->cls)) {
57
if (!is_snan(b->cls)) {
58
- which = is_qnan(b->cls) ? 1 : 0;
59
+ ret = is_qnan(b->cls) ? b : a;
60
break;
61
}
62
} else if (is_qnan(a->cls)) {
63
if (is_snan(b->cls) || !is_qnan(b->cls)) {
64
- which = 0;
65
+ ret = a;
66
break;
67
}
68
} else {
69
- which = 1;
70
+ ret = b;
71
break;
72
}
73
cmp = frac_cmp(a, b);
74
if (cmp == 0) {
75
cmp = a->sign < b->sign;
76
}
77
- which = cmp > 0 ? 0 : 1;
78
+ ret = cmp > 0 ? a : b;
79
break;
80
default:
81
g_assert_not_reached();
19
}
82
}
20
83
21
+ /* L2 cache controller */
84
- if (which) {
22
+ sysbus_create_simple("l2x0", FSL_IMX6_PL310_ADDR, NULL);
85
- a = b;
23
+
86
+ if (is_snan(ret->cls)) {
24
if (!sysbus_realize(SYS_BUS_DEVICE(&s->ccm), errp)) {
87
+ parts_silence_nan(ret, s);
25
return;
26
}
88
}
27
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
89
- if (is_snan(a->cls)) {
28
index XXXXXXX..XXXXXXX 100644
90
- parts_silence_nan(a, s);
29
--- a/hw/arm/Kconfig
91
- }
30
+++ b/hw/arm/Kconfig
92
- return a;
31
@@ -XXX,XX +XXX,XX @@ config FSL_IMX6
93
+ return ret;
32
select IMX_I2C
94
}
33
select IMX_USBPHY
95
34
select WDT_IMX2
96
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
35
+ select PL310 # cache controller
36
select SDHCI
37
38
config ASPEED_SOC
39
--
97
--
40
2.34.1
98
2.34.1
41
99
42
100
diff view generated by jsdifflib
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
This commit adds a new B-L475E-IOT01A board using the STM32L475VG SoC
3
I'm migrating to Qualcomm's new open source email infrastructure, so
4
as well as a dedicated documentation file.
4
update my email address, and update the mailmap to match.
5
The implementation is derived from the Netduino Plus 2 machine.
6
There are no peripherals implemented yet, only memory regions.
7
5
6
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
8
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
10
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
12
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
13
Message-id: 20240108135849.351719-3-ines.varhol@telecom-paris.fr
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
MAINTAINERS | 7 +++
14
MAINTAINERS | 2 +-
17
docs/system/arm/b-l475e-iot01a.rst | 46 ++++++++++++++++
15
.mailmap | 5 +++--
18
docs/system/arm/stm32.rst | 6 ++-
16
2 files changed, 4 insertions(+), 3 deletions(-)
19
docs/system/target-arm.rst | 1 +
20
configs/devices/arm-softmmu/default.mak | 1 +
21
hw/arm/b-l475e-iot01a.c | 72 +++++++++++++++++++++++++
22
hw/arm/Kconfig | 6 +++
23
hw/arm/meson.build | 1 +
24
8 files changed, 138 insertions(+), 2 deletions(-)
25
create mode 100644 docs/system/arm/b-l475e-iot01a.rst
26
create mode 100644 hw/arm/b-l475e-iot01a.c
27
17
28
diff --git a/MAINTAINERS b/MAINTAINERS
18
diff --git a/MAINTAINERS b/MAINTAINERS
29
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
30
--- a/MAINTAINERS
20
--- a/MAINTAINERS
31
+++ b/MAINTAINERS
21
+++ b/MAINTAINERS
32
@@ -XXX,XX +XXX,XX @@ S: Maintained
22
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
33
F: hw/arm/stm32l4x5_soc.c
23
SBSA-REF
34
F: include/hw/arm/stm32l4x5_soc.h
24
M: Radoslaw Biernacki <rad@semihalf.com>
35
36
+B-L475E-IOT01A IoT Node
37
+M: Arnaud Minier <arnaud.minier@telecom-paris.fr>
38
+M: Inès Varhol <ines.varhol@telecom-paris.fr>
39
+L: qemu-arm@nongnu.org
40
+S: Maintained
41
+F: hw/arm/b-l475e-iot01a.c
42
+
43
SmartFusion2
44
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
45
M: Peter Maydell <peter.maydell@linaro.org>
25
M: Peter Maydell <peter.maydell@linaro.org>
46
diff --git a/docs/system/arm/b-l475e-iot01a.rst b/docs/system/arm/b-l475e-iot01a.rst
26
-R: Leif Lindholm <quic_llindhol@quicinc.com>
47
new file mode 100644
27
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
48
index XXXXXXX..XXXXXXX
28
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
49
--- /dev/null
29
L: qemu-arm@nongnu.org
50
+++ b/docs/system/arm/b-l475e-iot01a.rst
30
S: Maintained
51
@@ -XXX,XX +XXX,XX @@
31
diff --git a/.mailmap b/.mailmap
52
+B-L475E-IOT01A IoT Node (``b-l475e-iot01a``)
53
+============================================
54
+
55
+The B-L475E-IOT01A IoT Node uses the STM32L475VG SoC which is based on
56
+ARM Cortex-M4F core. It is part of STMicroelectronics
57
+:doc:`STM32 boards </system/arm/stm32>` and more specifically the STM32L4
58
+ultra-low power series. The STM32L4x5 chip runs at up to 80 MHz and
59
+integrates 128 KiB of SRAM and up to 1MiB of Flash. The B-L475E-IOT01A board
60
+namely features 64 Mibit QSPI Flash, BT, WiFi and RF connectivity,
61
+USART, I2C, SPI, CAN and USB OTG, as well as a variety of sensors.
62
+
63
+Supported devices
64
+"""""""""""""""""
65
+
66
+Currently, B-L475E-IOT01A machine's implementation is minimal,
67
+it only supports the following device:
68
+
69
+- Cortex-M4F based STM32L4x5 SoC
70
+
71
+Missing devices
72
+"""""""""""""""
73
+
74
+The B-L475E-IOT01A does *not* support the following devices:
75
+
76
+- Extended interrupts and events controller (EXTI)
77
+- Reset and clock control (RCC)
78
+- Serial ports (UART)
79
+- System configuration controller (SYSCFG)
80
+- General-purpose I/Os (GPIO)
81
+- Analog to Digital Converter (ADC)
82
+- SPI controller
83
+- Timer controller (TIMER)
84
+
85
+See the complete list of unimplemented peripheral devices
86
+in the STM32L4x5 module : ``./hw/arm/stm32l4x5_soc.c``
87
+
88
+Boot options
89
+""""""""""""
90
+
91
+The B-L475E-IOT01A machine can be started using the ``-kernel``
92
+option to load a firmware. Example:
93
+
94
+.. code-block:: bash
95
+
96
+ $ qemu-system-arm -M b-l475e-iot01a -kernel firmware.bin
97
+
98
diff --git a/docs/system/arm/stm32.rst b/docs/system/arm/stm32.rst
99
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
100
--- a/docs/system/arm/stm32.rst
33
--- a/.mailmap
101
+++ b/docs/system/arm/stm32.rst
34
+++ b/.mailmap
102
@@ -XXX,XX +XXX,XX @@ based on this chip :
35
@@ -XXX,XX +XXX,XX @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
103
36
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
104
- ``netduino2`` Netduino 2 board with STM32F205RFT6 microcontroller
37
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
105
38
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
106
-The STM32F4 series is based on ARM Cortex-M4F core. This series is pin-to-pin
39
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
107
-compatible with STM32F2 series. The following machines are based on this chip :
40
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
108
+The STM32F4 series is based on ARM Cortex-M4F core, as well as the STM32L4
41
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
109
+ultra-low-power series. The STM32F4 series is pin-to-pin compatible with STM32F2 series.
42
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
110
+The following machines are based on this ARM Cortex-M4F chip :
43
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
111
44
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
112
- ``netduinoplus2`` Netduino Plus 2 board with STM32F405RGT6 microcontroller
45
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
113
- ``olimex-stm32-h405`` Olimex STM32 H405 board with STM32F405RGT6 microcontroller
46
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
114
+- ``b-l475e-iot01a`` :doc:`B-L475E-IOT01A IoT Node </system/arm/b-l475e-iot01a>` board with STM32L475VG microcontroller
115
116
There are many other STM32 series that are currently not supported by QEMU.
117
118
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
119
index XXXXXXX..XXXXXXX 100644
120
--- a/docs/system/target-arm.rst
121
+++ b/docs/system/target-arm.rst
122
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
123
arm/vexpress
124
arm/aspeed
125
arm/bananapi_m2u.rst
126
+ arm/b-l475e-iot01a.rst
127
arm/sabrelite
128
arm/digic
129
arm/cubieboard
130
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
131
index XXXXXXX..XXXXXXX 100644
132
--- a/configs/devices/arm-softmmu/default.mak
133
+++ b/configs/devices/arm-softmmu/default.mak
134
@@ -XXX,XX +XXX,XX @@ CONFIG_ARM_VIRT=y
135
# CONFIG_NSERIES=n
136
# CONFIG_STELLARIS=n
137
# CONFIG_STM32VLDISCOVERY=n
138
+# CONFIG_B_L475E_IOT01A=n
139
# CONFIG_REALVIEW=n
140
# CONFIG_VERSATILE=n
141
# CONFIG_VEXPRESS=n
142
diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c
143
new file mode 100644
144
index XXXXXXX..XXXXXXX
145
--- /dev/null
146
+++ b/hw/arm/b-l475e-iot01a.c
147
@@ -XXX,XX +XXX,XX @@
148
+/*
149
+ * B-L475E-IOT01A Discovery Kit machine
150
+ * (B-L475E-IOT01A IoT Node)
151
+ *
152
+ * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
153
+ * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
154
+ *
155
+ * SPDX-License-Identifier: GPL-2.0-or-later
156
+ *
157
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
158
+ * See the COPYING file in the top-level directory.
159
+ *
160
+ * This work is heavily inspired by the netduinoplus2 by Alistair Francis.
161
+ * Original code is licensed under the MIT License:
162
+ *
163
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
164
+ */
165
+
166
+/*
167
+ * The reference used is the STMicroElectronics UM2153 User manual
168
+ * Discovery kit for IoT node, multi-channel communication with STM32L4.
169
+ * https://www.st.com/en/evaluation-tools/b-l475e-iot01a.html#documentation
170
+ */
171
+
172
+#include "qemu/osdep.h"
173
+#include "qapi/error.h"
174
+#include "hw/boards.h"
175
+#include "hw/qdev-properties.h"
176
+#include "hw/qdev-clock.h"
177
+#include "qemu/error-report.h"
178
+#include "hw/arm/stm32l4x5_soc.h"
179
+#include "hw/arm/boot.h"
180
+
181
+/* Main SYSCLK frequency in Hz (80MHz) */
182
+#define MAIN_SYSCLK_FREQ_HZ 80000000ULL
183
+
184
+static void b_l475e_iot01a_init(MachineState *machine)
185
+{
186
+ const Stm32l4x5SocClass *sc;
187
+ DeviceState *dev;
188
+ Clock *sysclk;
189
+
190
+ /* This clock doesn't need migration because it is fixed-frequency */
191
+ sysclk = clock_new(OBJECT(machine), "SYSCLK");
192
+ clock_set_hz(sysclk, MAIN_SYSCLK_FREQ_HZ);
193
+
194
+ dev = qdev_new(TYPE_STM32L4X5XG_SOC);
195
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
196
+ qdev_connect_clock_in(dev, "sysclk", sysclk);
197
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
198
+
199
+ sc = STM32L4X5_SOC_GET_CLASS(dev);
200
+ armv7m_load_kernel(ARM_CPU(first_cpu),
201
+ machine->kernel_filename,
202
+ 0, sc->flash_size);
203
+}
204
+
205
+static void b_l475e_iot01a_machine_init(MachineClass *mc)
206
+{
207
+ static const char *machine_valid_cpu_types[] = {
208
+ ARM_CPU_TYPE_NAME("cortex-m4"),
209
+ NULL
210
+ };
211
+ mc->desc = "B-L475E-IOT01A Discovery Kit (Cortex-M4)";
212
+ mc->init = b_l475e_iot01a_init;
213
+ mc->valid_cpu_types = machine_valid_cpu_types;
214
+
215
+ /* SRAM pre-allocated as part of the SoC instantiation */
216
+ mc->default_ram_size = 0;
217
+}
218
+
219
+DEFINE_MACHINE("b-l475e-iot01a", b_l475e_iot01a_machine_init)
220
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
221
index XXXXXXX..XXXXXXX 100644
222
--- a/hw/arm/Kconfig
223
+++ b/hw/arm/Kconfig
224
@@ -XXX,XX +XXX,XX @@ config STM32F405_SOC
225
select STM32F4XX_SYSCFG
226
select STM32F4XX_EXTI
227
228
+config B_L475E_IOT01A
229
+ bool
230
+ default y
231
+ depends on TCG && ARM
232
+ select STM32L4X5_SOC
233
+
234
config STM32L4X5_SOC
235
bool
236
select ARM_V7M
237
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
238
index XXXXXXX..XXXXXXX 100644
239
--- a/hw/arm/meson.build
240
+++ b/hw/arm/meson.build
241
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
242
arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
243
arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
244
arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
245
+arm_ss.add(when: 'CONFIG_B_L475E_IOT01A', if_true: files('b-l475e-iot01a.c'))
246
arm_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_soc.c'))
247
arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c'))
248
arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-versal-virt.c'))
249
--
47
--
250
2.34.1
48
2.34.1
251
49
252
50
diff view generated by jsdifflib
1
From: Samuel Tardieu <sam@rfc1149.net>
1
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
2
2
3
Update the number of priority bits for a number of existing
3
Previously, maintainer role was paused due to inactive email id. Commit id:
4
SoCs according to their technical documentation:
4
c009d715721861984c4987bcc78b7ee183e86d75.
5
5
6
- STM32F100/F205/F405/L4x5: 4 bits
6
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
7
- Stellaris (Sandstorm/Fury): 3 bits
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
8
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
9
Signed-off-by: Samuel Tardieu <sam@rfc1149.net>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240106181503.1746200-4-sam@rfc1149.net
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
hw/arm/stellaris.c | 2 ++
11
MAINTAINERS | 2 ++
15
hw/arm/stm32f100_soc.c | 1 +
12
1 file changed, 2 insertions(+)
16
hw/arm/stm32f205_soc.c | 1 +
17
hw/arm/stm32f405_soc.c | 1 +
18
hw/arm/stm32l4x5_soc.c | 1 +
19
5 files changed, 6 insertions(+)
20
13
21
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
14
diff --git a/MAINTAINERS b/MAINTAINERS
22
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/stellaris.c
16
--- a/MAINTAINERS
24
+++ b/hw/arm/stellaris.c
17
+++ b/MAINTAINERS
25
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-sb16-test.c
26
#define BP_GAMEPAD 0x04
19
27
20
Xilinx CAN
28
#define NUM_IRQ_LINES 64
21
M: Francisco Iglesias <francisco.iglesias@amd.com>
29
+#define NUM_PRIO_BITS 3
22
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
30
23
S: Maintained
31
typedef const struct {
24
F: hw/net/can/xlnx-*
32
const char *name;
25
F: include/hw/net/xlnx-*
33
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
26
@@ -XXX,XX +XXX,XX @@ F: include/hw/rx/
34
27
CAN bus subsystem and hardware
35
nvic = qdev_new(TYPE_ARMV7M);
28
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
36
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
29
M: Francisco Iglesias <francisco.iglesias@amd.com>
37
+ qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
30
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
38
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
31
S: Maintained
39
qdev_prop_set_bit(nvic, "enable-bitband", true);
32
W: https://canbus.pages.fel.cvut.cz/
40
qdev_connect_clock_in(nvic, "cpuclk",
33
F: net/can/*
41
diff --git a/hw/arm/stm32f100_soc.c b/hw/arm/stm32f100_soc.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/stm32f100_soc.c
44
+++ b/hw/arm/stm32f100_soc.c
45
@@ -XXX,XX +XXX,XX @@ static void stm32f100_soc_realize(DeviceState *dev_soc, Error **errp)
46
/* Init ARMv7m */
47
armv7m = DEVICE(&s->armv7m);
48
qdev_prop_set_uint32(armv7m, "num-irq", 61);
49
+ qdev_prop_set_uint8(armv7m, "num-prio-bits", 4);
50
qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
51
qdev_prop_set_bit(armv7m, "enable-bitband", true);
52
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
53
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stm32f205_soc.c
56
+++ b/hw/arm/stm32f205_soc.c
57
@@ -XXX,XX +XXX,XX @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
58
59
armv7m = DEVICE(&s->armv7m);
60
qdev_prop_set_uint32(armv7m, "num-irq", 96);
61
+ qdev_prop_set_uint8(armv7m, "num-prio-bits", 4);
62
qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
63
qdev_prop_set_bit(armv7m, "enable-bitband", true);
64
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
65
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/stm32f405_soc.c
68
+++ b/hw/arm/stm32f405_soc.c
69
@@ -XXX,XX +XXX,XX @@ static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp)
70
71
armv7m = DEVICE(&s->armv7m);
72
qdev_prop_set_uint32(armv7m, "num-irq", 96);
73
+ qdev_prop_set_uint8(armv7m, "num-prio-bits", 4);
74
qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
75
qdev_prop_set_bit(armv7m, "enable-bitband", true);
76
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
77
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/stm32l4x5_soc.c
80
+++ b/hw/arm/stm32l4x5_soc.c
81
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
82
object_initialize_child(OBJECT(dev_soc), "armv7m", &s->armv7m, TYPE_ARMV7M);
83
armv7m = DEVICE(&s->armv7m);
84
qdev_prop_set_uint32(armv7m, "num-irq", 96);
85
+ qdev_prop_set_uint32(armv7m, "num-prio-bits", 4);
86
qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
87
qdev_prop_set_bit(armv7m, "enable-bitband", true);
88
qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
89
--
34
--
90
2.34.1
35
2.34.1
diff view generated by jsdifflib