1
The following changes since commit 64ada298b98a51eb2512607f6e6180cb330c47b1:
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
3
Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220302' into staging (2022-03-02 12:38:46 +0000)
5
thanks
6
-- PMM
7
8
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
9
10
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220302
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
8
15
9
for you to fetch changes up to 268c11984e67867c22f53beb3c7f8b98900d66b2:
16
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
10
17
11
ui/cocoa.m: Remove unnecessary NSAutoreleasePools (2022-03-02 19:27:37 +0000)
18
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
target-arm queue:
21
target-arm queue:
15
* mps3-an547: Add missing user ahb interfaces
22
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
16
* hw/arm/mps2-tz.c: Update AN547 documentation URL
23
* fpu: Make muladd NaN handling runtime-selected, not compile-time
17
* hw/input/tsc210x: Don't abort on bad SPI word widths
24
* fpu: Make default NaN pattern runtime-selected, not compile-time
18
* hw/i2c: flatten pca954x mux device
25
* fpu: Minor NaN-related cleanups
19
* target/arm: Support PSCI 1.1 and SMCCC 1.0
26
* MAINTAINERS: email address updates
20
* target/arm: Fix early free of TCG temp in handle_simd_shift_fpint_conv()
21
* tests/qtest: add qtests for npcm7xx sdhci
22
* Implement FEAT_LVA
23
* Implement FEAT_LPA
24
* Implement FEAT_LPA2 (but do not enable it yet)
25
* Report KVM's actual PSCI version to guest in dtb
26
* ui/cocoa.m: Fix updateUIInfo threading issues
27
* ui/cocoa.m: Remove unnecessary NSAutoreleasePools
28
27
29
----------------------------------------------------------------
28
----------------------------------------------------------------
30
Akihiko Odaki (1):
29
Bernhard Beschow (5):
31
target/arm: Support PSCI 1.1 and SMCCC 1.0
30
hw/net/lan9118: Extract lan9118_phy
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
Jimmy Brisson (1):
36
Leif Lindholm (1):
34
mps3-an547: Add missing user ahb interfaces
37
MAINTAINERS: update email address for Leif Lindholm
35
38
36
Patrick Venture (1):
39
Peter Maydell (54):
37
hw/i2c: flatten pca954x mux device
40
fpu: handle raising Invalid for infzero in pick_nan_muladd
41
fpu: Check for default_nan_mode before calling pickNaNMulAdd
42
softfloat: Allow runtime choice of inf * 0 + NaN result
43
tests/fp: Explicitly set inf-zero-nan rule
44
target/arm: Set FloatInfZeroNaNRule explicitly
45
target/s390: Set FloatInfZeroNaNRule explicitly
46
target/ppc: Set FloatInfZeroNaNRule explicitly
47
target/mips: Set FloatInfZeroNaNRule explicitly
48
target/sparc: Set FloatInfZeroNaNRule explicitly
49
target/xtensa: Set FloatInfZeroNaNRule explicitly
50
target/x86: Set FloatInfZeroNaNRule explicitly
51
target/loongarch: Set FloatInfZeroNaNRule explicitly
52
target/hppa: Set FloatInfZeroNaNRule explicitly
53
softfloat: Pass have_snan to pickNaNMulAdd
54
softfloat: Allow runtime choice of NaN propagation for muladd
55
tests/fp: Explicitly set 3-NaN propagation rule
56
target/arm: Set Float3NaNPropRule explicitly
57
target/loongarch: Set Float3NaNPropRule explicitly
58
target/ppc: Set Float3NaNPropRule explicitly
59
target/s390x: Set Float3NaNPropRule explicitly
60
target/sparc: Set Float3NaNPropRule explicitly
61
target/mips: Set Float3NaNPropRule explicitly
62
target/xtensa: Set Float3NaNPropRule explicitly
63
target/i386: Set Float3NaNPropRule explicitly
64
target/hppa: Set Float3NaNPropRule explicitly
65
fpu: Remove use_first_nan field from float_status
66
target/m68k: Don't pass NULL float_status to floatx80_default_nan()
67
softfloat: Create floatx80 default NaN from parts64_default_nan
68
target/loongarch: Use normal float_status in fclass_s and fclass_d helpers
69
target/m68k: In frem helper, initialize local float_status from env->fp_status
70
target/m68k: Init local float_status from env fp_status in gdb get/set reg
71
target/sparc: Initialize local scratch float_status from env->fp_status
72
target/ppc: Use env->fp_status in helper_compute_fprf functions
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
38
94
39
Peter Maydell (5):
95
Richard Henderson (11):
40
hw/arm/mps2-tz.c: Update AN547 documentation URL
96
target/arm: Copy entire float_status in is_ebf
41
hw/input/tsc210x: Don't abort on bad SPI word widths
97
softfloat: Inline pickNaNMulAdd
42
target/arm: Report KVM's actual PSCI version to guest in dtb
98
softfloat: Use goto for default nan case in pick_nan_muladd
43
ui/cocoa.m: Fix updateUIInfo threading issues
99
softfloat: Remove which from parts_pick_nan_muladd
44
ui/cocoa.m: Remove unnecessary NSAutoreleasePools
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
45
107
46
Richard Henderson (16):
108
Vikram Garhwal (1):
47
hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N>
109
MAINTAINERS: Add correct email address for Vikram Garhwal
48
target/arm: Set TCR_EL1.TSZ for user-only
49
target/arm: Fault on invalid TCR_ELx.TxSZ
50
target/arm: Move arm_pamax out of line
51
target/arm: Pass outputsize down to check_s2_mmu_setup
52
target/arm: Use MAKE_64BIT_MASK to compute indexmask
53
target/arm: Honor TCR_ELx.{I}PS
54
target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA
55
target/arm: Implement FEAT_LVA
56
target/arm: Implement FEAT_LPA
57
target/arm: Extend arm_fi_to_lfsc to level -1
58
target/arm: Introduce tlbi_aa64_get_range
59
target/arm: Fix TLBIRange.base for 16k and 64k pages
60
target/arm: Validate tlbi TG matches translation granule in use
61
target/arm: Advertise all page sizes for -cpu max
62
target/arm: Implement FEAT_LPA2
63
110
64
Shengtan Mao (1):
111
MAINTAINERS | 4 +-
65
tests/qtest: add qtests for npcm7xx sdhci
112
include/fpu/softfloat-helpers.h | 38 +++-
66
113
include/fpu/softfloat-types.h | 89 +++++++-
67
Wentao_Liang (1):
114
include/hw/net/imx_fec.h | 9 +-
68
target/arm: Fix early free of TCG temp in handle_simd_shift_fpint_conv()
115
include/hw/net/lan9118_phy.h | 37 ++++
69
116
include/hw/net/mii.h | 6 +
70
docs/system/arm/emulation.rst | 3 +
117
target/mips/fpu_helper.h | 20 ++
71
include/hw/registerfields.h | 48 +++++-
118
target/sparc/helper.h | 4 +-
72
target/arm/cpu-param.h | 4 +-
119
fpu/softfloat.c | 19 ++
73
target/arm/cpu.h | 27 ++++
120
hw/net/imx_fec.c | 146 ++------------
74
target/arm/internals.h | 58 ++++---
121
hw/net/lan9118.c | 137 ++-----------
75
target/arm/kvm-consts.h | 14 +-
122
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
76
hw/arm/boot.c | 11 +-
123
linux-user/arm/nwfpe/fpa11.c | 5 +
77
hw/arm/mps2-tz.c | 6 +-
124
target/alpha/cpu.c | 2 +
78
hw/i2c/i2c_mux_pca954x.c | 77 ++-------
125
target/arm/cpu.c | 10 +
79
hw/input/tsc210x.c | 8 +-
126
target/arm/tcg/vec_helper.c | 20 +-
80
target/arm/cpu.c | 8 +-
127
target/hexagon/cpu.c | 2 +
81
target/arm/cpu64.c | 7 +-
128
target/hppa/fpu_helper.c | 12 ++
82
target/arm/helper.c | 332 ++++++++++++++++++++++++++++++---------
129
target/i386/tcg/fpu_helper.c | 12 ++
83
target/arm/hvf/hvf.c | 27 +++-
130
target/loongarch/tcg/fpu_helper.c | 14 +-
84
target/arm/kvm64.c | 14 +-
131
target/m68k/cpu.c | 14 +-
85
target/arm/psci.c | 35 ++++-
132
target/m68k/fpu_helper.c | 6 +-
86
target/arm/translate-a64.c | 2 +-
133
target/m68k/helper.c | 6 +-
87
tests/qtest/npcm7xx_sdhci-test.c | 215 +++++++++++++++++++++++++
134
target/microblaze/cpu.c | 2 +
88
tests/qtest/meson.build | 1 +
135
target/mips/msa.c | 10 +
89
ui/cocoa.m | 31 ++--
136
target/openrisc/cpu.c | 2 +
90
20 files changed, 736 insertions(+), 192 deletions(-)
137
target/ppc/cpu_init.c | 19 ++
91
create mode 100644 tests/qtest/npcm7xx_sdhci-test.c
138
target/ppc/fpu_helper.c | 3 +-
139
target/riscv/cpu.c | 2 +
140
target/rx/cpu.c | 2 +
141
target/s390x/cpu.c | 5 +
142
target/sh4/cpu.c | 2 +
143
target/sparc/cpu.c | 6 +
144
target/sparc/fop_helper.c | 8 +-
145
target/sparc/translate.c | 4 +-
146
target/tricore/helper.c | 2 +
147
target/xtensa/cpu.c | 4 +
148
target/xtensa/fpu_helper.c | 3 +-
149
tests/fp/fp-bench.c | 7 +
150
tests/fp/fp-test-log2.c | 1 +
151
tests/fp/fp-test.c | 7 +
152
fpu/softfloat-parts.c.inc | 152 +++++++++++---
153
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
154
.mailmap | 5 +-
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: Shengtan Mao <stmao@google.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
3
A very similar implementation of the same device exists in imx_fec. Prepare for
4
Reviewed-by: Chris Rauer <crauer@google.com>
4
a common implementation by extracting a device model into its own files.
5
Signed-off-by: Shengtan Mao <stmao@google.com>
5
6
Signed-off-by: Patrick Venture <venture@google.com>
6
Some migration state has been moved into the new device model which breaks
7
Message-id: 20220225174451.192304-1-wuhaotsh@google.com
7
migration compatibility for the following machines:
8
* smdkc210
9
* realview-*
10
* vexpress-*
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
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
22
---
10
tests/qtest/npcm7xx_sdhci-test.c | 215 +++++++++++++++++++++++++++++++
23
include/hw/net/lan9118_phy.h | 37 ++++++++
11
tests/qtest/meson.build | 1 +
24
hw/net/lan9118.c | 137 +++++-----------------------
12
2 files changed, 216 insertions(+)
25
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
13
create mode 100644 tests/qtest/npcm7xx_sdhci-test.c
26
hw/net/Kconfig | 4 +
27
hw/net/meson.build | 1 +
28
5 files changed, 233 insertions(+), 115 deletions(-)
29
create mode 100644 include/hw/net/lan9118_phy.h
30
create mode 100644 hw/net/lan9118_phy.c
14
31
15
diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c
32
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
16
new file mode 100644
33
new file mode 100644
17
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
18
--- /dev/null
35
--- /dev/null
19
+++ b/tests/qtest/npcm7xx_sdhci-test.c
36
+++ b/include/hw/net/lan9118_phy.h
20
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
21
+/*
38
+/*
22
+ * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller
39
+ * SMSC LAN9118 PHY emulation
23
+ *
40
+ *
24
+ * Copyright (c) 2022 Google LLC
41
+ * Copyright (c) 2009 CodeSourcery, LLC.
42
+ * Written by Paul Brook
25
+ *
43
+ *
26
+ * This program is free software; you can redistribute it and/or modify it
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
27
+ * under the terms of the GNU General Public License as published by the
45
+ * See the COPYING file in the top-level directory.
28
+ * Free Software Foundation; either version 2 of the License, or
46
+ */
29
+ * (at your option) any later version.
47
+
48
+#ifndef HW_NET_LAN9118_PHY_H
49
+#define HW_NET_LAN9118_PHY_H
50
+
51
+#include "qom/object.h"
52
+#include "hw/sysbus.h"
53
+
54
+#define TYPE_LAN9118_PHY "lan9118-phy"
55
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
56
+
57
+typedef struct Lan9118PhyState {
58
+ SysBusDevice parent_obj;
59
+
60
+ uint16_t status;
61
+ uint16_t control;
62
+ uint16_t advertise;
63
+ uint16_t ints;
64
+ uint16_t int_mask;
65
+ qemu_irq irq;
66
+ bool link_down;
67
+} Lan9118PhyState;
68
+
69
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down);
70
+void lan9118_phy_reset(Lan9118PhyState *s);
71
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg);
72
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val);
73
+
74
+#endif
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
312
new file mode 100644
313
index XXXXXXX..XXXXXXX
314
--- /dev/null
315
+++ b/hw/net/lan9118_phy.c
316
@@ -XXX,XX +XXX,XX @@
317
+/*
318
+ * SMSC LAN9118 PHY emulation
30
+ *
319
+ *
31
+ * This program is distributed in the hope that it will be useful, but WITHOUT
320
+ * Copyright (c) 2009 CodeSourcery, LLC.
32
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
321
+ * Written by Paul Brook
33
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
322
+ *
34
+ * for more details.
323
+ * This code is licensed under the GNU GPL v2
324
+ *
325
+ * Contributions after 2012-01-13 are licensed under the terms of the
326
+ * GNU GPL, version 2 or (at your option) any later version.
35
+ */
327
+ */
36
+
328
+
37
+#include "qemu/osdep.h"
329
+#include "qemu/osdep.h"
38
+#include "hw/sd/npcm7xx_sdhci.h"
330
+#include "hw/net/lan9118_phy.h"
39
+
331
+#include "hw/irq.h"
40
+#include "libqos/libqtest.h"
332
+#include "hw/resettable.h"
41
+#include "libqtest-single.h"
333
+#include "migration/vmstate.h"
42
+#include "libqos/sdhci-cmd.h"
334
+#include "qemu/log.h"
43
+
335
+
44
+#define NPCM7XX_REG_SIZE 0x100
336
+#define PHY_INT_ENERGYON (1 << 7)
45
+#define NPCM7XX_MMC_BA 0xF0842000
337
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
46
+#define NPCM7XX_BLK_SIZE 512
338
+#define PHY_INT_FAULT (1 << 5)
47
+#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30)
339
+#define PHY_INT_DOWN (1 << 4)
48
+
340
+#define PHY_INT_AUTONEG_LP (1 << 3)
49
+char *sd_path;
341
+#define PHY_INT_PARFAULT (1 << 2)
50
+
342
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
51
+static QTestState *setup_sd_card(void)
343
+
52
+{
344
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
53
+ QTestState *qts = qtest_initf(
345
+{
54
+ "-machine kudo-bmc "
346
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
55
+ "-device sd-card,drive=drive0 "
347
+}
56
+ "-drive id=drive0,if=none,file=%s,format=raw,auto-read-only=off",
348
+
57
+ sd_path);
349
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
58
+
350
+{
59
+ qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_SWRST, SDHC_RESET_ALL);
351
+ uint16_t val;
60
+ qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_CLKCON,
352
+
61
+ SDHC_CLOCK_SDCLK_EN | SDHC_CLOCK_INT_STABLE |
353
+ switch (reg) {
62
+ SDHC_CLOCK_INT_EN);
354
+ case 0: /* Basic Control */
63
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_APP_CMD);
355
+ return s->control;
64
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x41200000, 0, (41 << 8));
356
+ case 1: /* Basic Status */
65
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_ALL_SEND_CID);
357
+ return s->status;
66
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_SEND_RELATIVE_ADDR);
358
+ case 2: /* ID1 */
67
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x45670000, 0,
359
+ return 0x0007;
68
+ SDHC_SELECT_DESELECT_CARD);
360
+ case 3: /* ID2 */
69
+
361
+ return 0xc0d1;
70
+ return qts;
362
+ case 4: /* Auto-neg advertisement */
71
+}
363
+ return s->advertise;
72
+
364
+ case 5: /* Auto-neg Link Partner Ability */
73
+static void write_sdread(QTestState *qts, const char *msg)
365
+ return 0x0f71;
74
+{
366
+ case 6: /* Auto-neg Expansion */
75
+ int fd, ret;
367
+ return 1;
76
+ size_t len = strlen(msg);
368
+ /* TODO 17, 18, 27, 29, 30, 31 */
77
+ char *rmsg = g_malloc(len);
369
+ case 29: /* Interrupt source. */
78
+
370
+ val = s->ints;
79
+ /* write message to sd */
371
+ s->ints = 0;
80
+ fd = open(sd_path, O_WRONLY);
372
+ lan9118_phy_update_irq(s);
81
+ g_assert(fd >= 0);
373
+ return val;
82
+ ret = write(fd, msg, len);
374
+ case 30: /* Interrupt mask */
83
+ close(fd);
375
+ return s->int_mask;
84
+ g_assert(ret == len);
376
+ default:
85
+
377
+ qemu_log_mask(LOG_GUEST_ERROR,
86
+ /* read message using sdhci */
378
+ "lan9118_phy_read: PHY read reg %d\n", reg);
87
+ ret = sdhci_read_cmd(qts, NPCM7XX_MMC_BA, rmsg, len);
379
+ return 0;
88
+ g_assert(ret == len);
380
+ }
89
+ g_assert(!memcmp(rmsg, msg, len));
381
+}
90
+
382
+
91
+ g_free(rmsg);
383
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
92
+}
384
+{
93
+
385
+ switch (reg) {
94
+/* Check MMC can read values from sd */
386
+ case 0: /* Basic Control */
95
+static void test_read_sd(void)
387
+ if (val & 0x8000) {
96
+{
388
+ lan9118_phy_reset(s);
97
+ QTestState *qts = setup_sd_card();
98
+
99
+ write_sdread(qts, "hello world");
100
+ write_sdread(qts, "goodbye");
101
+
102
+ qtest_quit(qts);
103
+}
104
+
105
+static void sdwrite_read(QTestState *qts, const char *msg)
106
+{
107
+ int fd, ret;
108
+ size_t len = strlen(msg);
109
+ char *rmsg = g_malloc(len);
110
+
111
+ /* write message using sdhci */
112
+ sdhci_write_cmd(qts, NPCM7XX_MMC_BA, msg, len, NPCM7XX_BLK_SIZE);
113
+
114
+ /* read message from sd */
115
+ fd = open(sd_path, O_RDONLY);
116
+ g_assert(fd >= 0);
117
+ ret = read(fd, rmsg, len);
118
+ close(fd);
119
+ g_assert(ret == len);
120
+
121
+ g_assert(!memcmp(rmsg, msg, len));
122
+
123
+ g_free(rmsg);
124
+}
125
+
126
+/* Check MMC can write values to sd */
127
+static void test_write_sd(void)
128
+{
129
+ QTestState *qts = setup_sd_card();
130
+
131
+ sdwrite_read(qts, "hello world");
132
+ sdwrite_read(qts, "goodbye");
133
+
134
+ qtest_quit(qts);
135
+}
136
+
137
+/* Check SDHCI has correct default values. */
138
+static void test_reset(void)
139
+{
140
+ QTestState *qts = qtest_init("-machine kudo-bmc");
141
+ uint64_t addr = NPCM7XX_MMC_BA;
142
+ uint64_t end_addr = addr + NPCM7XX_REG_SIZE;
143
+ uint16_t prstvals_resets[] = {NPCM7XX_PRSTVALS_0_RESET,
144
+ NPCM7XX_PRSTVALS_1_RESET,
145
+ 0,
146
+ NPCM7XX_PRSTVALS_3_RESET,
147
+ 0,
148
+ 0};
149
+ int i;
150
+ uint32_t mask;
151
+
152
+ while (addr < end_addr) {
153
+ switch (addr - NPCM7XX_MMC_BA) {
154
+ case SDHC_PRNSTS:
155
+ /*
156
+ * ignores bits 20 to 24: they are changed when reading registers
157
+ */
158
+ mask = 0x1f00000;
159
+ g_assert_cmphex(qtest_readl(qts, addr) | mask, ==,
160
+ NPCM7XX_PRSNTS_RESET | mask);
161
+ addr += 4;
162
+ break;
389
+ break;
163
+ case SDHC_BLKGAP:
164
+ g_assert_cmphex(qtest_readb(qts, addr), ==, NPCM7XX_BLKGAP_RESET);
165
+ addr += 1;
166
+ break;
167
+ case SDHC_CAPAB:
168
+ g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_CAPAB_RESET);
169
+ addr += 8;
170
+ break;
171
+ case SDHC_MAXCURR:
172
+ g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_MAXCURR_RESET);
173
+ addr += 8;
174
+ break;
175
+ case SDHC_HCVER:
176
+ g_assert_cmphex(qtest_readw(qts, addr), ==, NPCM7XX_HCVER_RESET);
177
+ addr += 2;
178
+ break;
179
+ case NPCM7XX_PRSTVALS:
180
+ for (i = 0; i < NPCM7XX_PRSTVALS_SIZE; ++i) {
181
+ g_assert_cmphex(qtest_readw(qts, addr + 2 * i), ==,
182
+ prstvals_resets[i]);
183
+ }
184
+ addr += NPCM7XX_PRSTVALS_SIZE * 2;
185
+ break;
186
+ default:
187
+ g_assert_cmphex(qtest_readb(qts, addr), ==, 0);
188
+ addr += 1;
189
+ }
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);
190
+ }
408
+ }
191
+
409
+}
192
+ qtest_quit(qts);
410
+
193
+}
411
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
194
+
412
+{
195
+static void drive_destroy(void)
413
+ s->link_down = link_down;
196
+{
414
+
197
+ unlink(sd_path);
415
+ /* Autonegotiation status mirrors link status. */
198
+ g_free(sd_path);
416
+ if (link_down) {
199
+}
417
+ s->status &= ~0x0024;
200
+
418
+ s->ints |= PHY_INT_DOWN;
201
+static void drive_create(void)
419
+ } else {
202
+{
420
+ s->status |= 0x0024;
203
+ int fd, ret;
421
+ s->ints |= PHY_INT_ENERGYON;
204
+ GError *error = NULL;
422
+ s->ints |= PHY_INT_AUTONEG_COMPLETE;
205
+
206
+ /* Create a temporary raw image */
207
+ fd = g_file_open_tmp("sdhci_XXXXXX", &sd_path, &error);
208
+ if (fd == -1) {
209
+ fprintf(stderr, "unable to create sdhci file: %s\n", error->message);
210
+ g_error_free(error);
211
+ }
423
+ }
212
+ g_assert(sd_path != NULL);
424
+ lan9118_phy_update_irq(s);
213
+
425
+}
214
+ ret = ftruncate(fd, NPCM7XX_TEST_IMAGE_SIZE);
426
+
215
+ g_assert_cmpint(ret, ==, 0);
427
+void lan9118_phy_reset(Lan9118PhyState *s)
216
+ g_message("%s", sd_path);
428
+{
217
+ close(fd);
429
+ s->control = 0x3000;
218
+}
430
+ s->status = 0x7809;
219
+
431
+ s->advertise = 0x01e1;
220
+int main(int argc, char **argv)
432
+ s->int_mask = 0;
221
+{
433
+ s->ints = 0;
222
+ int ret;
434
+ lan9118_phy_update_link(s, s->link_down);
223
+
435
+}
224
+ drive_create();
436
+
225
+
437
+static void lan9118_phy_reset_hold(Object *obj, ResetType type)
226
+ g_test_init(&argc, &argv, NULL);
438
+{
227
+
439
+ Lan9118PhyState *s = LAN9118_PHY(obj);
228
+ qtest_add_func("npcm7xx_sdhci/reset", test_reset);
440
+
229
+ qtest_add_func("npcm7xx_sdhci/write_sd", test_write_sd);
441
+ lan9118_phy_reset(s);
230
+ qtest_add_func("npcm7xx_sdhci/read_sd", test_read_sd);
442
+}
231
+
443
+
232
+ ret = g_test_run();
444
+static void lan9118_phy_init(Object *obj)
233
+ drive_destroy();
445
+{
234
+ return ret;
446
+ Lan9118PhyState *s = LAN9118_PHY(obj);
235
+}
447
+
236
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
448
+ qdev_init_gpio_out(DEVICE(s), &s->irq, 1);
449
+}
450
+
451
+static const VMStateDescription vmstate_lan9118_phy = {
452
+ .name = "lan9118-phy",
453
+ .version_id = 1,
454
+ .minimum_version_id = 1,
455
+ .fields = (const VMStateField[]) {
456
+ VMSTATE_UINT16(control, Lan9118PhyState),
457
+ VMSTATE_UINT16(status, Lan9118PhyState),
458
+ VMSTATE_UINT16(advertise, Lan9118PhyState),
459
+ VMSTATE_UINT16(ints, Lan9118PhyState),
460
+ VMSTATE_UINT16(int_mask, Lan9118PhyState),
461
+ VMSTATE_BOOL(link_down, Lan9118PhyState),
462
+ VMSTATE_END_OF_LIST()
463
+ }
464
+};
465
+
466
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
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
237
index XXXXXXX..XXXXXXX 100644
487
index XXXXXXX..XXXXXXX 100644
238
--- a/tests/qtest/meson.build
488
--- a/hw/net/Kconfig
239
+++ b/tests/qtest/meson.build
489
+++ b/hw/net/Kconfig
240
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
490
@@ -XXX,XX +XXX,XX @@ config VMXNET3_PCI
241
'npcm7xx_gpio-test',
491
config SMC91C111
242
'npcm7xx_pwm-test',
492
bool
243
'npcm7xx_rng-test',
493
244
+ 'npcm7xx_sdhci-test',
494
+config LAN9118_PHY
245
'npcm7xx_smbus-test',
495
+ bool
246
'npcm7xx_timer-test',
496
+
247
'npcm7xx_watchdog_timer-test'] + \
497
config LAN9118
498
bool
499
+ select LAN9118_PHY
500
select PTIMER
501
502
config NE2000_ISA
503
diff --git a/hw/net/meson.build b/hw/net/meson.build
504
index XXXXXXX..XXXXXXX 100644
505
--- a/hw/net/meson.build
506
+++ b/hw/net/meson.build
507
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('vmxnet3.c'))
508
509
system_ss.add(when: 'CONFIG_SMC91C111', if_true: files('smc91c111.c'))
510
system_ss.add(when: 'CONFIG_LAN9118', if_true: files('lan9118.c'))
511
+system_ss.add(when: 'CONFIG_LAN9118_PHY', if_true: files('lan9118_phy.c'))
512
system_ss.add(when: 'CONFIG_NE2000_ISA', if_true: files('ne2000-isa.c'))
513
system_ss.add(when: 'CONFIG_OPENCORES_ETH', if_true: files('opencores_eth.c'))
514
system_ss.add(when: 'CONFIG_XGMAC', if_true: files('xgmac.c'))
248
--
515
--
249
2.25.1
516
2.34.1
diff view generated by jsdifflib
New patch
1
From: Bernhard Beschow <shentey@gmail.com>
1
2
3
imx_fec models the same PHY as lan9118_phy. The code is almost the same with
4
imx_fec having more logging and tracing. Merge these improvements into
5
lan9118_phy and reuse in imx_fec to fix the code duplication.
6
7
Some migration state how resides in the new device model which breaks migration
8
compatibility for the following machines:
9
* imx25-pdk
10
* sabrelite
11
* mcimx7d-sabre
12
* mcimx6ul-evk
13
14
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
15
Tested-by: Guenter Roeck <linux@roeck-us.net>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20241102125724.532843-3-shentey@gmail.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
include/hw/net/imx_fec.h | 9 ++-
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(-)
26
27
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/include/hw/net/imx_fec.h
30
+++ b/include/hw/net/imx_fec.h
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
32
#define TYPE_IMX_ENET "imx.enet"
33
34
#include "hw/sysbus.h"
35
+#include "hw/net/lan9118_phy.h"
36
+#include "hw/irq.h"
37
#include "net/net.h"
38
39
#define ENET_EIR 1
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
},
80
};
81
82
-#define PHY_INT_ENERGYON (1 << 7)
83
-#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
84
-#define PHY_INT_FAULT (1 << 5)
85
-#define PHY_INT_DOWN (1 << 4)
86
-#define PHY_INT_AUTONEG_LP (1 << 3)
87
-#define PHY_INT_PARFAULT (1 << 2)
88
-#define PHY_INT_AUTONEG_PAGE (1 << 1)
89
-
90
static void imx_eth_update(IMXFECState *s);
91
92
/*
93
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s);
94
* For now we don't handle any GPIO/interrupt line, so the OS will
95
* have to poll for the PHY status.
96
*/
97
-static void imx_phy_update_irq(IMXFECState *s)
98
+static void imx_phy_update_irq(void *opaque, int n, int level)
99
{
100
- imx_eth_update(s);
101
-}
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;
260
+ }
261
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
262
+
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"
471
--
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
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
This feature widens physical addresses (and intermediate physical
3
Prefer named constants over magic values for better readability.
4
addresses for 2-stage translation) from 48 to 52 bits, when using
5
64k pages. The only thing left at this point is to handle the
6
extra bits in the TTBR and in the table descriptors.
7
8
Note that PAR_EL1 and HPFAR_EL2 are nominally extended, but we don't
9
mask out the high bits when writing to those registers, so no changes
10
are required there.
11
4
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
14
Message-id: 20220301215958.157011-11-richard.henderson@linaro.org
7
Tested-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20241102125724.532843-5-shentey@gmail.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
docs/system/arm/emulation.rst | 1 +
11
include/hw/net/mii.h | 6 +++++
18
target/arm/cpu-param.h | 2 +-
12
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
19
target/arm/cpu64.c | 2 +-
13
2 files changed, 46 insertions(+), 23 deletions(-)
20
target/arm/helper.c | 19 ++++++++++++++++---
21
4 files changed, 19 insertions(+), 5 deletions(-)
22
14
23
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
15
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/docs/system/arm/emulation.rst
17
--- a/include/hw/net/mii.h
26
+++ b/docs/system/arm/emulation.rst
18
+++ b/include/hw/net/mii.h
27
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
19
@@ -XXX,XX +XXX,XX @@
28
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
20
#define MII_BMSR_JABBER (1 << 1) /* Jabber detected */
29
- FEAT_JSCVT (JavaScript conversion instructions)
21
#define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */
30
- FEAT_LOR (Limited ordering regions)
22
31
+- FEAT_LPA (Large Physical Address space)
23
+#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */
32
- FEAT_LRCPC (Load-acquire RCpc instructions)
24
#define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */
33
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
25
#define MII_ANAR_PAUSE (1 << 10) /* Try for pause */
34
- FEAT_LSE (Large System Extensions)
26
#define MII_ANAR_TXFD (1 << 8)
35
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
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
36
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu-param.h
48
--- a/hw/net/lan9118_phy.c
38
+++ b/target/arm/cpu-param.h
49
+++ b/hw/net/lan9118_phy.c
39
@@ -XXX,XX +XXX,XX @@
50
@@ -XXX,XX +XXX,XX @@
40
51
41
#ifdef TARGET_AARCH64
52
#include "qemu/osdep.h"
42
# define TARGET_LONG_BITS 64
53
#include "hw/net/lan9118_phy.h"
43
-# define TARGET_PHYS_ADDR_SPACE_BITS 48
54
+#include "hw/net/mii.h"
44
+# define TARGET_PHYS_ADDR_SPACE_BITS 52
55
#include "hw/irq.h"
45
# define TARGET_VIRT_ADDR_SPACE_BITS 52
56
#include "hw/resettable.h"
46
#else
57
#include "migration/vmstate.h"
47
# define TARGET_LONG_BITS 32
58
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
48
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
59
uint16_t val;
49
index XXXXXXX..XXXXXXX 100644
60
50
--- a/target/arm/cpu64.c
61
switch (reg) {
51
+++ b/target/arm/cpu64.c
62
- case 0: /* Basic Control */
52
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
63
+ case MII_BMCR:
53
cpu->isar.id_aa64pfr1 = t;
64
val = s->control;
54
65
break;
55
t = cpu->isar.id_aa64mmfr0;
66
- case 1: /* Basic Status */
56
- t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 5); /* PARange: 48 bits */
67
+ case MII_BMSR:
57
+ t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
68
val = s->status;
58
cpu->isar.id_aa64mmfr0 = t;
69
break;
59
70
- case 2: /* ID1 */
60
t = cpu->isar.id_aa64mmfr1;
71
- val = 0x0007;
61
diff --git a/target/arm/helper.c b/target/arm/helper.c
72
+ case MII_PHYID1:
62
index XXXXXXX..XXXXXXX 100644
73
+ val = SMSCLAN9118_PHYID1;
63
--- a/target/arm/helper.c
74
break;
64
+++ b/target/arm/helper.c
75
- case 3: /* ID2 */
65
@@ -XXX,XX +XXX,XX @@ static const uint8_t pamax_map[] = {
76
- val = 0xc0d1;
66
[3] = 42,
77
+ case MII_PHYID2:
67
[4] = 44,
78
+ val = SMSCLAN9118_PHYID2;
68
[5] = 48,
79
break;
69
+ [6] = 52,
80
- case 4: /* Auto-neg advertisement */
70
};
81
+ case MII_ANAR:
71
82
val = s->advertise;
72
/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
83
break;
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
84
- case 5: /* Auto-neg Link Partner Ability */
74
descaddr = extract64(ttbr, 0, 48);
85
- val = 0x0fe1;
75
86
+ case MII_ANLPAR:
76
/*
87
+ val = MII_ANLPAR_PAUSEASY | MII_ANLPAR_PAUSE | MII_ANLPAR_T4 |
77
- * If the base address is out of range, raise AddressSizeFault.
88
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
78
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [5:2] of TTBR.
89
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
79
+ *
90
break;
80
+ * Otherwise, if the base address is out of range, raise AddressSizeFault.
91
- case 6: /* Auto-neg Expansion */
81
* In the pseudocode, this is !IsZero(baseregister<47:outputsize>),
92
- val = 1;
82
* but we've just cleared the bits above 47, so simplify the test.
93
+ case MII_ANER:
83
*/
94
+ val = MII_ANER_NWAY;
84
- if (descaddr >> outputsize) {
95
break;
85
+ if (outputsize > 48) {
96
case 29: /* Interrupt source. */
86
+ descaddr |= extract64(ttbr, 2, 4) << 48;
97
val = s->ints;
87
+ } else if (descaddr >> outputsize) {
98
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
88
level = 0;
99
trace_lan9118_phy_write(val, reg);
89
fault_type = ARMFault_AddressSize;
100
90
goto do_fault;
101
switch (reg) {
91
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
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
}
92
}
118
}
93
119
break;
94
descaddr = descriptor & descaddrmask;
120
- case 4: /* Auto-neg advertisement */
95
- if (descaddr >> outputsize) {
121
- s->advertise = (val & 0x2d7f) | 0x80;
96
+
122
+ case MII_ANAR:
97
+ /*
123
+ s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
98
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
124
+ MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
99
+ * of descriptor. Otherwise, if descaddr is out of range, raise
125
+ MII_ANAR_SELECT))
100
+ * AddressSizeFault.
126
+ | MII_ANAR_TX;
101
+ */
127
break;
102
+ if (outputsize > 48) {
128
case 30: /* Interrupt mask */
103
+ descaddr |= extract64(descriptor, 12, 4) << 48;
129
s->int_mask = val & 0xff;
104
+ } else if (descaddr >> outputsize) {
130
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
105
fault_type = ARMFault_AddressSize;
131
/* Autonegotiation status mirrors link status. */
106
goto do_fault;
132
if (link_down) {
107
}
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);
108
--
166
--
109
2.25.1
167
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
For FEAT_LPA2, we will need other ARMVAParameters, which themselves
3
The real device advertises this mode and the device model already advertises
4
depend on the translation granule in use. We might as well validate
4
100 mbps half duplex and 10 mbps full+half duplex. So advertise this mode to
5
that the given TG matches; the architecture "does not require that
5
make the model more realistic.
6
the instruction invalidates any entries" if this is not true.
7
6
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
10
Message-id: 20220301215958.157011-15-richard.henderson@linaro.org
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>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
target/arm/helper.c | 10 +++++++---
13
hw/net/lan9118_phy.c | 4 ++--
14
1 file changed, 7 insertions(+), 3 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
15
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
18
--- a/hw/net/lan9118_phy.c
19
+++ b/target/arm/helper.c
19
+++ b/hw/net/lan9118_phy.c
20
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
20
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
21
uint64_t value)
21
break;
22
{
22
case MII_ANAR:
23
unsigned int page_size_granule, page_shift, num, scale, exponent;
23
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
24
+ /* Extract one bit to represent the va selector in use. */
24
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
25
+ uint64_t select = sextract64(value, 36, 1);
25
- MII_ANAR_SELECT))
26
+ ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
26
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
27
TLBIRange ret = { };
27
+ MII_ANAR_10 | MII_ANAR_SELECT))
28
28
| MII_ANAR_TX;
29
page_size_granule = extract64(value, 46, 2);
29
break;
30
30
case 30: /* Interrupt mask */
31
- if (page_size_granule == 0) {
32
- qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
33
+ /* The granule encoded in value must match the granule in use. */
34
+ if (page_size_granule != (param.using64k ? 3 : param.using16k ? 2 : 1)) {
35
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
36
page_size_granule);
37
return ret;
38
}
39
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
40
41
ret.length = (num + 1) << (exponent + page_shift);
42
43
- if (regime_has_2_ranges(mmuidx)) {
44
+ if (param.select) {
45
ret.base = sextract64(value, 0, 37);
46
} else {
47
ret.base = extract64(value, 0, 37);
48
--
31
--
49
2.25.1
32
2.34.1
diff view generated by jsdifflib
New patch
1
For IEEE fused multiply-add, the (0 * inf) + NaN case should raise
2
Invalid for the multiplication of 0 by infinity. Currently we handle
3
this in the per-architecture ifdef ladder in pickNaNMulAdd().
4
However, since this isn't really architecture specific we can hoist
5
it up to the generic code.
1
6
7
For the cases where the infzero test in pickNaNMulAdd was
8
returning 2, we can delete the check entirely and allow the
9
code to fall into the normal pick-a-NaN handling, because this
10
will return 2 anyway (input 'c' being the only NaN in this case).
11
For the cases where infzero was returning 3 to indicate "return
12
the default NaN", we must retain that "return 3".
13
14
For Arm, this looks like it might be a behaviour change because we
15
used to set float_flag_invalid | float_flag_invalid_imz only if C is
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.
33
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
36
Message-id: 20241202131347.498124-2-peter.maydell@linaro.org
37
---
38
fpu/softfloat-parts.c.inc | 13 +++++++------
39
fpu/softfloat-specialize.c.inc | 29 +----------------------------
40
2 files changed, 8 insertions(+), 34 deletions(-)
41
42
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
43
index XXXXXXX..XXXXXXX 100644
44
--- a/fpu/softfloat-parts.c.inc
45
+++ b/fpu/softfloat-parts.c.inc
46
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
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);
54
}
55
56
- which = pickNaNMulAdd(a->cls, b->cls, c->cls,
57
- ab_mask == float_cmask_infzero, s);
58
+ if (infzero) {
59
+ /* This is (0 * inf) + NaN or (inf * 0) + NaN */
60
+ float_raise(float_flag_invalid | float_flag_invalid_imz, s);
61
+ }
62
+
63
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
64
65
if (s->default_nan_mode || which == 3) {
66
- /*
67
- * Note that this check is after pickNaNMulAdd so that function
68
- * has an opportunity to set the Invalid flag for infzero.
69
- */
70
parts_default_nan(a, s);
71
return a;
72
}
73
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
74
index XXXXXXX..XXXXXXX 100644
75
--- a/fpu/softfloat-specialize.c.inc
76
+++ b/fpu/softfloat-specialize.c.inc
77
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
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;
111
- }
112
+
113
/* Prefer sNaN over qNaN, in the c, a, b order. */
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;
165
--
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
The updateUIInfo method makes Cocoa API calls. It also calls back
1
IEEE 758 does not define a fixed rule for what NaN to return in
2
into QEMU functions like dpy_set_ui_info(). To do this safely, we
2
the case of a fused multiply-add of inf * 0 + NaN. Different
3
need to follow two rules:
3
architectures thus do different things:
4
* Cocoa API calls are made on the Cocoa UI thread
4
* some return the default NaN
5
* When calling back into QEMU we must hold the iothread lock
5
* some return the input NaN
6
6
* Arm returns the default NaN if the input NaN is quiet,
7
Fix the places where we got this wrong, by taking the iothread lock
7
and the input NaN if it is signalling
8
while executing updateUIInfo, and moving the call in cocoa_switch()
8
9
inside the dispatch_async block.
9
We want to make this logic be runtime selected rather than
10
10
hardcoded into the binary, because:
11
Some of the Cocoa UI methods which call updateUIInfo are invoked as
11
* this will let us have multiple targets in one QEMU binary
12
part of the initial application startup, while we're still doing the
12
* the Arm FEAT_AFP architectural feature includes letting
13
little cross-thread dance described in the comment just above
13
the guest select a NaN propagation rule at runtime
14
call_qemu_main(). This meant they were calling back into the QEMU UI
14
15
layer before we'd actually finished initializing our display and
15
In this commit we add an enum for the propagation rule, the field in
16
registered the DisplayChangeListener, which isn't really valid. Once
16
float_status, and the corresponding getters and setters. We change
17
updateUIInfo takes the iothread lock, we no longer get away with
17
pickNaNMulAdd to honour this, but because all targets still leave
18
this, because during this startup phase the iothread lock is held by
18
this field at its default 0 value, the fallback logic will pick the
19
the QEMU main-loop thread which is waiting for us to finish our
19
rule type with the old ifdef ladder.
20
display initialization. So we must suppress updateUIInfo until
20
21
applicationDidFinishLaunching allows the QEMU main-loop thread to
21
Note that four architectures both use the muladd softfloat functions
22
continue.
22
and did not have a branch of the ifdef ladder to specify their
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.
23
29
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
32
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
27
Message-id: 20220224101330.967429-2-peter.maydell@linaro.org
28
---
33
---
29
ui/cocoa.m | 25 ++++++++++++++++++++++---
34
include/fpu/softfloat-helpers.h | 11 ++++
30
1 file changed, 22 insertions(+), 3 deletions(-)
35
include/fpu/softfloat-types.h | 23 +++++++++
31
36
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
32
diff --git a/ui/cocoa.m b/ui/cocoa.m
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/ui/cocoa.m
41
--- a/include/fpu/softfloat-helpers.h
35
+++ b/ui/cocoa.m
42
+++ b/include/fpu/softfloat-helpers.h
36
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
43
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
37
}
44
status->float_2nan_prop_rule = rule;
38
}
45
}
39
46
40
-- (void) updateUIInfo
47
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
41
+- (void) updateUIInfoLocked
48
+ float_status *status)
49
+{
50
+ status->float_infzeronan_rule = rule;
51
+}
52
+
53
static inline void set_flush_to_zero(bool val, float_status *status)
42
{
54
{
43
+ /* Must be called with the iothread lock, i.e. via updateUIInfo */
55
status->flush_to_zero = val;
44
NSSize frameSize;
56
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
45
QemuUIInfo info;
57
return status->float_2nan_prop_rule;
46
47
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
48
dpy_set_ui_info(dcl.con, &info, TRUE);
49
}
58
}
50
59
51
+- (void) updateUIInfo
60
+static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
52
+{
61
+{
53
+ if (!allow_events) {
62
+ return status->float_infzeronan_rule;
54
+ /*
63
+}
55
+ * Don't try to tell QEMU about UI information in the application
64
+
56
+ * startup phase -- we haven't yet registered dcl with the QEMU UI
65
static inline bool get_flush_to_zero(float_status *status)
57
+ * layer, and also trying to take the iothread lock would deadlock.
66
{
58
+ * When cocoa_display_init() does register the dcl, the UI layer
67
return status->flush_to_zero;
59
+ * will call cocoa_switch(), which will call updateUIInfo, so
68
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
60
+ * we don't lose any information here.
69
index XXXXXXX..XXXXXXX 100644
61
+ */
70
--- a/include/fpu/softfloat-types.h
62
+ return;
71
+++ b/include/fpu/softfloat-types.h
72
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
73
float_2nan_prop_x87,
74
} Float2NaNPropRule;
75
76
+/*
77
+ * Rule for result of fused multiply-add 0 * Inf + NaN.
78
+ * This must be a NaN, but implementations differ on whether this
79
+ * is the input NaN or the default NaN.
80
+ *
81
+ * You don't need to set this if default_nan_mode is enabled.
82
+ * When not in default-NaN mode, it is an error for the target
83
+ * not to set the rule in float_status if it uses muladd, and we
84
+ * will assert if we need to handle an input NaN and no rule was
85
+ * selected.
86
+ */
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;
155
+ }
156
+#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
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();
188
+ }
63
+ }
189
+ }
64
+
190
+
65
+ with_iothread_lock(^{
191
+#if defined(TARGET_ARM)
66
+ [self updateUIInfoLocked];
192
+
67
+ });
193
/* This looks different from the ARM ARM pseudocode, because the ARM ARM
68
+}
194
* puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
69
+
195
*/
70
- (void)viewDidMoveToWindow
196
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
71
{
197
}
72
[self updateUIInfo];
198
#elif defined(TARGET_MIPS)
73
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
199
if (snan_bit_is_one(status)) {
74
200
- /*
75
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
201
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
76
202
- * case sets InvalidOp and returns the default NaN
77
- [cocoaView updateUIInfo];
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
- */
78
-
229
-
79
// The DisplaySurface will be freed as soon as this callback returns.
230
/* Prefer sNaN over qNaN, in the c, a, b order. */
80
// We take a reference to the underlying pixman image here so it does
231
if (is_snan(c_cls)) {
81
// not disappear from under our feet; the switchSurface method will
232
return 2;
82
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
233
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
83
pixman_image_ref(image);
234
return 1;
84
235
}
85
dispatch_async(dispatch_get_main_queue(), ^{
236
#elif defined(TARGET_PPC)
86
+ [cocoaView updateUIInfo];
237
- /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
87
[cocoaView switchSurface:image];
238
- * to return an input NaN if we have one (ie c) rather than generating
88
});
239
- * a default NaN
89
[pool release];
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)) {
90
--
256
--
91
2.25.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
New patch
1
Set the FloatInfZeroNaNRule explicitly for the Arm 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-6-peter.maydell@linaro.org
7
---
8
target/arm/cpu.c | 3 +++
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 4 insertions(+), 7 deletions(-)
11
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
17
* * tininess-before-rounding
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
20
+ * * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
21
+ * and the input NaN if it is signalling
22
*/
23
static void arm_set_default_fp_behaviours(float_status *s)
24
{
25
set_float_detect_tininess(float_tininess_before_rounding, s);
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
28
}
29
30
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
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
/*
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)
50
--
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
New patch
1
Set the FloatInfZeroNaNRule explicitly for the MIPS 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-9-peter.maydell@linaro.org
7
---
8
target/mips/fpu_helper.h | 9 +++++++++
9
target/mips/msa.c | 4 ++++
10
fpu/softfloat-specialize.c.inc | 16 +---------------
11
3 files changed, 14 insertions(+), 15 deletions(-)
12
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/mips/fpu_helper.h
16
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_flush_mode(CPUMIPSState *env)
18
static inline void restore_snan_bit_mode(CPUMIPSState *env)
19
{
20
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
21
+ FloatInfZeroNaNRule izn_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
set_snan_bit_is_one(!nan2008, &env->active_fpu.fp_status);
28
set_default_nan_mode(!nan2008, &env->active_fpu.fp_status);
29
+ /*
30
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
31
+ * case sets InvalidOp and returns the default NaN.
32
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
33
+ * case sets InvalidOp and returns the input value 'c'.
34
+ */
35
+ izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
36
+ set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
37
}
38
39
static inline void restore_fp_status(CPUMIPSState *env)
40
diff --git a/target/mips/msa.c b/target/mips/msa.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/mips/msa.c
43
+++ b/target/mips/msa.c
44
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
45
46
/* set proper signanling bit meaning ("1" means "quiet") */
47
set_snan_bit_is_one(0, &env->active_tc.msa_fp_status);
48
+
49
+ /* Inf * 0 + NaN returns the input NaN */
50
+ set_float_infzeronan_rule(float_infzeronan_dnan_never,
51
+ &env->active_tc.msa_fp_status);
52
}
53
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
54
index XXXXXXX..XXXXXXX 100644
55
--- a/fpu/softfloat-specialize.c.inc
56
+++ b/fpu/softfloat-specialize.c.inc
57
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
58
/*
59
* Temporarily fall back to ifdef ladder
60
*/
61
-#if defined(TARGET_MIPS)
62
- if (snan_bit_is_one(status)) {
63
- /*
64
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
65
- * case sets InvalidOp and returns the default NaN
66
- */
67
- rule = float_infzeronan_dnan_always;
68
- } else {
69
- /*
70
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
71
- * case sets InvalidOp and returns the input value 'c'
72
- */
73
- rule = float_infzeronan_dnan_never;
74
- }
75
-#elif defined(TARGET_SPARC) || \
76
+#if defined(TARGET_SPARC) || \
77
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
78
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
79
/*
80
--
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
When we're using KVM, the PSCI implementation is provided by the
1
IEEE 758 does not define a fixed rule for which NaN to pick as the
2
kernel, but QEMU has to tell the guest about it via the device tree.
2
result if both operands of a 3-operand fused multiply-add operation
3
Currently we look at the KVM_CAP_ARM_PSCI_0_2 capability to determine
3
are NaNs. As a result different architectures have ended up with
4
if the kernel is providing at least PSCI 0.2, but if the kernel
4
different rules for propagating NaNs.
5
provides a newer version than that we will still only tell the guest
5
6
it has PSCI 0.2. (This is fairly harmless; it just means the guest
6
QEMU currently hardcodes the NaN propagation logic into the binary
7
won't use newer parts of the PSCI API.)
7
because pickNaNMulAdd() has an ifdef ladder for different targets.
8
8
We want to make the propagation rule instead be selectable at
9
The kernel exposes the specific PSCI version it is implementing via
9
runtime, because:
10
the ONE_REG API; use this to report in the dtb that the PSCI
10
* this will let us have multiple targets in one QEMU binary
11
implementation is 1.0-compatible if appropriate. (The device tree
11
* the Arm FEAT_AFP architectural feature includes letting
12
binding currently only distinguishes "pre-0.2", "0.2-compatible" and
12
the guest select a NaN propagation rule at runtime
13
"1.0-compatible".)
13
14
In this commit we add an enum for the propagation rule, the field in
15
float_status, and the corresponding getters and setters. We change
16
pickNaNMulAdd to honour this, but because all targets still leave
17
this field at its default 0 value, the fallback logic will pick the
18
rule type with the old ifdef ladder.
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.
14
23
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Marc Zyngier <maz@kernel.org>
17
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Andrew Jones <drjones@redhat.com>
26
Message-id: 20241202131347.498124-16-peter.maydell@linaro.org
20
Message-id: 20220224134655.1207865-1-peter.maydell@linaro.org
21
---
27
---
22
target/arm/kvm-consts.h | 1 +
28
include/fpu/softfloat-helpers.h | 11 +++
23
hw/arm/boot.c | 5 ++---
29
include/fpu/softfloat-types.h | 55 +++++++++++
24
target/arm/kvm64.c | 12 ++++++++++++
30
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
25
3 files changed, 15 insertions(+), 3 deletions(-)
31
3 files changed, 107 insertions(+), 126 deletions(-)
26
32
27
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
33
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
28
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/kvm-consts.h
35
--- a/include/fpu/softfloat-helpers.h
30
+++ b/target/arm/kvm-consts.h
36
+++ b/include/fpu/softfloat-helpers.h
31
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
37
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
32
38
status->float_2nan_prop_rule = rule;
33
#define QEMU_PSCI_VERSION_0_1 0x00001
39
}
34
#define QEMU_PSCI_VERSION_0_2 0x00002
40
35
+#define QEMU_PSCI_VERSION_1_0 0x10000
41
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
36
#define QEMU_PSCI_VERSION_1_1 0x10001
42
+ float_status *status)
37
43
+{
38
MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
44
+ status->float_3nan_prop_rule = rule;
39
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
45
+}
46
+
47
static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
float_status *status)
49
{
50
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
51
return status->float_2nan_prop_rule;
52
}
53
54
+static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
55
+{
56
+ return status->float_3nan_prop_rule;
57
+}
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
40
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/arm/boot.c
64
--- a/include/fpu/softfloat-types.h
42
+++ b/hw/arm/boot.c
65
+++ b/include/fpu/softfloat-types.h
43
@@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt)
66
@@ -XXX,XX +XXX,XX @@ this code that are retained.
44
}
67
#ifndef SOFTFLOAT_TYPES_H
45
68
#define SOFTFLOAT_TYPES_H
46
qemu_fdt_add_subnode(fdt, "/psci");
69
47
- if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
70
+#include "hw/registerfields.h"
48
- armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
71
+
49
- if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
72
/*
50
+ if (armcpu->psci_version >= QEMU_PSCI_VERSION_0_2) {
73
* Software IEC/IEEE floating-point types.
51
+ if (armcpu->psci_version < QEMU_PSCI_VERSION_1_0) {
74
*/
52
const char comp[] = "arm,psci-0.2\0arm,psci";
75
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
53
qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
76
float_2nan_prop_x87,
54
} else {
77
} Float2NaNPropRule;
55
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
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
56
index XXXXXXX..XXXXXXX 100644
143
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/kvm64.c
144
--- a/fpu/softfloat-specialize.c.inc
58
+++ b/target/arm/kvm64.c
145
+++ b/fpu/softfloat-specialize.c.inc
59
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
146
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
60
uint64_t mpidr;
147
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
61
ARMCPU *cpu = ARM_CPU(cs);
148
bool infzero, bool have_snan, float_status *status)
62
CPUARMState *env = &cpu->env;
149
{
63
+ uint64_t psciver;
150
+ FloatClass cls[3] = { a_cls, b_cls, c_cls };
64
151
+ Float3NaNPropRule rule = status->float_3nan_prop_rule;
65
if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
152
+ int which;
66
!object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) {
153
+
67
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
154
/*
155
* We guarantee not to require the target to tell us how to
156
* pick a NaN if we're always returning the default NaN.
157
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
68
}
158
}
69
}
159
}
70
160
71
+ /*
161
+ if (rule == float_3nan_prop_none) {
72
+ * KVM reports the exact PSCI version it is implementing via a
162
#if defined(TARGET_ARM)
73
+ * special sysreg. If it is present, use its contents to determine
163
-
74
+ * what to report to the guest in the dtb (it is the PSCI version,
164
- /* This looks different from the ARM ARM pseudocode, because the ARM ARM
75
+ * in the same 15-bits major 16-bits minor format that PSCI_VERSION
165
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
76
+ * returns).
166
- */
77
+ */
167
- if (is_snan(c_cls)) {
78
+ if (!kvm_get_one_reg(cs, KVM_REG_ARM_PSCI_VERSION, &psciver)) {
168
- return 2;
79
+ cpu->psci_version = psciver;
169
- } else if (is_snan(a_cls)) {
170
- return 0;
171
- } else if (is_snan(b_cls)) {
172
- return 1;
173
- } else if (is_qnan(c_cls)) {
174
- return 2;
175
- } else if (is_qnan(a_cls)) {
176
- return 0;
177
- } else {
178
- return 1;
179
- }
180
+ /*
181
+ * This looks different from the ARM ARM pseudocode, because the ARM ARM
182
+ * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
183
+ */
184
+ rule = float_3nan_prop_s_cab;
185
#elif defined(TARGET_MIPS)
186
- if (snan_bit_is_one(status)) {
187
- /* Prefer sNaN over qNaN, in the a, b, c order. */
188
- if (is_snan(a_cls)) {
189
- return 0;
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
80
+ }
321
+ }
81
+
322
+
82
/*
323
+ assert(rule != float_3nan_prop_none);
83
* When KVM is in use, PSCI is emulated in-kernel and not by qemu.
324
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
84
* Currently KVM has its own idea about MPIDR assignment, so we
325
+ /* We have at least one SNaN input and should prefer it */
326
+ do {
327
+ which = rule & R_3NAN_1ST_MASK;
328
+ rule >>= R_3NAN_1ST_LENGTH;
329
+ } while (!is_snan(cls[which]));
330
+ } else {
331
+ do {
332
+ which = rule & R_3NAN_1ST_MASK;
333
+ rule >>= R_3NAN_1ST_LENGTH;
334
+ } while (!is_nan(cls[which]));
335
+ }
336
+ return which;
337
}
338
339
/*----------------------------------------------------------------------------
85
--
340
--
86
2.25.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
From: Richard Henderson <richard.henderson@linaro.org>
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
ifdef from pickNaNMulAdd().
2
3
3
Set this as the kernel would, to 48 bits, to keep the computation
4
of the address space correct for PAuth.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220301215958.157011-3-richard.henderson@linaro.org
9
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>
6
Message-id: 20241202131347.498124-18-peter.maydell@linaro.org
10
---
7
---
11
target/arm/cpu.c | 3 ++-
8
target/arm/cpu.c | 5 +++++
12
1 file changed, 2 insertions(+), 1 deletion(-)
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 6 insertions(+), 7 deletions(-)
13
11
14
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
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
14
--- a/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
19
aarch64_sve_zcr_get_valid_len(cpu, cpu->sve_default_vq - 1);
17
* * tininess-before-rounding
20
}
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
21
/*
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
22
+ * Enable 48-bit address space (TODO: take reserved_va into account).
20
+ * * 3-input NaN propagation prefers SNaN over QNaN, and then
23
* Enable TBI0 but not TBI1.
21
+ * operand C over A over B (see FPProcessNaNs3() pseudocode,
24
* Note that this must match useronly_clean_ptr.
22
+ * but note that for QEMU muladd is a * b + c, whereas for
25
*/
23
+ * the pseudocode function the arguments are in the order c, a, b.
26
- env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
24
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
27
+ env->cp15.tcr_el[1].raw_tcr = 5 | (1ULL << 37);
25
* and the input NaN if it is signalling
28
26
*/
29
/* Enable MTE */
27
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
30
if (cpu_isar_feature(aa64_mte, cpu)) {
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,
40
}
41
42
if (rule == float_3nan_prop_none) {
43
-#if defined(TARGET_ARM)
44
- /*
45
- * This looks different from the ARM ARM pseudocode, because the ARM ARM
46
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
47
- */
48
- rule = float_3nan_prop_s_cab;
49
-#elif defined(TARGET_MIPS)
50
+#if defined(TARGET_MIPS)
51
if (snan_bit_is_one(status)) {
52
rule = float_3nan_prop_s_abc;
53
} else {
31
--
54
--
32
2.25.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
New patch
1
Set the Float3NaNPropRule explicitly for Arm, 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-23-peter.maydell@linaro.org
7
---
8
target/mips/fpu_helper.h | 4 ++++
9
target/mips/msa.c | 3 +++
10
fpu/softfloat-specialize.c.inc | 8 +-------
11
3 files changed, 8 insertions(+), 7 deletions(-)
12
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/mips/fpu_helper.h
16
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
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
+
32
}
33
34
static inline void restore_fp_status(CPUMIPSState *env)
35
diff --git a/target/mips/msa.c b/target/mips/msa.c
36
index XXXXXXX..XXXXXXX 100644
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);
45
+
46
/* clear float_status exception flags */
47
set_float_exception_flags(0, &env->active_tc.msa_fp_status);
48
49
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
50
index XXXXXXX..XXXXXXX 100644
51
--- a/fpu/softfloat-specialize.c.inc
52
+++ b/fpu/softfloat-specialize.c.inc
53
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
54
}
55
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 {
68
--
69
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for xtensa, 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-24-peter.maydell@linaro.org
7
---
8
target/xtensa/fpu_helper.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 8 --------
10
2 files changed, 2 insertions(+), 8 deletions(-)
11
12
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/xtensa/fpu_helper.c
15
+++ b/target/xtensa/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
17
set_use_first_nan(use_first, &env->fp_status);
18
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
19
&env->fp_status);
20
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
21
+ &env->fp_status);
22
}
23
24
void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
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
32
if (rule == float_3nan_prop_none) {
33
-#if defined(TARGET_XTENSA)
34
- if (status->use_first_nan) {
35
- rule = float_3nan_prop_abc;
36
- } else {
37
- rule = float_3nan_prop_cba;
38
- }
39
-#else
40
rule = float_3nan_prop_abc;
41
-#endif
42
}
43
44
assert(rule != float_3nan_prop_none);
45
--
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
New patch
1
Set the Float3NaNPropRule explicitly for HPPA, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
HPPA is the only target that was using the default branch of the
5
ifdef ladder (other targets either do not use muladd or set
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.
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-26-peter.maydell@linaro.org
16
---
17
target/hppa/fpu_helper.c | 8 ++++++++
18
fpu/softfloat-specialize.c.inc | 4 ----
19
2 files changed, 8 insertions(+), 4 deletions(-)
20
21
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/hppa/fpu_helper.c
24
+++ b/target/hppa/fpu_helper.c
25
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
26
* HPPA does note implement a CPU reset method at all...
27
*/
28
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
29
+ /*
30
+ * TODO: The HPPA architecture reference only documents its NaN
31
+ * propagation rule for 2-operand operations. Testing on real hardware
32
+ * might be necessary to confirm whether this order for muladd is correct.
33
+ * Not preferring the SNaN is almost certainly incorrect as it diverges
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
41
index XXXXXXX..XXXXXXX 100644
42
--- a/fpu/softfloat-specialize.c.inc
43
+++ b/fpu/softfloat-specialize.c.inc
44
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
45
}
46
}
47
48
- if (rule == float_3nan_prop_none) {
49
- rule = float_3nan_prop_abc;
50
- }
51
-
52
assert(rule != float_3nan_prop_none);
53
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
54
/* We have at least one SNaN input and should prefer it */
55
--
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
New patch
1
In cf_fpu_gdb_get_reg() and cf_fpu_gdb_set_reg() we do the conversion
2
from float64 to floatx80 using a scratch float_status, because we
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.
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-32-peter.maydell@linaro.org
13
---
14
target/m68k/helper.c | 6 ++++--
15
1 file changed, 4 insertions(+), 2 deletions(-)
16
17
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/m68k/helper.c
20
+++ b/target/m68k/helper.c
21
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
22
CPUM68KState *env = &cpu->env;
23
24
if (n < 8) {
25
- float_status s = {};
26
+ /* Use scratch float_status so any exceptions don't change CPU state */
27
+ float_status s = env->fp_status;
28
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
29
}
30
switch (n) {
31
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
32
CPUM68KState *env = &cpu->env;
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
}
41
--
42
2.34.1
diff view generated by jsdifflib
1
In commit 6e657e64cdc478 in 2013 we added some autorelease pools to
1
In the helper functions flcmps and flcmpd we use a scratch float_status
2
deal with complaints from macOS when we made calls into Cocoa from
2
so that we don't change the CPU state if the comparison raises any
3
threads that didn't have automatically created autorelease pools.
3
floating point exception flags. Instead of zero-initializing this
4
Later on, macOS got stricter about forbidding cross-thread Cocoa
4
scratch float_status, initialize it as a copy of env->fp_status. This
5
calls, and in commit 5588840ff77800e839d8 we restructured the code to
5
avoids the need to explicitly initialize settings like the NaN
6
avoid them. This left the autorelease pool creation in several
6
propagation rule or others we might add to softfloat in future.
7
functions without any purpose; delete it.
8
7
9
We still need the pool in cocoa_refresh() for the clipboard related
8
To do this we need to pass the CPU env pointer in to the helper.
10
code which is called directly there.
11
9
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
12
Message-id: 20241202131347.498124-33-peter.maydell@linaro.org
15
Message-id: 20220224101330.967429-3-peter.maydell@linaro.org
16
---
13
---
17
ui/cocoa.m | 6 ------
14
target/sparc/helper.h | 4 ++--
18
1 file changed, 6 deletions(-)
15
target/sparc/fop_helper.c | 8 ++++----
16
target/sparc/translate.c | 4 ++--
17
3 files changed, 8 insertions(+), 8 deletions(-)
19
18
20
diff --git a/ui/cocoa.m b/ui/cocoa.m
19
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
21
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
22
--- a/ui/cocoa.m
21
--- a/target/sparc/helper.h
23
+++ b/ui/cocoa.m
22
+++ b/target/sparc/helper.h
24
@@ -XXX,XX +XXX,XX @@ int main (int argc, char **argv) {
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
25
static void cocoa_update(DisplayChangeListener *dcl,
24
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
26
int x, int y, int w, int h)
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());
40
}
41
42
-uint32_t helper_flcmps(float32 src1, float32 src2)
43
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
27
{
44
{
28
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
45
/*
29
-
46
* FLCMP never raises an exception nor modifies any FSR fields.
30
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
47
* Perform the comparison with a dummy fp environment.
31
48
*/
32
dispatch_async(dispatch_get_main_queue(), ^{
49
- float_status discard = { };
33
@@ -XXX,XX +XXX,XX @@ static void cocoa_update(DisplayChangeListener *dcl,
50
+ float_status discard = env->fp_status;
34
}
51
FloatRelation r;
35
[cocoaView setNeedsDisplayInRect:rect];
52
36
});
53
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
37
-
54
@@ -XXX,XX +XXX,XX @@ uint32_t helper_flcmps(float32 src1, float32 src2)
38
- [pool release];
55
g_assert_not_reached();
39
}
56
}
40
57
41
static void cocoa_switch(DisplayChangeListener *dcl,
58
-uint32_t helper_flcmpd(float64 src1, float64 src2)
42
DisplaySurface *surface)
59
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
43
{
60
{
44
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
61
- float_status discard = { };
45
pixman_image_t *image = surface->image;
62
+ float_status discard = env->fp_status;
46
63
FloatRelation r;
47
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
64
48
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
65
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
49
[cocoaView updateUIInfo];
66
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
50
[cocoaView switchSurface:image];
67
index XXXXXXX..XXXXXXX 100644
51
});
68
--- a/target/sparc/translate.c
52
- [pool release];
69
+++ b/target/sparc/translate.c
70
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPs(DisasContext *dc, arg_FLCMPs *a)
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);
53
}
77
}
54
78
55
static void cocoa_refresh(DisplayChangeListener *dcl)
79
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPd(DisasContext *dc, arg_FLCMPd *a)
80
81
src1 = gen_load_fpr_D(dc, a->rs1);
82
src2 = gen_load_fpr_D(dc, a->rs2);
83
- gen_helper_flcmpd(cpu_fcc[a->cc], src1, src2);
84
+ gen_helper_flcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
85
return advance_pc(dc);
86
}
87
56
--
88
--
57
2.25.1
89
2.34.1
diff view generated by jsdifflib
New patch
1
In the helper_compute_fprf functions, we pass a dummy float_status
2
in to the is_signaling_nan() function. This is unnecessary, because
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.
1
8
9
Use env->fp_status instead of the dummy fp_status.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20241202131347.498124-34-peter.maydell@linaro.org
14
---
15
target/ppc/fpu_helper.c | 3 +--
16
1 file changed, 1 insertion(+), 2 deletions(-)
17
18
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/ppc/fpu_helper.c
21
+++ b/target/ppc/fpu_helper.c
22
@@ -XXX,XX +XXX,XX @@ void helper_compute_fprf_##tp(CPUPPCState *env, tp arg) \
23
} else if (tp##_is_infinity(arg)) { \
24
fprf = neg ? 0x09 << FPSCR_FPRF : 0x05 << FPSCR_FPRF; \
25
} else { \
26
- float_status dummy = { }; /* snan_bit_is_one = 0 */ \
27
- if (tp##_is_signaling_nan(arg, &dummy)) { \
28
+ if (tp##_is_signaling_nan(arg, &env->fp_status)) { \
29
fprf = 0x00 << FPSCR_FPRF; \
30
} else { \
31
fprf = 0x11 << FPSCR_FPRF; \
32
--
33
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add new macros to manipulate signed fields within the register.
3
Now that float_status has a bunch of fp parameters,
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.
4
8
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220301215958.157011-2-richard.henderson@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241203203949.483774-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
include/hw/registerfields.h | 48 ++++++++++++++++++++++++++++++++++++-
15
target/arm/tcg/vec_helper.c | 20 +++++++-------------
13
1 file changed, 47 insertions(+), 1 deletion(-)
16
1 file changed, 7 insertions(+), 13 deletions(-)
14
17
15
diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
18
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/registerfields.h
20
--- a/target/arm/tcg/vec_helper.c
18
+++ b/include/hw/registerfields.h
21
+++ b/target/arm/tcg/vec_helper.c
19
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
20
extract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
23
* no effect on AArch32 instructions.
21
R_ ## reg ## _ ## field ## _LENGTH)
24
*/
22
25
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
23
+#define FIELD_SEX8(storage, reg, field) \
26
- *statusp = (float_status){
24
+ sextract8((storage), R_ ## reg ## _ ## field ## _SHIFT, \
27
- .tininess_before_rounding = float_tininess_before_rounding,
25
+ R_ ## reg ## _ ## field ## _LENGTH)
28
- .float_rounding_mode = float_round_to_odd_inf,
26
+#define FIELD_SEX16(storage, reg, field) \
29
- .flush_to_zero = true,
27
+ sextract16((storage), R_ ## reg ## _ ## field ## _SHIFT, \
30
- .flush_inputs_to_zero = true,
28
+ R_ ## reg ## _ ## field ## _LENGTH)
31
- .default_nan_mode = true,
29
+#define FIELD_SEX32(storage, reg, field) \
32
- };
30
+ sextract32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
31
+ R_ ## reg ## _ ## field ## _LENGTH)
32
+#define FIELD_SEX64(storage, reg, field) \
33
+ sextract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
34
+ R_ ## reg ## _ ## field ## _LENGTH)
35
+
33
+
36
/* Extract a field from an array of registers */
34
+ *statusp = env->vfp.fp_status;
37
#define ARRAY_FIELD_EX32(regs, reg, field) \
35
+ set_default_nan_mode(true, statusp);
38
FIELD_EX32((regs)[R_ ## reg], reg, field)
36
39
@@ -XXX,XX +XXX,XX @@
37
if (ebf) {
40
_d; })
38
- float_status *fpst = &env->vfp.fp_status;
41
#define FIELD_DP64(storage, reg, field, val) ({ \
39
- set_flush_to_zero(get_flush_to_zero(fpst), statusp);
42
struct { \
40
- set_flush_inputs_to_zero(get_flush_inputs_to_zero(fpst), statusp);
43
- uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
41
- set_float_rounding_mode(get_float_rounding_mode(fpst), statusp);
44
+ uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
42
-
45
+ } _v = { .v = val }; \
43
/* EBF=1 needs to do a step with round-to-odd semantics */
46
+ uint64_t _d; \
44
*oddstatusp = *statusp;
47
+ _d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
45
set_float_rounding_mode(float_round_to_odd, oddstatusp);
48
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
46
+ } else {
49
+ _d; })
47
+ set_flush_to_zero(true, statusp);
50
+
48
+ set_flush_inputs_to_zero(true, statusp);
51
+#define FIELD_SDP8(storage, reg, field, val) ({ \
49
+ set_float_rounding_mode(float_round_to_odd_inf, statusp);
52
+ struct { \
50
}
53
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
51
-
54
+ } _v = { .v = val }; \
52
return ebf;
55
+ uint8_t _d; \
53
}
56
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
54
57
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
58
+ _d; })
59
+#define FIELD_SDP16(storage, reg, field, val) ({ \
60
+ struct { \
61
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
62
+ } _v = { .v = val }; \
63
+ uint16_t _d; \
64
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
65
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
66
+ _d; })
67
+#define FIELD_SDP32(storage, reg, field, val) ({ \
68
+ struct { \
69
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
70
+ } _v = { .v = val }; \
71
+ uint32_t _d; \
72
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
73
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
74
+ _d; })
75
+#define FIELD_SDP64(storage, reg, field, val) ({ \
76
+ struct { \
77
+ int64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
78
} _v = { .v = val }; \
79
uint64_t _d; \
80
_d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
81
--
55
--
82
2.25.1
56
2.34.1
83
57
84
58
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Currently we hardcode the default NaN value in parts64_default_nan()
2
using a compile-time ifdef ladder. This is awkward for two cases:
3
* for single-QEMU-binary we can't hard-code target-specifics like this
4
* for Arm FEAT_AFP the default NaN value depends on FPCR.AH
5
(specifically the sign bit is different)
2
6
3
This feature is relatively small, as it applies only to
7
Add a field to float_status to specify the default NaN value; fall
4
64k pages and thus requires no additional changes to the
8
back to the old ifdef behaviour if these are not set.
5
table descriptor walking algorithm, only a change to the
6
minimum TSZ (which is the inverse of the maximum virtual
7
address space size).
8
9
9
Note that this feature widens VBAR_ELx, but we already
10
The default NaN value is specified by setting a uint8_t to a
10
treat the register as being 64 bits wide.
11
pattern corresponding to the sign and upper fraction parts of
12
the NaN; the lower bits of the fraction are set from bit 0 of
13
the pattern.
11
14
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20220301215958.157011-10-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
16
---
18
---
17
docs/system/arm/emulation.rst | 1 +
19
include/fpu/softfloat-helpers.h | 11 +++++++
18
target/arm/cpu-param.h | 2 +-
20
include/fpu/softfloat-types.h | 10 ++++++
19
target/arm/cpu.h | 5 +++++
21
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
20
target/arm/cpu64.c | 1 +
22
3 files changed, 54 insertions(+), 22 deletions(-)
21
target/arm/helper.c | 9 ++++++++-
22
5 files changed, 16 insertions(+), 2 deletions(-)
23
23
24
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
24
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
25
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
26
--- a/docs/system/arm/emulation.rst
26
--- a/include/fpu/softfloat-helpers.h
27
+++ b/docs/system/arm/emulation.rst
27
+++ b/include/fpu/softfloat-helpers.h
28
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
28
@@ -XXX,XX +XXX,XX @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
29
- FEAT_LRCPC (Load-acquire RCpc instructions)
29
status->float_infzeronan_rule = rule;
30
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
31
- FEAT_LSE (Large System Extensions)
32
+- FEAT_LVA (Large Virtual Address space)
33
- FEAT_MTE (Memory Tagging Extension)
34
- FEAT_MTE2 (Memory Tagging Extension)
35
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
36
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu-param.h
39
+++ b/target/arm/cpu-param.h
40
@@ -XXX,XX +XXX,XX @@
41
#ifdef TARGET_AARCH64
42
# define TARGET_LONG_BITS 64
43
# define TARGET_PHYS_ADDR_SPACE_BITS 48
44
-# define TARGET_VIRT_ADDR_SPACE_BITS 48
45
+# define TARGET_VIRT_ADDR_SPACE_BITS 52
46
#else
47
# define TARGET_LONG_BITS 32
48
# define TARGET_PHYS_ADDR_SPACE_BITS 40
49
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/cpu.h
52
+++ b/target/arm/cpu.h
53
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
54
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
55
}
30
}
56
31
57
+static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
32
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
33
+ float_status *status)
58
+{
34
+{
59
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
35
+ status->default_nan_pattern = dnan_pattern;
60
+}
36
+}
61
+
37
+
62
static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
38
static inline void set_flush_to_zero(bool val, float_status *status)
63
{
39
{
64
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
40
status->flush_to_zero = val;
65
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
41
@@ -XXX,XX +XXX,XX @@ static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status
42
return status->float_infzeronan_rule;
43
}
44
45
+static inline uint8_t get_float_default_nan_pattern(float_status *status)
46
+{
47
+ return status->default_nan_pattern;
48
+}
49
+
50
static inline bool get_flush_to_zero(float_status *status)
51
{
52
return status->flush_to_zero;
53
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
66
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/cpu64.c
55
--- a/include/fpu/softfloat-types.h
68
+++ b/target/arm/cpu64.c
56
+++ b/include/fpu/softfloat-types.h
69
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
57
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
70
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
58
/* should denormalised inputs go to zero and set the input_denormal flag? */
71
t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
59
bool flush_inputs_to_zero;
72
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */
60
bool default_nan_mode;
73
+ t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
61
+ /*
74
cpu->isar.id_aa64mmfr2 = t;
62
+ * The pattern to use for the default NaN. Here the high bit specifies
75
63
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
76
t = cpu->isar.id_aa64zfr0;
64
+ * fractional part. The low bits of the fractional part are copies of bit 0.
77
diff --git a/target/arm/helper.c b/target/arm/helper.c
65
+ * The exponent of the default NaN is (as for any NaN) always all 1s.
66
+ * Note that a value of 0 here is not a valid NaN. The target must set
67
+ * this to the correct non-zero value, or we will assert when trying to
68
+ * create a default NaN.
69
+ */
70
+ uint8_t default_nan_pattern;
71
/*
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
78
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/helper.c
76
--- a/fpu/softfloat-specialize.c.inc
80
+++ b/target/arm/helper.c
77
+++ b/fpu/softfloat-specialize.c.inc
81
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
78
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
82
} else {
79
{
83
max_tsz = 39;
80
bool sign = 0;
84
}
81
uint64_t frac;
85
- min_tsz = 16; /* TODO: ARMv8.2-LVA */
82
+ uint8_t dnan_pattern = status->default_nan_pattern;
83
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;
132
+ }
133
#endif
134
+ }
135
+ assert(dnan_pattern != 0);
86
+
136
+
87
+ min_tsz = 16;
137
+ sign = dnan_pattern >> 7;
88
+ if (using64k) {
138
+ /*
89
+ if (cpu_isar_feature(aa64_lva, env_archcpu(env))) {
139
+ * Place default_nan_pattern [6:0] into bits [62:56],
90
+ min_tsz = 12;
140
+ * and replecate bit [0] down into [55:0]
91
+ }
141
+ */
92
+ }
142
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
93
+ /* TODO: FEAT_LPA2 */
143
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
94
144
95
if (tsz > max_tsz) {
145
*p = (FloatParts64) {
96
tsz = max_tsz;
146
.cls = float_class_qnan,
97
--
147
--
98
2.25.1
148
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the tests/fp code.
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-36-peter.maydell@linaro.org
6
---
7
tests/fp/fp-bench.c | 1 +
8
tests/fp/fp-test-log2.c | 1 +
9
tests/fp/fp-test.c | 1 +
10
3 files changed, 3 insertions(+)
11
12
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/fp/fp-bench.c
15
+++ b/tests/fp/fp-bench.c
16
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
17
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
18
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
19
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
20
+ set_float_default_nan_pattern(0b01000000, &soft_status);
21
22
f = bench_funcs[operation][precision];
23
g_assert(f);
24
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/tests/fp/fp-test-log2.c
27
+++ b/tests/fp/fp-test-log2.c
28
@@ -XXX,XX +XXX,XX @@ int main(int ac, char **av)
29
int i;
30
31
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
32
+ set_float_default_nan_pattern(0b01000000, &qsf);
33
set_float_rounding_mode(float_round_nearest_even, &qsf);
34
35
test.d = 0.0;
36
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/fp/fp-test.c
39
+++ b/tests/fp/fp-test.c
40
@@ -XXX,XX +XXX,XX @@ void run_test(void)
41
*/
42
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
43
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
44
+ set_float_default_nan_pattern(0b01000000, &qsf);
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
46
47
genCases_setLevel(test_level);
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
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-37-peter.maydell@linaro.org
7
---
8
target/microblaze/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/microblaze/cpu.c
15
+++ b/target/microblaze/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_reset_hold(Object *obj, ResetType type)
17
* this architecture.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
23
#if defined(CONFIG_USER_ONLY)
24
/* start in user mode with interrupts enabled. */
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 void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
34
- || defined(TARGET_MICROBLAZE)
35
+#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
/* Sign bit set, most significant frac bit set */
37
dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
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-38-peter.maydell@linaro.org
7
---
8
target/i386/tcg/fpu_helper.c | 4 ++++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 4 insertions(+), 3 deletions(-)
11
12
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/i386/tcg/fpu_helper.c
15
+++ b/target/i386/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
17
*/
18
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
19
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
+ set_float_default_nan_pattern(0b11000000, &env->mmx_status);
23
+ set_float_default_nan_pattern(0b11000000, &env->sse_status);
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
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 void parts64_default_nan(FloatParts64 *p, float_status *status)
32
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
/* Sign bit clear, all frac bits set */
34
dnan_pattern = 0b01111111;
35
-#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
- /* Sign bit set, most significant frac bit set */
37
- dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
/* Sign bit clear, msb-1 frac bit set */
40
dnan_pattern = 0b00100000;
41
--
42
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
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-39-peter.maydell@linaro.org
7
---
8
target/hppa/fpu_helper.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 2 insertions(+), 3 deletions(-)
11
12
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/hppa/fpu_helper.c
15
+++ b/target/hppa/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
17
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
18
/* For inf * 0 + NaN, return the input NaN */
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ /* Default NaN: sign bit clear, msb-1 frac bit set */
21
+ set_float_default_nan_pattern(0b00100000, &env->fp_status);
22
}
23
24
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
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 void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_HPPA)
34
- /* Sign bit clear, msb-1 frac bit set */
35
- dnan_pattern = 0b00100000;
36
#elif defined(TARGET_HEXAGON)
37
/* Sign bit set, all frac bits set. */
38
dnan_pattern = 0b11111111;
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the alpha 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-40-peter.maydell@linaro.org
6
---
7
target/alpha/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/alpha/cpu.c
13
+++ b/target/alpha/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_initfn(Object *obj)
15
* operand in Fa. That is float_2nan_prop_ba.
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
18
+ /* Default NaN: sign bit clear, msb frac bit set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
#if defined(CONFIG_USER_ONLY)
21
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
22
cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD
23
--
24
2.34.1
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@gmail.com>
1
Set the default NaN pattern explicitly for the arm target.
2
This includes setting it for the old linux-user nwfpe emulation.
3
For nwfpe, our default doesn't match the real kernel, but we
4
avoid making a behaviour change in this commit.
2
5
3
Support the latest PSCI on TCG and HVF. A 64-bit function called from
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
AArch32 now returns NOT_SUPPORTED, which is necessary to adhere to SMC
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Calling Convention 1.0. It is still not compliant with SMCCC 1.3 since
8
Message-id: 20241202131347.498124-41-peter.maydell@linaro.org
6
they do not implement mandatory functions.
9
---
10
linux-user/arm/nwfpe/fpa11.c | 5 +++++
11
target/arm/cpu.c | 2 ++
12
2 files changed, 7 insertions(+)
7
13
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
14
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
9
Message-id: 20220213035753.34577-1-akihiko.odaki@gmail.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: update MISMATCH_CHECK checks on PSCI_VERSION macros to match]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/kvm-consts.h | 13 +++++++++----
15
hw/arm/boot.c | 12 +++++++++---
16
target/arm/cpu.c | 5 +++--
17
target/arm/hvf/hvf.c | 27 ++++++++++++++++++++++++++-
18
target/arm/kvm64.c | 2 +-
19
target/arm/psci.c | 35 ++++++++++++++++++++++++++++++++---
20
6 files changed, 80 insertions(+), 14 deletions(-)
21
22
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/kvm-consts.h
16
--- a/linux-user/arm/nwfpe/fpa11.c
25
+++ b/target/arm/kvm-consts.h
17
+++ b/linux-user/arm/nwfpe/fpa11.c
26
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_0_1_FN_MIGRATE, KVM_PSCI_FN_MIGRATE);
18
@@ -XXX,XX +XXX,XX @@ void resetFPA11(void)
27
#define QEMU_PSCI_0_2_FN64_AFFINITY_INFO QEMU_PSCI_0_2_FN64(4)
19
* this late date.
28
#define QEMU_PSCI_0_2_FN64_MIGRATE QEMU_PSCI_0_2_FN64(5)
20
*/
29
21
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
30
+#define QEMU_PSCI_1_0_FN_PSCI_FEATURES QEMU_PSCI_0_2_FN(10)
22
+ /*
31
+
23
+ * Use the same default NaN value as Arm VFP. This doesn't match
32
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_SUSPEND, PSCI_0_2_FN_CPU_SUSPEND);
24
+ * the Linux kernel's nwfpe emulation, which uses an all-1s value.
33
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_OFF, PSCI_0_2_FN_CPU_OFF);
25
+ */
34
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_ON, PSCI_0_2_FN_CPU_ON);
26
+ set_float_default_nan_pattern(0b01000000, &fpa11->fp_status);
35
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_0_2_FN_MIGRATE, PSCI_0_2_FN_MIGRATE);
27
}
36
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_SUSPEND, PSCI_0_2_FN64_CPU_SUSPEND);
28
37
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_ON, PSCI_0_2_FN64_CPU_ON);
29
void SetRoundingMode(const unsigned int opcode)
38
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_MIGRATE, PSCI_0_2_FN64_MIGRATE);
39
+MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
40
41
/* PSCI v0.2 return values used by TCG emulation of PSCI */
42
43
/* No Trusted OS migration to worry about when offlining CPUs */
44
#define QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED 2
45
46
-/* We implement version 0.2 only */
47
-#define QEMU_PSCI_0_2_RET_VERSION_0_2 2
48
+#define QEMU_PSCI_VERSION_0_1 0x00001
49
+#define QEMU_PSCI_VERSION_0_2 0x00002
50
+#define QEMU_PSCI_VERSION_1_1 0x10001
51
52
MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
53
-MISMATCH_CHECK(QEMU_PSCI_0_2_RET_VERSION_0_2,
54
- (PSCI_VERSION_MAJOR(0) | PSCI_VERSION_MINOR(2)));
55
+/* We don't bother to check every possible version value */
56
+MISMATCH_CHECK(QEMU_PSCI_VERSION_0_2, PSCI_VERSION(0, 2));
57
+MISMATCH_CHECK(QEMU_PSCI_VERSION_1_1, PSCI_VERSION(1, 1));
58
59
/* PSCI return values (inclusive of all PSCI versions) */
60
#define QEMU_PSCI_RET_SUCCESS 0
61
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/boot.c
64
+++ b/hw/arm/boot.c
65
@@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt)
66
}
67
68
qemu_fdt_add_subnode(fdt, "/psci");
69
- if (armcpu->psci_version == 2) {
70
- const char comp[] = "arm,psci-0.2\0arm,psci";
71
- qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
72
+ if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
73
+ armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
74
+ if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
75
+ const char comp[] = "arm,psci-0.2\0arm,psci";
76
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
77
+ } else {
78
+ const char comp[] = "arm,psci-1.0\0arm,psci-0.2\0arm,psci";
79
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
80
+ }
81
82
cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
83
if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
84
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
85
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/cpu.c
32
--- a/target/arm/cpu.c
87
+++ b/target/arm/cpu.c
33
+++ b/target/arm/cpu.c
88
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
34
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
89
* picky DTB consumer will also provide a helpful error message.
35
* the pseudocode function the arguments are in the order c, a, b.
90
*/
36
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
91
cpu->dtb_compatible = "qemu,unknown";
37
* and the input NaN if it is signalling
92
- cpu->psci_version = 1; /* By default assume PSCI v0.1 */
38
+ * * Default NaN has sign bit clear, msb frac bit set
93
+ cpu->psci_version = QEMU_PSCI_VERSION_0_1; /* By default assume PSCI v0.1 */
39
*/
94
cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
40
static void arm_set_default_fp_behaviours(float_status *s)
95
41
{
96
if (tcg_enabled() || hvf_enabled()) {
42
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
97
- cpu->psci_version = 2; /* TCG and HVF implement PSCI 0.2 */
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
98
+ /* TCG and HVF implement PSCI 1.1 */
44
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
99
+ cpu->psci_version = QEMU_PSCI_VERSION_1_1;
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
100
}
46
+ set_float_default_nan_pattern(0b01000000, s);
101
}
47
}
102
48
103
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
49
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/hvf/hvf.c
106
+++ b/target/arm/hvf/hvf.c
107
@@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu)
108
109
switch (param[0]) {
110
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
111
- ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
112
+ ret = QEMU_PSCI_VERSION_1_1;
113
break;
114
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
115
ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
116
@@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu)
117
case QEMU_PSCI_0_2_FN_MIGRATE:
118
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
119
break;
120
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
121
+ switch (param[1]) {
122
+ case QEMU_PSCI_0_2_FN_PSCI_VERSION:
123
+ case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
124
+ case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
125
+ case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
126
+ case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
127
+ case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
128
+ case QEMU_PSCI_0_1_FN_CPU_ON:
129
+ case QEMU_PSCI_0_2_FN_CPU_ON:
130
+ case QEMU_PSCI_0_2_FN64_CPU_ON:
131
+ case QEMU_PSCI_0_1_FN_CPU_OFF:
132
+ case QEMU_PSCI_0_2_FN_CPU_OFF:
133
+ case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
134
+ case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
135
+ case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
136
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
137
+ ret = 0;
138
+ break;
139
+ case QEMU_PSCI_0_1_FN_MIGRATE:
140
+ case QEMU_PSCI_0_2_FN_MIGRATE:
141
+ default:
142
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
143
+ }
144
+ break;
145
default:
146
return false;
147
}
148
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/kvm64.c
151
+++ b/target/arm/kvm64.c
152
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
153
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
154
}
155
if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
156
- cpu->psci_version = 2;
157
+ cpu->psci_version = QEMU_PSCI_VERSION_0_2;
158
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;
159
}
160
if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
161
diff --git a/target/arm/psci.c b/target/arm/psci.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/target/arm/psci.c
164
+++ b/target/arm/psci.c
165
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
166
{
167
/*
168
* This function partially implements the logic for dispatching Power State
169
- * Coordination Interface (PSCI) calls (as described in ARM DEN 0022B.b),
170
+ * Coordination Interface (PSCI) calls (as described in ARM DEN 0022D.b),
171
* to the extent required for bringing up and taking down secondary cores,
172
* and for handling reset and poweroff requests.
173
* Additional information about the calling convention used is available in
174
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
175
}
176
177
if ((param[0] & QEMU_PSCI_0_2_64BIT) && !is_a64(env)) {
178
- ret = QEMU_PSCI_RET_INVALID_PARAMS;
179
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
180
goto err;
181
}
182
183
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
184
ARMCPU *target_cpu;
185
186
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
187
- ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
188
+ ret = QEMU_PSCI_VERSION_1_1;
189
break;
190
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
191
ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
192
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
193
}
194
helper_wfi(env, 4);
195
break;
196
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
197
+ switch (param[1]) {
198
+ case QEMU_PSCI_0_2_FN_PSCI_VERSION:
199
+ case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
200
+ case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
201
+ case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
202
+ case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
203
+ case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
204
+ case QEMU_PSCI_0_1_FN_CPU_ON:
205
+ case QEMU_PSCI_0_2_FN_CPU_ON:
206
+ case QEMU_PSCI_0_2_FN64_CPU_ON:
207
+ case QEMU_PSCI_0_1_FN_CPU_OFF:
208
+ case QEMU_PSCI_0_2_FN_CPU_OFF:
209
+ case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
210
+ case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
211
+ case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
212
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
213
+ if (!(param[1] & QEMU_PSCI_0_2_64BIT) || is_a64(env)) {
214
+ ret = 0;
215
+ break;
216
+ }
217
+ /* fallthrough */
218
+ case QEMU_PSCI_0_1_FN_MIGRATE:
219
+ case QEMU_PSCI_0_2_FN_MIGRATE:
220
+ default:
221
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
222
+ break;
223
+ }
224
+ break;
225
case QEMU_PSCI_0_1_FN_MIGRATE:
226
case QEMU_PSCI_0_2_FN_MIGRATE:
227
default:
228
--
50
--
229
2.25.1
51
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for loongarch.
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-42-peter.maydell@linaro.org
6
---
7
target/loongarch/tcg/fpu_helper.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/loongarch/tcg/fpu_helper.c
13
+++ b/target/loongarch/tcg/fpu_helper.c
14
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
15
*/
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
17
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
18
+ /* Default NaN: sign bit clear, msb frac bit set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
}
21
22
int ieee_ex_to_loongarch(int xcpt)
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for m68k.
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-43-peter.maydell@linaro.org
6
---
7
target/m68k/cpu.c | 2 ++
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 3 insertions(+), 1 deletion(-)
10
11
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/m68k/cpu.c
14
+++ b/target/m68k/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
16
* preceding paragraph for nonsignaling NaNs.
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
+ /* Default NaN: sign bit clear, all frac bits set */
20
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
21
22
nan = floatx80_default_nan(&env->fp_status);
23
for (i = 0; i < 8; i++) {
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 void parts64_default_nan(FloatParts64 *p, float_status *status)
29
uint8_t dnan_pattern = status->default_nan_pattern;
30
31
if (dnan_pattern == 0) {
32
-#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
+#if defined(TARGET_SPARC)
34
/* Sign bit clear, all frac bits set */
35
dnan_pattern = 0b01111111;
36
#elif defined(TARGET_HEXAGON)
37
--
38
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Set the default NaN pattern explicitly for MIPS. Note that this
2
is our only target which currently changes the default NaN
3
at runtime (which it was previously doing indirectly when it
4
changed the snan_bit_is_one setting).
2
5
3
The shift of the BaseADDR field depends on the translation
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
granule in use.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-44-peter.maydell@linaro.org
9
---
10
target/mips/fpu_helper.h | 7 +++++++
11
target/mips/msa.c | 3 +++
12
2 files changed, 10 insertions(+)
5
13
6
Fixes: 84940ed8255 ("target/arm: Add support for FEAT_TLBIRANGE")
14
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
7
Reported-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220301215958.157011-14-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/helper.c | 5 +++--
14
1 file changed, 3 insertions(+), 2 deletions(-)
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
16
--- a/target/mips/fpu_helper.h
19
+++ b/target/arm/helper.c
17
+++ b/target/mips/fpu_helper.h
20
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
18
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
21
ret.length = (num + 1) << (exponent + page_shift);
19
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
22
20
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
23
if (regime_has_2_ranges(mmuidx)) {
21
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
24
- ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
22
+ /*
25
+ ret.base = sextract64(value, 0, 37);
23
+ * With nan2008, the default NaN value has the sign bit clear and the
26
} else {
24
+ * frac msb set; with the older mode, the sign bit is clear, and all
27
- ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS;
25
+ * frac bits except the msb are set.
28
+ ret.base = extract64(value, 0, 37);
26
+ */
29
}
27
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
30
+ ret.base <<= page_shift;
28
+ &env->active_fpu.fp_status);
31
29
32
return ret;
30
}
31
32
diff --git a/target/mips/msa.c b/target/mips/msa.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/mips/msa.c
35
+++ b/target/mips/msa.c
36
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
37
/* Inf * 0 + NaN returns the input NaN */
38
set_float_infzeronan_rule(float_infzeronan_dnan_never,
39
&env->active_tc.msa_fp_status);
40
+ /* Default NaN: sign bit clear, frac msb set */
41
+ set_float_default_nan_pattern(0b01000000,
42
+ &env->active_tc.msa_fp_status);
33
}
43
}
34
--
44
--
35
2.25.1
45
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for openrisc.
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-45-peter.maydell@linaro.org
6
---
7
target/openrisc/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/openrisc/cpu.c
13
+++ b/target/openrisc/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
15
*/
16
set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
17
18
+ /* Default NaN: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
20
21
#ifndef CONFIG_USER_ONLY
22
cpu->env.picmr = 0x00000000;
23
--
24
2.34.1
diff view generated by jsdifflib
1
From: Jimmy Brisson <jimmy.brisson@linaro.org>
1
Set the default NaN pattern explicitly for ppc.
2
2
3
With these interfaces missing, TFM would delegate peripherals 0, 1,
4
2, 3 and 8, and qemu would ignore the delegation of interface 8, as
5
it thought interface 4 was eth & USB.
6
7
This patch corrects this behavior and allows TFM to delegate the
8
eth & USB peripheral to NS mode.
9
10
(The old QEMU behaviour was based on revision B of the AN547
11
appnote; revision C corrects this error in the documentation,
12
and this commit brings QEMU in to line with how the FPGA
13
image really behaves.)
14
15
Signed-off-by: Jimmy Brisson <jimmy.brisson@linaro.org>
16
Message-id: 20220210210227.3203883-1-jimmy.brisson@linaro.org
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
[PMM: added commit message note clarifying that the old behaviour
19
was a docs issue, not because there were two different versions
20
of the FPGA image]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-46-peter.maydell@linaro.org
22
---
6
---
23
hw/arm/mps2-tz.c | 4 ++++
7
target/ppc/cpu_init.c | 4 ++++
24
1 file changed, 4 insertions(+)
8
1 file changed, 4 insertions(+)
25
9
26
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
10
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
27
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/mps2-tz.c
12
--- a/target/ppc/cpu_init.c
29
+++ b/hw/arm/mps2-tz.c
13
+++ b/target/ppc/cpu_init.c
30
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
14
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
31
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
15
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
32
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
33
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
17
34
+ { /* port 4 USER AHB interface 0 */ },
18
+ /* Default NaN: sign bit clear, set frac msb */
35
+ { /* port 5 USER AHB interface 1 */ },
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
36
+ { /* port 6 USER AHB interface 2 */ },
20
+ set_float_default_nan_pattern(0b01000000, &env->vec_status);
37
+ { /* port 7 USER AHB interface 3 */ },
21
+
38
{ "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 49 } },
22
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
39
},
23
ppc_spr_t *spr = &env->spr_cb[i];
40
},
24
41
--
25
--
42
2.25.1
26
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for sh4. Note that sh4
2
is one of the only three targets (the others being HPPA and
3
sometimes MIPS) that has snan_bit_is_one set.
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-47-peter.maydell@linaro.org
8
---
9
target/sh4/cpu.c | 2 ++
10
1 file changed, 2 insertions(+)
11
12
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sh4/cpu.c
15
+++ b/target/sh4/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_reset_hold(Object *obj, ResetType type)
17
set_flush_to_zero(1, &env->fp_status);
18
#endif
19
set_default_nan_mode(1, &env->fp_status);
20
+ /* sign bit clear, set all frac bits other than msb */
21
+ set_float_default_nan_pattern(0b00111111, &env->fp_status);
22
}
23
24
static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
25
--
26
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for rx.
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-48-peter.maydell@linaro.org
6
---
7
target/rx/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/rx/cpu.c
13
+++ b/target/rx/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_reset_hold(Object *obj, ResetType type)
15
* then prefer dest over source", which is float_2nan_prop_s_ab.
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
18
+ /* Default NaN value: sign bit clear, set frac msb */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
}
21
22
static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for s390x.
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-49-peter.maydell@linaro.org
6
---
7
target/s390x/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/s390x/cpu.c
13
+++ b/target/s390x/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
15
set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
16
set_float_infzeronan_rule(float_infzeronan_dnan_always,
17
&env->fpu_status);
18
+ /* Default NaN value: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fpu_status);
20
/* fall through */
21
case RESET_TYPE_S390_CPU_NORMAL:
22
env->psw.mask &= ~PSW_MASK_RI;
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for SPARC, and remove
2
the ifdef from parts64_default_nan.
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-50-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 5 +----
10
2 files changed, 3 insertions(+), 4 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
set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
18
/* For inf * 0 + NaN, return the input NaN */
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ /* Default NaN value: sign bit clear, all frac bits set */
21
+ set_float_default_nan_pattern(0b01111111, &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 void parts64_default_nan(FloatParts64 *p, float_status *status)
30
uint8_t dnan_pattern = status->default_nan_pattern;
31
32
if (dnan_pattern == 0) {
33
-#if defined(TARGET_SPARC)
34
- /* Sign bit clear, all frac bits set */
35
- dnan_pattern = 0b01111111;
36
-#elif defined(TARGET_HEXAGON)
37
+#if defined(TARGET_HEXAGON)
38
/* Sign bit set, all frac bits set. */
39
dnan_pattern = 0b11111111;
40
#else
41
--
42
2.34.1
diff view generated by jsdifflib
1
From: Wentao_Liang <Wentao_Liang_g@163.com>
1
Set the default NaN pattern explicitly for xtensa.
2
2
3
handle_simd_shift_fpint_conv() was accidentally freeing the TCG
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
temporary tcg_fpstatus too early, before the last use of it. Move
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
the free down to where it belongs.
5
Message-id: 20241202131347.498124-51-peter.maydell@linaro.org
6
---
7
target/xtensa/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
6
9
7
Signed-off-by: Wentao_Liang <Wentao_Liang_g@163.com>
10
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
[PMM: cleaned up commit message]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
12
--- a/target/xtensa/cpu.c
18
+++ b/target/arm/translate-a64.c
13
+++ b/target/xtensa/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
14
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
20
}
15
/* For inf * 0 + NaN, return the input NaN */
21
}
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
17
set_no_signaling_nans(!dfpu, &env->fp_status);
23
- tcg_temp_free_ptr(tcg_fpstatus);
18
+ /* Default NaN value: sign bit clear, set frac msb */
24
tcg_temp_free_i32(tcg_shift);
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
25
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
20
xtensa_use_first_nan(env, !dfpu);
26
+ tcg_temp_free_ptr(tcg_fpstatus);
27
tcg_temp_free_i32(tcg_rmode);
28
}
21
}
29
22
30
--
23
--
31
2.25.1
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for hexagon.
2
Remove the ifdef from parts64_default_nan(); the only
3
remaining unconverted targets all use the default case.
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-52-peter.maydell@linaro.org
8
---
9
target/hexagon/cpu.c | 2 ++
10
fpu/softfloat-specialize.c.inc | 5 -----
11
2 files changed, 2 insertions(+), 5 deletions(-)
12
13
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/hexagon/cpu.c
16
+++ b/target/hexagon/cpu.c
17
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
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);
23
}
24
25
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
26
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
27
index XXXXXXX..XXXXXXX 100644
28
--- a/fpu/softfloat-specialize.c.inc
29
+++ b/fpu/softfloat-specialize.c.inc
30
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
31
uint8_t dnan_pattern = status->default_nan_pattern;
32
33
if (dnan_pattern == 0) {
34
-#if defined(TARGET_HEXAGON)
35
- /* Sign bit set, all frac bits set. */
36
- dnan_pattern = 0b11111111;
37
-#else
38
/*
39
* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
40
* S390, SH4, TriCore, and Xtensa. Our other supported targets
41
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
42
/* sign bit clear, set frac msb */
43
dnan_pattern = 0b01000000;
44
}
45
-#endif
46
}
47
assert(dnan_pattern != 0);
48
49
--
50
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for riscv.
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-53-peter.maydell@linaro.org
6
---
7
target/riscv/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/riscv/cpu.c
13
+++ b/target/riscv/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
15
cs->exception_index = RISCV_EXCP_NONE;
16
env->load_res = -1;
17
set_default_nan_mode(1, &env->fp_status);
18
+ /* Default NaN value: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
env->vill = true;
21
22
#ifndef CONFIG_USER_ONLY
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for tricore.
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-54-peter.maydell@linaro.org
6
---
7
target/tricore/helper.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/tricore/helper.c
13
+++ b/target/tricore/helper.c
14
@@ -XXX,XX +XXX,XX @@ void fpu_set_state(CPUTriCoreState *env)
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);
20
}
21
22
uint32_t psw_read(CPUTriCoreState *env)
23
--
24
2.34.1
diff view generated by jsdifflib
1
The AN547 application note URL has changed: update our comment
1
Now that all our targets have bene converted to explicitly specify
2
accordingly. (Rev B is still downloadable from the old URL,
2
their pattern for the default NaN value we can remove the remaining
3
but there is a new Rev C of the document now.)
3
fallback code in parts64_default_nan().
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: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20241202131347.498124-55-peter.maydell@linaro.org
8
Message-id: 20220221094144.426191-1-peter.maydell@linaro.org
9
---
8
---
10
hw/arm/mps2-tz.c | 2 +-
9
fpu/softfloat-specialize.c.inc | 14 --------------
11
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 14 deletions(-)
12
11
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
12
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
14
--- a/fpu/softfloat-specialize.c.inc
16
+++ b/hw/arm/mps2-tz.c
15
+++ b/fpu/softfloat-specialize.c.inc
17
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
18
* Application Note AN524:
17
uint64_t frac;
19
* https://developer.arm.com/documentation/dai0524/latest/
18
uint8_t dnan_pattern = status->default_nan_pattern;
20
* Application Note AN547:
19
21
- * https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/DAI0547B_SSE300_PLUS_U55_FPGA_for_mps3.pdf
20
- if (dnan_pattern == 0) {
22
+ * https://developer.arm.com/documentation/dai0547/latest/
21
- /*
23
*
22
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
24
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
23
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
25
* (ARM ECM0601256) for the details of some of the device layout:
24
- * do not have floating-point.
25
- */
26
- if (snan_bit_is_one(status)) {
27
- /* sign bit clear, set all frac bits other than msb */
28
- dnan_pattern = 0b00111111;
29
- } else {
30
- /* sign bit clear, set frac msb */
31
- dnan_pattern = 0b01000000;
32
- }
33
- }
34
assert(dnan_pattern != 0);
35
36
sign = dnan_pattern >> 7;
26
--
37
--
27
2.25.1
38
2.34.1
28
29
diff view generated by jsdifflib
1
From: Patrick Venture <venture@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Previously this device created N subdevices which each owned an i2c bus.
3
Inline pickNaNMulAdd into its only caller. This makes
4
Now this device simply owns the N i2c busses directly.
4
one assert redundant with the immediately preceding IF.
5
5
6
Tested: Verified devices behind mux are still accessible via qmp and i2c
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
from within an arm32 SoC.
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
8
Message-id: 20241203203949.483774-3-richard.henderson@linaro.org
9
Reviewed-by: Hao Wu <wuhaotsh@google.com>
9
[PMM: keep comment from old code in new location]
10
Signed-off-by: Patrick Venture <venture@google.com>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20220202164533.1283668-1-venture@google.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
11
---
16
hw/i2c/i2c_mux_pca954x.c | 77 +++++++---------------------------------
12
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
17
1 file changed, 13 insertions(+), 64 deletions(-)
13
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
14
2 files changed, 40 insertions(+), 55 deletions(-)
18
15
19
diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/i2c/i2c_mux_pca954x.c
18
--- a/fpu/softfloat-parts.c.inc
22
+++ b/hw/i2c/i2c_mux_pca954x.c
19
+++ b/fpu/softfloat-parts.c.inc
23
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
24
#define PCA9548_CHANNEL_COUNT 8
25
#define PCA9546_CHANNEL_COUNT 4
26
27
-/*
28
- * struct Pca954xChannel - The i2c mux device will have N of these states
29
- * that own the i2c channel bus.
30
- * @bus: The owned channel bus.
31
- * @enabled: Is this channel active?
32
- */
33
-typedef struct Pca954xChannel {
34
- SysBusDevice parent;
35
-
36
- I2CBus *bus;
37
-
38
- bool enabled;
39
-} Pca954xChannel;
40
-
41
-#define TYPE_PCA954X_CHANNEL "pca954x-channel"
42
-#define PCA954X_CHANNEL(obj) \
43
- OBJECT_CHECK(Pca954xChannel, (obj), TYPE_PCA954X_CHANNEL)
44
-
45
/*
46
* struct Pca954xState - The pca954x state object.
47
* @control: The value written to the mux control.
48
@@ -XXX,XX +XXX,XX @@ typedef struct Pca954xState {
49
50
uint8_t control;
51
52
- /* The channel i2c buses. */
53
- Pca954xChannel channel[PCA9548_CHANNEL_COUNT];
54
+ bool enabled[PCA9548_CHANNEL_COUNT];
55
+ I2CBus *bus[PCA9548_CHANNEL_COUNT];
56
} Pca954xState;
57
58
/*
59
@@ -XXX,XX +XXX,XX @@ static bool pca954x_match(I2CSlave *candidate, uint8_t address,
60
}
21
}
61
22
62
for (i = 0; i < mc->nchans; i++) {
23
if (s->default_nan_mode) {
63
- if (!mux->channel[i].enabled) {
24
+ /*
64
+ if (!mux->enabled[i]) {
25
+ * We guarantee not to require the target to tell us how to
65
continue;
26
+ * pick a NaN if we're always returning the default NaN.
66
}
27
+ * But if we're not in default-NaN mode then the target must
67
28
+ * specify.
68
- if (i2c_scan_bus(mux->channel[i].bus, address, broadcast,
29
+ */
69
+ if (i2c_scan_bus(mux->bus[i], address, broadcast,
30
which = 3;
70
current_devs)) {
31
+ } else if (infzero) {
71
if (!broadcast) {
32
+ /*
72
return true;
33
+ * Inf * 0 + NaN -- some implementations return the
73
@@ -XXX,XX +XXX,XX @@ static void pca954x_enable_channel(Pca954xState *s, uint8_t enable_mask)
34
+ * default NaN here, and some return the input NaN.
74
*/
35
+ */
75
for (i = 0; i < mc->nchans; i++) {
36
+ switch (s->float_infzeronan_rule) {
76
if (enable_mask & (1 << i)) {
37
+ case float_infzeronan_dnan_never:
77
- s->channel[i].enabled = true;
38
+ which = 2;
78
+ s->enabled[i] = true;
39
+ break;
79
} else {
40
+ case float_infzeronan_dnan_always:
80
- s->channel[i].enabled = false;
41
+ which = 3;
81
+ s->enabled[i] = false;
42
+ break;
82
}
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,
83
}
75
}
84
}
76
}
85
@@ -XXX,XX +XXX,XX @@ I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel)
77
86
Pca954xState *pca954x = PCA954X(mux);
78
-/*----------------------------------------------------------------------------
87
79
-| Select which NaN to propagate for a three-input operation.
88
g_assert(channel < pc->nchans);
80
-| For the moment we assume that no CPU needs the 'larger significand'
89
- return I2C_BUS(qdev_get_child_bus(DEVICE(&pca954x->channel[channel]),
81
-| information.
90
- "i2c-bus"));
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;
91
-}
130
-}
92
-
131
-
93
-static void pca954x_channel_init(Object *obj)
132
/*----------------------------------------------------------------------------
94
-{
133
| Returns 1 if the double-precision floating-point value `a' is a quiet
95
- Pca954xChannel *s = PCA954X_CHANNEL(obj);
134
| NaN; otherwise returns 0.
96
- s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
97
-
98
- /* Start all channels as disabled. */
99
- s->enabled = false;
100
-}
101
-
102
-static void pca954x_channel_class_init(ObjectClass *klass, void *data)
103
-{
104
- DeviceClass *dc = DEVICE_CLASS(klass);
105
- dc->desc = "Pca954x Channel";
106
+ return pca954x->bus[channel];
107
}
108
109
static void pca9546_class_init(ObjectClass *klass, void *data)
110
@@ -XXX,XX +XXX,XX @@ static void pca9548_class_init(ObjectClass *klass, void *data)
111
s->nchans = PCA9548_CHANNEL_COUNT;
112
}
113
114
-static void pca954x_realize(DeviceState *dev, Error **errp)
115
-{
116
- Pca954xState *s = PCA954X(dev);
117
- Pca954xClass *c = PCA954X_GET_CLASS(s);
118
- int i;
119
-
120
- /* SMBus modules. Cannot fail. */
121
- for (i = 0; i < c->nchans; i++) {
122
- sysbus_realize(SYS_BUS_DEVICE(&s->channel[i]), &error_abort);
123
- }
124
-}
125
-
126
static void pca954x_init(Object *obj)
127
{
128
Pca954xState *s = PCA954X(obj);
129
Pca954xClass *c = PCA954X_GET_CLASS(obj);
130
int i;
131
132
- /* Only initialize the children we expect. */
133
+ /* SMBus modules. Cannot fail. */
134
for (i = 0; i < c->nchans; i++) {
135
- object_initialize_child(obj, "channel[*]", &s->channel[i],
136
- TYPE_PCA954X_CHANNEL);
137
+ g_autofree gchar *bus_name = g_strdup_printf("i2c.%d", i);
138
+
139
+ /* start all channels as disabled. */
140
+ s->enabled[i] = false;
141
+ s->bus[i] = i2c_init_bus(DEVICE(s), bus_name);
142
}
143
}
144
145
@@ -XXX,XX +XXX,XX @@ static void pca954x_class_init(ObjectClass *klass, void *data)
146
rc->phases.enter = pca954x_enter_reset;
147
148
dc->desc = "Pca954x i2c-mux";
149
- dc->realize = pca954x_realize;
150
151
k->write_data = pca954x_write_data;
152
k->receive_byte = pca954x_read_byte;
153
@@ -XXX,XX +XXX,XX @@ static const TypeInfo pca954x_info[] = {
154
.parent = TYPE_PCA954X,
155
.class_init = pca9548_class_init,
156
},
157
- {
158
- .name = TYPE_PCA954X_CHANNEL,
159
- .parent = TYPE_SYS_BUS_DEVICE,
160
- .class_init = pca954x_channel_class_init,
161
- .instance_size = sizeof(Pca954xChannel),
162
- .instance_init = pca954x_channel_init,
163
- }
164
};
165
166
DEFINE_TYPES(pca954x_info)
167
--
135
--
168
2.25.1
136
2.34.1
169
137
170
138
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The macro is a bit more readable than the inlined computation.
3
Remove "3" as a special case for which and simply
4
branch to return the desired value.
4
5
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220301215958.157011-7-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/helper.c | 4 ++--
11
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
11
1 file changed, 2 insertions(+), 2 deletions(-)
12
1 file changed, 10 insertions(+), 10 deletions(-)
12
13
13
diff --git a/target/arm/helper.c b/target/arm/helper.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/target/arm/helper.c
16
--- a/fpu/softfloat-parts.c.inc
16
+++ b/target/arm/helper.c
17
+++ b/fpu/softfloat-parts.c.inc
17
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
18
level = startlevel;
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
}
19
}
52
}
20
53
21
- indexmask_grainsize = (1ULL << (stride + 3)) - 1;
54
- if (which == 3) {
22
- indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
55
- parts_default_nan(a, s);
23
+ indexmask_grainsize = MAKE_64BIT_MASK(0, stride + 3);
56
- return a;
24
+ indexmask = MAKE_64BIT_MASK(0, inputsize - (stride * (4 - level)));
57
- }
25
58
-
26
/* Now we can extract the actual base address from the TTBR */
59
switch (which) {
27
descaddr = extract64(ttbr, 0, 48);
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
/*
28
--
73
--
29
2.25.1
74
2.34.1
30
75
31
76
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This field controls the output (intermediate) physical address size
3
Assign the pointer return value to 'a' directly,
4
of the translation process. V8 requires to raise an AddressSize
4
rather than going through an intermediary index.
5
fault if the page tables are programmed incorrectly, such that any
6
intermediate descriptor address, or the final translated address,
7
is out of range.
8
5
9
Add a PS field to ARMVAParameters, and properly compute outputsize
10
in get_phys_addr_lpae. Test the descaddr as extracted from TTBR
11
and from page table entries.
12
13
Restrict descaddrmask so that we won't raise the fault for v7.
14
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20220301215958.157011-8-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
10
---
21
target/arm/internals.h | 1 +
11
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
22
target/arm/helper.c | 72 ++++++++++++++++++++++++++++++++----------
12
1 file changed, 10 insertions(+), 22 deletions(-)
23
2 files changed, 57 insertions(+), 16 deletions(-)
24
13
25
diff --git a/target/arm/internals.h b/target/arm/internals.h
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
26
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/internals.h
16
--- a/fpu/softfloat-parts.c.inc
28
+++ b/target/arm/internals.h
17
+++ b/fpu/softfloat-parts.c.inc
29
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
*/
19
FloatPartsN *c, float_status *s,
31
typedef struct ARMVAParameters {
20
int ab_mask, int abc_mask)
32
unsigned tsz : 8;
33
+ unsigned ps : 3;
34
unsigned select : 1;
35
bool tbi : 1;
36
bool epd : 1;
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
42
}
43
#endif /* !CONFIG_USER_ONLY */
44
45
+/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
46
+static const uint8_t pamax_map[] = {
47
+ [0] = 32,
48
+ [1] = 36,
49
+ [2] = 40,
50
+ [3] = 42,
51
+ [4] = 44,
52
+ [5] = 48,
53
+};
54
+
55
/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
56
unsigned int arm_pamax(ARMCPU *cpu)
57
{
21
{
58
- static const unsigned int pamax_map[] = {
22
- int which;
59
- [0] = 32,
23
bool infzero = (ab_mask == float_cmask_infzero);
60
- [1] = 36,
24
bool have_snan = (abc_mask & float_cmask_snan);
61
- [2] = 40,
25
+ FloatPartsN *ret;
62
- [3] = 42,
26
63
- [4] = 44,
27
if (unlikely(have_snan)) {
64
- [5] = 48,
28
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
65
- };
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
66
unsigned int parange =
30
default:
67
FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
31
g_assert_not_reached();
68
69
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
70
{
71
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
72
bool epd, hpd, using16k, using64k, tsz_oob;
73
- int select, tsz, tbi, max_tsz, min_tsz;
74
+ int select, tsz, tbi, max_tsz, min_tsz, ps;
75
76
if (!regime_has_2_ranges(mmu_idx)) {
77
select = 0;
78
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
79
hpd = extract32(tcr, 24, 1);
80
}
32
}
81
epd = false;
33
- which = 2;
82
+ ps = extract32(tcr, 16, 3);
34
+ ret = c;
83
} else {
35
} else {
84
/*
36
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
85
* Bit 55 is always between the two regions, and is canonical for
37
+ FloatPartsN *val[3] = { a, b, c };
86
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
38
Float3NaNPropRule rule = s->float_3nan_prop_rule;
87
epd = extract32(tcr, 23, 1);
39
88
hpd = extract64(tcr, 42, 1);
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));
89
}
56
}
90
+ ps = extract64(tcr, 32, 3);
91
}
57
}
92
58
93
if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
59
- switch (which) {
94
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
60
- case 0:
95
61
- break;
96
return (ARMVAParameters) {
62
- case 1:
97
.tsz = tsz,
63
- a = b;
98
+ .ps = ps,
64
- break;
99
.select = select,
65
- case 2:
100
.tbi = tbi,
66
- a = c;
101
.epd = epd,
67
- break;
102
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
68
- default:
103
69
- g_assert_not_reached();
104
/* TODO: This code does not support shareability levels. */
70
+ if (is_snan(ret->cls)) {
105
if (aarch64) {
71
+ parts_silence_nan(ret, s);
106
+ int ps;
72
}
107
+
73
- if (is_snan(a->cls)) {
108
param = aa64_va_parameters(env, address, mmu_idx,
74
- parts_silence_nan(a, s);
109
access_type != MMU_INST_FETCH);
75
- }
110
level = 0;
76
- return a;
111
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
77
+ return ret;
112
78
113
addrsize = 64 - 8 * param.tbi;
79
default_nan:
114
inputsize = 64 - param.tsz;
80
parts_default_nan(a, s);
115
- outputsize = arm_pamax(cpu);
116
+
117
+ /*
118
+ * Bound PS by PARANGE to find the effective output address size.
119
+ * ID_AA64MMFR0 is a read-only register so values outside of the
120
+ * supported mappings can be considered an implementation error.
121
+ */
122
+ ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
123
+ ps = MIN(ps, param.ps);
124
+ assert(ps < ARRAY_SIZE(pamax_map));
125
+ outputsize = pamax_map[ps];
126
} else {
127
param = aa32_va_parameters(env, address, mmu_idx);
128
level = 1;
129
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
130
131
/* Now we can extract the actual base address from the TTBR */
132
descaddr = extract64(ttbr, 0, 48);
133
+
134
+ /*
135
+ * If the base address is out of range, raise AddressSizeFault.
136
+ * In the pseudocode, this is !IsZero(baseregister<47:outputsize>),
137
+ * but we've just cleared the bits above 47, so simplify the test.
138
+ */
139
+ if (descaddr >> outputsize) {
140
+ level = 0;
141
+ fault_type = ARMFault_AddressSize;
142
+ goto do_fault;
143
+ }
144
+
145
/*
146
* We rely on this masking to clear the RES0 bits at the bottom of the TTBR
147
* and also to mask out CnP (bit 0) which could validly be non-zero.
148
*/
149
descaddr &= ~indexmask;
150
151
- /* The address field in the descriptor goes up to bit 39 for ARMv7
152
- * but up to bit 47 for ARMv8, but we use the descaddrmask
153
- * up to bit 39 for AArch32, because we don't need other bits in that case
154
- * to construct next descriptor address (anyway they should be all zeroes).
155
+ /*
156
+ * For AArch32, the address field in the descriptor goes up to bit 39
157
+ * for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0
158
+ * or an AddressSize fault is raised. So for v8 we extract those SBZ
159
+ * bits as part of the address, which will be checked via outputsize.
160
+ * For AArch64, the address field always goes up to bit 47 (with extra
161
+ * bits for FEAT_LPA placed elsewhere). AArch64 implies v8.
162
*/
163
- descaddrmask = ((1ull << (aarch64 ? 48 : 40)) - 1) &
164
- ~indexmask_grainsize;
165
+ if (arm_feature(env, ARM_FEATURE_V8)) {
166
+ descaddrmask = MAKE_64BIT_MASK(0, 48);
167
+ } else {
168
+ descaddrmask = MAKE_64BIT_MASK(0, 40);
169
+ }
170
+ descaddrmask &= ~indexmask_grainsize;
171
172
/* Secure accesses start with the page table in secure memory and
173
* can be downgraded to non-secure at any step. Non-secure accesses
174
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
175
/* Invalid, or the Reserved level 3 encoding */
176
goto do_fault;
177
}
178
+
179
descaddr = descriptor & descaddrmask;
180
+ if (descaddr >> outputsize) {
181
+ fault_type = ARMFault_AddressSize;
182
+ goto do_fault;
183
+ }
184
185
if ((descriptor & 2) && (level < 3)) {
186
/* Table entry. The top five bits are attributes which may
187
--
81
--
188
2.25.1
82
2.34.1
189
83
190
84
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We will shortly share parts of this function with other portions
3
While all indices into val[] should be in [0-2], the mask
4
of address translation.
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.
5
7
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220301215958.157011-5-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>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
target/arm/internals.h | 19 +------------------
13
fpu/softfloat-parts.c.inc | 2 +-
14
target/arm/helper.c | 22 ++++++++++++++++++++++
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
2 files changed, 23 insertions(+), 18 deletions(-)
16
15
17
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/internals.h
18
--- a/fpu/softfloat-parts.c.inc
20
+++ b/target/arm/internals.h
19
+++ b/fpu/softfloat-parts.c.inc
21
@@ -XXX,XX +XXX,XX @@ static inline void update_spsel(CPUARMState *env, uint32_t imm)
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
22
* Returns the implementation defined bit-width of physical addresses.
21
}
23
* The ARMv8 reference manuals refer to this as PAMax().
22
ret = c;
24
*/
23
} else {
25
-static inline unsigned int arm_pamax(ARMCPU *cpu)
24
- FloatPartsN *val[3] = { a, b, c };
26
-{
25
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
27
- static const unsigned int pamax_map[] = {
26
Float3NaNPropRule rule = s->float_3nan_prop_rule;
28
- [0] = 32,
27
29
- [1] = 36,
28
assert(rule != float_3nan_prop_none);
30
- [2] = 40,
31
- [3] = 42,
32
- [4] = 44,
33
- [5] = 48,
34
- };
35
- unsigned int parange =
36
- FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
37
-
38
- /* id_aa64mmfr0 is a read-only register so values outside of the
39
- * supported mappings can be considered an implementation error. */
40
- assert(parange < ARRAY_SIZE(pamax_map));
41
- return pamax_map[parange];
42
-}
43
+unsigned int arm_pamax(ARMCPU *cpu);
44
45
/* Return true if extended addresses are enabled.
46
* This is always the case if our translation regime is 64 bit,
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/helper.c
50
+++ b/target/arm/helper.c
51
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
52
}
53
#endif /* !CONFIG_USER_ONLY */
54
55
+/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
56
+unsigned int arm_pamax(ARMCPU *cpu)
57
+{
58
+ static const unsigned int pamax_map[] = {
59
+ [0] = 32,
60
+ [1] = 36,
61
+ [2] = 40,
62
+ [3] = 42,
63
+ [4] = 44,
64
+ [5] = 48,
65
+ };
66
+ unsigned int parange =
67
+ FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
68
+
69
+ /*
70
+ * id_aa64mmfr0 is a read-only register so values outside of the
71
+ * supported mappings can be considered an implementation error.
72
+ */
73
+ assert(parange < ARRAY_SIZE(pamax_map));
74
+ return pamax_map[parange];
75
+}
76
+
77
static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
78
{
79
if (regime_has_2_ranges(mmu_idx)) {
80
--
29
--
81
2.25.1
30
2.34.1
82
31
83
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This feature widens physical addresses (and intermediate physical
3
This function is part of the public interface and
4
addresses for 2-stage translation) from 48 to 52 bits, when using
4
is not "specialized" to any target in any way.
5
4k or 16k pages.
6
5
7
This introduces the DS bit to TCR_ELx, which is RES0 unless the
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
page size is enabled and supports LPA2, resulting in the effective
9
value of DS for a given table walk. The DS bit changes the format
10
of the page table descriptor slightly, moving the PS field out to
11
TCR so that all pages have the same sharability and repurposing
12
those bits of the page table descriptor for the highest bits of
13
the output address.
14
15
Do not yet enable FEAT_LPA2; we need extra plumbing to avoid
16
tickling an old kernel bug.
17
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
20
Message-id: 20220301215958.157011-17-richard.henderson@linaro.org
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
10
---
23
docs/system/arm/emulation.rst | 1 +
11
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
24
target/arm/cpu.h | 22 ++++++++
12
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
25
target/arm/internals.h | 2 +
13
2 files changed, 52 insertions(+), 52 deletions(-)
26
target/arm/helper.c | 102 +++++++++++++++++++++++++++++-----
27
4 files changed, 112 insertions(+), 15 deletions(-)
28
14
29
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
30
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
31
--- a/docs/system/arm/emulation.rst
17
--- a/fpu/softfloat.c
32
+++ b/docs/system/arm/emulation.rst
18
+++ b/fpu/softfloat.c
33
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
34
- FEAT_JSCVT (JavaScript conversion instructions)
20
*zExpPtr = 1 - shiftCount;
35
- FEAT_LOR (Limited ordering regions)
36
- FEAT_LPA (Large Physical Address space)
37
+- FEAT_LPA2 (Large Physical and virtual Address space v2)
38
- FEAT_LRCPC (Load-acquire RCpc instructions)
39
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
40
- FEAT_LSE (Large System Extensions)
41
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/cpu.h
44
+++ b/target/arm/cpu.h
45
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id)
46
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0;
47
}
21
}
48
22
49
+static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
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)
50
+{
30
+{
51
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
31
+ bool aIsLargerSignificand;
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;
58
+ } else {
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;
72
+ }
52
+}
73
+}
53
+
74
+
54
+static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
75
/*----------------------------------------------------------------------------
55
+{
76
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
56
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
77
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
57
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
78
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
58
+}
59
+
60
+static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
61
+{
62
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
63
+}
64
+
65
+static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
66
+{
67
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
68
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
69
+}
70
+
71
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
72
{
73
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
74
diff --git a/target/arm/internals.h b/target/arm/internals.h
75
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/internals.h
80
--- a/fpu/softfloat-specialize.c.inc
77
+++ b/target/arm/internals.h
81
+++ b/fpu/softfloat-specialize.c.inc
78
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
82
@@ -XXX,XX +XXX,XX @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
79
typedef struct ARMVAParameters {
83
return a;
80
unsigned tsz : 8;
81
unsigned ps : 3;
82
+ unsigned sh : 2;
83
unsigned select : 1;
84
bool tbi : 1;
85
bool epd : 1;
86
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
87
bool using16k : 1;
88
bool using64k : 1;
89
bool tsz_oob : 1; /* tsz has been clamped to legal range */
90
+ bool ds : 1;
91
} ARMVAParameters;
92
93
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
94
diff --git a/target/arm/helper.c b/target/arm/helper.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/helper.c
97
+++ b/target/arm/helper.c
98
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
99
} else {
100
ret.base = extract64(value, 0, 37);
101
}
102
+ if (param.ds) {
103
+ /*
104
+ * With DS=1, BaseADDR is always shifted 16 so that it is able
105
+ * to address all 52 va bits. The input address is perforce
106
+ * aligned on a 64k boundary regardless of translation granule.
107
+ */
108
+ page_shift = 16;
109
+ }
110
ret.base <<= page_shift;
111
112
return ret;
113
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
114
const int grainsize = stride + 3;
115
int startsizecheck;
116
117
- /* Negative levels are never allowed. */
118
- if (level < 0) {
119
+ /*
120
+ * Negative levels are usually not allowed...
121
+ * Except for FEAT_LPA2, 4k page table, 52-bit address space, which
122
+ * begins with level -1. Note that previous feature tests will have
123
+ * eliminated this combination if it is not enabled.
124
+ */
125
+ if (level < (inputsize == 52 && stride == 9 ? -1 : 0)) {
126
return false;
127
}
128
129
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
130
ARMMMUIdx mmu_idx, bool data)
131
{
132
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
133
- bool epd, hpd, using16k, using64k, tsz_oob;
134
- int select, tsz, tbi, max_tsz, min_tsz, ps;
135
+ bool epd, hpd, using16k, using64k, tsz_oob, ds;
136
+ int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
137
+ ARMCPU *cpu = env_archcpu(env);
138
139
if (!regime_has_2_ranges(mmu_idx)) {
140
select = 0;
141
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
142
hpd = extract32(tcr, 24, 1);
143
}
144
epd = false;
145
+ sh = extract32(tcr, 12, 2);
146
ps = extract32(tcr, 16, 3);
147
+ ds = extract64(tcr, 32, 1);
148
} else {
149
/*
150
* Bit 55 is always between the two regions, and is canonical for
151
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
152
if (!select) {
153
tsz = extract32(tcr, 0, 6);
154
epd = extract32(tcr, 7, 1);
155
+ sh = extract32(tcr, 12, 2);
156
using64k = extract32(tcr, 14, 1);
157
using16k = extract32(tcr, 15, 1);
158
hpd = extract64(tcr, 41, 1);
159
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
160
using64k = tg == 3;
161
tsz = extract32(tcr, 16, 6);
162
epd = extract32(tcr, 23, 1);
163
+ sh = extract32(tcr, 28, 2);
164
hpd = extract64(tcr, 42, 1);
165
}
166
ps = extract64(tcr, 32, 3);
167
+ ds = extract64(tcr, 59, 1);
168
}
169
170
- if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
171
+ if (cpu_isar_feature(aa64_st, cpu)) {
172
max_tsz = 48 - using64k;
173
} else {
174
max_tsz = 39;
175
}
176
177
+ /*
178
+ * DS is RES0 unless FEAT_LPA2 is supported for the given page size;
179
+ * adjust the effective value of DS, as documented.
180
+ */
181
min_tsz = 16;
182
if (using64k) {
183
- if (cpu_isar_feature(aa64_lva, env_archcpu(env))) {
184
+ if (cpu_isar_feature(aa64_lva, cpu)) {
185
+ min_tsz = 12;
186
+ }
187
+ ds = false;
188
+ } else if (ds) {
189
+ switch (mmu_idx) {
190
+ case ARMMMUIdx_Stage2:
191
+ case ARMMMUIdx_Stage2_S:
192
+ if (using16k) {
193
+ ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
194
+ } else {
195
+ ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
196
+ }
197
+ break;
198
+ default:
199
+ if (using16k) {
200
+ ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
201
+ } else {
202
+ ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
203
+ }
204
+ break;
205
+ }
206
+ if (ds) {
207
min_tsz = 12;
208
}
209
}
210
- /* TODO: FEAT_LPA2 */
211
212
if (tsz > max_tsz) {
213
tsz = max_tsz;
214
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
215
return (ARMVAParameters) {
216
.tsz = tsz,
217
.ps = ps,
218
+ .sh = sh,
219
.select = select,
220
.tbi = tbi,
221
.epd = epd,
222
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
223
.using16k = using16k,
224
.using64k = using64k,
225
.tsz_oob = tsz_oob,
226
+ .ds = ds,
227
};
228
}
84
}
229
85
230
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
86
-/*----------------------------------------------------------------------------
231
* VTCR_EL2.SL0 field (whose interpretation depends on the page size)
87
-| Takes two extended double-precision floating-point values `a' and `b', one
232
*/
88
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
233
uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2);
89
-| `b' is a signaling NaN, the invalid exception is raised.
234
+ uint32_t sl2 = extract64(tcr->raw_tcr, 33, 1);
90
-*----------------------------------------------------------------------------*/
235
uint32_t startlevel;
91
-
236
bool ok;
92
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
237
93
-{
238
- if (!aarch64 || stride == 9) {
94
- bool aIsLargerSignificand;
239
+ /* SL2 is RES0 unless DS=1 & 4kb granule. */
95
- FloatClass a_cls, b_cls;
240
+ if (param.ds && stride == 9 && sl2) {
96
-
241
+ if (sl0 != 0) {
97
- /* This is not complete, but is good enough for pickNaN. */
242
+ level = 0;
98
- a_cls = (!floatx80_is_any_nan(a)
243
+ fault_type = ARMFault_Translation;
99
- ? float_class_normal
244
+ goto do_fault;
100
- : floatx80_is_signaling_nan(a, status)
245
+ }
101
- ? float_class_snan
246
+ startlevel = -1;
102
- : float_class_qnan);
247
+ } else if (!aarch64 || stride == 9) {
103
- b_cls = (!floatx80_is_any_nan(b)
248
/* AArch32 or 4KB pages */
104
- ? float_class_normal
249
startlevel = 2 - sl0;
105
- : floatx80_is_signaling_nan(b, status)
250
106
- ? float_class_snan
251
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
107
- : float_class_qnan);
252
* for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0
108
-
253
* or an AddressSize fault is raised. So for v8 we extract those SBZ
109
- if (is_snan(a_cls) || is_snan(b_cls)) {
254
* bits as part of the address, which will be checked via outputsize.
110
- float_raise(float_flag_invalid, status);
255
- * For AArch64, the address field always goes up to bit 47 (with extra
111
- }
256
- * bits for FEAT_LPA placed elsewhere). AArch64 implies v8.
112
-
257
+ * For AArch64, the address field goes up to bit 47, or 49 with FEAT_LPA2;
113
- if (status->default_nan_mode) {
258
+ * the highest bits of a 52-bit output are placed elsewhere.
114
- return floatx80_default_nan(status);
259
*/
115
- }
260
- if (arm_feature(env, ARM_FEATURE_V8)) {
116
-
261
+ if (param.ds) {
117
- if (a.low < b.low) {
262
+ descaddrmask = MAKE_64BIT_MASK(0, 50);
118
- aIsLargerSignificand = 0;
263
+ } else if (arm_feature(env, ARM_FEATURE_V8)) {
119
- } else if (b.low < a.low) {
264
descaddrmask = MAKE_64BIT_MASK(0, 48);
120
- aIsLargerSignificand = 1;
265
} else {
121
- } else {
266
descaddrmask = MAKE_64BIT_MASK(0, 40);
122
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
267
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
123
- }
268
124
-
269
/*
125
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
270
* For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
126
- if (is_snan(b_cls)) {
271
- * of descriptor. Otherwise, if descaddr is out of range, raise
127
- return floatx80_silence_nan(b, status);
272
- * AddressSizeFault.
128
- }
273
+ * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of
129
- return b;
274
+ * descaddr are in [9:8]. Otherwise, if descaddr is out of range,
130
- } else {
275
+ * raise AddressSizeFault.
131
- if (is_snan(a_cls)) {
276
*/
132
- return floatx80_silence_nan(a, status);
277
if (outputsize > 48) {
133
- }
278
- descaddr |= extract64(descriptor, 12, 4) << 48;
134
- return a;
279
+ if (param.ds) {
135
- }
280
+ descaddr |= extract64(descriptor, 8, 2) << 50;
136
-}
281
+ } else {
137
-
282
+ descaddr |= extract64(descriptor, 12, 4) << 48;
138
/*----------------------------------------------------------------------------
283
+ }
139
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
284
} else if (descaddr >> outputsize) {
140
| NaN; otherwise returns 0.
285
fault_type = ARMFault_AddressSize;
286
goto do_fault;
287
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
288
assert(attrindx <= 7);
289
cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
290
}
291
- cacheattrs->shareability = extract32(attrs, 6, 2);
292
+
293
+ /*
294
+ * For FEAT_LPA2 and effective DS, the SH field in the attributes
295
+ * was re-purposed for output address bits. The SH attribute in
296
+ * that case comes from TCR_ELx, which we extracted earlier.
297
+ */
298
+ if (param.ds) {
299
+ cacheattrs->shareability = param.sh;
300
+ } else {
301
+ cacheattrs->shareability = extract32(attrs, 6, 2);
302
+ }
303
304
*phys_ptr = descaddr;
305
*page_size_ptr = page_size;
306
--
141
--
307
2.25.1
142
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Pass down the width of the output address from translation.
3
Unpacking and repacking the parts may be slightly more work
4
For now this is still just PAMax, but a subsequent patch will
4
than we did before, but we get to reuse more code. For a
5
compute the correct value from TCR_ELx.{I}PS.
5
code path handling exceptional values, this is an improvement.
6
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>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220301215958.157011-6-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
target/arm/helper.c | 21 ++++++++++-----------
12
fpu/softfloat.c | 43 +++++--------------------------------------
13
1 file changed, 10 insertions(+), 11 deletions(-)
13
1 file changed, 5 insertions(+), 38 deletions(-)
14
14
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
17
--- a/fpu/softfloat.c
18
+++ b/target/arm/helper.c
18
+++ b/fpu/softfloat.c
19
@@ -XXX,XX +XXX,XX @@ do_fault:
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
20
* false otherwise.
20
21
*/
21
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
22
static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
23
- int inputsize, int stride)
24
+ int inputsize, int stride, int outputsize)
25
{
22
{
26
const int grainsize = stride + 3;
23
- bool aIsLargerSignificand;
27
int startsizecheck;
24
- FloatClass a_cls, b_cls;
28
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
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);
29
}
47
}
30
48
31
if (is_aa64) {
49
- if (a.low < b.low) {
32
- CPUARMState *env = &cpu->env;
50
- aIsLargerSignificand = 0;
33
- unsigned int pamax = arm_pamax(cpu);
51
- } else if (b.low < a.low) {
52
- aIsLargerSignificand = 1;
53
- } else {
54
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
55
- }
34
-
56
-
35
switch (stride) {
57
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
36
case 13: /* 64KB Pages. */
58
- if (is_snan(b_cls)) {
37
- if (level == 0 || (level == 1 && pamax <= 42)) {
59
- return floatx80_silence_nan(b, status);
38
+ if (level == 0 || (level == 1 && outputsize <= 42)) {
60
- }
39
return false;
61
- return b;
40
}
62
- } else {
41
break;
63
- if (is_snan(a_cls)) {
42
case 11: /* 16KB Pages. */
64
- return floatx80_silence_nan(a, status);
43
- if (level == 0 || (level == 1 && pamax <= 40)) {
65
- }
44
+ if (level == 0 || (level == 1 && outputsize <= 40)) {
66
- return a;
45
return false;
67
- }
46
}
68
+ pr = parts_pick_nan(&pa, &pb, status);
47
break;
69
+ return floatx80_round_pack_canonical(pr, status);
48
case 9: /* 4KB Pages. */
70
}
49
- if (level == 0 && pamax <= 42) {
71
50
+ if (level == 0 && outputsize <= 42) {
72
/*----------------------------------------------------------------------------
51
return false;
52
}
53
break;
54
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
55
}
56
57
/* Inputsize checks. */
58
- if (inputsize > pamax &&
59
- (arm_el_is_aa64(env, 1) || inputsize > 40)) {
60
+ if (inputsize > outputsize &&
61
+ (arm_el_is_aa64(&cpu->env, 1) || inputsize > 40)) {
62
/* This is CONSTRAINED UNPREDICTABLE and we choose to fault. */
63
return false;
64
}
65
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
66
target_ulong page_size;
67
uint32_t attrs;
68
int32_t stride;
69
- int addrsize, inputsize;
70
+ int addrsize, inputsize, outputsize;
71
TCR *tcr = regime_tcr(env, mmu_idx);
72
int ap, ns, xn, pxn;
73
uint32_t el = regime_el(env, mmu_idx);
74
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
75
76
addrsize = 64 - 8 * param.tbi;
77
inputsize = 64 - param.tsz;
78
+ outputsize = arm_pamax(cpu);
79
} else {
80
param = aa32_va_parameters(env, address, mmu_idx);
81
level = 1;
82
addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
83
inputsize = addrsize - param.tsz;
84
+ outputsize = 40;
85
}
86
87
/*
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
89
90
/* Check that the starting level is valid. */
91
ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
92
- inputsize, stride);
93
+ inputsize, stride, outputsize);
94
if (!ok) {
95
fault_type = ARMFault_Translation;
96
goto do_fault;
97
--
73
--
98
2.25.1
74
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Without FEAT_LVA, the behaviour of programming an invalid value
3
Inline pickNaN into its only caller. This makes one assert
4
is IMPLEMENTATION DEFINED. With FEAT_LVA, programming an invalid
4
redundant with the immediately preceding IF.
5
minimum value requires a Translation fault.
5
6
7
It is most self-consistent to choose to generate the fault always.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220301215958.157011-4-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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
target/arm/internals.h | 1 +
11
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
15
target/arm/helper.c | 32 ++++++++++++++++++++++++++++----
12
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
16
2 files changed, 29 insertions(+), 4 deletions(-)
13
2 files changed, 73 insertions(+), 105 deletions(-)
17
14
18
diff --git a/target/arm/internals.h b/target/arm/internals.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/target/arm/internals.h
17
--- a/fpu/softfloat-parts.c.inc
21
+++ b/target/arm/internals.h
18
+++ b/fpu/softfloat-parts.c.inc
22
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
19
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
23
bool hpd : 1;
20
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
24
bool using16k : 1;
21
float_status *s)
25
bool using64k : 1;
22
{
26
+ bool tsz_oob : 1; /* tsz has been clamped to legal range */
23
+ int cmp, which;
27
} ARMVAParameters;
24
+
28
25
if (is_snan(a->cls) || is_snan(b->cls)) {
29
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
30
diff --git a/target/arm/helper.c b/target/arm/helper.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/target/arm/helper.c
119
--- a/fpu/softfloat-specialize.c.inc
33
+++ b/target/arm/helper.c
120
+++ b/fpu/softfloat-specialize.c.inc
34
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
121
@@ -XXX,XX +XXX,XX @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
35
ARMMMUIdx mmu_idx, bool data)
36
{
37
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
38
- bool epd, hpd, using16k, using64k;
39
- int select, tsz, tbi, max_tsz;
40
+ bool epd, hpd, using16k, using64k, tsz_oob;
41
+ int select, tsz, tbi, max_tsz, min_tsz;
42
43
if (!regime_has_2_ranges(mmu_idx)) {
44
select = 0;
45
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
46
} else {
47
max_tsz = 39;
48
}
122
}
49
+ min_tsz = 16; /* TODO: ARMv8.2-LVA */
50
51
- tsz = MIN(tsz, max_tsz);
52
- tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
53
+ if (tsz > max_tsz) {
54
+ tsz = max_tsz;
55
+ tsz_oob = true;
56
+ } else if (tsz < min_tsz) {
57
+ tsz = min_tsz;
58
+ tsz_oob = true;
59
+ } else {
60
+ tsz_oob = false;
61
+ }
62
63
/* Present TBI as a composite with TBID. */
64
tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
65
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
66
.hpd = hpd,
67
.using16k = using16k,
68
.using64k = using64k,
69
+ .tsz_oob = tsz_oob,
70
};
71
}
123
}
72
124
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
125
-/*----------------------------------------------------------------------------
74
param = aa64_va_parameters(env, address, mmu_idx,
126
-| Select which NaN to propagate for a two-input operation.
75
access_type != MMU_INST_FETCH);
127
-| IEEE754 doesn't specify all the details of this, so the
76
level = 0;
128
-| algorithm is target-specific.
77
+
129
-| The routine is passed various bits of information about the
78
+ /*
130
-| two NaNs and should return 0 to select NaN a and 1 for NaN b.
79
+ * If TxSZ is programmed to a value larger than the maximum,
131
-| Note that signalling NaNs are always squashed to quiet NaNs
80
+ * or smaller than the effective minimum, it is IMPLEMENTATION
132
-| by the caller, by calling floatXX_silence_nan() before
81
+ * DEFINED whether we behave as if the field were programmed
133
-| returning them.
82
+ * within bounds, or if a level 0 Translation fault is generated.
134
-|
83
+ *
135
-| aIsLargerSignificand is only valid if both a and b are NaNs
84
+ * With FEAT_LVA, fault on less than minimum becomes required,
136
-| of some kind, and is true if a has the larger significand,
85
+ * so our choice is to always raise the fault.
137
-| or if both a and b have the same significand but a is
86
+ */
138
-| positive but b is negative. It is only needed for the x87
87
+ if (param.tsz_oob) {
139
-| tie-break rule.
88
+ fault_type = ARMFault_Translation;
140
-*----------------------------------------------------------------------------*/
89
+ goto do_fault;
141
-
90
+ }
142
-static int pickNaN(FloatClass a_cls, FloatClass b_cls,
91
+
143
- bool aIsLargerSignificand, float_status *status)
92
addrsize = 64 - 8 * param.tbi;
144
-{
93
inputsize = 64 - param.tsz;
145
- /*
94
} else {
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.
95
--
224
--
96
2.25.1
225
2.34.1
226
227
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
With FEAT_LPA2, rather than introducing translation level 4,
3
Remember if there was an SNaN, and use that to simplify
4
we introduce level -1, below the current level 0. Extend
4
float_2nan_prop_s_{ab,ba} to only the snan component.
5
arm_fi_to_lfsc to handle these faults.
5
Then, fall through to the corresponding
6
float_2nan_prop_{ab,ba} case to handle any remaining
7
nans, which must be quiet.
6
8
7
Assert that this new translation level does not leak into
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
fault types for which it is not defined, which allows some
9
masking of fi->level to be removed.
10
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20241203203949.483774-10-richard.henderson@linaro.org
13
Message-id: 20220301215958.157011-12-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
target/arm/internals.h | 35 +++++++++++++++++++++++++++++------
14
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
17
1 file changed, 29 insertions(+), 6 deletions(-)
15
1 file changed, 12 insertions(+), 20 deletions(-)
18
16
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/internals.h
19
--- a/fpu/softfloat-parts.c.inc
22
+++ b/target/arm/internals.h
20
+++ b/fpu/softfloat-parts.c.inc
23
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
21
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
24
case ARMFault_None:
22
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
25
return 0;
23
float_status *s)
26
case ARMFault_AddressSize:
24
{
27
- fsc = fi->level & 3;
25
+ bool have_snan = false;
28
+ assert(fi->level >= -1 && fi->level <= 3);
26
int cmp, which;
29
+ if (fi->level < 0) {
27
30
+ fsc = 0b101001;
28
if (is_snan(a->cls) || is_snan(b->cls)) {
31
+ } else {
29
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
32
+ fsc = fi->level;
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;
33
+ }
70
+ }
71
+ /* fall through */
72
case float_2nan_prop_ba:
73
which = is_nan(b->cls) ? 1 : 0;
34
break;
74
break;
35
case ARMFault_AccessFlag:
36
- fsc = (fi->level & 3) | (0x2 << 2);
37
+ assert(fi->level >= 0 && fi->level <= 3);
38
+ fsc = 0b001000 | fi->level;
39
break;
40
case ARMFault_Permission:
41
- fsc = (fi->level & 3) | (0x3 << 2);
42
+ assert(fi->level >= 0 && fi->level <= 3);
43
+ fsc = 0b001100 | fi->level;
44
break;
45
case ARMFault_Translation:
46
- fsc = (fi->level & 3) | (0x1 << 2);
47
+ assert(fi->level >= -1 && fi->level <= 3);
48
+ if (fi->level < 0) {
49
+ fsc = 0b101011;
50
+ } else {
51
+ fsc = 0b000100 | fi->level;
52
+ }
53
break;
54
case ARMFault_SyncExternal:
55
fsc = 0x10 | (fi->ea << 12);
56
break;
57
case ARMFault_SyncExternalOnWalk:
58
- fsc = (fi->level & 3) | (0x5 << 2) | (fi->ea << 12);
59
+ assert(fi->level >= -1 && fi->level <= 3);
60
+ if (fi->level < 0) {
61
+ fsc = 0b010011;
62
+ } else {
63
+ fsc = 0b010100 | fi->level;
64
+ }
65
+ fsc |= fi->ea << 12;
66
break;
67
case ARMFault_SyncParity:
68
fsc = 0x18;
69
break;
70
case ARMFault_SyncParityOnWalk:
71
- fsc = (fi->level & 3) | (0x7 << 2);
72
+ assert(fi->level >= -1 && fi->level <= 3);
73
+ if (fi->level < 0) {
74
+ fsc = 0b011011;
75
+ } else {
76
+ fsc = 0b011100 | fi->level;
77
+ }
78
break;
79
case ARMFault_AsyncParity:
80
fsc = 0x19;
81
--
75
--
82
2.25.1
76
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We support 16k pages, but do not advertize that in ID_AA64MMFR0.
3
Move the fractional comparison to the end of the
4
4
float_2nan_prop_x87 case. This is not required for
5
The value 0 in the TGRAN*_2 fields indicates that stage2 lookups defer
5
any other 2nan propagation rule. Reorganize the
6
to the same support as stage1 lookups. This setting is deprecated, so
6
x87 case itself to break out of the switch when the
7
indicate support for all stage2 page sizes directly.
7
fractional comparison is not required.
8
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20220301215958.157011-16-richard.henderson@linaro.org
11
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
target/arm/cpu64.c | 4 ++++
14
fpu/softfloat-parts.c.inc | 19 +++++++++----------
15
1 file changed, 4 insertions(+)
15
1 file changed, 9 insertions(+), 10 deletions(-)
16
16
17
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu64.c
19
--- a/fpu/softfloat-parts.c.inc
20
+++ b/target/arm/cpu64.c
20
+++ b/fpu/softfloat-parts.c.inc
21
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
22
22
return a;
23
t = cpu->isar.id_aa64mmfr0;
23
}
24
t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
24
25
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1); /* 16k pages supported */
25
- cmp = frac_cmp(a, b);
26
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */
26
- if (cmp == 0) {
27
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
27
- cmp = a->sign < b->sign;
28
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
28
- }
29
cpu->isar.id_aa64mmfr0 = t;
29
-
30
30
switch (s->float_2nan_prop_rule) {
31
t = cpu->isar.id_aa64mmfr1;
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();
32
--
63
--
33
2.25.1
64
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Merge tlbi_aa64_range_get_length and tlbi_aa64_range_get_base,
3
Replace the "index" selecting between A and B with a result variable
4
returning a structure containing both results. Pass in the
4
of the proper type. This improves clarity within the function.
5
ARMMMUIdx, rather than the digested two_ranges boolean.
6
5
7
This is in preparation for FEAT_LPA2, where the interpretation
8
of 'value' depends on the effective value of DS for the regime.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20220301215958.157011-13-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-12-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
---
10
---
15
target/arm/helper.c | 58 +++++++++++++++++++--------------------------
11
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
16
1 file changed, 24 insertions(+), 34 deletions(-)
12
1 file changed, 13 insertions(+), 15 deletions(-)
17
13
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
16
--- a/fpu/softfloat-parts.c.inc
21
+++ b/target/arm/helper.c
17
+++ b/fpu/softfloat-parts.c.inc
22
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
23
}
19
float_status *s)
24
20
{
25
#ifdef TARGET_AARCH64
21
bool have_snan = false;
26
-static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
22
- int cmp, which;
27
- uint64_t value)
23
+ FloatPartsN *ret;
28
-{
24
+ int cmp;
29
- unsigned int page_shift;
25
30
- unsigned int page_size_granule;
26
if (is_snan(a->cls) || is_snan(b->cls)) {
31
- uint64_t num;
27
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
32
- uint64_t scale;
28
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
33
- uint64_t exponent;
29
switch (s->float_2nan_prop_rule) {
34
+typedef struct {
30
case float_2nan_prop_s_ab:
35
+ uint64_t base;
31
if (have_snan) {
36
uint64_t length;
32
- which = is_snan(a->cls) ? 0 : 1;
37
+} TLBIRange;
33
+ ret = is_snan(a->cls) ? a : b;
38
+
34
break;
39
+static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
35
}
40
+ uint64_t value)
36
/* fall through */
41
+{
37
case float_2nan_prop_ab:
42
+ unsigned int page_size_granule, page_shift, num, scale, exponent;
38
- which = is_nan(a->cls) ? 0 : 1;
43
+ TLBIRange ret = { };
39
+ ret = is_nan(a->cls) ? a : b;
44
40
break;
45
- num = extract64(value, 39, 5);
41
case float_2nan_prop_s_ba:
46
- scale = extract64(value, 44, 2);
42
if (have_snan) {
47
page_size_granule = extract64(value, 46, 2);
43
- which = is_snan(b->cls) ? 1 : 0;
48
44
+ ret = is_snan(b->cls) ? b : a;
49
if (page_size_granule == 0) {
45
break;
50
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
46
}
51
page_size_granule);
47
/* fall through */
52
- return 0;
48
case float_2nan_prop_ba:
53
+ return ret;
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();
54
}
82
}
55
83
56
page_shift = (page_size_granule - 1) * 2 + 12;
84
- if (which) {
57
-
85
- a = b;
58
+ num = extract64(value, 39, 5);
86
+ if (is_snan(ret->cls)) {
59
+ scale = extract64(value, 44, 2);
87
+ parts_silence_nan(ret, s);
60
exponent = (5 * scale) + 1;
61
- length = (num + 1) << (exponent + page_shift);
62
63
- return length;
64
-}
65
+ ret.length = (num + 1) << (exponent + page_shift);
66
67
-static uint64_t tlbi_aa64_range_get_base(CPUARMState *env, uint64_t value,
68
- bool two_ranges)
69
-{
70
- /* TODO: ARMv8.7 FEAT_LPA2 */
71
- uint64_t pageaddr;
72
-
73
- if (two_ranges) {
74
- pageaddr = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
75
+ if (regime_has_2_ranges(mmuidx)) {
76
+ ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
77
} else {
78
- pageaddr = extract64(value, 0, 37) << TARGET_PAGE_BITS;
79
+ ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS;
80
}
88
}
81
89
- if (is_snan(a->cls)) {
82
- return pageaddr;
90
- parts_silence_nan(a, s);
91
- }
92
- return a;
83
+ return ret;
93
+ return ret;
84
}
94
}
85
95
86
static void do_rvae_write(CPUARMState *env, uint64_t value,
96
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
87
int idxmap, bool synced)
88
{
89
ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
90
- bool two_ranges = regime_has_2_ranges(one_idx);
91
- uint64_t baseaddr, length;
92
+ TLBIRange range;
93
int bits;
94
95
- baseaddr = tlbi_aa64_range_get_base(env, value, two_ranges);
96
- length = tlbi_aa64_range_get_length(env, value);
97
- bits = tlbbits_for_regime(env, one_idx, baseaddr);
98
+ range = tlbi_aa64_get_range(env, one_idx, value);
99
+ bits = tlbbits_for_regime(env, one_idx, range.base);
100
101
if (synced) {
102
tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env),
103
- baseaddr,
104
- length,
105
+ range.base,
106
+ range.length,
107
idxmap,
108
bits);
109
} else {
110
- tlb_flush_range_by_mmuidx(env_cpu(env), baseaddr,
111
- length, idxmap, bits);
112
+ tlb_flush_range_by_mmuidx(env_cpu(env), range.base,
113
+ range.length, idxmap, bits);
114
}
115
}
116
117
--
97
--
118
2.25.1
98
2.34.1
99
100
diff view generated by jsdifflib
1
The tsc210x doesn't support anything other than 16-bit reads on the
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
SPI bus, but the guest can program the SPI controller to attempt
3
them anyway. If this happens, don't abort QEMU, just log this as
4
a guest error.
5
2
6
This fixes our machine_arm_n8x0.py:N8x0Machine.test_n800
3
I'm migrating to Qualcomm's new open source email infrastructure, so
7
acceptance test, which hits this assertion.
4
update my email address, and update the mailmap to match.
8
5
9
The reason we hit the assertion is because the guest kernel thinks
6
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
10
there is a TSC2005 on this SPI bus address, not a TSC210x. (The n810
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
11
*does* have a TSC2005 at this address.) The TSC2005 supports the
8
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
12
24-bit accesses which the guest driver makes, and the TSC210x does
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
not (that is, our TSC210x emulation is not missing support for a word
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
width the hardware can handle). It's not clear whether the problem
11
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
15
here is that the guest kernel incorrectly thinks the n800 has the
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
same device at this SPI bus address as the n810, or that QEMU's n810
13
---
17
board model doesn't get the SPI devices right. At this late date
14
MAINTAINERS | 2 +-
18
there no longer appears to be any reliable information on the web
15
.mailmap | 5 +++--
19
about the hardware behaviour, but I am inclined to think this is a
16
2 files changed, 4 insertions(+), 3 deletions(-)
20
guest kernel bug. In any case, we prefer not to abort QEMU for
21
guest-triggerable conditions, so logging the error is the right thing
22
to do.
23
17
24
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/736
18
diff --git a/MAINTAINERS b/MAINTAINERS
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
27
Message-id: 20220221140750.514557-1-peter.maydell@linaro.org
28
---
29
hw/input/tsc210x.c | 8 ++++++--
30
1 file changed, 6 insertions(+), 2 deletions(-)
31
32
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
33
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/input/tsc210x.c
20
--- a/MAINTAINERS
35
+++ b/hw/input/tsc210x.c
21
+++ b/MAINTAINERS
36
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
37
#include "hw/hw.h"
23
SBSA-REF
38
#include "audio/audio.h"
24
M: Radoslaw Biernacki <rad@semihalf.com>
39
#include "qemu/timer.h"
25
M: Peter Maydell <peter.maydell@linaro.org>
40
+#include "qemu/log.h"
26
-R: Leif Lindholm <quic_llindhol@quicinc.com>
41
#include "sysemu/reset.h"
27
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
42
#include "ui/console.h"
28
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
43
#include "hw/arm/omap.h" /* For I2SCodec */
29
L: qemu-arm@nongnu.org
44
@@ -XXX,XX +XXX,XX @@ uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
30
S: Maintained
45
TSC210xState *s = opaque;
31
diff --git a/.mailmap b/.mailmap
46
uint32_t ret = 0;
32
index XXXXXXX..XXXXXXX 100644
47
33
--- a/.mailmap
48
- if (len != 16)
34
+++ b/.mailmap
49
- hw_error("%s: FIXME: bad SPI word width %i\n", __func__, len);
35
@@ -XXX,XX +XXX,XX @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
50
+ if (len != 16) {
36
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
51
+ qemu_log_mask(LOG_GUEST_ERROR,
37
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
52
+ "%s: bad SPI word width %i\n", __func__, len);
38
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
53
+ return 0;
39
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
54
+ }
40
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
55
41
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
56
/* TODO: sequential reads etc - how do we make sure the host doesn't
42
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
57
* unintentionally read out a conversion result from a register while
43
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
44
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
45
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
46
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
58
--
47
--
59
2.25.1
48
2.34.1
60
49
61
50
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
2
2
3
The original A.a revision of the AArch64 ARM required that we
3
Previously, maintainer role was paused due to inactive email id. Commit id:
4
force-extend the addresses in these registers from 49 bits.
4
c009d715721861984c4987bcc78b7ee183e86d75.
5
This language has been loosened via a combination of IMPLEMENTATION
6
DEFINED and CONSTRAINTED UNPREDICTABLE to allow consideration of
7
the entire aligned address.
8
5
9
This means that we do not have to consider whether or not FEAT_LVA
6
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
10
is enabled, and decide from which bit an address might need to be
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
11
extended.
8
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
12
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220301215958.157011-9-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
target/arm/helper.c | 32 ++++++++++++++++++++++++--------
11
MAINTAINERS | 2 ++
19
1 file changed, 24 insertions(+), 8 deletions(-)
12
1 file changed, 2 insertions(+)
20
13
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/MAINTAINERS b/MAINTAINERS
22
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
16
--- a/MAINTAINERS
24
+++ b/target/arm/helper.c
17
+++ b/MAINTAINERS
25
@@ -XXX,XX +XXX,XX @@ static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
18
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-sb16-test.c
26
ARMCPU *cpu = env_archcpu(env);
19
27
int i = ri->crm;
20
Xilinx CAN
28
21
M: Francisco Iglesias <francisco.iglesias@amd.com>
29
- /* Bits [63:49] are hardwired to the value of bit [48]; that is, the
22
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
30
- * register reads and behaves as if values written are sign extended.
23
S: Maintained
31
+ /*
24
F: hw/net/can/xlnx-*
32
* Bits [1:0] are RES0.
25
F: include/hw/net/xlnx-*
33
+ *
26
@@ -XXX,XX +XXX,XX @@ F: include/hw/rx/
34
+ * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA)
27
CAN bus subsystem and hardware
35
+ * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if
28
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
36
+ * they contain the value written. It is CONSTRAINED UNPREDICTABLE
29
M: Francisco Iglesias <francisco.iglesias@amd.com>
37
+ * whether the RESS bits are ignored when comparing an address.
30
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
38
+ *
31
S: Maintained
39
+ * Therefore we are allowed to compare the entire register, which lets
32
W: https://canbus.pages.fel.cvut.cz/
40
+ * us avoid considering whether or not FEAT_LVA is actually enabled.
33
F: net/can/*
41
*/
42
- value = sextract64(value, 0, 49) & ~3ULL;
43
+ value &= ~3ULL;
44
45
raw_write(env, ri, value);
46
hw_watchpoint_update(cpu, i);
47
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
48
case 0: /* unlinked address match */
49
case 1: /* linked address match */
50
{
51
- /* Bits [63:49] are hardwired to the value of bit [48]; that is,
52
- * we behave as if the register was sign extended. Bits [1:0] are
53
- * RES0. The BAS field is used to allow setting breakpoints on 16
54
- * bit wide instructions; it is CONSTRAINED UNPREDICTABLE whether
55
+ /*
56
+ * Bits [1:0] are RES0.
57
+ *
58
+ * It is IMPLEMENTATION DEFINED whether bits [63:49]
59
+ * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
60
+ * of the VA field ([48] or [52] for FEAT_LVA), or whether the
61
+ * value is read as written. It is CONSTRAINED UNPREDICTABLE
62
+ * whether the RESS bits are ignored when comparing an address.
63
+ * Therefore we are allowed to compare the entire register, which
64
+ * lets us avoid considering whether FEAT_LVA is actually enabled.
65
+ *
66
+ * The BAS field is used to allow setting breakpoints on 16-bit
67
+ * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
68
* a bp will fire if the addresses covered by the bp and the addresses
69
* covered by the insn overlap but the insn doesn't start at the
70
* start of the bp address range. We choose to require the insn and
71
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
72
* See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
73
*/
74
int bas = extract64(bcr, 5, 4);
75
- addr = sextract64(bvr, 0, 49) & ~3ULL;
76
+ addr = bvr & ~3ULL;
77
if (bas == 0) {
78
return;
79
}
80
--
34
--
81
2.25.1
35
2.34.1
diff view generated by jsdifflib