1
target-arm queue. The big thing here is the landing of the 3-phase
1
First arm pullreq of the cycle; this is mostly my softfloat NaN
2
reset patches...
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 :-))
3
4
5
thanks
4
-- PMM
6
-- PMM
5
7
6
The following changes since commit 204aa60b37c23a89e690d418f49787d274303ca7:
8
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
7
9
8
Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-jan-29-2020' into staging (2020-01-30 14:18:45 +0000)
10
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
9
11
10
are available in the Git repository at:
12
are available in the Git repository at:
11
13
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200130
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
13
15
14
for you to fetch changes up to dea101a1ae9968c9fec6ab0291489dad7c49f36f:
16
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
15
17
16
target/arm/cpu: Add the kvm-no-adjvtime CPU property (2020-01-30 16:02:06 +0000)
18
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
17
19
18
----------------------------------------------------------------
20
----------------------------------------------------------------
19
target-arm queue:
21
target-arm queue:
20
* hw/core/or-irq: Fix incorrect assert forbidding num-lines == MAX_OR_LINES
22
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
21
* target/arm/arm-semi: Don't let the guest close stdin/stdout/stderr
23
* fpu: Make muladd NaN handling runtime-selected, not compile-time
22
* aspeed: some minor bugfixes
24
* fpu: Make default NaN pattern runtime-selected, not compile-time
23
* aspeed: add eMMC controller model for AST2600 SoC
25
* fpu: Minor NaN-related cleanups
24
* hw/arm/raspi: Remove obsolete use of -smp to set the soc 'enabled-cpus'
26
* MAINTAINERS: email address updates
25
* New 3-phase reset API for device models
26
* hw/intc/arm_gicv3_kvm: Stop wrongly programming GICR_PENDBASER.PTZ bit
27
* Arm KVM: stop/restart the guest counter when the VM is stopped and started
28
27
29
----------------------------------------------------------------
28
----------------------------------------------------------------
30
Andrew Jeffery (2):
29
Bernhard Beschow (5):
31
hw/sd: Configure number of slots exposed by the ASPEED SDHCI model
30
hw/net/lan9118: Extract lan9118_phy
32
hw/arm: ast2600: Wire up the eMMC controller
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
33
35
34
Andrew Jones (6):
36
Leif Lindholm (1):
35
target/arm/kvm: trivial: Clean up header documentation
37
MAINTAINERS: update email address for Leif Lindholm
36
hw/arm/virt: Add missing 5.0 options call to 4.2 options
37
target/arm/kvm64: kvm64 cpus have timer registers
38
tests/arm-cpu-features: Check feature default values
39
target/arm/kvm: Implement virtual time adjustment
40
target/arm/cpu: Add the kvm-no-adjvtime CPU property
41
38
42
Cédric Le Goater (2):
39
Peter Maydell (54):
43
ftgmac100: check RX and TX buffer alignment
40
fpu: handle raising Invalid for infzero in pick_nan_muladd
44
hw/arm/aspeed: add a 'execute-in-place' property to boot directly from CE0
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
45
94
46
Damien Hedde (11):
95
Richard Henderson (11):
47
add device_legacy_reset function to prepare for reset api change
96
target/arm: Copy entire float_status in is_ebf
48
hw/core/qdev: add trace events to help with resettable transition
97
softfloat: Inline pickNaNMulAdd
49
hw/core: create Resettable QOM interface
98
softfloat: Use goto for default nan case in pick_nan_muladd
50
hw/core: add Resettable support to BusClass and DeviceClass
99
softfloat: Remove which from parts_pick_nan_muladd
51
hw/core/resettable: add support for changing parent
100
softfloat: Pad array size in pick_nan_muladd
52
hw/core/qdev: handle parent bus change regarding resettable
101
softfloat: Move propagateFloatx80NaN to softfloat.c
53
hw/core/qdev: update hotplug reset regarding resettable
102
softfloat: Use parts_pick_nan in propagateFloatx80NaN
54
hw/core: deprecate old reset functions and introduce new ones
103
softfloat: Inline pickNaN
55
docs/devel/reset.rst: add doc about Resettable interface
104
softfloat: Share code between parts_pick_nan cases
56
vl: replace deprecated qbus_reset_all registration
105
softfloat: Sink frac_cmp in parts_pick_nan until needed
57
hw/s390x/ipl: replace deprecated qdev_reset_all registration
106
softfloat: Replace WHICH with RET in parts_pick_nan
58
107
59
Joel Stanley (1):
108
Vikram Garhwal (1):
60
misc/pca9552: Add qom set and get
109
MAINTAINERS: Add correct email address for Vikram Garhwal
61
110
62
Peter Maydell (2):
111
MAINTAINERS | 4 +-
63
hw/core/or-irq: Fix incorrect assert forbidding num-lines == MAX_OR_LINES
112
include/fpu/softfloat-helpers.h | 38 +++-
64
target/arm/arm-semi: Don't let the guest close stdin/stdout/stderr
113
include/fpu/softfloat-types.h | 89 +++++++-
65
114
include/hw/net/imx_fec.h | 9 +-
66
Philippe Mathieu-Daudé (1):
115
include/hw/net/lan9118_phy.h | 37 ++++
67
hw/arm/raspi: Remove obsolete use of -smp to set the soc 'enabled-cpus'
116
include/hw/net/mii.h | 6 +
68
117
target/mips/fpu_helper.h | 20 ++
69
Zenghui Yu (1):
118
target/sparc/helper.h | 4 +-
70
hw/intc/arm_gicv3_kvm: Stop wrongly programming GICR_PENDBASER.PTZ bit
119
fpu/softfloat.c | 19 ++
71
120
hw/net/imx_fec.c | 146 ++------------
72
hw/core/Makefile.objs | 1 +
121
hw/net/lan9118.c | 137 ++-----------
73
tests/Makefile.include | 1 +
122
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
74
include/hw/arm/aspeed.h | 2 +
123
linux-user/arm/nwfpe/fpa11.c | 5 +
75
include/hw/arm/aspeed_soc.h | 2 +
124
target/alpha/cpu.c | 2 +
76
include/hw/arm/virt.h | 1 +
125
target/arm/cpu.c | 10 +
77
include/hw/qdev-core.h | 58 +++++++-
126
target/arm/tcg/vec_helper.c | 20 +-
78
include/hw/resettable.h | 247 +++++++++++++++++++++++++++++++++
127
target/hexagon/cpu.c | 2 +
79
include/hw/sd/aspeed_sdhci.h | 1 +
128
target/hppa/fpu_helper.c | 12 ++
80
target/arm/cpu.h | 7 +
129
target/i386/tcg/fpu_helper.c | 12 ++
81
target/arm/kvm_arm.h | 95 ++++++++++---
130
target/loongarch/tcg/fpu_helper.c | 14 +-
82
hw/arm/aspeed.c | 72 ++++++++--
131
target/m68k/cpu.c | 14 +-
83
hw/arm/aspeed_ast2600.c | 31 ++++-
132
target/m68k/fpu_helper.c | 6 +-
84
hw/arm/aspeed_soc.c | 2 +
133
target/m68k/helper.c | 6 +-
85
hw/arm/raspi.c | 2 -
134
target/microblaze/cpu.c | 2 +
86
hw/arm/virt.c | 9 ++
135
target/mips/msa.c | 10 +
87
hw/audio/intel-hda.c | 2 +-
136
target/openrisc/cpu.c | 2 +
88
hw/core/bus.c | 102 ++++++++++++++
137
target/ppc/cpu_init.c | 19 ++
89
hw/core/or-irq.c | 2 +-
138
target/ppc/fpu_helper.c | 3 +-
90
hw/core/qdev.c | 160 ++++++++++++++++++++--
139
target/riscv/cpu.c | 2 +
91
hw/core/resettable.c | 301 +++++++++++++++++++++++++++++++++++++++++
140
target/rx/cpu.c | 2 +
92
hw/hyperv/hyperv.c | 2 +-
141
target/s390x/cpu.c | 5 +
93
hw/i386/microvm.c | 2 +-
142
target/sh4/cpu.c | 2 +
94
hw/i386/pc.c | 2 +-
143
target/sparc/cpu.c | 6 +
95
hw/ide/microdrive.c | 8 +-
144
target/sparc/fop_helper.c | 8 +-
96
hw/intc/arm_gicv3_kvm.c | 11 +-
145
target/sparc/translate.c | 4 +-
97
hw/intc/spapr_xive.c | 2 +-
146
target/tricore/helper.c | 2 +
98
hw/misc/pca9552.c | 90 ++++++++++++
147
target/xtensa/cpu.c | 4 +
99
hw/net/ftgmac100.c | 13 ++
148
target/xtensa/fpu_helper.c | 3 +-
100
hw/ppc/pnv_psi.c | 4 +-
149
tests/fp/fp-bench.c | 7 +
101
hw/ppc/spapr_pci.c | 2 +-
150
tests/fp/fp-test-log2.c | 1 +
102
hw/ppc/spapr_vio.c | 2 +-
151
tests/fp/fp-test.c | 7 +
103
hw/s390x/ipl.c | 10 +-
152
fpu/softfloat-parts.c.inc | 152 +++++++++++---
104
hw/s390x/s390-pci-inst.c | 2 +-
153
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
105
hw/scsi/vmw_pvscsi.c | 2 +-
154
.mailmap | 5 +-
106
hw/sd/aspeed_sdhci.c | 11 +-
155
hw/net/Kconfig | 5 +
107
hw/sd/omap_mmc.c | 2 +-
156
hw/net/meson.build | 1 +
108
hw/sd/pl181.c | 2 +-
157
hw/net/trace-events | 10 +-
109
target/arm/arm-semi.c | 9 ++
158
47 files changed, 778 insertions(+), 730 deletions(-)
110
target/arm/cpu.c | 2 +
159
create mode 100644 include/hw/net/lan9118_phy.h
111
target/arm/cpu64.c | 1 +
160
create mode 100644 hw/net/lan9118_phy.c
112
target/arm/kvm.c | 120 ++++++++++++++++
113
target/arm/kvm32.c | 3 +
114
target/arm/kvm64.c | 4 +
115
target/arm/machine.c | 7 +
116
target/arm/monitor.c | 1 +
117
tests/qtest/arm-cpu-features.c | 41 ++++--
118
vl.c | 10 +-
119
docs/arm-cpu-features.rst | 37 ++++-
120
docs/devel/index.rst | 1 +
121
docs/devel/reset.rst | 289 +++++++++++++++++++++++++++++++++++++++
122
hw/core/trace-events | 27 ++++
123
51 files changed, 1727 insertions(+), 90 deletions(-)
124
create mode 100644 include/hw/resettable.h
125
create mode 100644 hw/core/resettable.c
126
create mode 100644 docs/devel/reset.rst
127
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
This commit defines an interface allowing multi-phase reset. This aims
3
A very similar implementation of the same device exists in imx_fec. Prepare for
4
to solve a problem of the actual single-phase reset (built in
4
a common implementation by extracting a device model into its own files.
5
DeviceClass and BusClass): reset behavior is dependent on the order
6
in which reset handlers are called. In particular doing external
7
side-effect (like setting an qemu_irq) is problematic because receiving
8
object may not be reset yet.
9
5
10
The Resettable interface divides the reset in 3 well defined phases.
6
Some migration state has been moved into the new device model which breaks
11
To reset an object tree, all 1st phases are executed then all 2nd then
7
migration compatibility for the following machines:
12
all 3rd. See the comments in include/hw/resettable.h for a more complete
8
* smdkc210
13
description. The interface defines 3 phases to let the future
9
* realview-*
14
possibility of holding an object into reset for some time.
10
* vexpress-*
11
* kzm
12
* mps2-*
15
13
16
The qdev/qbus reset in DeviceClass and BusClass will be modified in
14
While breaking migration ABI, fix the size of the MII registers to be 16 bit,
17
following commits to use this interface. A mechanism is provided
15
as defined by IEEE 802.3u.
18
to allow executing a transitional reset handler in place of the 2nd
19
phase which is executed in children-then-parent order inside a tree.
20
This will allow to transition devices and buses smoothly while
21
keeping the exact current qdev/qbus reset behavior for now.
22
16
23
Documentation will be added in a following commit.
17
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
24
18
Tested-by: Guenter Roeck <linux@roeck-us.net>
25
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20241102125724.532843-2-shentey@gmail.com
27
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
28
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
29
Message-id: 20200123132823.1117486-4-damien.hedde@greensocs.com
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
---
22
---
32
hw/core/Makefile.objs | 1 +
23
include/hw/net/lan9118_phy.h | 37 ++++++++
33
include/hw/resettable.h | 211 +++++++++++++++++++++++++++++++++++
24
hw/net/lan9118.c | 137 +++++-----------------------
34
hw/core/resettable.c | 238 ++++++++++++++++++++++++++++++++++++++++
25
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
35
hw/core/trace-events | 17 +++
26
hw/net/Kconfig | 4 +
36
4 files changed, 467 insertions(+)
27
hw/net/meson.build | 1 +
37
create mode 100644 include/hw/resettable.h
28
5 files changed, 233 insertions(+), 115 deletions(-)
38
create mode 100644 hw/core/resettable.c
29
create mode 100644 include/hw/net/lan9118_phy.h
30
create mode 100644 hw/net/lan9118_phy.c
39
31
40
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
32
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/core/Makefile.objs
43
+++ b/hw/core/Makefile.objs
44
@@ -XXX,XX +XXX,XX @@
45
common-obj-y += qdev.o qdev-properties.o
46
common-obj-y += bus.o
47
common-obj-y += cpu.o
48
+common-obj-y += resettable.o
49
common-obj-y += hotplug.o
50
common-obj-y += vmstate-if.o
51
# irq.o needed for qdev GPIO handling:
52
diff --git a/include/hw/resettable.h b/include/hw/resettable.h
53
new file mode 100644
33
new file mode 100644
54
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
55
--- /dev/null
35
--- /dev/null
56
+++ b/include/hw/resettable.h
36
+++ b/include/hw/net/lan9118_phy.h
57
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
58
+/*
38
+/*
59
+ * Resettable interface header.
39
+ * SMSC LAN9118 PHY emulation
60
+ *
40
+ *
61
+ * Copyright (c) 2019 GreenSocs SAS
41
+ * Copyright (c) 2009 CodeSourcery, LLC.
62
+ *
42
+ * Written by Paul Brook
63
+ * Authors:
64
+ * Damien Hedde
65
+ *
43
+ *
66
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
67
+ * See the COPYING file in the top-level directory.
45
+ * See the COPYING file in the top-level directory.
68
+ */
46
+ */
69
+
47
+
70
+#ifndef HW_RESETTABLE_H
48
+#ifndef HW_NET_LAN9118_PHY_H
71
+#define HW_RESETTABLE_H
49
+#define HW_NET_LAN9118_PHY_H
72
+
50
+
73
+#include "qom/object.h"
51
+#include "qom/object.h"
74
+
52
+#include "hw/sysbus.h"
75
+#define TYPE_RESETTABLE_INTERFACE "resettable"
53
+
76
+
54
+#define TYPE_LAN9118_PHY "lan9118-phy"
77
+#define RESETTABLE_CLASS(class) \
55
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
78
+ OBJECT_CLASS_CHECK(ResettableClass, (class), TYPE_RESETTABLE_INTERFACE)
56
+
79
+
57
+typedef struct Lan9118PhyState {
80
+#define RESETTABLE_GET_CLASS(obj) \
58
+ SysBusDevice parent_obj;
81
+ OBJECT_GET_CLASS(ResettableClass, (obj), TYPE_RESETTABLE_INTERFACE)
59
+
82
+
60
+ uint16_t status;
83
+typedef struct ResettableState ResettableState;
61
+ uint16_t control;
84
+
62
+ uint16_t advertise;
85
+/**
63
+ uint16_t ints;
86
+ * ResetType:
64
+ uint16_t int_mask;
87
+ * Types of reset.
65
+ qemu_irq irq;
88
+ *
66
+ bool link_down;
89
+ * + Cold: reset resulting from a power cycle of the object.
67
+} Lan9118PhyState;
90
+ *
68
+
91
+ * TODO: Support has to be added to handle more types. In particular,
69
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down);
92
+ * ResettableState structure needs to be expanded.
70
+void lan9118_phy_reset(Lan9118PhyState *s);
93
+ */
71
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg);
94
+typedef enum ResetType {
72
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val);
95
+ RESET_TYPE_COLD,
96
+} ResetType;
97
+
98
+/*
99
+ * ResettableClass:
100
+ * Interface for resettable objects.
101
+ *
102
+ * See docs/devel/reset.rst for more detailed information about how QEMU models
103
+ * reset. This whole API must only be used when holding the iothread mutex.
104
+ *
105
+ * All objects which can be reset must implement this interface;
106
+ * it is usually provided by a base class such as DeviceClass or BusClass.
107
+ * Every Resettable object must maintain some state tracking the
108
+ * progress of a reset operation by providing a ResettableState structure.
109
+ * The functions defined in this module take care of updating the
110
+ * state of the reset.
111
+ * The base class implementation of the interface provides this
112
+ * state and implements the associated method: get_state.
113
+ *
114
+ * Concrete object implementations (typically specific devices
115
+ * such as a UART model) should provide the functions
116
+ * for the phases.enter, phases.hold and phases.exit methods, which
117
+ * they can set in their class init function, either directly or
118
+ * by calling resettable_class_set_parent_phases().
119
+ * The phase methods are guaranteed to only only ever be called once
120
+ * for any reset event, in the order 'enter', 'hold', 'exit'.
121
+ * An object will always move quickly from 'enter' to 'hold'
122
+ * but might remain in 'hold' for an arbitrary period of time
123
+ * before eventually reset is deasserted and the 'exit' phase is called.
124
+ * Object implementations should be prepared for functions handling
125
+ * inbound connections from other devices (such as qemu_irq handler
126
+ * functions) to be called at any point during reset after their
127
+ * 'enter' method has been called.
128
+ *
129
+ * Users of a resettable object should not call these methods
130
+ * directly, but instead use the function resettable_reset().
131
+ *
132
+ * @phases.enter: This phase is called when the object enters reset. It
133
+ * should reset local state of the object, but it must not do anything that
134
+ * has a side-effect on other objects, such as raising or lowering a qemu_irq
135
+ * line or reading or writing guest memory. It takes the reset's type as
136
+ * argument.
137
+ *
138
+ * @phases.hold: This phase is called for entry into reset, once every object
139
+ * in the system which is being reset has had its @phases.enter method called.
140
+ * At this point devices can do actions that affect other objects.
141
+ *
142
+ * @phases.exit: This phase is called when the object leaves the reset state.
143
+ * Actions affecting other objects are permitted.
144
+ *
145
+ * @get_state: Mandatory method which must return a pointer to a
146
+ * ResettableState.
147
+ *
148
+ * @get_transitional_function: transitional method to handle Resettable objects
149
+ * not yet fully moved to this interface. It will be removed as soon as it is
150
+ * not needed anymore. This method is optional and may return a pointer to a
151
+ * function to be used instead of the phases. If the method exists and returns
152
+ * a non-NULL function pointer then that function is executed as a replacement
153
+ * of the 'hold' phase method taking the object as argument. The two other phase
154
+ * methods are not executed.
155
+ *
156
+ * @child_foreach: Executes a given callback on every Resettable child. Child
157
+ * in this context means a child in the qbus tree, so the children of a qbus
158
+ * are the devices on it, and the children of a device are all the buses it
159
+ * owns. This is not the same as the QOM object hierarchy. The function takes
160
+ * additional opaque and ResetType arguments which must be passed unmodified to
161
+ * the callback.
162
+ */
163
+typedef void (*ResettableEnterPhase)(Object *obj, ResetType type);
164
+typedef void (*ResettableHoldPhase)(Object *obj);
165
+typedef void (*ResettableExitPhase)(Object *obj);
166
+typedef ResettableState * (*ResettableGetState)(Object *obj);
167
+typedef void (*ResettableTrFunction)(Object *obj);
168
+typedef ResettableTrFunction (*ResettableGetTrFunction)(Object *obj);
169
+typedef void (*ResettableChildCallback)(Object *, void *opaque,
170
+ ResetType type);
171
+typedef void (*ResettableChildForeach)(Object *obj,
172
+ ResettableChildCallback cb,
173
+ void *opaque, ResetType type);
174
+typedef struct ResettablePhases {
175
+ ResettableEnterPhase enter;
176
+ ResettableHoldPhase hold;
177
+ ResettableExitPhase exit;
178
+} ResettablePhases;
179
+typedef struct ResettableClass {
180
+ InterfaceClass parent_class;
181
+
182
+ /* Phase methods */
183
+ ResettablePhases phases;
184
+
185
+ /* State access method */
186
+ ResettableGetState get_state;
187
+
188
+ /* Transitional method for legacy reset compatibility */
189
+ ResettableGetTrFunction get_transitional_function;
190
+
191
+ /* Hierarchy handling method */
192
+ ResettableChildForeach child_foreach;
193
+} ResettableClass;
194
+
195
+/**
196
+ * ResettableState:
197
+ * Structure holding reset related state. The fields should not be accessed
198
+ * directly; the definition is here to allow further inclusion into other
199
+ * objects.
200
+ *
201
+ * @count: Number of reset level the object is into. It is incremented when
202
+ * the reset operation starts and decremented when it finishes.
203
+ * @hold_phase_pending: flag which indicates that we need to invoke the 'hold'
204
+ * phase handler for this object.
205
+ * @exit_phase_in_progress: true if we are currently in the exit phase
206
+ */
207
+struct ResettableState {
208
+ unsigned count;
209
+ bool hold_phase_pending;
210
+ bool exit_phase_in_progress;
211
+};
212
+
213
+/**
214
+ * resettable_reset:
215
+ * Trigger a reset on an object @obj of type @type. @obj must implement
216
+ * Resettable interface.
217
+ *
218
+ * Calling this function is equivalent to calling @resettable_assert_reset()
219
+ * then @resettable_release_reset().
220
+ */
221
+void resettable_reset(Object *obj, ResetType type);
222
+
223
+/**
224
+ * resettable_assert_reset:
225
+ * Put an object @obj into reset. @obj must implement Resettable interface.
226
+ *
227
+ * @resettable_release_reset() must eventually be called after this call.
228
+ * There must be one call to @resettable_release_reset() per call of
229
+ * @resettable_assert_reset(), with the same type argument.
230
+ *
231
+ * NOTE: Until support for migration is added, the @resettable_release_reset()
232
+ * must not be delayed. It must occur just after @resettable_assert_reset() so
233
+ * that migration cannot be triggered in between. Prefer using
234
+ * @resettable_reset() for now.
235
+ */
236
+void resettable_assert_reset(Object *obj, ResetType type);
237
+
238
+/**
239
+ * resettable_release_reset:
240
+ * Release the object @obj from reset. @obj must implement Resettable interface.
241
+ *
242
+ * See @resettable_assert_reset() description for details.
243
+ */
244
+void resettable_release_reset(Object *obj, ResetType type);
245
+
246
+/**
247
+ * resettable_is_in_reset:
248
+ * Return true if @obj is under reset.
249
+ *
250
+ * @obj must implement Resettable interface.
251
+ */
252
+bool resettable_is_in_reset(Object *obj);
253
+
254
+/**
255
+ * resettable_class_set_parent_phases:
256
+ *
257
+ * Save @rc current reset phases into @parent_phases and override @rc phases
258
+ * by the given new methods (@enter, @hold and @exit).
259
+ * Each phase is overridden only if the new one is not NULL allowing to
260
+ * override a subset of phases.
261
+ */
262
+void resettable_class_set_parent_phases(ResettableClass *rc,
263
+ ResettableEnterPhase enter,
264
+ ResettableHoldPhase hold,
265
+ ResettableExitPhase exit,
266
+ ResettablePhases *parent_phases);
267
+
73
+
268
+#endif
74
+#endif
269
diff --git a/hw/core/resettable.c b/hw/core/resettable.c
75
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/net/lan9118.c
78
+++ b/hw/net/lan9118.c
79
@@ -XXX,XX +XXX,XX @@
80
#include "net/net.h"
81
#include "net/eth.h"
82
#include "hw/irq.h"
83
+#include "hw/net/lan9118_phy.h"
84
#include "hw/net/lan9118.h"
85
#include "hw/ptimer.h"
86
#include "hw/qdev-properties.h"
87
@@ -XXX,XX +XXX,XX @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
88
#define MAC_CR_RXEN 0x00000004
89
#define MAC_CR_RESERVED 0x7f404213
90
91
-#define PHY_INT_ENERGYON 0x80
92
-#define PHY_INT_AUTONEG_COMPLETE 0x40
93
-#define PHY_INT_FAULT 0x20
94
-#define PHY_INT_DOWN 0x10
95
-#define PHY_INT_AUTONEG_LP 0x08
96
-#define PHY_INT_PARFAULT 0x04
97
-#define PHY_INT_AUTONEG_PAGE 0x02
98
-
99
#define GPT_TIMER_EN 0x20000000
100
101
/*
102
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
103
uint32_t mac_mii_data;
104
uint32_t mac_flow;
105
106
- uint32_t phy_status;
107
- uint32_t phy_control;
108
- uint32_t phy_advertise;
109
- uint32_t phy_int;
110
- uint32_t phy_int_mask;
111
+ Lan9118PhyState mii;
112
+ IRQState mii_irq;
113
114
int32_t eeprom_writable;
115
uint8_t eeprom[128];
116
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
117
118
static const VMStateDescription vmstate_lan9118 = {
119
.name = "lan9118",
120
- .version_id = 2,
121
- .minimum_version_id = 1,
122
+ .version_id = 3,
123
+ .minimum_version_id = 3,
124
.fields = (const VMStateField[]) {
125
VMSTATE_PTIMER(timer, lan9118_state),
126
VMSTATE_UINT32(irq_cfg, lan9118_state),
127
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118 = {
128
VMSTATE_UINT32(mac_mii_acc, lan9118_state),
129
VMSTATE_UINT32(mac_mii_data, lan9118_state),
130
VMSTATE_UINT32(mac_flow, lan9118_state),
131
- VMSTATE_UINT32(phy_status, lan9118_state),
132
- VMSTATE_UINT32(phy_control, lan9118_state),
133
- VMSTATE_UINT32(phy_advertise, lan9118_state),
134
- VMSTATE_UINT32(phy_int, lan9118_state),
135
- VMSTATE_UINT32(phy_int_mask, lan9118_state),
136
VMSTATE_INT32(eeprom_writable, lan9118_state),
137
VMSTATE_UINT8_ARRAY(eeprom, lan9118_state, 128),
138
VMSTATE_INT32(tx_fifo_size, lan9118_state),
139
@@ -XXX,XX +XXX,XX @@ static void lan9118_reload_eeprom(lan9118_state *s)
140
lan9118_mac_changed(s);
141
}
142
143
-static void phy_update_irq(lan9118_state *s)
144
+static void lan9118_update_irq(void *opaque, int n, int level)
145
{
146
- if (s->phy_int & s->phy_int_mask) {
147
+ lan9118_state *s = opaque;
148
+
149
+ if (level) {
150
s->int_sts |= PHY_INT;
151
} else {
152
s->int_sts &= ~PHY_INT;
153
@@ -XXX,XX +XXX,XX @@ static void phy_update_irq(lan9118_state *s)
154
lan9118_update(s);
155
}
156
157
-static void phy_update_link(lan9118_state *s)
158
-{
159
- /* Autonegotiation status mirrors link status. */
160
- if (qemu_get_queue(s->nic)->link_down) {
161
- s->phy_status &= ~0x0024;
162
- s->phy_int |= PHY_INT_DOWN;
163
- } else {
164
- s->phy_status |= 0x0024;
165
- s->phy_int |= PHY_INT_ENERGYON;
166
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
167
- }
168
- phy_update_irq(s);
169
-}
170
-
171
static void lan9118_set_link(NetClientState *nc)
172
{
173
- phy_update_link(qemu_get_nic_opaque(nc));
174
-}
175
-
176
-static void phy_reset(lan9118_state *s)
177
-{
178
- s->phy_status = 0x7809;
179
- s->phy_control = 0x3000;
180
- s->phy_advertise = 0x01e1;
181
- s->phy_int_mask = 0;
182
- s->phy_int = 0;
183
- phy_update_link(s);
184
+ lan9118_phy_update_link(&LAN9118(qemu_get_nic_opaque(nc))->mii,
185
+ nc->link_down);
186
}
187
188
static void lan9118_reset(DeviceState *d)
189
@@ -XXX,XX +XXX,XX @@ static void lan9118_reset(DeviceState *d)
190
s->read_word_n = 0;
191
s->write_word_n = 0;
192
193
- phy_reset(s);
194
-
195
s->eeprom_writable = 0;
196
lan9118_reload_eeprom(s);
197
}
198
@@ -XXX,XX +XXX,XX @@ static void do_tx_packet(lan9118_state *s)
199
uint32_t status;
200
201
/* FIXME: Honor TX disable, and allow queueing of packets. */
202
- if (s->phy_control & 0x4000) {
203
+ if (s->mii.control & 0x4000) {
204
/* This assumes the receive routine doesn't touch the VLANClient. */
205
qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
206
} else {
207
@@ -XXX,XX +XXX,XX @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
208
}
209
}
210
211
-static uint32_t do_phy_read(lan9118_state *s, int reg)
212
-{
213
- uint32_t val;
214
-
215
- switch (reg) {
216
- case 0: /* Basic Control */
217
- return s->phy_control;
218
- case 1: /* Basic Status */
219
- return s->phy_status;
220
- case 2: /* ID1 */
221
- return 0x0007;
222
- case 3: /* ID2 */
223
- return 0xc0d1;
224
- case 4: /* Auto-neg advertisement */
225
- return s->phy_advertise;
226
- case 5: /* Auto-neg Link Partner Ability */
227
- return 0x0f71;
228
- case 6: /* Auto-neg Expansion */
229
- return 1;
230
- /* TODO 17, 18, 27, 29, 30, 31 */
231
- case 29: /* Interrupt source. */
232
- val = s->phy_int;
233
- s->phy_int = 0;
234
- phy_update_irq(s);
235
- return val;
236
- case 30: /* Interrupt mask */
237
- return s->phy_int_mask;
238
- default:
239
- qemu_log_mask(LOG_GUEST_ERROR,
240
- "do_phy_read: PHY read reg %d\n", reg);
241
- return 0;
242
- }
243
-}
244
-
245
-static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
246
-{
247
- switch (reg) {
248
- case 0: /* Basic Control */
249
- if (val & 0x8000) {
250
- phy_reset(s);
251
- break;
252
- }
253
- s->phy_control = val & 0x7980;
254
- /* Complete autonegotiation immediately. */
255
- if (val & 0x1000) {
256
- s->phy_status |= 0x0020;
257
- }
258
- break;
259
- case 4: /* Auto-neg advertisement */
260
- s->phy_advertise = (val & 0x2d7f) | 0x80;
261
- break;
262
- /* TODO 17, 18, 27, 31 */
263
- case 30: /* Interrupt mask */
264
- s->phy_int_mask = val & 0xff;
265
- phy_update_irq(s);
266
- break;
267
- default:
268
- qemu_log_mask(LOG_GUEST_ERROR,
269
- "do_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
270
- }
271
-}
272
-
273
static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
274
{
275
switch (reg) {
276
@@ -XXX,XX +XXX,XX @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
277
if (val & 2) {
278
DPRINTF("PHY write %d = 0x%04x\n",
279
(val >> 6) & 0x1f, s->mac_mii_data);
280
- do_phy_write(s, (val >> 6) & 0x1f, s->mac_mii_data);
281
+ lan9118_phy_write(&s->mii, (val >> 6) & 0x1f, s->mac_mii_data);
282
} else {
283
- s->mac_mii_data = do_phy_read(s, (val >> 6) & 0x1f);
284
+ s->mac_mii_data = lan9118_phy_read(&s->mii, (val >> 6) & 0x1f);
285
DPRINTF("PHY read %d = 0x%04x\n",
286
(val >> 6) & 0x1f, s->mac_mii_data);
287
}
288
@@ -XXX,XX +XXX,XX @@ static void lan9118_writel(void *opaque, hwaddr offset,
289
break;
290
case CSR_PMT_CTRL:
291
if (val & 0x400) {
292
- phy_reset(s);
293
+ lan9118_phy_reset(&s->mii);
294
}
295
s->pmt_ctrl &= ~0x34e;
296
s->pmt_ctrl |= (val & 0x34e);
297
@@ -XXX,XX +XXX,XX @@ static void lan9118_realize(DeviceState *dev, Error **errp)
298
const MemoryRegionOps *mem_ops =
299
s->mode_16bit ? &lan9118_16bit_mem_ops : &lan9118_mem_ops;
300
301
+ qemu_init_irq(&s->mii_irq, lan9118_update_irq, s, 0);
302
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
303
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
304
+ return;
305
+ }
306
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
307
+
308
memory_region_init_io(&s->mmio, OBJECT(dev), mem_ops, s,
309
"lan9118-mmio", 0x100);
310
sysbus_init_mmio(sbd, &s->mmio);
311
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
270
new file mode 100644
312
new file mode 100644
271
index XXXXXXX..XXXXXXX
313
index XXXXXXX..XXXXXXX
272
--- /dev/null
314
--- /dev/null
273
+++ b/hw/core/resettable.c
315
+++ b/hw/net/lan9118_phy.c
274
@@ -XXX,XX +XXX,XX @@
316
@@ -XXX,XX +XXX,XX @@
275
+/*
317
+/*
276
+ * Resettable interface.
318
+ * SMSC LAN9118 PHY emulation
277
+ *
319
+ *
278
+ * Copyright (c) 2019 GreenSocs SAS
320
+ * Copyright (c) 2009 CodeSourcery, LLC.
321
+ * Written by Paul Brook
279
+ *
322
+ *
280
+ * Authors:
323
+ * This code is licensed under the GNU GPL v2
281
+ * Damien Hedde
282
+ *
324
+ *
283
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
325
+ * Contributions after 2012-01-13 are licensed under the terms of the
284
+ * See the COPYING file in the top-level directory.
326
+ * GNU GPL, version 2 or (at your option) any later version.
285
+ */
327
+ */
286
+
328
+
287
+#include "qemu/osdep.h"
329
+#include "qemu/osdep.h"
288
+#include "qemu/module.h"
330
+#include "hw/net/lan9118_phy.h"
331
+#include "hw/irq.h"
289
+#include "hw/resettable.h"
332
+#include "hw/resettable.h"
290
+#include "trace.h"
333
+#include "migration/vmstate.h"
291
+
334
+#include "qemu/log.h"
292
+/**
335
+
293
+ * resettable_phase_enter/hold/exit:
336
+#define PHY_INT_ENERGYON (1 << 7)
294
+ * Function executing a phase recursively in a resettable object and its
337
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
295
+ * children.
338
+#define PHY_INT_FAULT (1 << 5)
296
+ */
339
+#define PHY_INT_DOWN (1 << 4)
297
+static void resettable_phase_enter(Object *obj, void *opaque, ResetType type);
340
+#define PHY_INT_AUTONEG_LP (1 << 3)
298
+static void resettable_phase_hold(Object *obj, void *opaque, ResetType type);
341
+#define PHY_INT_PARFAULT (1 << 2)
299
+static void resettable_phase_exit(Object *obj, void *opaque, ResetType type);
342
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
300
+
343
+
301
+/**
344
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
302
+ * enter_phase_in_progress:
345
+{
303
+ * True if we are currently in reset enter phase.
346
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
304
+ *
347
+}
305
+ * Note: This flag is only used to guarantee (using asserts) that the reset
348
+
306
+ * API is used correctly. We can use a global variable because we rely on the
349
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
307
+ * iothread mutex to ensure only one reset operation is in a progress at a
350
+{
308
+ * given time.
351
+ uint16_t val;
309
+ */
352
+
310
+static bool enter_phase_in_progress;
353
+ switch (reg) {
311
+
354
+ case 0: /* Basic Control */
312
+void resettable_reset(Object *obj, ResetType type)
355
+ return s->control;
313
+{
356
+ case 1: /* Basic Status */
314
+ trace_resettable_reset(obj, type);
357
+ return s->status;
315
+ resettable_assert_reset(obj, type);
358
+ case 2: /* ID1 */
316
+ resettable_release_reset(obj, type);
359
+ return 0x0007;
317
+}
360
+ case 3: /* ID2 */
318
+
361
+ return 0xc0d1;
319
+void resettable_assert_reset(Object *obj, ResetType type)
362
+ case 4: /* Auto-neg advertisement */
320
+{
363
+ return s->advertise;
321
+ /* TODO: change this assert when adding support for other reset types */
364
+ case 5: /* Auto-neg Link Partner Ability */
322
+ assert(type == RESET_TYPE_COLD);
365
+ return 0x0f71;
323
+ trace_resettable_reset_assert_begin(obj, type);
366
+ case 6: /* Auto-neg Expansion */
324
+ assert(!enter_phase_in_progress);
367
+ return 1;
325
+
368
+ /* TODO 17, 18, 27, 29, 30, 31 */
326
+ enter_phase_in_progress = true;
369
+ case 29: /* Interrupt source. */
327
+ resettable_phase_enter(obj, NULL, type);
370
+ val = s->ints;
328
+ enter_phase_in_progress = false;
371
+ s->ints = 0;
329
+
372
+ lan9118_phy_update_irq(s);
330
+ resettable_phase_hold(obj, NULL, type);
373
+ return val;
331
+
374
+ case 30: /* Interrupt mask */
332
+ trace_resettable_reset_assert_end(obj);
375
+ return s->int_mask;
333
+}
376
+ default:
334
+
377
+ qemu_log_mask(LOG_GUEST_ERROR,
335
+void resettable_release_reset(Object *obj, ResetType type)
378
+ "lan9118_phy_read: PHY read reg %d\n", reg);
336
+{
379
+ return 0;
337
+ /* TODO: change this assert when adding support for other reset types */
338
+ assert(type == RESET_TYPE_COLD);
339
+ trace_resettable_reset_release_begin(obj, type);
340
+ assert(!enter_phase_in_progress);
341
+
342
+ resettable_phase_exit(obj, NULL, type);
343
+
344
+ trace_resettable_reset_release_end(obj);
345
+}
346
+
347
+bool resettable_is_in_reset(Object *obj)
348
+{
349
+ ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
350
+ ResettableState *s = rc->get_state(obj);
351
+
352
+ return s->count > 0;
353
+}
354
+
355
+/**
356
+ * resettable_child_foreach:
357
+ * helper to avoid checking the existence of the method.
358
+ */
359
+static void resettable_child_foreach(ResettableClass *rc, Object *obj,
360
+ ResettableChildCallback cb,
361
+ void *opaque, ResetType type)
362
+{
363
+ if (rc->child_foreach) {
364
+ rc->child_foreach(obj, cb, opaque, type);
365
+ }
380
+ }
366
+}
381
+}
367
+
382
+
368
+/**
383
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
369
+ * resettable_get_tr_func:
384
+{
370
+ * helper to fetch transitional reset callback if any.
385
+ switch (reg) {
371
+ */
386
+ case 0: /* Basic Control */
372
+static ResettableTrFunction resettable_get_tr_func(ResettableClass *rc,
387
+ if (val & 0x8000) {
373
+ Object *obj)
388
+ lan9118_phy_reset(s);
374
+{
389
+ break;
375
+ ResettableTrFunction tr_func = NULL;
390
+ }
376
+ if (rc->get_transitional_function) {
391
+ s->control = val & 0x7980;
377
+ tr_func = rc->get_transitional_function(obj);
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);
378
+ }
408
+ }
379
+ return tr_func;
409
+}
380
+}
410
+
381
+
411
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
382
+static void resettable_phase_enter(Object *obj, void *opaque, ResetType type)
412
+{
383
+{
413
+ s->link_down = link_down;
384
+ ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
414
+
385
+ ResettableState *s = rc->get_state(obj);
415
+ /* Autonegotiation status mirrors link status. */
386
+ const char *obj_typename = object_get_typename(obj);
416
+ if (link_down) {
387
+ bool action_needed = false;
417
+ s->status &= ~0x0024;
388
+
418
+ s->ints |= PHY_INT_DOWN;
389
+ /* exit phase has to finish properly before entering back in reset */
419
+ } else {
390
+ assert(!s->exit_phase_in_progress);
420
+ s->status |= 0x0024;
391
+
421
+ s->ints |= PHY_INT_ENERGYON;
392
+ trace_resettable_phase_enter_begin(obj, obj_typename, s->count, type);
422
+ s->ints |= PHY_INT_AUTONEG_COMPLETE;
393
+
394
+ /* Only take action if we really enter reset for the 1st time. */
395
+ /*
396
+ * TODO: if adding more ResetType support, some additional checks
397
+ * are probably needed here.
398
+ */
399
+ if (s->count++ == 0) {
400
+ action_needed = true;
401
+ }
423
+ }
402
+ /*
424
+ lan9118_phy_update_irq(s);
403
+ * We limit the count to an arbitrary "big" value. The value is big
425
+}
404
+ * enough not to be triggered normally.
426
+
405
+ * The assert will stop an infinite loop if there is a cycle in the
427
+void lan9118_phy_reset(Lan9118PhyState *s)
406
+ * reset tree. The loop goes through resettable_foreach_child below
428
+{
407
+ * which at some point will call us again.
429
+ s->control = 0x3000;
408
+ */
430
+ s->status = 0x7809;
409
+ assert(s->count <= 50);
431
+ s->advertise = 0x01e1;
410
+
432
+ s->int_mask = 0;
411
+ /*
433
+ s->ints = 0;
412
+ * handle the children even if action_needed is at false so that
434
+ lan9118_phy_update_link(s, s->link_down);
413
+ * child counts are incremented too
435
+}
414
+ */
436
+
415
+ resettable_child_foreach(rc, obj, resettable_phase_enter, NULL, type);
437
+static void lan9118_phy_reset_hold(Object *obj, ResetType type)
416
+
438
+{
417
+ /* execute enter phase for the object if needed */
439
+ Lan9118PhyState *s = LAN9118_PHY(obj);
418
+ if (action_needed) {
440
+
419
+ trace_resettable_phase_enter_exec(obj, obj_typename, type,
441
+ lan9118_phy_reset(s);
420
+ !!rc->phases.enter);
442
+}
421
+ if (rc->phases.enter && !resettable_get_tr_func(rc, obj)) {
443
+
422
+ rc->phases.enter(obj, type);
444
+static void lan9118_phy_init(Object *obj)
423
+ }
445
+{
424
+ s->hold_phase_pending = true;
446
+ Lan9118PhyState *s = LAN9118_PHY(obj);
447
+
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()
425
+ }
463
+ }
426
+ trace_resettable_phase_enter_end(obj, obj_typename, s->count);
464
+};
427
+}
465
+
428
+
466
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
429
+static void resettable_phase_hold(Object *obj, void *opaque, ResetType type)
467
+{
430
+{
468
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
431
+ ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
469
+ DeviceClass *dc = DEVICE_CLASS(klass);
432
+ ResettableState *s = rc->get_state(obj);
470
+
433
+ const char *obj_typename = object_get_typename(obj);
471
+ rc->phases.hold = lan9118_phy_reset_hold;
434
+
472
+ dc->vmsd = &vmstate_lan9118_phy;
435
+ /* exit phase has to finish properly before entering back in reset */
473
+}
436
+ assert(!s->exit_phase_in_progress);
474
+
437
+
475
+static const TypeInfo types[] = {
438
+ trace_resettable_phase_hold_begin(obj, obj_typename, s->count, type);
476
+ {
439
+
477
+ .name = TYPE_LAN9118_PHY,
440
+ /* handle children first */
478
+ .parent = TYPE_SYS_BUS_DEVICE,
441
+ resettable_child_foreach(rc, obj, resettable_phase_hold, NULL, type);
479
+ .instance_size = sizeof(Lan9118PhyState),
442
+
480
+ .instance_init = lan9118_phy_init,
443
+ /* exec hold phase */
481
+ .class_init = lan9118_phy_class_init,
444
+ if (s->hold_phase_pending) {
445
+ s->hold_phase_pending = false;
446
+ ResettableTrFunction tr_func = resettable_get_tr_func(rc, obj);
447
+ trace_resettable_phase_hold_exec(obj, obj_typename, !!rc->phases.hold);
448
+ if (tr_func) {
449
+ trace_resettable_transitional_function(obj, obj_typename);
450
+ tr_func(obj);
451
+ } else if (rc->phases.hold) {
452
+ rc->phases.hold(obj);
453
+ }
454
+ }
482
+ }
455
+ trace_resettable_phase_hold_end(obj, obj_typename, s->count);
456
+}
457
+
458
+static void resettable_phase_exit(Object *obj, void *opaque, ResetType type)
459
+{
460
+ ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
461
+ ResettableState *s = rc->get_state(obj);
462
+ const char *obj_typename = object_get_typename(obj);
463
+
464
+ assert(!s->exit_phase_in_progress);
465
+ trace_resettable_phase_exit_begin(obj, obj_typename, s->count, type);
466
+
467
+ /* exit_phase_in_progress ensures this phase is 'atomic' */
468
+ s->exit_phase_in_progress = true;
469
+ resettable_child_foreach(rc, obj, resettable_phase_exit, NULL, type);
470
+
471
+ assert(s->count > 0);
472
+ if (s->count == 1) {
473
+ trace_resettable_phase_exit_exec(obj, obj_typename, !!rc->phases.exit);
474
+ if (rc->phases.exit && !resettable_get_tr_func(rc, obj)) {
475
+ rc->phases.exit(obj);
476
+ }
477
+ s->count = 0;
478
+ }
479
+ s->exit_phase_in_progress = false;
480
+ trace_resettable_phase_exit_end(obj, obj_typename, s->count);
481
+}
482
+
483
+void resettable_class_set_parent_phases(ResettableClass *rc,
484
+ ResettableEnterPhase enter,
485
+ ResettableHoldPhase hold,
486
+ ResettableExitPhase exit,
487
+ ResettablePhases *parent_phases)
488
+{
489
+ *parent_phases = rc->phases;
490
+ if (enter) {
491
+ rc->phases.enter = enter;
492
+ }
493
+ if (hold) {
494
+ rc->phases.hold = hold;
495
+ }
496
+ if (exit) {
497
+ rc->phases.exit = exit;
498
+ }
499
+}
500
+
501
+static const TypeInfo resettable_interface_info = {
502
+ .name = TYPE_RESETTABLE_INTERFACE,
503
+ .parent = TYPE_INTERFACE,
504
+ .class_size = sizeof(ResettableClass),
505
+};
483
+};
506
+
484
+
507
+static void reset_register_types(void)
485
+DEFINE_TYPES(types)
508
+{
486
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
509
+ type_register_static(&resettable_interface_info);
510
+}
511
+
512
+type_init(reset_register_types)
513
diff --git a/hw/core/trace-events b/hw/core/trace-events
514
index XXXXXXX..XXXXXXX 100644
487
index XXXXXXX..XXXXXXX 100644
515
--- a/hw/core/trace-events
488
--- a/hw/net/Kconfig
516
+++ b/hw/core/trace-events
489
+++ b/hw/net/Kconfig
517
@@ -XXX,XX +XXX,XX @@ qbus_reset(void *obj, const char *objtype) "obj=%p(%s)"
490
@@ -XXX,XX +XXX,XX @@ config VMXNET3_PCI
518
qbus_reset_all(void *obj, const char *objtype) "obj=%p(%s)"
491
config SMC91C111
519
qbus_reset_tree(void *obj, const char *objtype) "obj=%p(%s)"
492
bool
520
qdev_update_parent_bus(void *obj, const char *objtype, void *oldp, const char *oldptype, void *newp, const char *newptype) "obj=%p(%s) old_parent=%p(%s) new_parent=%p(%s)"
493
521
+
494
+config LAN9118_PHY
522
+# resettable.c
495
+ bool
523
+resettable_reset(void *obj, int cold) "obj=%p cold=%d"
496
+
524
+resettable_reset_assert_begin(void *obj, int cold) "obj=%p cold=%d"
497
config LAN9118
525
+resettable_reset_assert_end(void *obj) "obj=%p"
498
bool
526
+resettable_reset_release_begin(void *obj, int cold) "obj=%p cold=%d"
499
+ select LAN9118_PHY
527
+resettable_reset_release_end(void *obj) "obj=%p"
500
select PTIMER
528
+resettable_phase_enter_begin(void *obj, const char *objtype, unsigned count, int type) "obj=%p(%s) count=%d type=%d"
501
529
+resettable_phase_enter_exec(void *obj, const char *objtype, int type, int has_method) "obj=%p(%s) type=%d method=%d"
502
config NE2000_ISA
530
+resettable_phase_enter_end(void *obj, const char *objtype, unsigned count) "obj=%p(%s) count=%d"
503
diff --git a/hw/net/meson.build b/hw/net/meson.build
531
+resettable_phase_hold_begin(void *obj, const char *objtype, unsigned count, int type) "obj=%p(%s) count=%d type=%d"
504
index XXXXXXX..XXXXXXX 100644
532
+resettable_phase_hold_exec(void *obj, const char *objtype, int has_method) "obj=%p(%s) method=%d"
505
--- a/hw/net/meson.build
533
+resettable_phase_hold_end(void *obj, const char *objtype, unsigned count) "obj=%p(%s) count=%d"
506
+++ b/hw/net/meson.build
534
+resettable_phase_exit_begin(void *obj, const char *objtype, unsigned count, int type) "obj=%p(%s) count=%d type=%d"
507
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('vmxnet3.c'))
535
+resettable_phase_exit_exec(void *obj, const char *objtype, int has_method) "obj=%p(%s) method=%d"
508
536
+resettable_phase_exit_end(void *obj, const char *objtype, unsigned count) "obj=%p(%s) count=%d"
509
system_ss.add(when: 'CONFIG_SMC91C111', if_true: files('smc91c111.c'))
537
+resettable_transitional_function(void *obj, const char *objtype) "obj=%p(%s)"
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'))
538
--
515
--
539
2.20.1
516
2.34.1
540
541
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
In qdev_set_parent_bus(), when changing the parent bus of a
3
imx_fec models the same PHY as lan9118_phy. The code is almost the same with
4
realized device, if the source and destination buses are not in the
4
imx_fec having more logging and tracing. Merge these improvements into
5
same reset state, some adaptations are required. This patch adds
5
lan9118_phy and reuse in imx_fec to fix the code duplication.
6
needed call to resettable_change_parent() to make sure a device reset
7
state stays coherent with its parent bus.
8
6
9
The addition is a no-op if:
7
Some migration state how resides in the new device model which breaks migration
10
1. the device being parented is not realized.
8
compatibility for the following machines:
11
2. the device is realized, but both buses are not under reset.
9
* imx25-pdk
10
* sabrelite
11
* mcimx7d-sabre
12
* mcimx6ul-evk
12
13
13
Case 2 means that as long as qdev_set_parent_bus() is called
14
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
14
during the machine realization procedure (which is before the
15
Tested-by: Guenter Roeck <linux@roeck-us.net>
15
machine reset so nothing is in reset), it is a no op.
16
17
There are 52 call sites of qdev_set_parent_bus(). All but one fall
18
into the no-op case:
19
+ 29 trivial calls related to virtio (in hw/{s390x,display,virtio}/
20
{vhost,virtio}-xxx.c) to set a vdev(or vgpu) composing device
21
parent bus just before realizing the same vdev(vgpu).
22
+ hw/core/qdev.c: when creating a device in qdev_try_create()
23
+ hw/core/sysbus.c: when initializing a device in the sysbus
24
+ hw/i386/amd_iommu.c: before realizing AMDVIState/pci
25
+ hw/isa/piix4.c: before realizing PIIX4State/rtc
26
+ hw/misc/auxbus.c: when creating an AUXBus
27
+ hw/misc/auxbus.c: when creating an AUXBus child
28
+ hw/misc/macio/macio.c: when initializing a MACIOState child
29
+ hw/misc/macio/macio.c: before realizing NewWorldMacIOState/pmu
30
+ hw/misc/macio/macio.c: before realizing NewWorldMacIOState/cuda
31
+ hw/net/virtio-net.c: Used for migration when using the failover
32
mechanism to migration a vfio-pci/net. It is
33
a no-op because at this point the device is
34
already on the bus.
35
+ hw/pci-host/designware.c: before realizing DesignwarePCIEHost/root
36
+ hw/pci-host/gpex.c: before realizing GPEXHost/root
37
+ hw/pci-host/prep.c: when initialiazing PREPPCIState/pci_dev
38
+ hw/pci-host/q35.c: before realizing Q35PCIHost/mch
39
+ hw/pci-host/versatile.c: when initializing PCIVPBState/pci_dev
40
+ hw/pci-host/xilinx-pcie.c: before realizing XilinxPCIEHost/root
41
+ hw/s390x/event-facility.c: when creating SCLPEventFacility/
42
TYPE_SCLP_QUIESCE
43
+ hw/s390x/event-facility.c: ditto with SCLPEventFacility/
44
TYPE_SCLP_CPU_HOTPLUG
45
+ hw/s390x/sclp.c: Not trivial because it is called on a SLCPDevice
46
just after realizing it. Ok because at this point the destination
47
bus (sysbus) is not in reset; the realize step is before the
48
machine reset.
49
+ hw/sd/core.c: Not OK. Used in sdbus_reparent_card(). See below.
50
+ hw/ssi/ssi.c: Used to put spi slave on spi bus and connect the cs
51
line in ssi_auto_connect_slave(). Ok because this function is only
52
used in realize step in hw/ssi/aspeed_smc.ci, hw/ssi/imx_spi.c,
53
hw/ssi/mss-spi.c, hw/ssi/xilinx_spi.c and hw/ssi/xilinx_spips.c.
54
+ hw/xen/xen-legacy-backend.c: when creating a XenLegacyDevice device
55
+ qdev-monitor.c: in device hotplug creation procedure before realize
56
57
Note that this commit alone will have no effect, right now there is no
58
use of resettable API to reset anything. So a bus will never be tagged
59
as in-reset by this same API.
60
61
The one place where side-effect will occurs is in hw/sd/core.c in
62
sdbus_reparent_card(). This function is only used in the raspi machines,
63
including during the sysbus reset procedure. This case will be
64
carrefully handled when doing the multiple phase reset transition.
65
66
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
67
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
68
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20241102125724.532843-3-shentey@gmail.com
69
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
70
Message-id: 20200123132823.1117486-7-damien.hedde@greensocs.com
71
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
72
---
19
---
73
hw/core/qdev.c | 16 +++++++++++-----
20
include/hw/net/imx_fec.h | 9 ++-
74
1 file changed, 11 insertions(+), 5 deletions(-)
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(-)
75
26
76
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
27
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
77
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
78
--- a/hw/core/qdev.c
29
--- a/include/hw/net/imx_fec.h
79
+++ b/hw/core/qdev.c
30
+++ b/include/hw/net/imx_fec.h
80
@@ -XXX,XX +XXX,XX @@ static void bus_add_child(BusState *bus, DeviceState *child)
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
81
32
#define TYPE_IMX_ENET "imx.enet"
82
void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
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)
83
{
99
{
84
- bool replugging = dev->parent_bus != NULL;
100
- imx_eth_update(s);
85
+ BusState *old_parent_bus = dev->parent_bus;
101
-}
86
102
-
87
- if (replugging) {
103
-static void imx_phy_update_link(IMXFECState *s)
88
+ if (old_parent_bus) {
104
-{
89
trace_qdev_update_parent_bus(dev, object_get_typename(OBJECT(dev)),
105
- /* Autonegotiation status mirrors link status. */
90
- dev->parent_bus, object_get_typename(OBJECT(dev->parent_bus)),
106
- if (qemu_get_queue(s->nic)->link_down) {
91
+ old_parent_bus, object_get_typename(OBJECT(old_parent_bus)),
107
- trace_imx_phy_update_link("down");
92
OBJECT(bus), object_get_typename(OBJECT(bus)));
108
- s->phy_status &= ~0x0024;
93
/*
109
- s->phy_int |= PHY_INT_DOWN;
94
* Keep a reference to the device while it's not plugged into
110
- } else {
95
* any bus, to avoid it potentially evaporating when it is
111
- trace_imx_phy_update_link("up");
96
* dereffed in bus_remove_child().
112
- s->phy_status |= 0x0024;
97
+ * Also keep the ref of the parent bus until the end, so that
113
- s->phy_int |= PHY_INT_ENERGYON;
98
+ * we can safely call resettable_change_parent() below.
114
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
99
*/
115
- }
100
object_ref(OBJECT(dev));
116
- imx_phy_update_irq(s);
101
bus_remove_child(dev->parent_bus, dev);
117
+ imx_eth_update(opaque);
102
- object_unref(OBJECT(dev->parent_bus));
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;
103
}
345
}
104
dev->parent_bus = bus;
346
+
105
object_ref(OBJECT(bus));
347
+ trace_lan9118_phy_read(val, reg);
106
bus_add_child(bus, dev);
348
+
107
- if (replugging) {
349
+ return val;
108
+ if (dev->realized) {
350
}
109
+ resettable_change_parent(OBJECT(dev), OBJECT(bus),
351
110
+ OBJECT(old_parent_bus));
352
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
111
+ }
353
{
112
+ if (old_parent_bus) {
354
+ trace_lan9118_phy_write(val, reg);
113
+ object_unref(OBJECT(old_parent_bus));
355
+
114
object_unref(OBJECT(dev));
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;
115
}
395
}
116
}
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"
117
--
471
--
118
2.20.1
472
2.34.1
119
120
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
If we know what the default value should be then we can test for
3
Turns 0x70 into 0xe0 (== 0x70 << 1) which adds the missing MII_ANLPAR_TX and
4
that as well as the feature existence.
4
fixes the MSB of selector field to be zero, as specified in the datasheet.
5
5
6
Signed-off-by: Andrew Jones <drjones@redhat.com>
6
Fixes: 2a424990170b "LAN9118 emulation"
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
8
Message-id: 20200120101023.16030-5-drjones@redhat.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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
tests/qtest/arm-cpu-features.c | 37 +++++++++++++++++++++++++---------
13
hw/net/lan9118_phy.c | 2 +-
12
1 file changed, 28 insertions(+), 9 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
13
15
14
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qtest/arm-cpu-features.c
18
--- a/hw/net/lan9118_phy.c
17
+++ b/tests/qtest/arm-cpu-features.c
19
+++ b/hw/net/lan9118_phy.c
18
@@ -XXX,XX +XXX,XX @@ static bool resp_get_feature(QDict *resp, const char *feature)
20
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
19
qobject_unref(_resp); \
21
val = s->advertise;
20
})
22
break;
21
23
case 5: /* Auto-neg Link Partner Ability */
22
+#define assert_feature(qts, cpu_type, feature, expected_value) \
24
- val = 0x0f71;
23
+({ \
25
+ val = 0x0fe1;
24
+ QDict *_resp, *_props; \
26
break;
25
+ \
27
case 6: /* Auto-neg Expansion */
26
+ _resp = do_query_no_props(qts, cpu_type); \
28
val = 1;
27
+ g_assert(_resp); \
28
+ g_assert(resp_has_props(_resp)); \
29
+ _props = resp_get_props(_resp); \
30
+ g_assert(qdict_get(_props, feature)); \
31
+ g_assert(qdict_get_bool(_props, feature) == (expected_value)); \
32
+ qobject_unref(_resp); \
33
+})
34
+
35
+#define assert_has_feature_enabled(qts, cpu_type, feature) \
36
+ assert_feature(qts, cpu_type, feature, true)
37
+
38
+#define assert_has_feature_disabled(qts, cpu_type, feature) \
39
+ assert_feature(qts, cpu_type, feature, false)
40
+
41
static void assert_type_full(QTestState *qts)
42
{
43
const char *error;
44
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion(const void *data)
45
assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
46
47
/* Test expected feature presence/absence for some cpu types */
48
- assert_has_feature(qts, "max", "pmu");
49
- assert_has_feature(qts, "cortex-a15", "pmu");
50
+ assert_has_feature_enabled(qts, "max", "pmu");
51
+ assert_has_feature_enabled(qts, "cortex-a15", "pmu");
52
assert_has_not_feature(qts, "cortex-a15", "aarch64");
53
54
if (g_str_equal(qtest_get_arch(), "aarch64")) {
55
- assert_has_feature(qts, "max", "aarch64");
56
- assert_has_feature(qts, "max", "sve");
57
- assert_has_feature(qts, "max", "sve128");
58
- assert_has_feature(qts, "cortex-a57", "pmu");
59
- assert_has_feature(qts, "cortex-a57", "aarch64");
60
+ assert_has_feature_enabled(qts, "max", "aarch64");
61
+ assert_has_feature_enabled(qts, "max", "sve");
62
+ assert_has_feature_enabled(qts, "max", "sve128");
63
+ assert_has_feature_enabled(qts, "cortex-a57", "pmu");
64
+ assert_has_feature_enabled(qts, "cortex-a57", "aarch64");
65
66
sve_tests_default(qts, "max");
67
68
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
69
QDict *resp;
70
char *error;
71
72
- assert_has_feature(qts, "host", "aarch64");
73
- assert_has_feature(qts, "host", "pmu");
74
+ assert_has_feature_enabled(qts, "host", "aarch64");
75
+ assert_has_feature_enabled(qts, "host", "pmu");
76
77
assert_error(qts, "cortex-a15",
78
"We cannot guarantee the CPU type 'cortex-a15' works "
79
--
29
--
80
2.20.1
30
2.34.1
81
82
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
This commit make use of the resettable API to reset the device being
3
Prefer named constants over magic values for better readability.
4
hotplugged when it is realized. Also it ensures it is put in a reset
5
state coherent with the parent it is plugged into.
6
4
7
Note that there is a difference in the reset. Instead of resetting
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
only the hotplugged device, we reset also its subtree (switch to
6
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
9
resettable API). This is not expected to be a problem because
7
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
sub-buses are just realized too. If a hotplugged device has any
8
Message-id: 20241102125724.532843-5-shentey@gmail.com
11
sub-buses it is logical to reset them too at this point.
12
13
The recently added should_be_hidden and PCI's partially_hotplugged
14
mechanisms do not interfere with realize operation:
15
+ In the should_be_hidden use case, device creation is
16
delayed.
17
+ The partially_hotplugged mechanism prevents a device to be
18
unplugged and unrealized from qdev POV and unrealized.
19
20
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
23
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
24
Message-id: 20200123132823.1117486-8-damien.hedde@greensocs.com
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
10
---
27
include/hw/resettable.h | 11 +++++++++++
11
include/hw/net/mii.h | 6 +++++
28
hw/core/qdev.c | 15 ++++++++++++++-
12
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
29
2 files changed, 25 insertions(+), 1 deletion(-)
13
2 files changed, 46 insertions(+), 23 deletions(-)
30
14
31
diff --git a/include/hw/resettable.h b/include/hw/resettable.h
15
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
32
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
33
--- a/include/hw/resettable.h
17
--- a/include/hw/net/mii.h
34
+++ b/include/hw/resettable.h
18
+++ b/include/hw/net/mii.h
35
@@ -XXX,XX +XXX,XX @@ struct ResettableState {
19
@@ -XXX,XX +XXX,XX @@
36
bool exit_phase_in_progress;
20
#define MII_BMSR_JABBER (1 << 1) /* Jabber detected */
37
};
21
#define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */
38
22
39
+/**
23
+#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */
40
+ * resettable_state_clear:
24
#define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */
41
+ * Clear the state. It puts the state to the initial (zeroed) state required
25
#define MII_ANAR_PAUSE (1 << 10) /* Try for pause */
42
+ * to reuse an object. Typically used in realize step of base classes
26
#define MII_ANAR_TXFD (1 << 8)
43
+ * implementing the interface.
27
@@ -XXX,XX +XXX,XX @@
44
+ */
28
#define MII_ANAR_10FD (1 << 6)
45
+static inline void resettable_state_clear(ResettableState *state)
29
#define MII_ANAR_10 (1 << 5)
46
+{
30
#define MII_ANAR_CSMACD (1 << 0)
47
+ memset(state, 0, sizeof(ResettableState));
31
+#define MII_ANAR_SELECT (0x001f) /* Selector bits */
48
+}
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
49
+
42
+
50
/**
43
/* RealTek 8211E */
51
* resettable_reset:
44
#define RTL8211E_PHYID1 0x001c
52
* Trigger a reset on an object @obj of type @type. @obj must implement
45
#define RTL8211E_PHYID2 0xc915
53
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
46
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
54
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/core/qdev.c
48
--- a/hw/net/lan9118_phy.c
56
+++ b/hw/core/qdev.c
49
+++ b/hw/net/lan9118_phy.c
57
@@ -XXX,XX +XXX,XX @@ static void device_set_realized(Object *obj, bool value, Error **errp)
50
@@ -XXX,XX +XXX,XX @@
51
52
#include "qemu/osdep.h"
53
#include "hw/net/lan9118_phy.h"
54
+#include "hw/net/mii.h"
55
#include "hw/irq.h"
56
#include "hw/resettable.h"
57
#include "migration/vmstate.h"
58
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
59
uint16_t val;
60
61
switch (reg) {
62
- case 0: /* Basic Control */
63
+ case MII_BMCR:
64
val = s->control;
65
break;
66
- case 1: /* Basic Status */
67
+ case MII_BMSR:
68
val = s->status;
69
break;
70
- case 2: /* ID1 */
71
- val = 0x0007;
72
+ case MII_PHYID1:
73
+ val = SMSCLAN9118_PHYID1;
74
break;
75
- case 3: /* ID2 */
76
- val = 0xc0d1;
77
+ case MII_PHYID2:
78
+ val = SMSCLAN9118_PHYID2;
79
break;
80
- case 4: /* Auto-neg advertisement */
81
+ case MII_ANAR:
82
val = s->advertise;
83
break;
84
- case 5: /* Auto-neg Link Partner Ability */
85
- val = 0x0fe1;
86
+ case MII_ANLPAR:
87
+ val = MII_ANLPAR_PAUSEASY | MII_ANLPAR_PAUSE | MII_ANLPAR_T4 |
88
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
89
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
90
break;
91
- case 6: /* Auto-neg Expansion */
92
- val = 1;
93
+ case MII_ANER:
94
+ val = MII_ANER_NWAY;
95
break;
96
case 29: /* Interrupt source. */
97
val = s->ints;
98
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
99
trace_lan9118_phy_write(val, reg);
100
101
switch (reg) {
102
- case 0: /* Basic Control */
103
- if (val & 0x8000) {
104
+ case MII_BMCR:
105
+ if (val & MII_BMCR_RESET) {
106
lan9118_phy_reset(s);
107
} else {
108
- s->control = val & 0x7980;
109
+ s->control = val & (MII_BMCR_LOOPBACK | MII_BMCR_SPEED100 |
110
+ MII_BMCR_AUTOEN | MII_BMCR_PDOWN | MII_BMCR_FD |
111
+ MII_BMCR_CTST);
112
/* Complete autonegotiation immediately. */
113
- if (val & 0x1000) {
114
- s->status |= 0x0020;
115
+ if (val & MII_BMCR_AUTOEN) {
116
+ s->status |= MII_BMSR_AN_COMP;
58
}
117
}
59
}
118
}
60
119
break;
61
+ /*
120
- case 4: /* Auto-neg advertisement */
62
+ * Clear the reset state, in case the object was previously unrealized
121
- s->advertise = (val & 0x2d7f) | 0x80;
63
+ * with a dirty state.
122
+ case MII_ANAR:
64
+ */
123
+ s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
65
+ resettable_state_clear(&dev->reset);
124
+ MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
66
+
125
+ MII_ANAR_SELECT))
67
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
126
+ | MII_ANAR_TX;
68
object_property_set_bool(OBJECT(bus), true, "realized",
127
break;
69
&local_err);
128
case 30: /* Interrupt mask */
70
@@ -XXX,XX +XXX,XX @@ static void device_set_realized(Object *obj, bool value, Error **errp)
129
s->int_mask = val & 0xff;
71
}
130
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
72
}
131
/* Autonegotiation status mirrors link status. */
73
if (dev->hotplugged) {
132
if (link_down) {
74
- device_legacy_reset(dev);
133
trace_lan9118_phy_update_link("down");
75
+ /*
134
- s->status &= ~0x0024;
76
+ * Reset the device, as well as its subtree which, at this point,
135
+ s->status &= ~(MII_BMSR_AN_COMP | MII_BMSR_LINK_ST);
77
+ * should be realized too.
136
s->ints |= PHY_INT_DOWN;
78
+ */
137
} else {
79
+ resettable_assert_reset(OBJECT(dev), RESET_TYPE_COLD);
138
trace_lan9118_phy_update_link("up");
80
+ resettable_change_parent(OBJECT(dev), OBJECT(dev->parent_bus),
139
- s->status |= 0x0024;
81
+ NULL);
140
+ s->status |= MII_BMSR_AN_COMP | MII_BMSR_LINK_ST;
82
+ resettable_release_reset(OBJECT(dev), RESET_TYPE_COLD);
141
s->ints |= PHY_INT_ENERGYON;
83
}
142
s->ints |= PHY_INT_AUTONEG_COMPLETE;
84
dev->pending_deleted_event = false;
143
}
85
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);
86
--
166
--
87
2.20.1
167
2.34.1
88
89
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Signed-off-by: Andrew Jones <drjones@redhat.com>
3
The real device advertises this mode and the device model already advertises
4
Message-id: 20200120101023.16030-2-drjones@redhat.com
4
100 mbps half duplex and 10 mbps full+half duplex. So advertise this mode to
5
make the model more realistic.
6
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
9
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
Message-id: 20241102125724.532843-6-shentey@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
target/arm/kvm_arm.h | 46 ++++++++++++++++++++++++++------------------
13
hw/net/lan9118_phy.c | 4 ++--
9
1 file changed, 27 insertions(+), 19 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
10
15
11
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/kvm_arm.h
18
--- a/hw/net/lan9118_phy.c
14
+++ b/target/arm/kvm_arm.h
19
+++ b/hw/net/lan9118_phy.c
15
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
16
int kvm_arm_vcpu_init(CPUState *cs);
21
break;
17
22
case MII_ANAR:
18
/**
23
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
19
- * kvm_arm_vcpu_finalize
24
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
20
+ * kvm_arm_vcpu_finalize:
25
- MII_ANAR_SELECT))
21
* @cs: CPUState
26
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
22
- * @feature: int
27
+ MII_ANAR_10 | MII_ANAR_SELECT))
23
+ * @feature: feature to finalize
28
| MII_ANAR_TX;
24
*
29
break;
25
* Finalizes the configuration of the specified VCPU feature by
30
case 30: /* Interrupt mask */
26
* invoking the KVM_ARM_VCPU_FINALIZE ioctl. Features requiring
27
@@ -XXX,XX +XXX,XX @@ void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
28
int kvm_arm_init_cpreg_list(ARMCPU *cpu);
29
30
/**
31
- * kvm_arm_reg_syncs_via_cpreg_list
32
- * regidx: KVM register index
33
+ * kvm_arm_reg_syncs_via_cpreg_list:
34
+ * @regidx: KVM register index
35
*
36
* Return true if this KVM register should be synchronized via the
37
* cpreg list of arbitrary system registers, false if it is synchronized
38
@@ -XXX,XX +XXX,XX @@ int kvm_arm_init_cpreg_list(ARMCPU *cpu);
39
bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx);
40
41
/**
42
- * kvm_arm_cpreg_level
43
- * regidx: KVM register index
44
+ * kvm_arm_cpreg_level:
45
+ * @regidx: KVM register index
46
*
47
* Return the level of this coprocessor/system register. Return value is
48
* either KVM_PUT_RUNTIME_STATE, KVM_PUT_RESET_STATE, or KVM_PUT_FULL_STATE.
49
@@ -XXX,XX +XXX,XX @@ void kvm_arm_init_serror_injection(CPUState *cs);
50
* @cpu: ARMCPU
51
*
52
* Get VCPU related state from kvm.
53
+ *
54
+ * Returns: 0 if success else < 0 error code
55
*/
56
int kvm_get_vcpu_events(ARMCPU *cpu);
57
58
@@ -XXX,XX +XXX,XX @@ int kvm_get_vcpu_events(ARMCPU *cpu);
59
* @cpu: ARMCPU
60
*
61
* Put VCPU related state to kvm.
62
+ *
63
+ * Returns: 0 if success else < 0 error code
64
*/
65
int kvm_put_vcpu_events(ARMCPU *cpu);
66
67
@@ -XXX,XX +XXX,XX @@ typedef struct ARMHostCPUFeatures {
68
69
/**
70
* kvm_arm_get_host_cpu_features:
71
- * @ahcc: ARMHostCPUClass to fill in
72
+ * @ahcf: ARMHostCPUClass to fill in
73
*
74
* Probe the capabilities of the host kernel's preferred CPU and fill
75
* in the ARMHostCPUClass struct accordingly.
76
+ *
77
+ * Returns true on success and false otherwise.
78
*/
79
bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
80
81
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
82
bool kvm_arm_aarch32_supported(CPUState *cs);
83
84
/**
85
- * bool kvm_arm_pmu_supported:
86
+ * kvm_arm_pmu_supported:
87
* @cs: CPUState
88
*
89
* Returns: true if the KVM VCPU can enable its PMU
90
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_aarch32_supported(CPUState *cs);
91
bool kvm_arm_pmu_supported(CPUState *cs);
92
93
/**
94
- * bool kvm_arm_sve_supported:
95
+ * kvm_arm_sve_supported:
96
* @cs: CPUState
97
*
98
* Returns true if the KVM VCPU can enable SVE and false otherwise.
99
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_pmu_supported(CPUState *cs);
100
bool kvm_arm_sve_supported(CPUState *cs);
101
102
/**
103
- * kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the
104
- * IPA address space supported by KVM
105
- *
106
+ * kvm_arm_get_max_vm_ipa_size:
107
* @ms: Machine state handle
108
+ *
109
+ * Returns the number of bits in the IPA address space supported by KVM
110
*/
111
int kvm_arm_get_max_vm_ipa_size(MachineState *ms);
112
113
/**
114
- * kvm_arm_sync_mpstate_to_kvm
115
+ * kvm_arm_sync_mpstate_to_kvm:
116
* @cpu: ARMCPU
117
*
118
* If supported set the KVM MP_STATE based on QEMU's model.
119
+ *
120
+ * Returns 0 on success and -1 on failure.
121
*/
122
int kvm_arm_sync_mpstate_to_kvm(ARMCPU *cpu);
123
124
/**
125
- * kvm_arm_sync_mpstate_to_qemu
126
+ * kvm_arm_sync_mpstate_to_qemu:
127
* @cpu: ARMCPU
128
*
129
* If supported get the MP_STATE from KVM and store in QEMU's model.
130
+ *
131
+ * Returns 0 on success and aborts on failure.
132
*/
133
int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu);
134
135
@@ -XXX,XX +XXX,XX @@ int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
136
137
static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
138
{
139
- /* This should never actually be called in the "not KVM" case,
140
+ /*
141
+ * This should never actually be called in the "not KVM" case,
142
* but set up the fields to indicate an error anyway.
143
*/
144
cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
145
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit);
146
*
147
* Return: TRUE if any hardware breakpoints in use.
148
*/
149
-
150
bool kvm_arm_hw_debug_active(CPUState *cs);
151
152
/**
153
* kvm_arm_copy_hw_debug_data:
154
- *
155
* @ptr: kvm_guest_debug_arch structure
156
*
157
* Copy the architecture specific debug registers into the
158
* kvm_guest_debug ioctl structure.
159
*/
160
struct kvm_guest_debug_arch;
161
-
162
void kvm_arm_copy_hw_debug_data(struct kvm_guest_debug_arch *ptr);
163
164
/**
165
- * its_class_name
166
+ * its_class_name:
167
*
168
* Return the ITS class name to use depending on whether KVM acceleration
169
* and KVM CAP_SIGNAL_MSI are supported
170
--
31
--
171
2.20.1
32
2.34.1
172
173
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
From: Damien Hedde <damien.hedde@greensocs.com>
1
IEEE 758 does not define a fixed rule for what NaN to return in
2
2
the case of a fused multiply-add of inf * 0 + NaN. Different
3
Adds trace events to reset procedure and when updating the parent
3
architectures thus do different things:
4
bus of a device.
4
* some return the default NaN
5
5
* some return the input NaN
6
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
6
* Arm returns the default NaN if the input NaN is quiet,
7
and the input NaN if it is signalling
8
9
We want to make this logic be runtime selected rather than
10
hardcoded into the binary, because:
11
* this will let us have multiple targets in one QEMU binary
12
* the Arm FEAT_AFP architectural feature includes letting
13
the guest select a NaN propagation rule at runtime
14
15
In this commit we add an enum for the propagation rule, the field in
16
float_status, and the corresponding getters and setters. We change
17
pickNaNMulAdd to honour this, but because all targets still leave
18
this field at its default 0 value, the fallback logic will pick the
19
rule type with the old ifdef ladder.
20
21
Note that four architectures both use the muladd softfloat functions
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.
29
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
32
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
9
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
10
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20200123132823.1117486-3-damien.hedde@greensocs.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
33
---
14
hw/core/qdev.c | 29 ++++++++++++++++++++++++++---
34
include/fpu/softfloat-helpers.h | 11 ++++
15
hw/core/trace-events | 9 +++++++++
35
include/fpu/softfloat-types.h | 23 +++++++++
16
2 files changed, 35 insertions(+), 3 deletions(-)
36
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
17
37
3 files changed, 95 insertions(+), 30 deletions(-)
18
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
38
39
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
19
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/core/qdev.c
41
--- a/include/fpu/softfloat-helpers.h
21
+++ b/hw/core/qdev.c
42
+++ b/include/fpu/softfloat-helpers.h
22
@@ -XXX,XX +XXX,XX @@
43
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
23
#include "hw/boards.h"
44
status->float_2nan_prop_rule = rule;
24
#include "hw/sysbus.h"
25
#include "migration/vmstate.h"
26
+#include "trace.h"
27
28
bool qdev_hotplug = false;
29
static bool qdev_hot_added = false;
30
@@ -XXX,XX +XXX,XX @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
31
bool replugging = dev->parent_bus != NULL;
32
33
if (replugging) {
34
- /* Keep a reference to the device while it's not plugged into
35
+ trace_qdev_update_parent_bus(dev, object_get_typename(OBJECT(dev)),
36
+ dev->parent_bus, object_get_typename(OBJECT(dev->parent_bus)),
37
+ OBJECT(bus), object_get_typename(OBJECT(bus)));
38
+ /*
39
+ * Keep a reference to the device while it's not plugged into
40
* any bus, to avoid it potentially evaporating when it is
41
* dereffed in bus_remove_child().
42
*/
43
@@ -XXX,XX +XXX,XX @@ HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
44
return hotplug_ctrl;
45
}
45
}
46
46
47
+static int qdev_prereset(DeviceState *dev, void *opaque)
47
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
+ float_status *status)
48
+{
49
+{
49
+ trace_qdev_reset_tree(dev, object_get_typename(OBJECT(dev)));
50
+ status->float_infzeronan_rule = rule;
50
+ return 0;
51
+}
51
+}
52
+
52
+
53
+static int qbus_prereset(BusState *bus, void *opaque)
53
static inline void set_flush_to_zero(bool val, float_status *status)
54
{
55
status->flush_to_zero = val;
56
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
57
return status->float_2nan_prop_rule;
58
}
59
60
+static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
54
+{
61
+{
55
+ trace_qbus_reset_tree(bus, object_get_typename(OBJECT(bus)));
62
+ return status->float_infzeronan_rule;
56
+ return 0;
57
+}
63
+}
58
+
64
+
59
static int qdev_reset_one(DeviceState *dev, void *opaque)
65
static inline bool get_flush_to_zero(float_status *status)
60
{
66
{
61
device_legacy_reset(dev);
67
return status->flush_to_zero;
62
@@ -XXX,XX +XXX,XX @@ static int qdev_reset_one(DeviceState *dev, void *opaque)
68
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
63
static int qbus_reset_one(BusState *bus, void *opaque)
69
index XXXXXXX..XXXXXXX 100644
70
--- a/include/fpu/softfloat-types.h
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)
64
{
116
{
65
BusClass *bc = BUS_GET_CLASS(bus);
117
+ FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
66
+ trace_qbus_reset(bus, object_get_typename(OBJECT(bus)));
118
+
67
if (bc->reset) {
119
/*
68
bc->reset(bus);
120
* We guarantee not to require the target to tell us how to
69
}
121
* pick a NaN if we're always returning the default NaN.
70
@@ -XXX,XX +XXX,XX @@ static int qbus_reset_one(BusState *bus, void *opaque)
122
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
71
123
* specify.
72
void qdev_reset_all(DeviceState *dev)
124
*/
73
{
125
assert(!status->default_nan_mode);
74
- qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
126
+
75
+ trace_qdev_reset_all(dev, object_get_typename(OBJECT(dev)));
127
+ if (rule == float_infzeronan_none) {
76
+ qdev_walk_children(dev, qdev_prereset, qbus_prereset,
128
+ /*
77
+ qdev_reset_one, qbus_reset_one, NULL);
129
+ * Temporarily fall back to ifdef ladder
78
}
130
+ */
79
131
#if defined(TARGET_ARM)
80
void qdev_reset_all_fn(void *opaque)
132
- /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
81
@@ -XXX,XX +XXX,XX @@ void qdev_reset_all_fn(void *opaque)
133
- * the default NaN
82
134
- */
83
void qbus_reset_all(BusState *bus)
135
- if (infzero && is_qnan(c_cls)) {
84
{
136
- return 3;
85
- qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
137
+ /*
86
+ trace_qbus_reset_all(bus, object_get_typename(OBJECT(bus)));
138
+ * For ARM, the (inf,zero,qnan) case returns the default NaN,
87
+ qbus_walk_children(bus, qdev_prereset, qbus_prereset,
139
+ * but (inf,zero,snan) returns the input NaN.
88
+ qdev_reset_one, qbus_reset_one, NULL);
140
+ */
89
}
141
+ rule = float_infzeronan_dnan_if_qnan;
90
142
+#elif defined(TARGET_MIPS)
91
void qbus_reset_all_fn(void *opaque)
143
+ if (snan_bit_is_one(status)) {
92
@@ -XXX,XX +XXX,XX @@ void device_legacy_reset(DeviceState *dev)
144
+ /*
93
{
145
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
94
DeviceClass *klass = DEVICE_GET_CLASS(dev);
146
+ * case sets InvalidOp and returns the default NaN
95
147
+ */
96
+ trace_qdev_reset(dev, object_get_typename(OBJECT(dev)));
148
+ rule = float_infzeronan_dnan_always;
97
if (klass->reset) {
149
+ } else {
98
klass->reset(dev);
150
+ /*
99
}
151
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
100
diff --git a/hw/core/trace-events b/hw/core/trace-events
152
+ * case sets InvalidOp and returns the input value 'c'
101
index XXXXXXX..XXXXXXX 100644
153
+ */
102
--- a/hw/core/trace-events
154
+ rule = float_infzeronan_dnan_never;
103
+++ b/hw/core/trace-events
155
+ }
104
@@ -XXX,XX +XXX,XX @@
156
+#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
105
# loader.c
157
+ defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
106
loader_write_rom(const char *name, uint64_t gpa, uint64_t size, bool isrom) "%s: @0x%"PRIx64" size=0x%"PRIx64" ROM=%d"
158
+ defined(TARGET_I386) || defined(TARGET_LOONGARCH)
107
+
159
+ /*
108
+# qdev.c
160
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
109
+qdev_reset(void *obj, const char *objtype) "obj=%p(%s)"
161
+ * case sets InvalidOp and returns the input value 'c'
110
+qdev_reset_all(void *obj, const char *objtype) "obj=%p(%s)"
162
+ */
111
+qdev_reset_tree(void *obj, const char *objtype) "obj=%p(%s)"
163
+ /*
112
+qbus_reset(void *obj, const char *objtype) "obj=%p(%s)"
164
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
113
+qbus_reset_all(void *obj, const char *objtype) "obj=%p(%s)"
165
+ * to return an input NaN if we have one (ie c) rather than generating
114
+qbus_reset_tree(void *obj, const char *objtype) "obj=%p(%s)"
166
+ * a default NaN
115
+qdev_update_parent_bus(void *obj, const char *objtype, void *oldp, const char *oldptype, void *newp, const char *newptype) "obj=%p(%s) old_parent=%p(%s) new_parent=%p(%s)"
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
+ }
189
+ }
190
+
191
+#if defined(TARGET_ARM)
192
+
193
/* This looks different from the ARM ARM pseudocode, because the ARM ARM
194
* puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
195
*/
196
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
197
}
198
#elif defined(TARGET_MIPS)
199
if (snan_bit_is_one(status)) {
200
- /*
201
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
202
- * case sets InvalidOp and returns the default NaN
203
- */
204
- if (infzero) {
205
- return 3;
206
- }
207
/* Prefer sNaN over qNaN, in the a, b, c order. */
208
if (is_snan(a_cls)) {
209
return 0;
210
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
211
return 2;
212
}
213
} else {
214
- /*
215
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
216
- * case sets InvalidOp and returns the input value 'c'
217
- */
218
/* Prefer sNaN over qNaN, in the c, a, b order. */
219
if (is_snan(c_cls)) {
220
return 2;
221
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
222
}
223
}
224
#elif defined(TARGET_LOONGARCH64)
225
- /*
226
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
227
- * case sets InvalidOp and returns the input value 'c'
228
- */
229
-
230
/* Prefer sNaN over qNaN, in the c, a, b order. */
231
if (is_snan(c_cls)) {
232
return 2;
233
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
234
return 1;
235
}
236
#elif defined(TARGET_PPC)
237
- /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
238
- * to return an input NaN if we have one (ie c) rather than generating
239
- * a default NaN
240
- */
241
-
242
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
243
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
244
*/
245
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
246
return 1;
247
}
248
#elif defined(TARGET_S390X)
249
- if (infzero) {
250
- return 3;
251
- }
252
-
253
if (is_snan(a_cls)) {
254
return 0;
255
} else if (is_snan(b_cls)) {
116
--
256
--
117
2.20.1
257
2.34.1
118
119
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
From: Joel Stanley <joel@jms.id.au>
1
IEEE 758 does not define a fixed rule for which NaN to pick as the
2
2
result if both operands of a 3-operand fused multiply-add operation
3
Following the pattern of the work recently done with the ASPEED GPIO
3
are NaNs. As a result different architectures have ended up with
4
model, this adds support for inspecting and modifying the PCA9552 LEDs
4
different rules for propagating NaNs.
5
from the monitor.
5
6
6
QEMU currently hardcodes the NaN propagation logic into the binary
7
(qemu) qom-set /machine/unattached/device[17] led0 on
7
because pickNaNMulAdd() has an ifdef ladder for different targets.
8
(qemu) qom-set /machine/unattached/device[17] led0 off
8
We want to make the propagation rule instead be selectable at
9
(qemu) qom-set /machine/unattached/device[17] led0 pwm0
9
runtime, because:
10
(qemu) qom-set /machine/unattached/device[17] led0 pwm1
10
* this will let us have multiple targets in one QEMU binary
11
11
* the Arm FEAT_AFP architectural feature includes letting
12
Signed-off-by: Joel Stanley <joel@jms.id.au>
12
the guest select a NaN propagation rule at runtime
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
14
Message-id: 20200114103433.30534-6-clg@kaod.org
14
In this commit we add an enum for the propagation rule, the field in
15
[clg: - removed the "qom-get" examples from the commit log
15
float_status, and the corresponding getters and setters. We change
16
- merged memory leak fixes from Joel ]
16
pickNaNMulAdd to honour this, but because all targets still leave
17
Signed-off-by: Cédric Le Goater <clg@kaod.org>
17
this field at its default 0 value, the fallback logic will pick the
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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.
23
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20241202131347.498124-16-peter.maydell@linaro.org
20
---
27
---
21
hw/misc/pca9552.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++
28
include/fpu/softfloat-helpers.h | 11 +++
22
1 file changed, 90 insertions(+)
29
include/fpu/softfloat-types.h | 55 +++++++++++
23
30
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
24
diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
31
3 files changed, 107 insertions(+), 126 deletions(-)
32
33
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
25
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/misc/pca9552.c
35
--- a/include/fpu/softfloat-helpers.h
27
+++ b/hw/misc/pca9552.c
36
+++ b/include/fpu/softfloat-helpers.h
28
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
29
#include "hw/misc/pca9552.h"
38
status->float_2nan_prop_rule = rule;
30
#include "hw/misc/pca9552_regs.h"
39
}
31
#include "migration/vmstate.h"
40
32
+#include "qapi/error.h"
41
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
33
+#include "qapi/visitor.h"
42
+ float_status *status)
34
43
+{
35
#define PCA9552_LED_ON 0x0
44
+ status->float_3nan_prop_rule = rule;
36
#define PCA9552_LED_OFF 0x1
45
+}
37
#define PCA9552_LED_PWM0 0x2
46
+
38
#define PCA9552_LED_PWM1 0x3
47
static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
39
48
float_status *status)
40
+static const char *led_state[] = {"on", "off", "pwm0", "pwm1"};
41
+
42
static uint8_t pca9552_pin_get_config(PCA9552State *s, int pin)
43
{
49
{
44
uint8_t reg = PCA9552_LS0 + (pin / 4);
50
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
45
@@ -XXX,XX +XXX,XX @@ static int pca9552_event(I2CSlave *i2c, enum i2c_event event)
51
return status->float_2nan_prop_rule;
46
return 0;
47
}
52
}
48
53
49
+static void pca9552_get_led(Object *obj, Visitor *v, const char *name,
54
+static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
50
+ void *opaque, Error **errp)
51
+{
55
+{
52
+ PCA9552State *s = PCA9552(obj);
56
+ return status->float_3nan_prop_rule;
53
+ int led, rc, reg;
57
+}
54
+ uint8_t state;
58
+
55
+
59
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
56
+ rc = sscanf(name, "led%2d", &led);
60
{
57
+ if (rc != 1) {
61
return status->float_infzeronan_rule;
58
+ error_setg(errp, "%s: error reading %s", __func__, name);
62
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
59
+ return;
63
index XXXXXXX..XXXXXXX 100644
64
--- a/include/fpu/softfloat-types.h
65
+++ b/include/fpu/softfloat-types.h
66
@@ -XXX,XX +XXX,XX @@ this code that are retained.
67
#ifndef SOFTFLOAT_TYPES_H
68
#define SOFTFLOAT_TYPES_H
69
70
+#include "hw/registerfields.h"
71
+
72
/*
73
* Software IEC/IEEE floating-point types.
74
*/
75
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
76
float_2nan_prop_x87,
77
} Float2NaNPropRule;
78
79
+/*
80
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
81
+ * architectures have different rules for which input NaN is
82
+ * propagated to the output when there is more than one NaN on the
83
+ * input.
84
+ *
85
+ * If default_nan_mode is enabled then it is valid not to set a NaN
86
+ * propagation rule, because the softfloat code guarantees not to try
87
+ * to pick a NaN to propagate in default NaN mode. When not in
88
+ * default-NaN mode, it is an error for the target not to set the rule
89
+ * in float_status if it uses a muladd, and we will assert if we need
90
+ * to handle an input NaN and no rule was selected.
91
+ *
92
+ * The naming scheme for Float3NaNPropRule values is:
93
+ * float_3nan_prop_s_abc:
94
+ * = "Prefer SNaN over QNaN, then operand A over B over C"
95
+ * float_3nan_prop_abc:
96
+ * = "Prefer A over B over C regardless of SNaN vs QNAN"
97
+ *
98
+ * For QEMU, the multiply-add operation is A * B + C.
99
+ */
100
+
101
+/*
102
+ * We set the Float3NaNPropRule enum values up so we can select the
103
+ * right value in pickNaNMulAdd in a data driven way.
104
+ */
105
+FIELD(3NAN, 1ST, 0, 2) /* which operand is most preferred ? */
106
+FIELD(3NAN, 2ND, 2, 2) /* which operand is next most preferred ? */
107
+FIELD(3NAN, 3RD, 4, 2) /* which operand is least preferred ? */
108
+FIELD(3NAN, SNAN, 6, 1) /* do we prefer SNaN over QNaN ? */
109
+
110
+#define PROPRULE(X, Y, Z) \
111
+ ((X << R_3NAN_1ST_SHIFT) | (Y << R_3NAN_2ND_SHIFT) | (Z << R_3NAN_3RD_SHIFT))
112
+
113
+typedef enum __attribute__((__packed__)) {
114
+ float_3nan_prop_none = 0, /* No propagation rule specified */
115
+ float_3nan_prop_abc = PROPRULE(0, 1, 2),
116
+ float_3nan_prop_acb = PROPRULE(0, 2, 1),
117
+ float_3nan_prop_bac = PROPRULE(1, 0, 2),
118
+ float_3nan_prop_bca = PROPRULE(1, 2, 0),
119
+ float_3nan_prop_cab = PROPRULE(2, 0, 1),
120
+ float_3nan_prop_cba = PROPRULE(2, 1, 0),
121
+ float_3nan_prop_s_abc = float_3nan_prop_abc | R_3NAN_SNAN_MASK,
122
+ float_3nan_prop_s_acb = float_3nan_prop_acb | R_3NAN_SNAN_MASK,
123
+ float_3nan_prop_s_bac = float_3nan_prop_bac | R_3NAN_SNAN_MASK,
124
+ float_3nan_prop_s_bca = float_3nan_prop_bca | R_3NAN_SNAN_MASK,
125
+ float_3nan_prop_s_cab = float_3nan_prop_cab | R_3NAN_SNAN_MASK,
126
+ float_3nan_prop_s_cba = float_3nan_prop_cba | R_3NAN_SNAN_MASK,
127
+} Float3NaNPropRule;
128
+
129
+#undef PROPRULE
130
+
131
/*
132
* Rule for result of fused multiply-add 0 * Inf + NaN.
133
* This must be a NaN, but implementations differ on whether this
134
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
135
FloatRoundMode float_rounding_mode;
136
FloatX80RoundPrec floatx80_rounding_precision;
137
Float2NaNPropRule float_2nan_prop_rule;
138
+ Float3NaNPropRule float_3nan_prop_rule;
139
FloatInfZeroNaNRule float_infzeronan_rule;
140
bool tininess_before_rounding;
141
/* should denormalised results go to zero and set the inexact flag? */
142
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
143
index XXXXXXX..XXXXXXX 100644
144
--- a/fpu/softfloat-specialize.c.inc
145
+++ b/fpu/softfloat-specialize.c.inc
146
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
147
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
148
bool infzero, bool have_snan, float_status *status)
149
{
150
+ FloatClass cls[3] = { a_cls, b_cls, c_cls };
151
+ Float3NaNPropRule rule = status->float_3nan_prop_rule;
152
+ int which;
153
+
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,
158
}
159
}
160
161
+ if (rule == float_3nan_prop_none) {
162
#if defined(TARGET_ARM)
163
-
164
- /* This looks different from the ARM ARM pseudocode, because the ARM ARM
165
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
166
- */
167
- if (is_snan(c_cls)) {
168
- return 2;
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
60
+ }
321
+ }
61
+ if (led < 0 || led > s->nr_leds) {
322
+
62
+ error_setg(errp, "%s invalid led %s", __func__, name);
323
+ assert(rule != float_3nan_prop_none);
63
+ return;
324
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
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]));
64
+ }
335
+ }
65
+ /*
336
+ return which;
66
+ * Get the LSx register as the qom interface should expose the device
67
+ * state, not the modeled 'input line' behaviour which would come from
68
+ * reading the INPUTx reg
69
+ */
70
+ reg = PCA9552_LS0 + led / 4;
71
+ state = (pca9552_read(s, reg) >> (led % 8)) & 0x3;
72
+ visit_type_str(v, name, (char **)&led_state[state], errp);
73
+}
74
+
75
+/*
76
+ * Return an LED selector register value based on an existing one, with
77
+ * the appropriate 2-bit state value set for the given LED number (0-3).
78
+ */
79
+static inline uint8_t pca955x_ledsel(uint8_t oldval, int led_num, int state)
80
+{
81
+ return (oldval & (~(0x3 << (led_num << 1)))) |
82
+ ((state & 0x3) << (led_num << 1));
83
+}
84
+
85
+static void pca9552_set_led(Object *obj, Visitor *v, const char *name,
86
+ void *opaque, Error **errp)
87
+{
88
+ PCA9552State *s = PCA9552(obj);
89
+ Error *local_err = NULL;
90
+ int led, rc, reg, val;
91
+ uint8_t state;
92
+ char *state_str;
93
+
94
+ visit_type_str(v, name, &state_str, &local_err);
95
+ if (local_err) {
96
+ error_propagate(errp, local_err);
97
+ return;
98
+ }
99
+ rc = sscanf(name, "led%2d", &led);
100
+ if (rc != 1) {
101
+ error_setg(errp, "%s: error reading %s", __func__, name);
102
+ return;
103
+ }
104
+ if (led < 0 || led > s->nr_leds) {
105
+ error_setg(errp, "%s invalid led %s", __func__, name);
106
+ return;
107
+ }
108
+
109
+ for (state = 0; state < ARRAY_SIZE(led_state); state++) {
110
+ if (!strcmp(state_str, led_state[state])) {
111
+ break;
112
+ }
113
+ }
114
+ if (state >= ARRAY_SIZE(led_state)) {
115
+ error_setg(errp, "%s invalid led state %s", __func__, state_str);
116
+ return;
117
+ }
118
+
119
+ reg = PCA9552_LS0 + led / 4;
120
+ val = pca9552_read(s, reg);
121
+ val = pca955x_ledsel(val, led % 4, state);
122
+ pca9552_write(s, reg, val);
123
+}
124
+
125
static const VMStateDescription pca9552_vmstate = {
126
.name = "PCA9552",
127
.version_id = 0,
128
@@ -XXX,XX +XXX,XX @@ static void pca9552_reset(DeviceState *dev)
129
static void pca9552_initfn(Object *obj)
130
{
131
PCA9552State *s = PCA9552(obj);
132
+ int led;
133
134
/* If support for the other PCA955X devices are implemented, these
135
* constant values might be part of class structure describing the
136
@@ -XXX,XX +XXX,XX @@ static void pca9552_initfn(Object *obj)
137
*/
138
s->max_reg = PCA9552_LS3;
139
s->nr_leds = 16;
140
+
141
+ for (led = 0; led < s->nr_leds; led++) {
142
+ char *name;
143
+
144
+ name = g_strdup_printf("led%d", led);
145
+ object_property_add(obj, name, "bool", pca9552_get_led, pca9552_set_led,
146
+ NULL, NULL, NULL);
147
+ g_free(name);
148
+ }
149
}
337
}
150
338
151
static void pca9552_class_init(ObjectClass *klass, void *data)
339
/*----------------------------------------------------------------------------
152
--
340
--
153
2.20.1
341
2.34.1
154
155
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
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-18-peter.maydell@linaro.org
7
---
8
target/arm/cpu.c | 5 +++++
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 6 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
+ * * 3-input NaN propagation prefers SNaN over QNaN, and then
21
+ * operand C over A over B (see FPProcessNaNs3() pseudocode,
22
+ * but note that for QEMU muladd is a * b + c, whereas for
23
+ * the pseudocode function the arguments are in the order c, a, b.
24
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
25
* and the input NaN if it is signalling
26
*/
27
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
28
{
29
set_float_detect_tininess(float_tininess_before_rounding, s);
30
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
31
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
32
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
33
}
34
35
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
36
index XXXXXXX..XXXXXXX 100644
37
--- a/fpu/softfloat-specialize.c.inc
38
+++ b/fpu/softfloat-specialize.c.inc
39
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
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 {
54
--
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
1
From: Andrew Jones <drjones@redhat.com>
1
Set the Float3NaNPropRule explicitly for xtensa, and remove the
2
ifdef from pickNaNMulAdd().
2
3
3
When a VM is stopped (such as when it's paused) guest virtual time
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
should stop counting. Otherwise, when the VM is resumed it will
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
experience time jumps and its kernel may report soft lockups. Not
6
Message-id: 20241202131347.498124-24-peter.maydell@linaro.org
6
counting virtual time while the VM is stopped has the side effect
7
---
7
of making the guest's time appear to lag when compared with real
8
target/xtensa/fpu_helper.c | 2 ++
8
time, and even with time derived from the physical counter. For
9
fpu/softfloat-specialize.c.inc | 8 --------
9
this reason, this change, which is enabled by default, comes with
10
2 files changed, 2 insertions(+), 8 deletions(-)
10
a KVM CPU feature allowing it to be disabled, restoring legacy
11
behavior.
12
11
13
This patch only provides the implementation of the virtual time
12
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
14
adjustment. A subsequent patch will provide the CPU property
15
allowing the change to be enabled and disabled.
16
17
Reported-by: Bijan Mottahedeh <bijan.mottahedeh@oracle.com>
18
Signed-off-by: Andrew Jones <drjones@redhat.com>
19
Message-id: 20200120101023.16030-6-drjones@redhat.com
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
target/arm/cpu.h | 7 ++++
24
target/arm/kvm_arm.h | 38 ++++++++++++++++++
25
target/arm/kvm.c | 92 ++++++++++++++++++++++++++++++++++++++++++++
26
target/arm/kvm32.c | 3 ++
27
target/arm/kvm64.c | 3 ++
28
target/arm/machine.c | 7 ++++
29
6 files changed, 150 insertions(+)
30
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
14
--- a/target/xtensa/fpu_helper.c
34
+++ b/target/arm/cpu.h
15
+++ b/target/xtensa/fpu_helper.c
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
16
@@ -XXX,XX +XXX,XX @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
36
/* KVM init features for this CPU */
17
set_use_first_nan(use_first, &env->fp_status);
37
uint32_t kvm_init_features[7];
18
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
38
19
&env->fp_status);
39
+ /* KVM CPU state */
20
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
40
+
21
+ &env->fp_status);
41
+ /* KVM virtual time adjustment */
22
}
42
+ bool kvm_adjvtime;
23
43
+ bool kvm_vtime_dirty;
24
void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
44
+ uint64_t kvm_vtime;
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
45
+
46
/* Uniprocessor system with MP extensions */
47
bool mp_is_up;
48
49
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
50
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/kvm_arm.h
27
--- a/fpu/softfloat-specialize.c.inc
52
+++ b/target/arm/kvm_arm.h
28
+++ b/fpu/softfloat-specialize.c.inc
53
@@ -XXX,XX +XXX,XX @@ bool write_list_to_kvmstate(ARMCPU *cpu, int level);
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
54
*/
55
bool write_kvmstate_to_list(ARMCPU *cpu);
56
57
+/**
58
+ * kvm_arm_cpu_pre_save:
59
+ * @cpu: ARMCPU
60
+ *
61
+ * Called after write_kvmstate_to_list() from cpu_pre_save() to update
62
+ * the cpreg list with KVM CPU state.
63
+ */
64
+void kvm_arm_cpu_pre_save(ARMCPU *cpu);
65
+
66
+/**
67
+ * kvm_arm_cpu_post_load:
68
+ * @cpu: ARMCPU
69
+ *
70
+ * Called from cpu_post_load() to update KVM CPU state from the cpreg list.
71
+ */
72
+void kvm_arm_cpu_post_load(ARMCPU *cpu);
73
+
74
/**
75
* kvm_arm_reset_vcpu:
76
* @cpu: ARMCPU
77
@@ -XXX,XX +XXX,XX @@ int kvm_arm_sync_mpstate_to_kvm(ARMCPU *cpu);
78
*/
79
int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu);
80
81
+/**
82
+ * kvm_arm_get_virtual_time:
83
+ * @cs: CPUState
84
+ *
85
+ * Gets the VCPU's virtual counter and stores it in the KVM CPU state.
86
+ */
87
+void kvm_arm_get_virtual_time(CPUState *cs);
88
+
89
+/**
90
+ * kvm_arm_put_virtual_time:
91
+ * @cs: CPUState
92
+ *
93
+ * Sets the VCPU's virtual counter to the value stored in the KVM CPU state.
94
+ */
95
+void kvm_arm_put_virtual_time(CPUState *cs);
96
+
97
+void kvm_arm_vm_state_change(void *opaque, int running, RunState state);
98
+
99
int kvm_arm_vgic_probe(void);
100
101
void kvm_arm_pmu_set_irq(CPUState *cs, int irq);
102
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_pmu_set_irq(CPUState *cs, int irq) {}
103
static inline void kvm_arm_pmu_init(CPUState *cs) {}
104
105
static inline void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map) {}
106
+
107
+static inline void kvm_arm_get_virtual_time(CPUState *cs) {}
108
+static inline void kvm_arm_put_virtual_time(CPUState *cs) {}
109
#endif
110
111
static inline const char *gic_class_name(void)
112
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/kvm.c
115
+++ b/target/arm/kvm.c
116
@@ -XXX,XX +XXX,XX @@ static int compare_u64(const void *a, const void *b)
117
return 0;
118
}
119
120
+/*
121
+ * cpreg_values are sorted in ascending order by KVM register ID
122
+ * (see kvm_arm_init_cpreg_list). This allows us to cheaply find
123
+ * the storage for a KVM register by ID with a binary search.
124
+ */
125
+static uint64_t *kvm_arm_get_cpreg_ptr(ARMCPU *cpu, uint64_t regidx)
126
+{
127
+ uint64_t *res;
128
+
129
+ res = bsearch(&regidx, cpu->cpreg_indexes, cpu->cpreg_array_len,
130
+ sizeof(uint64_t), compare_u64);
131
+ assert(res);
132
+
133
+ return &cpu->cpreg_values[res - cpu->cpreg_indexes];
134
+}
135
+
136
/* Initialize the ARMCPU cpreg list according to the kernel's
137
* definition of what CPU registers it knows about (and throw away
138
* the previous TCG-created cpreg list).
139
@@ -XXX,XX +XXX,XX @@ bool write_list_to_kvmstate(ARMCPU *cpu, int level)
140
return ok;
141
}
142
143
+void kvm_arm_cpu_pre_save(ARMCPU *cpu)
144
+{
145
+ /* KVM virtual time adjustment */
146
+ if (cpu->kvm_vtime_dirty) {
147
+ *kvm_arm_get_cpreg_ptr(cpu, KVM_REG_ARM_TIMER_CNT) = cpu->kvm_vtime;
148
+ }
149
+}
150
+
151
+void kvm_arm_cpu_post_load(ARMCPU *cpu)
152
+{
153
+ /* KVM virtual time adjustment */
154
+ if (cpu->kvm_adjvtime) {
155
+ cpu->kvm_vtime = *kvm_arm_get_cpreg_ptr(cpu, KVM_REG_ARM_TIMER_CNT);
156
+ cpu->kvm_vtime_dirty = true;
157
+ }
158
+}
159
+
160
void kvm_arm_reset_vcpu(ARMCPU *cpu)
161
{
162
int ret;
163
@@ -XXX,XX +XXX,XX @@ int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu)
164
return 0;
165
}
166
167
+void kvm_arm_get_virtual_time(CPUState *cs)
168
+{
169
+ ARMCPU *cpu = ARM_CPU(cs);
170
+ struct kvm_one_reg reg = {
171
+ .id = KVM_REG_ARM_TIMER_CNT,
172
+ .addr = (uintptr_t)&cpu->kvm_vtime,
173
+ };
174
+ int ret;
175
+
176
+ if (cpu->kvm_vtime_dirty) {
177
+ return;
178
+ }
179
+
180
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
181
+ if (ret) {
182
+ error_report("Failed to get KVM_REG_ARM_TIMER_CNT");
183
+ abort();
184
+ }
185
+
186
+ cpu->kvm_vtime_dirty = true;
187
+}
188
+
189
+void kvm_arm_put_virtual_time(CPUState *cs)
190
+{
191
+ ARMCPU *cpu = ARM_CPU(cs);
192
+ struct kvm_one_reg reg = {
193
+ .id = KVM_REG_ARM_TIMER_CNT,
194
+ .addr = (uintptr_t)&cpu->kvm_vtime,
195
+ };
196
+ int ret;
197
+
198
+ if (!cpu->kvm_vtime_dirty) {
199
+ return;
200
+ }
201
+
202
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
203
+ if (ret) {
204
+ error_report("Failed to set KVM_REG_ARM_TIMER_CNT");
205
+ abort();
206
+ }
207
+
208
+ cpu->kvm_vtime_dirty = false;
209
+}
210
+
211
int kvm_put_vcpu_events(ARMCPU *cpu)
212
{
213
CPUARMState *env = &cpu->env;
214
@@ -XXX,XX +XXX,XX @@ MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
215
return MEMTXATTRS_UNSPECIFIED;
216
}
217
218
+void kvm_arm_vm_state_change(void *opaque, int running, RunState state)
219
+{
220
+ CPUState *cs = opaque;
221
+ ARMCPU *cpu = ARM_CPU(cs);
222
+
223
+ if (running) {
224
+ if (cpu->kvm_adjvtime) {
225
+ kvm_arm_put_virtual_time(cs);
226
+ }
227
+ } else {
228
+ if (cpu->kvm_adjvtime) {
229
+ kvm_arm_get_virtual_time(cs);
230
+ }
231
+ }
232
+}
233
234
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
235
{
236
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
237
index XXXXXXX..XXXXXXX 100644
238
--- a/target/arm/kvm32.c
239
+++ b/target/arm/kvm32.c
240
@@ -XXX,XX +XXX,XX @@
241
#include "qemu-common.h"
242
#include "cpu.h"
243
#include "qemu/timer.h"
244
+#include "sysemu/runstate.h"
245
#include "sysemu/kvm.h"
246
#include "kvm_arm.h"
247
#include "internals.h"
248
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
249
return -EINVAL;
250
}
30
}
251
31
252
+ qemu_add_vm_change_state_handler(kvm_arm_vm_state_change, cs);
32
if (rule == float_3nan_prop_none) {
253
+
33
-#if defined(TARGET_XTENSA)
254
/* Determine init features for this CPU */
34
- if (status->use_first_nan) {
255
memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));
35
- rule = float_3nan_prop_abc;
256
if (cpu->start_powered_off) {
36
- } else {
257
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
37
- rule = float_3nan_prop_cba;
258
index XXXXXXX..XXXXXXX 100644
38
- }
259
--- a/target/arm/kvm64.c
39
-#else
260
+++ b/target/arm/kvm64.c
40
rule = float_3nan_prop_abc;
261
@@ -XXX,XX +XXX,XX @@
41
-#endif
262
#include "qemu/host-utils.h"
263
#include "qemu/main-loop.h"
264
#include "exec/gdbstub.h"
265
+#include "sysemu/runstate.h"
266
#include "sysemu/kvm.h"
267
#include "sysemu/kvm_int.h"
268
#include "kvm_arm.h"
269
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
270
return -EINVAL;
271
}
42
}
272
43
273
+ qemu_add_vm_change_state_handler(kvm_arm_vm_state_change, cs);
44
assert(rule != float_3nan_prop_none);
274
+
275
/* Determine init features for this CPU */
276
memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));
277
if (cpu->start_powered_off) {
278
diff --git a/target/arm/machine.c b/target/arm/machine.c
279
index XXXXXXX..XXXXXXX 100644
280
--- a/target/arm/machine.c
281
+++ b/target/arm/machine.c
282
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
283
/* This should never fail */
284
abort();
285
}
286
+
287
+ /*
288
+ * kvm_arm_cpu_pre_save() must be called after
289
+ * write_kvmstate_to_list()
290
+ */
291
+ kvm_arm_cpu_pre_save(cpu);
292
} else {
293
if (!write_cpustate_to_list(cpu, false)) {
294
/* This should never fail. */
295
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
296
* we're using it.
297
*/
298
write_list_to_cpustate(cpu);
299
+ kvm_arm_cpu_post_load(cpu);
300
} else {
301
if (!write_list_to_cpustate(cpu)) {
302
return -1;
303
--
45
--
304
2.20.1
46
2.34.1
305
306
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
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.
2
5
3
Signed-off-by: Andrew Jones <drjones@redhat.com>
4
Message-id: 20200120101023.16030-3-drjones@redhat.com
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
7
---
9
---
8
hw/arm/virt.c | 1 +
10
target/i386/tcg/fpu_helper.c | 1 +
9
1 file changed, 1 insertion(+)
11
1 file changed, 1 insertion(+)
10
12
11
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
13
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/virt.c
15
--- a/target/i386/tcg/fpu_helper.c
14
+++ b/hw/arm/virt.c
16
+++ b/target/i386/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(5, 0)
17
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
16
18
* there are multiple input NaNs they are selected in the order a, b, c.
17
static void virt_machine_4_2_options(MachineClass *mc)
19
*/
18
{
20
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
19
+ virt_machine_5_0_options(mc);
21
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
20
compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
21
}
22
}
22
DEFINE_VIRT_MACHINE(4, 2)
23
24
static inline uint8_t save_exception_flags(CPUX86State *env)
23
--
25
--
24
2.20.1
26
2.34.1
25
26
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
From: Andrew Jeffery <andrew@aj.id.au>
1
In the helper functions flcmps and flcmpd we use a scratch float_status
2
so that we don't change the CPU state if the comparison raises any
3
floating point exception flags. Instead of zero-initializing this
4
scratch float_status, initialize it as a copy of env->fp_status. This
5
avoids the need to explicitly initialize settings like the NaN
6
propagation rule or others we might add to softfloat in future.
2
7
3
Initialise another SDHCI model instance for the AST2600's eMMC
8
To do this we need to pass the CPU env pointer in to the helper.
4
controller and use the SDHCI's num_slots value introduced previously to
5
determine whether we should create an SD card instance for the new slot.
6
9
7
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20200114103433.30534-3-clg@kaod.org
12
[ clg : - removed ternary operator from sdhci_attach_drive()
13
- renamed SDHCI objects with a '-controller' prefix ]
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-33-peter.maydell@linaro.org
16
---
13
---
17
include/hw/arm/aspeed_soc.h | 2 ++
14
target/sparc/helper.h | 4 ++--
18
hw/arm/aspeed.c | 26 +++++++++++++++++---------
15
target/sparc/fop_helper.c | 8 ++++----
19
hw/arm/aspeed_ast2600.c | 29 ++++++++++++++++++++++++++---
16
target/sparc/translate.c | 4 ++--
20
3 files changed, 45 insertions(+), 12 deletions(-)
17
3 files changed, 8 insertions(+), 8 deletions(-)
21
18
22
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
19
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
23
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/aspeed_soc.h
21
--- a/target/sparc/helper.h
25
+++ b/include/hw/arm/aspeed_soc.h
22
+++ b/target/sparc/helper.h
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
27
AspeedGPIOState gpio;
24
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
28
AspeedGPIOState gpio_1_8v;
25
DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
29
AspeedSDHCIState sdhci;
26
DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
30
+ AspeedSDHCIState emmc;
27
-DEF_HELPER_FLAGS_2(flcmps, TCG_CALL_NO_RWG_SE, i32, f32, f32)
31
} AspeedSoCState;
28
-DEF_HELPER_FLAGS_2(flcmpd, TCG_CALL_NO_RWG_SE, i32, f64, f64)
32
29
+DEF_HELPER_FLAGS_3(flcmps, TCG_CALL_NO_RWG_SE, i32, env, f32, f32)
33
#define TYPE_ASPEED_SOC "aspeed-soc"
30
+DEF_HELPER_FLAGS_3(flcmpd, TCG_CALL_NO_RWG_SE, i32, env, f64, f64)
34
@@ -XXX,XX +XXX,XX @@ enum {
31
DEF_HELPER_2(raise_exception, noreturn, env, int)
35
ASPEED_MII4,
32
36
ASPEED_SDRAM,
33
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
37
ASPEED_XDMA,
34
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
38
+ ASPEED_EMMC,
39
};
40
41
#endif /* ASPEED_SOC_H */
42
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
43
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/aspeed.c
36
--- a/target/sparc/fop_helper.c
45
+++ b/hw/arm/aspeed.c
37
+++ b/target/sparc/fop_helper.c
46
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
38
@@ -XXX,XX +XXX,XX @@ uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
47
}
39
return finish_fcmp(env, r, GETPC());
48
}
40
}
49
41
50
+static void sdhci_attach_drive(SDHCIState *sdhci, DriveInfo *dinfo)
42
-uint32_t helper_flcmps(float32 src1, float32 src2)
51
+{
43
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
52
+ DeviceState *card;
53
+
54
+ card = qdev_create(qdev_get_child_bus(DEVICE(sdhci), "sd-bus"),
55
+ TYPE_SD_CARD);
56
+ if (dinfo) {
57
+ qdev_prop_set_drive(card, "drive", blk_by_legacy_dinfo(dinfo),
58
+ &error_fatal);
59
+ }
60
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
61
+}
62
+
63
static void aspeed_machine_init(MachineState *machine)
64
{
44
{
65
AspeedBoardState *bmc;
45
/*
66
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_init(MachineState *machine)
46
* FLCMP never raises an exception nor modifies any FSR fields.
67
}
47
* Perform the comparison with a dummy fp environment.
68
48
*/
69
for (i = 0; i < bmc->soc.sdhci.num_slots; i++) {
49
- float_status discard = { };
70
- SDHCIState *sdhci = &bmc->soc.sdhci.slots[i];
50
+ float_status discard = env->fp_status;
71
- DriveInfo *dinfo = drive_get_next(IF_SD);
51
FloatRelation r;
72
- BlockBackend *blk;
52
73
- DeviceState *card;
53
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
74
+ sdhci_attach_drive(&bmc->soc.sdhci.slots[i], drive_get_next(IF_SD));
54
@@ -XXX,XX +XXX,XX @@ uint32_t helper_flcmps(float32 src1, float32 src2)
75
+ }
55
g_assert_not_reached();
76
56
}
77
- blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
57
78
- card = qdev_create(qdev_get_child_bus(DEVICE(sdhci), "sd-bus"),
58
-uint32_t helper_flcmpd(float64 src1, float64 src2)
79
- TYPE_SD_CARD);
59
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
80
- qdev_prop_set_drive(card, "drive", blk, &error_fatal);
60
{
81
- object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
61
- float_status discard = { };
82
+ if (bmc->soc.emmc.num_slots) {
62
+ float_status discard = env->fp_status;
83
+ sdhci_attach_drive(&bmc->soc.emmc.slots[0], drive_get_next(IF_SD));
63
FloatRelation r;
84
}
64
85
65
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
86
arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo);
66
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
87
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
88
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/arm/aspeed_ast2600.c
68
--- a/target/sparc/translate.c
90
+++ b/hw/arm/aspeed_ast2600.c
69
+++ b/target/sparc/translate.c
91
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
70
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPs(DisasContext *dc, arg_FLCMPs *a)
92
[ASPEED_ADC] = 0x1E6E9000,
71
93
[ASPEED_VIDEO] = 0x1E700000,
72
src1 = gen_load_fpr_F(dc, a->rs1);
94
[ASPEED_SDHCI] = 0x1E740000,
73
src2 = gen_load_fpr_F(dc, a->rs2);
95
+ [ASPEED_EMMC] = 0x1E750000,
74
- gen_helper_flcmps(cpu_fcc[a->cc], src1, src2);
96
[ASPEED_GPIO] = 0x1E780000,
75
+ gen_helper_flcmps(cpu_fcc[a->cc], tcg_env, src1, src2);
97
[ASPEED_GPIO_1_8V] = 0x1E780800,
76
return advance_pc(dc);
98
[ASPEED_RTC] = 0x1E781000,
99
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
100
101
#define ASPEED_SOC_AST2600_MAX_IRQ 128
102
103
+/* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
104
static const int aspeed_soc_ast2600_irqmap[] = {
105
[ASPEED_UART1] = 47,
106
[ASPEED_UART2] = 48,
107
@@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2600_irqmap[] = {
108
[ASPEED_ADC] = 78,
109
[ASPEED_XDMA] = 6,
110
[ASPEED_SDHCI] = 43,
111
+ [ASPEED_EMMC] = 15,
112
[ASPEED_GPIO] = 40,
113
[ASPEED_GPIO_1_8V] = 11,
114
[ASPEED_RTC] = 13,
115
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
116
sysbus_init_child_obj(obj, "gpio_1_8v", OBJECT(&s->gpio_1_8v),
117
sizeof(s->gpio_1_8v), typename);
118
119
- sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
120
- TYPE_ASPEED_SDHCI);
121
+ sysbus_init_child_obj(obj, "sd-controller", OBJECT(&s->sdhci),
122
+ sizeof(s->sdhci), TYPE_ASPEED_SDHCI);
123
124
object_property_set_int(OBJECT(&s->sdhci), 2, "num-slots", &error_abort);
125
126
/* Init sd card slot class here so that they're under the correct parent */
127
for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
128
- sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
129
+ sysbus_init_child_obj(obj, "sd-controller.sdhci[*]",
130
+ OBJECT(&s->sdhci.slots[i]),
131
sizeof(s->sdhci.slots[i]), TYPE_SYSBUS_SDHCI);
132
}
133
+
134
+ sysbus_init_child_obj(obj, "emmc-controller", OBJECT(&s->emmc),
135
+ sizeof(s->emmc), TYPE_ASPEED_SDHCI);
136
+
137
+ object_property_set_int(OBJECT(&s->emmc), 1, "num-slots", &error_abort);
138
+
139
+ sysbus_init_child_obj(obj, "emmc-controller.sdhci",
140
+ OBJECT(&s->emmc.slots[0]), sizeof(s->emmc.slots[0]),
141
+ TYPE_SYSBUS_SDHCI);
142
}
77
}
143
78
144
/*
79
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPd(DisasContext *dc, arg_FLCMPd *a)
145
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
80
146
sc->memmap[ASPEED_SDHCI]);
81
src1 = gen_load_fpr_D(dc, a->rs1);
147
sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
82
src2 = gen_load_fpr_D(dc, a->rs2);
148
aspeed_soc_get_irq(s, ASPEED_SDHCI));
83
- gen_helper_flcmpd(cpu_fcc[a->cc], src1, src2);
149
+
84
+ gen_helper_flcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
150
+ /* eMMC */
85
return advance_pc(dc);
151
+ object_property_set_bool(OBJECT(&s->emmc), true, "realized", &err);
152
+ if (err) {
153
+ error_propagate(errp, err);
154
+ return;
155
+ }
156
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->emmc), 0, sc->memmap[ASPEED_EMMC]);
157
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->emmc), 0,
158
+ aspeed_soc_get_irq(s, ASPEED_EMMC));
159
}
86
}
160
87
161
static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
162
--
88
--
163
2.20.1
89
2.34.1
164
165
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: Andrew Jones <drjones@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add the missing GENERIC_TIMER feature to kvm64 cpus.
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
We don't currently use these registers when KVM is enabled, but it's
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
probably best we add the feature flag for consistency and potential
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
future use. There's also precedent, as we add the PMU feature flag to
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
KVM enabled guests, even though we don't use those registers either.
12
Message-id: 20241203203949.483774-2-richard.henderson@linaro.org
9
10
This change was originally posted as a hunk of a different, never
11
merged patch from Bijan Mottahedeh.
12
13
Signed-off-by: Andrew Jones <drjones@redhat.com>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20200120101023.16030-4-drjones@redhat.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
14
---
18
target/arm/kvm64.c | 1 +
15
target/arm/tcg/vec_helper.c | 20 +++++++-------------
19
1 file changed, 1 insertion(+)
16
1 file changed, 7 insertions(+), 13 deletions(-)
20
17
21
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
18
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/kvm64.c
20
--- a/target/arm/tcg/vec_helper.c
24
+++ b/target/arm/kvm64.c
21
+++ b/target/arm/tcg/vec_helper.c
25
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
22
@@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
26
set_feature(&features, ARM_FEATURE_NEON);
23
* no effect on AArch32 instructions.
27
set_feature(&features, ARM_FEATURE_AARCH64);
24
*/
28
set_feature(&features, ARM_FEATURE_PMU);
25
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
29
+ set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
26
- *statusp = (float_status){
30
27
- .tininess_before_rounding = float_tininess_before_rounding,
31
ahcf->features = features;
28
- .float_rounding_mode = float_round_to_odd_inf,
29
- .flush_to_zero = true,
30
- .flush_inputs_to_zero = true,
31
- .default_nan_mode = true,
32
- };
33
+
34
+ *statusp = env->vfp.fp_status;
35
+ set_default_nan_mode(true, statusp);
36
37
if (ebf) {
38
- float_status *fpst = &env->vfp.fp_status;
39
- set_flush_to_zero(get_flush_to_zero(fpst), statusp);
40
- set_flush_inputs_to_zero(get_flush_inputs_to_zero(fpst), statusp);
41
- set_float_rounding_mode(get_float_rounding_mode(fpst), statusp);
42
-
43
/* EBF=1 needs to do a step with round-to-odd semantics */
44
*oddstatusp = *statusp;
45
set_float_rounding_mode(float_round_to_odd, oddstatusp);
46
+ } else {
47
+ set_flush_to_zero(true, statusp);
48
+ set_flush_inputs_to_zero(true, statusp);
49
+ set_float_rounding_mode(float_round_to_odd_inf, statusp);
50
}
51
-
52
return ebf;
53
}
32
54
33
--
55
--
34
2.20.1
56
2.34.1
35
57
36
58
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
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
Deprecate device_legacy_reset(), qdev_reset_all() and
7
Add a field to float_status to specify the default NaN value; fall
4
qbus_reset_all() to be replaced by new functions
8
back to the old ifdef behaviour if these are not set.
5
device_cold_reset() and bus_cold_reset() which uses resettable API.
6
9
7
Also introduce resettable_cold_reset_fn() which may be used as a
10
The default NaN value is specified by setting a uint8_t to a
8
replacement for qdev_reset_all_fn and qbus_reset_all_fn().
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.
9
14
10
Following patches will be needed to look at legacy reset call sites
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
and switch to resettable api. The legacy functions will be removed
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
when unused.
17
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
18
---
19
include/fpu/softfloat-helpers.h | 11 +++++++
20
include/fpu/softfloat-types.h | 10 ++++++
21
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
22
3 files changed, 54 insertions(+), 22 deletions(-)
13
23
14
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
24
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Message-id: 20200123132823.1117486-9-damien.hedde@greensocs.com
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
include/hw/qdev-core.h | 27 +++++++++++++++++++++++++++
23
include/hw/resettable.h | 9 +++++++++
24
hw/core/bus.c | 5 +++++
25
hw/core/qdev.c | 5 +++++
26
hw/core/resettable.c | 5 +++++
27
5 files changed, 51 insertions(+)
28
29
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
30
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/qdev-core.h
26
--- a/include/fpu/softfloat-helpers.h
32
+++ b/include/hw/qdev-core.h
27
+++ b/include/fpu/softfloat-helpers.h
33
@@ -XXX,XX +XXX,XX @@ int qdev_walk_children(DeviceState *dev,
28
@@ -XXX,XX +XXX,XX @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
34
qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
29
status->float_infzeronan_rule = rule;
35
void *opaque);
36
37
+/**
38
+ * @qdev_reset_all:
39
+ * Reset @dev. See @qbus_reset_all() for more details.
40
+ *
41
+ * Note: This function is deprecated and will be removed when it becomes unused.
42
+ * Please use device_cold_reset() now.
43
+ */
44
void qdev_reset_all(DeviceState *dev);
45
void qdev_reset_all_fn(void *opaque);
46
47
@@ -XXX,XX +XXX,XX @@ void qdev_reset_all_fn(void *opaque);
48
* hard reset means that qbus_reset_all will reset all state of the device.
49
* For PCI devices, for example, this will include the base address registers
50
* or configuration space.
51
+ *
52
+ * Note: This function is deprecated and will be removed when it becomes unused.
53
+ * Please use bus_cold_reset() now.
54
*/
55
void qbus_reset_all(BusState *bus);
56
void qbus_reset_all_fn(void *opaque);
57
58
+/**
59
+ * device_cold_reset:
60
+ * Reset device @dev and perform a recursive processing using the resettable
61
+ * interface. It triggers a RESET_TYPE_COLD.
62
+ */
63
+void device_cold_reset(DeviceState *dev);
64
+
65
+/**
66
+ * bus_cold_reset:
67
+ *
68
+ * Reset bus @bus and perform a recursive processing using the resettable
69
+ * interface. It triggers a RESET_TYPE_COLD.
70
+ */
71
+void bus_cold_reset(BusState *bus);
72
+
73
/**
74
* device_is_in_reset:
75
* Return true if the device @dev is currently being reset.
76
@@ -XXX,XX +XXX,XX @@ void qdev_machine_init(void);
77
* device_legacy_reset:
78
*
79
* Reset a single device (by calling the reset method).
80
+ * Note: This function is deprecated and will be removed when it becomes unused.
81
+ * Please use device_cold_reset() now.
82
*/
83
void device_legacy_reset(DeviceState *dev);
84
85
diff --git a/include/hw/resettable.h b/include/hw/resettable.h
86
index XXXXXXX..XXXXXXX 100644
87
--- a/include/hw/resettable.h
88
+++ b/include/hw/resettable.h
89
@@ -XXX,XX +XXX,XX @@ bool resettable_is_in_reset(Object *obj);
90
*/
91
void resettable_change_parent(Object *obj, Object *newp, Object *oldp);
92
93
+/**
94
+ * resettable_cold_reset_fn:
95
+ * Helper to call resettable_reset((Object *) opaque, RESET_TYPE_COLD).
96
+ *
97
+ * This function is typically useful to register a reset handler with
98
+ * qemu_register_reset.
99
+ */
100
+void resettable_cold_reset_fn(void *opaque);
101
+
102
/**
103
* resettable_class_set_parent_phases:
104
*
105
diff --git a/hw/core/bus.c b/hw/core/bus.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/hw/core/bus.c
108
+++ b/hw/core/bus.c
109
@@ -XXX,XX +XXX,XX @@ int qbus_walk_children(BusState *bus,
110
return 0;
111
}
30
}
112
31
113
+void bus_cold_reset(BusState *bus)
32
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
33
+ float_status *status)
114
+{
34
+{
115
+ resettable_reset(OBJECT(bus), RESET_TYPE_COLD);
35
+ status->default_nan_pattern = dnan_pattern;
116
+}
36
+}
117
+
37
+
118
bool bus_is_in_reset(BusState *bus)
38
static inline void set_flush_to_zero(bool val, float_status *status)
119
{
39
{
120
return resettable_is_in_reset(OBJECT(bus));
40
status->flush_to_zero = val;
121
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
41
@@ -XXX,XX +XXX,XX @@ static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status
122
index XXXXXXX..XXXXXXX 100644
42
return status->float_infzeronan_rule;
123
--- a/hw/core/qdev.c
124
+++ b/hw/core/qdev.c
125
@@ -XXX,XX +XXX,XX @@ void qbus_reset_all_fn(void *opaque)
126
qbus_reset_all(bus);
127
}
43
}
128
44
129
+void device_cold_reset(DeviceState *dev)
45
+static inline uint8_t get_float_default_nan_pattern(float_status *status)
130
+{
46
+{
131
+ resettable_reset(OBJECT(dev), RESET_TYPE_COLD);
47
+ return status->default_nan_pattern;
132
+}
48
+}
133
+
49
+
134
bool device_is_in_reset(DeviceState *dev)
50
static inline bool get_flush_to_zero(float_status *status)
135
{
51
{
136
return resettable_is_in_reset(OBJECT(dev));
52
return status->flush_to_zero;
137
diff --git a/hw/core/resettable.c b/hw/core/resettable.c
53
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
138
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
139
--- a/hw/core/resettable.c
55
--- a/include/fpu/softfloat-types.h
140
+++ b/hw/core/resettable.c
56
+++ b/include/fpu/softfloat-types.h
141
@@ -XXX,XX +XXX,XX @@ void resettable_change_parent(Object *obj, Object *newp, Object *oldp)
57
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
142
}
58
/* should denormalised inputs go to zero and set the input_denormal flag? */
143
}
59
bool flush_inputs_to_zero;
144
60
bool default_nan_mode;
145
+void resettable_cold_reset_fn(void *opaque)
61
+ /*
146
+{
62
+ * The pattern to use for the default NaN. Here the high bit specifies
147
+ resettable_reset((Object *) opaque, RESET_TYPE_COLD);
63
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
148
+}
64
+ * fractional part. The low bits of the fractional part are copies of bit 0.
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
75
index XXXXXXX..XXXXXXX 100644
76
--- a/fpu/softfloat-specialize.c.inc
77
+++ b/fpu/softfloat-specialize.c.inc
78
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
79
{
80
bool sign = 0;
81
uint64_t frac;
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);
149
+
136
+
150
void resettable_class_set_parent_phases(ResettableClass *rc,
137
+ sign = dnan_pattern >> 7;
151
ResettableEnterPhase enter,
138
+ /*
152
ResettableHoldPhase hold,
139
+ * Place default_nan_pattern [6:0] into bits [62:56],
140
+ * and replecate bit [0] down into [55:0]
141
+ */
142
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
143
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
144
145
*p = (FloatParts64) {
146
.cls = float_class_qnan,
153
--
147
--
154
2.20.1
148
2.34.1
155
156
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: Andrew Jones <drjones@redhat.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
kvm-no-adjvtime is a KVM specific CPU property and a first of its
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
kind. To accommodate it we also add kvm_arm_add_vcpu_properties()
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
and a KVM specific CPU properties description to the CPU features
8
Message-id: 20241202131347.498124-41-peter.maydell@linaro.org
6
document.
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: Andrew Jones <drjones@redhat.com>
14
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
9
Message-id: 20200120101023.16030-7-drjones@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/arm/virt.h | 1 +
14
target/arm/kvm_arm.h | 11 ++++++++++
15
hw/arm/virt.c | 8 ++++++++
16
target/arm/cpu.c | 2 ++
17
target/arm/cpu64.c | 1 +
18
target/arm/kvm.c | 28 +++++++++++++++++++++++++
19
target/arm/monitor.c | 1 +
20
tests/qtest/arm-cpu-features.c | 4 ++++
21
docs/arm-cpu-features.rst | 37 +++++++++++++++++++++++++++++++++-
22
9 files changed, 92 insertions(+), 1 deletion(-)
23
24
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/arm/virt.h
16
--- a/linux-user/arm/nwfpe/fpa11.c
27
+++ b/include/hw/arm/virt.h
17
+++ b/linux-user/arm/nwfpe/fpa11.c
28
@@ -XXX,XX +XXX,XX @@ typedef struct {
18
@@ -XXX,XX +XXX,XX @@ void resetFPA11(void)
29
bool smbios_old_sys_ver;
19
* this late date.
30
bool no_highmem_ecam;
20
*/
31
bool no_ged; /* Machines < 4.2 has no support for ACPI GED device */
21
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
32
+ bool kvm_no_adjvtime;
22
+ /*
33
} VirtMachineClass;
23
+ * Use the same default NaN value as Arm VFP. This doesn't match
34
24
+ * the Linux kernel's nwfpe emulation, which uses an all-1s value.
35
typedef struct {
25
+ */
36
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
26
+ set_float_default_nan_pattern(0b01000000, &fpa11->fp_status);
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/kvm_arm.h
39
+++ b/target/arm/kvm_arm.h
40
@@ -XXX,XX +XXX,XX @@ void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map);
41
*/
42
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
43
44
+/**
45
+ * kvm_arm_add_vcpu_properties:
46
+ * @obj: The CPU object to add the properties to
47
+ *
48
+ * Add all KVM specific CPU properties to the CPU object. These
49
+ * are the CPU properties with "kvm-" prefixed names.
50
+ */
51
+void kvm_arm_add_vcpu_properties(Object *obj);
52
+
53
/**
54
* kvm_arm_aarch32_supported:
55
* @cs: CPUState
56
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
57
cpu->host_cpu_probe_failed = true;
58
}
27
}
59
28
60
+static inline void kvm_arm_add_vcpu_properties(Object *obj) {}
29
void SetRoundingMode(const unsigned int opcode)
61
+
62
static inline bool kvm_arm_aarch32_supported(CPUState *cs)
63
{
64
return false;
65
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/virt.c
68
+++ b/hw/arm/virt.c
69
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
70
}
71
}
72
73
+ if (vmc->kvm_no_adjvtime &&
74
+ object_property_find(cpuobj, "kvm-no-adjvtime", NULL)) {
75
+ object_property_set_bool(cpuobj, true, "kvm-no-adjvtime", NULL);
76
+ }
77
+
78
if (vmc->no_pmu && object_property_find(cpuobj, "pmu", NULL)) {
79
object_property_set_bool(cpuobj, false, "pmu", NULL);
80
}
81
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(5, 0)
82
83
static void virt_machine_4_2_options(MachineClass *mc)
84
{
85
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
86
+
87
virt_machine_5_0_options(mc);
88
compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
89
+ vmc->kvm_no_adjvtime = true;
90
}
91
DEFINE_VIRT_MACHINE(4, 2)
92
93
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
94
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/cpu.c
32
--- a/target/arm/cpu.c
96
+++ b/target/arm/cpu.c
33
+++ b/target/arm/cpu.c
97
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
34
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
98
35
* the pseudocode function the arguments are in the order c, a, b.
99
if (kvm_enabled()) {
36
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
100
kvm_arm_set_cpu_features_from_host(cpu);
37
* and the input NaN if it is signalling
101
+ kvm_arm_add_vcpu_properties(obj);
38
+ * * Default NaN has sign bit clear, msb frac bit set
102
} else {
39
*/
103
cortex_a15_initfn(obj);
40
static void arm_set_default_fp_behaviours(float_status *s)
104
41
{
105
@@ -XXX,XX +XXX,XX @@ static void arm_host_initfn(Object *obj)
42
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
106
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
107
aarch64_add_sve_properties(obj);
44
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
108
}
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
109
+ kvm_arm_add_vcpu_properties(obj);
46
+ set_float_default_nan_pattern(0b01000000, s);
110
arm_cpu_post_init(obj);
111
}
47
}
112
48
113
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
49
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/cpu64.c
116
+++ b/target/arm/cpu64.c
117
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
118
119
if (kvm_enabled()) {
120
kvm_arm_set_cpu_features_from_host(cpu);
121
+ kvm_arm_add_vcpu_properties(obj);
122
} else {
123
uint64_t t;
124
uint32_t u;
125
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/arm/kvm.c
128
+++ b/target/arm/kvm.c
129
@@ -XXX,XX +XXX,XX @@
130
#include "qemu/timer.h"
131
#include "qemu/error-report.h"
132
#include "qemu/main-loop.h"
133
+#include "qom/object.h"
134
+#include "qapi/error.h"
135
#include "sysemu/sysemu.h"
136
#include "sysemu/kvm.h"
137
#include "sysemu/kvm_int.h"
138
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
139
env->features = arm_host_cpu_features.features;
140
}
141
142
+static bool kvm_no_adjvtime_get(Object *obj, Error **errp)
143
+{
144
+ return !ARM_CPU(obj)->kvm_adjvtime;
145
+}
146
+
147
+static void kvm_no_adjvtime_set(Object *obj, bool value, Error **errp)
148
+{
149
+ ARM_CPU(obj)->kvm_adjvtime = !value;
150
+}
151
+
152
+/* KVM VCPU properties should be prefixed with "kvm-". */
153
+void kvm_arm_add_vcpu_properties(Object *obj)
154
+{
155
+ if (!kvm_enabled()) {
156
+ return;
157
+ }
158
+
159
+ ARM_CPU(obj)->kvm_adjvtime = true;
160
+ object_property_add_bool(obj, "kvm-no-adjvtime", kvm_no_adjvtime_get,
161
+ kvm_no_adjvtime_set, &error_abort);
162
+ object_property_set_description(obj, "kvm-no-adjvtime",
163
+ "Set on to disable the adjustment of "
164
+ "the virtual counter. VM stopped time "
165
+ "will be counted.", &error_abort);
166
+}
167
+
168
bool kvm_arm_pmu_supported(CPUState *cpu)
169
{
170
return kvm_check_extension(cpu->kvm_state, KVM_CAP_ARM_PMU_V3);
171
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
172
index XXXXXXX..XXXXXXX 100644
173
--- a/target/arm/monitor.c
174
+++ b/target/arm/monitor.c
175
@@ -XXX,XX +XXX,XX @@ static const char *cpu_model_advertised_features[] = {
176
"sve128", "sve256", "sve384", "sve512",
177
"sve640", "sve768", "sve896", "sve1024", "sve1152", "sve1280",
178
"sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048",
179
+ "kvm-no-adjvtime",
180
NULL
181
};
182
183
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
184
index XXXXXXX..XXXXXXX 100644
185
--- a/tests/qtest/arm-cpu-features.c
186
+++ b/tests/qtest/arm-cpu-features.c
187
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion(const void *data)
188
assert_has_feature_enabled(qts, "cortex-a15", "pmu");
189
assert_has_not_feature(qts, "cortex-a15", "aarch64");
190
191
+ assert_has_not_feature(qts, "max", "kvm-no-adjvtime");
192
+
193
if (g_str_equal(qtest_get_arch(), "aarch64")) {
194
assert_has_feature_enabled(qts, "max", "aarch64");
195
assert_has_feature_enabled(qts, "max", "sve");
196
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
197
return;
198
}
199
200
+ assert_has_feature_disabled(qts, "host", "kvm-no-adjvtime");
201
+
202
if (g_str_equal(qtest_get_arch(), "aarch64")) {
203
bool kvm_supports_sve;
204
char max_name[8], name[8];
205
diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst
206
index XXXXXXX..XXXXXXX 100644
207
--- a/docs/arm-cpu-features.rst
208
+++ b/docs/arm-cpu-features.rst
209
@@ -XXX,XX +XXX,XX @@ supporting the feature or only supporting the feature under certain
210
configurations. For example, the `aarch64` CPU feature, which, when
211
disabled, enables the optional AArch32 CPU feature, is only supported
212
when using the KVM accelerator and when running on a host CPU type that
213
-supports the feature.
214
+supports the feature. While `aarch64` currently only works with KVM,
215
+it could work with TCG. CPU features that are specific to KVM are
216
+prefixed with "kvm-" and are described in "KVM VCPU Features".
217
218
CPU Feature Probing
219
===================
220
@@ -XXX,XX +XXX,XX @@ disabling many SVE vector lengths would be quite verbose, the `sve<N>` CPU
221
properties have special semantics (see "SVE CPU Property Parsing
222
Semantics").
223
224
+KVM VCPU Features
225
+=================
226
+
227
+KVM VCPU features are CPU features that are specific to KVM, such as
228
+paravirt features or features that enable CPU virtualization extensions.
229
+The features' CPU properties are only available when KVM is enabled and
230
+are named with the prefix "kvm-". KVM VCPU features may be probed,
231
+enabled, and disabled in the same way as other CPU features. Below is
232
+the list of KVM VCPU features and their descriptions.
233
+
234
+ kvm-no-adjvtime By default kvm-no-adjvtime is disabled. This
235
+ means that by default the virtual time
236
+ adjustment is enabled (vtime is *not not*
237
+ adjusted).
238
+
239
+ When virtual time adjustment is enabled each
240
+ time the VM transitions back to running state
241
+ the VCPU's virtual counter is updated to ensure
242
+ stopped time is not counted. This avoids time
243
+ jumps surprising guest OSes and applications,
244
+ as long as they use the virtual counter for
245
+ timekeeping. However it has the side effect of
246
+ the virtual and physical counters diverging.
247
+ All timekeeping based on the virtual counter
248
+ will appear to lag behind any timekeeping that
249
+ does not subtract VM stopped time. The guest
250
+ may resynchronize its virtual counter with
251
+ other time sources as needed.
252
+
253
+ Enable kvm-no-adjvtime to disable virtual time
254
+ adjustment, also restoring the legacy (pre-5.0)
255
+ behavior.
256
+
257
SVE CPU Properties
258
==================
259
260
--
50
--
261
2.20.1
51
2.34.1
262
263
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: Damien Hedde <damien.hedde@greensocs.com>
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
Replace deprecated qdev_reset_all by resettable_cold_reset_fn for
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
the ipl registration in the main reset handlers.
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
This does not impact the behavior for the following reasons:
14
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
7
+ at this point resettable just call the old reset methods of devices
8
and buses in the same order than qdev/qbus.
9
+ resettable handlers registered with qemu_register_reset are
10
serialized; there is no interleaving.
11
+ eventual explicit calls to legacy reset API (device_reset or
12
qdev/qbus_reset) inside this reset handler will not be masked out
13
by resettable mechanism; they do not go through resettable api.
14
15
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20200123132823.1117486-12-damien.hedde@greensocs.com
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
hw/s390x/ipl.c | 10 +++++++++-
24
1 file changed, 9 insertions(+), 1 deletion(-)
25
26
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
27
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/s390x/ipl.c
16
--- a/target/mips/fpu_helper.h
29
+++ b/hw/s390x/ipl.c
17
+++ b/target/mips/fpu_helper.h
30
@@ -XXX,XX +XXX,XX @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
31
*/
19
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
32
ipl->compat_start_addr = ipl->start_addr;
20
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
33
ipl->compat_bios_start_addr = ipl->bios_start_addr;
21
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
34
- qemu_register_reset(qdev_reset_all_fn, dev);
35
+ /*
22
+ /*
36
+ * Because this Device is not on any bus in the qbus tree (it is
23
+ * With nan2008, the default NaN value has the sign bit clear and the
37
+ * not a sysbus device and it's not on some other bus like a PCI
24
+ * frac msb set; with the older mode, the sign bit is clear, and all
38
+ * bus) it will not be automatically reset by the 'reset the
25
+ * frac bits except the msb are set.
39
+ * sysbus' hook registered by vl.c like most devices. So we must
40
+ * manually register a reset hook for it.
41
+ * TODO: there should be a better way to do this.
42
+ */
26
+ */
43
+ qemu_register_reset(resettable_cold_reset_fn, dev);
27
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
44
error:
28
+ &env->active_fpu.fp_status);
45
error_propagate(errp, err);
29
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);
46
}
43
}
47
--
44
--
48
2.20.1
45
2.34.1
49
50
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
New patch
1
Set the default NaN pattern explicitly for ppc.
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-46-peter.maydell@linaro.org
6
---
7
target/ppc/cpu_init.c | 4 ++++
8
1 file changed, 4 insertions(+)
9
10
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/ppc/cpu_init.c
13
+++ b/target/ppc/cpu_init.c
14
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
15
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
17
18
+ /* Default NaN: sign bit clear, set frac msb */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
+ set_float_default_nan_pattern(0b01000000, &env->vec_status);
21
+
22
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
23
ppc_spr_t *spr = &env->spr_cb[i];
24
25
--
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
The guest can use the semihosting API to open a handle
1
Set the default NaN pattern explicitly for xtensa.
2
corresponding to QEMU's own stdin, stdout, or stderr.
3
When the guest closes this handle, we should not
4
close the underlying host stdin/stdout/stderr
5
the way we would do if the handle corresponded to
6
a host fd we'd opened on behalf of the guest in SYS_OPEN.
7
2
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20241202131347.498124-51-peter.maydell@linaro.org
11
Message-id: 20200124172954.28481-1-peter.maydell@linaro.org
12
---
6
---
13
target/arm/arm-semi.c | 9 +++++++++
7
target/xtensa/cpu.c | 2 ++
14
1 file changed, 9 insertions(+)
8
1 file changed, 2 insertions(+)
15
9
16
diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
10
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/arm-semi.c
12
--- a/target/xtensa/cpu.c
19
+++ b/target/arm/arm-semi.c
13
+++ b/target/xtensa/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static uint32_t host_closefn(ARMCPU *cpu, GuestFD *gf)
14
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
21
{
15
/* For inf * 0 + NaN, return the input NaN */
22
CPUARMState *env = &cpu->env;
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
23
17
set_no_signaling_nans(!dfpu, &env->fp_status);
24
+ /*
18
+ /* Default NaN value: sign bit clear, set frac msb */
25
+ * Only close the underlying host fd if it's one we opened on behalf
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
26
+ * of the guest in SYS_OPEN.
20
xtensa_use_first_nan(env, !dfpu);
27
+ */
28
+ if (gf->hostfd == STDIN_FILENO ||
29
+ gf->hostfd == STDOUT_FILENO ||
30
+ gf->hostfd == STDERR_FILENO) {
31
+ return 0;
32
+ }
33
return set_swi_errno(env, close(gf->hostfd));
34
}
21
}
35
22
36
--
23
--
37
2.20.1
24
2.34.1
38
39
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
New patch
1
Now that all our targets have bene converted to explicitly specify
2
their pattern for the default NaN value we can remove the remaining
3
fallback code in parts64_default_nan().
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-55-peter.maydell@linaro.org
8
---
9
fpu/softfloat-specialize.c.inc | 14 --------------
10
1 file changed, 14 deletions(-)
11
12
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
13
index XXXXXXX..XXXXXXX 100644
14
--- a/fpu/softfloat-specialize.c.inc
15
+++ b/fpu/softfloat-specialize.c.inc
16
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
17
uint64_t frac;
18
uint8_t dnan_pattern = status->default_nan_pattern;
19
20
- if (dnan_pattern == 0) {
21
- /*
22
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
23
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
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;
37
--
38
2.34.1
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The overhead for the OpenBMC firmware images using the a custom U-Boot
3
Inline pickNaNMulAdd into its only caller. This makes
4
is around 2 seconds, which is fine, but with a U-Boot from mainline,
4
one assert redundant with the immediately preceding IF.
5
it takes an extra 50 seconds or so to reach Linux. A quick survey on
6
the number of reads performed on the flash memory region gives the
7
following figures :
8
5
9
OpenBMC U-Boot 922478 (~ 3.5 MBytes)
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Mainline U-Boot 20569977 (~ 80 MBytes)
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
8
Message-id: 20241203203949.483774-3-richard.henderson@linaro.org
12
QEMU must be trashing the TCG TBs and reloading text very often. Some
9
[PMM: keep comment from old code in new location]
13
addresses are read more than 250.000 times. Until we find a solution
14
to improve boot time, execution from MMIO is not activated by default.
15
16
Setting this option also breaks migration compatibility.
17
18
Signed-off-by: Cédric Le Goater <clg@kaod.org>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Message-id: 20200114103433.30534-5-clg@kaod.org
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
11
---
24
include/hw/arm/aspeed.h | 2 ++
12
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
25
hw/arm/aspeed.c | 44 ++++++++++++++++++++++++++++++++++++-----
13
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
26
2 files changed, 41 insertions(+), 5 deletions(-)
14
2 files changed, 40 insertions(+), 55 deletions(-)
27
15
28
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
29
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/aspeed.h
18
--- a/fpu/softfloat-parts.c.inc
31
+++ b/include/hw/arm/aspeed.h
19
+++ b/fpu/softfloat-parts.c.inc
32
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedBoardState AspeedBoardState;
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
33
21
}
34
typedef struct AspeedMachine {
22
35
MachineState parent_obj;
23
if (s->default_nan_mode) {
24
+ /*
25
+ * We guarantee not to require the target to tell us how to
26
+ * pick a NaN if we're always returning the default NaN.
27
+ * But if we're not in default-NaN mode then the target must
28
+ * specify.
29
+ */
30
which = 3;
31
+ } else if (infzero) {
32
+ /*
33
+ * Inf * 0 + NaN -- some implementations return the
34
+ * default NaN here, and some return the input NaN.
35
+ */
36
+ switch (s->float_infzeronan_rule) {
37
+ case float_infzeronan_dnan_never:
38
+ which = 2;
39
+ break;
40
+ case float_infzeronan_dnan_always:
41
+ which = 3;
42
+ break;
43
+ case float_infzeronan_dnan_if_qnan:
44
+ which = is_qnan(c->cls) ? 3 : 2;
45
+ break;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
} else {
50
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
51
+ FloatClass cls[3] = { a->cls, b->cls, c->cls };
52
+ Float3NaNPropRule rule = s->float_3nan_prop_rule;
36
+
53
+
37
+ bool mmio_exec;
54
+ assert(rule != float_3nan_prop_none);
38
} AspeedMachine;
55
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
39
56
+ /* We have at least one SNaN input and should prefer it */
40
#define ASPEED_MACHINE_CLASS(klass) \
57
+ do {
41
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
58
+ which = rule & R_3NAN_1ST_MASK;
42
index XXXXXXX..XXXXXXX 100644
59
+ rule >>= R_3NAN_1ST_LENGTH;
43
--- a/hw/arm/aspeed.c
60
+ } while (!is_snan(cls[which]));
44
+++ b/hw/arm/aspeed.c
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_init(MachineState *machine)
46
* SoC and 128MB for the AST2500 SoC, which is twice as big as
47
* needed by the flash modules of the Aspeed machines.
48
*/
49
- memory_region_init_rom(boot_rom, OBJECT(bmc), "aspeed.boot_rom",
50
- fl->size, &error_abort);
51
- memory_region_add_subregion(get_system_memory(), FIRMWARE_ADDR,
52
- boot_rom);
53
- write_boot_rom(drive0, FIRMWARE_ADDR, fl->size, &error_abort);
54
+ if (ASPEED_MACHINE(machine)->mmio_exec) {
55
+ memory_region_init_alias(boot_rom, OBJECT(bmc), "aspeed.boot_rom",
56
+ &fl->mmio, 0, fl->size);
57
+ memory_region_add_subregion(get_system_memory(), FIRMWARE_ADDR,
58
+ boot_rom);
59
+ } else {
61
+ } else {
60
+ memory_region_init_rom(boot_rom, OBJECT(bmc), "aspeed.boot_rom",
62
+ do {
61
+ fl->size, &error_abort);
63
+ which = rule & R_3NAN_1ST_MASK;
62
+ memory_region_add_subregion(get_system_memory(), FIRMWARE_ADDR,
64
+ rule >>= R_3NAN_1ST_LENGTH;
63
+ boot_rom);
65
+ } while (!is_nan(cls[which]));
64
+ write_boot_rom(drive0, FIRMWARE_ADDR, fl->size, &error_abort);
65
+ }
66
+ }
66
}
67
}
67
68
68
aspeed_board_binfo.ram_size = ram_size;
69
if (which == 3) {
69
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
70
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
70
/* Bus 11: TODO ucd90160@64 */
71
index XXXXXXX..XXXXXXX 100644
72
--- a/fpu/softfloat-specialize.c.inc
73
+++ b/fpu/softfloat-specialize.c.inc
74
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
75
}
71
}
76
}
72
77
73
+static bool aspeed_get_mmio_exec(Object *obj, Error **errp)
78
-/*----------------------------------------------------------------------------
74
+{
79
-| Select which NaN to propagate for a three-input operation.
75
+ return ASPEED_MACHINE(obj)->mmio_exec;
80
-| For the moment we assume that no CPU needs the 'larger significand'
76
+}
81
-| information.
77
+
82
-| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
78
+static void aspeed_set_mmio_exec(Object *obj, bool value, Error **errp)
83
-*----------------------------------------------------------------------------*/
79
+{
84
-static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
80
+ ASPEED_MACHINE(obj)->mmio_exec = value;
85
- bool infzero, bool have_snan, float_status *status)
81
+}
86
-{
82
+
87
- FloatClass cls[3] = { a_cls, b_cls, c_cls };
83
+static void aspeed_machine_instance_init(Object *obj)
88
- Float3NaNPropRule rule = status->float_3nan_prop_rule;
84
+{
89
- int which;
85
+ ASPEED_MACHINE(obj)->mmio_exec = false;
90
-
86
+}
91
- /*
87
+
92
- * We guarantee not to require the target to tell us how to
88
+static void aspeed_machine_class_props_init(ObjectClass *oc)
93
- * pick a NaN if we're always returning the default NaN.
89
+{
94
- * But if we're not in default-NaN mode then the target must
90
+ object_class_property_add_bool(oc, "execute-in-place",
95
- * specify.
91
+ aspeed_get_mmio_exec,
96
- */
92
+ aspeed_set_mmio_exec, &error_abort);
97
- assert(!status->default_nan_mode);
93
+ object_class_property_set_description(oc, "execute-in-place",
98
-
94
+ "boot directly from CE0 flash device", &error_abort);
99
- if (infzero) {
95
+}
100
- /*
96
+
101
- * Inf * 0 + NaN -- some implementations return the default NaN here,
97
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
102
- * and some return the input NaN.
98
{
103
- */
99
MachineClass *mc = MACHINE_CLASS(oc);
104
- switch (status->float_infzeronan_rule) {
100
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_class_init(ObjectClass *oc, void *data)
105
- case float_infzeronan_dnan_never:
101
mc->no_floppy = 1;
106
- return 2;
102
mc->no_cdrom = 1;
107
- case float_infzeronan_dnan_always:
103
mc->no_parallel = 1;
108
- return 3;
104
+
109
- case float_infzeronan_dnan_if_qnan:
105
+ aspeed_machine_class_props_init(oc);
110
- return is_qnan(c_cls) ? 3 : 2;
106
}
111
- default:
107
112
- g_assert_not_reached();
108
static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data)
113
- }
109
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
114
- }
110
.name = TYPE_ASPEED_MACHINE,
115
-
111
.parent = TYPE_MACHINE,
116
- assert(rule != float_3nan_prop_none);
112
.instance_size = sizeof(AspeedMachine),
117
- if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
113
+ .instance_init = aspeed_machine_instance_init,
118
- /* We have at least one SNaN input and should prefer it */
114
.class_size = sizeof(AspeedMachineClass),
119
- do {
115
.class_init = aspeed_machine_class_init,
120
- which = rule & R_3NAN_1ST_MASK;
116
.abstract = true,
121
- rule >>= R_3NAN_1ST_LENGTH;
122
- } while (!is_snan(cls[which]));
123
- } else {
124
- do {
125
- which = rule & R_3NAN_1ST_MASK;
126
- rule >>= R_3NAN_1ST_LENGTH;
127
- } while (!is_nan(cls[which]));
128
- }
129
- return which;
130
-}
131
-
132
/*----------------------------------------------------------------------------
133
| Returns 1 if the double-precision floating-point value `a' is a quiet
134
| NaN; otherwise returns 0.
117
--
135
--
118
2.20.1
136
2.34.1
119
137
120
138
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This commit adds support of Resettable interface to buses and devices:
3
Remove "3" as a special case for which and simply
4
+ ResettableState structure is added in the Bus/Device state
4
branch to return the desired value.
5
+ Resettable methods are implemented.
6
+ device/bus_is_in_reset function defined
7
5
8
This commit allows to transition the objects to the new
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
multi-phase interface without changing the reset behavior at all.
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Object single reset method can be split into the 3 different phases
8
Message-id: 20241203203949.483774-4-richard.henderson@linaro.org
11
but the 3 phases are still executed in a row for a given object.
12
From the qdev/qbus reset api point of view, nothing is changed.
13
qdev_reset_all() and qbus_reset_all() are not modified as well as
14
device_legacy_reset().
15
16
Transition of an object must be done from parent class to child class.
17
Care has been taken to allow the transition of a parent class
18
without requiring the child classes to be transitioned at the same
19
time. Note that SysBus and SysBusDevice class do not need any transition
20
because they do not override the legacy reset method.
21
22
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
26
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
27
Message-id: 20200123132823.1117486-5-damien.hedde@greensocs.com
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
10
---
30
tests/Makefile.include | 1 +
11
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
31
include/hw/qdev-core.h | 27 ++++++++++++
12
1 file changed, 10 insertions(+), 10 deletions(-)
32
hw/core/bus.c | 97 ++++++++++++++++++++++++++++++++++++++++++
33
hw/core/qdev.c | 93 ++++++++++++++++++++++++++++++++++++++++
34
4 files changed, 218 insertions(+)
35
13
36
diff --git a/tests/Makefile.include b/tests/Makefile.include
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
37
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/Makefile.include
16
--- a/fpu/softfloat-parts.c.inc
39
+++ b/tests/Makefile.include
17
+++ b/fpu/softfloat-parts.c.inc
40
@@ -XXX,XX +XXX,XX @@ tests/fp/%:
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
41
tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
19
* But if we're not in default-NaN mode then the target must
42
    hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\
20
* specify.
43
    hw/core/bus.o \
21
*/
44
+    hw/core/resettable.o \
22
- which = 3;
45
    hw/core/irq.o \
23
+ goto default_nan;
46
    hw/core/fw-path-provider.o \
24
} else if (infzero) {
47
    hw/core/reset.o \
25
/*
48
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
26
* Inf * 0 + NaN -- some implementations return the
49
index XXXXXXX..XXXXXXX 100644
27
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
50
--- a/include/hw/qdev-core.h
28
*/
51
+++ b/include/hw/qdev-core.h
29
switch (s->float_infzeronan_rule) {
52
@@ -XXX,XX +XXX,XX @@
30
case float_infzeronan_dnan_never:
53
#include "qemu/bitmap.h"
31
- which = 2;
54
#include "qom/object.h"
32
break;
55
#include "hw/hotplug.h"
33
case float_infzeronan_dnan_always:
56
+#include "hw/resettable.h"
34
- which = 3;
57
35
- break;
58
enum {
36
+ goto default_nan;
59
DEV_NVECTORS_UNSPECIFIED = -1,
37
case float_infzeronan_dnan_if_qnan:
60
@@ -XXX,XX +XXX,XX @@ typedef struct DeviceClass {
38
- which = is_qnan(c->cls) ? 3 : 2;
61
bool hotpluggable;
39
+ if (is_qnan(c->cls)) {
62
40
+ goto default_nan;
63
/* callbacks */
41
+ }
64
+ /*
42
break;
65
+ * Reset method here is deprecated and replaced by methods in the
43
default:
66
+ * resettable class interface to implement a multi-phase reset.
44
g_assert_not_reached();
67
+ * TODO: remove once every reset callback is unused
45
}
68
+ */
46
+ which = 2;
69
DeviceReset reset;
47
} else {
70
DeviceRealize realize;
48
FloatClass cls[3] = { a->cls, b->cls, c->cls };
71
DeviceUnrealize unrealize;
49
Float3NaNPropRule rule = s->float_3nan_prop_rule;
72
@@ -XXX,XX +XXX,XX @@ struct NamedGPIOList {
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
73
/**
51
}
74
* DeviceState:
52
}
75
* @realized: Indicates whether the device has been fully constructed.
53
76
+ * @reset: ResettableState for the device; handled by Resettable interface.
54
- if (which == 3) {
77
*
55
- parts_default_nan(a, s);
78
* This structure should not be accessed directly. We declare it here
56
- return a;
79
* so that it can be embedded in individual device state structures.
57
- }
80
@@ -XXX,XX +XXX,XX @@ struct DeviceState {
58
-
81
int num_child_bus;
59
switch (which) {
82
int instance_id_alias;
60
case 0:
83
int alias_required_for_version;
61
break;
84
+ ResettableState reset;
62
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
85
};
63
parts_silence_nan(a, s);
86
64
}
87
struct DeviceListener {
65
return a;
88
@@ -XXX,XX +XXX,XX @@ typedef struct BusChild {
89
/**
90
* BusState:
91
* @hotplug_handler: link to a hotplug handler associated with bus.
92
+ * @reset: ResettableState for the bus; handled by Resettable interface.
93
*/
94
struct BusState {
95
Object obj;
96
@@ -XXX,XX +XXX,XX @@ struct BusState {
97
int num_children;
98
QTAILQ_HEAD(, BusChild) children;
99
QLIST_ENTRY(BusState) sibling;
100
+ ResettableState reset;
101
};
102
103
/**
104
@@ -XXX,XX +XXX,XX @@ void qdev_reset_all_fn(void *opaque);
105
void qbus_reset_all(BusState *bus);
106
void qbus_reset_all_fn(void *opaque);
107
108
+/**
109
+ * device_is_in_reset:
110
+ * Return true if the device @dev is currently being reset.
111
+ */
112
+bool device_is_in_reset(DeviceState *dev);
113
+
66
+
114
+/**
67
+ default_nan:
115
+ * bus_is_in_reset:
68
+ parts_default_nan(a, s);
116
+ * Return true if the bus @bus is currently being reset.
69
+ return a;
117
+ */
118
+bool bus_is_in_reset(BusState *bus);
119
+
120
/* This should go away once we get rid of the NULL bus hack */
121
BusState *sysbus_get_default(void);
122
123
@@ -XXX,XX +XXX,XX @@ void device_legacy_reset(DeviceState *dev);
124
125
void device_class_set_props(DeviceClass *dc, Property *props);
126
127
+/**
128
+ * device_class_set_parent_reset:
129
+ * TODO: remove the function when DeviceClass's reset method
130
+ * is not used anymore.
131
+ */
132
void device_class_set_parent_reset(DeviceClass *dc,
133
DeviceReset dev_reset,
134
DeviceReset *parent_reset);
135
diff --git a/hw/core/bus.c b/hw/core/bus.c
136
index XXXXXXX..XXXXXXX 100644
137
--- a/hw/core/bus.c
138
+++ b/hw/core/bus.c
139
@@ -XXX,XX +XXX,XX @@ int qbus_walk_children(BusState *bus,
140
return 0;
141
}
70
}
142
71
143
+bool bus_is_in_reset(BusState *bus)
72
/*
144
+{
145
+ return resettable_is_in_reset(OBJECT(bus));
146
+}
147
+
148
+static ResettableState *bus_get_reset_state(Object *obj)
149
+{
150
+ BusState *bus = BUS(obj);
151
+ return &bus->reset;
152
+}
153
+
154
+static void bus_reset_child_foreach(Object *obj, ResettableChildCallback cb,
155
+ void *opaque, ResetType type)
156
+{
157
+ BusState *bus = BUS(obj);
158
+ BusChild *kid;
159
+
160
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
161
+ cb(OBJECT(kid->child), opaque, type);
162
+ }
163
+}
164
+
165
static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
166
{
167
const char *typename = object_get_typename(OBJECT(bus));
168
@@ -XXX,XX +XXX,XX @@ static char *default_bus_get_fw_dev_path(DeviceState *dev)
169
return g_strdup(object_get_typename(OBJECT(dev)));
170
}
171
172
+/**
173
+ * bus_phases_reset:
174
+ * Transition reset method for buses to allow moving
175
+ * smoothly from legacy reset method to multi-phases
176
+ */
177
+static void bus_phases_reset(BusState *bus)
178
+{
179
+ ResettableClass *rc = RESETTABLE_GET_CLASS(bus);
180
+
181
+ if (rc->phases.enter) {
182
+ rc->phases.enter(OBJECT(bus), RESET_TYPE_COLD);
183
+ }
184
+ if (rc->phases.hold) {
185
+ rc->phases.hold(OBJECT(bus));
186
+ }
187
+ if (rc->phases.exit) {
188
+ rc->phases.exit(OBJECT(bus));
189
+ }
190
+}
191
+
192
+static void bus_transitional_reset(Object *obj)
193
+{
194
+ BusClass *bc = BUS_GET_CLASS(obj);
195
+
196
+ /*
197
+ * This will call either @bus_phases_reset (for multi-phases transitioned
198
+ * buses) or a bus's specific method for not-yet transitioned buses.
199
+ * In both case, it does not reset children.
200
+ */
201
+ if (bc->reset) {
202
+ bc->reset(BUS(obj));
203
+ }
204
+}
205
+
206
+/**
207
+ * bus_get_transitional_reset:
208
+ * check if the bus's class is ready for multi-phase
209
+ */
210
+static ResettableTrFunction bus_get_transitional_reset(Object *obj)
211
+{
212
+ BusClass *dc = BUS_GET_CLASS(obj);
213
+ if (dc->reset != bus_phases_reset) {
214
+ /*
215
+ * dc->reset has been overridden by a subclass,
216
+ * the bus is not ready for multi phase yet.
217
+ */
218
+ return bus_transitional_reset;
219
+ }
220
+ return NULL;
221
+}
222
+
223
static void bus_class_init(ObjectClass *class, void *data)
224
{
225
BusClass *bc = BUS_CLASS(class);
226
+ ResettableClass *rc = RESETTABLE_CLASS(class);
227
228
class->unparent = bus_unparent;
229
bc->get_fw_dev_path = default_bus_get_fw_dev_path;
230
+
231
+ rc->get_state = bus_get_reset_state;
232
+ rc->child_foreach = bus_reset_child_foreach;
233
+
234
+ /*
235
+ * @bus_phases_reset is put as the default reset method below, allowing
236
+ * to do the multi-phase transition from base classes to leaf classes. It
237
+ * allows a legacy-reset Bus class to extend a multi-phases-reset
238
+ * Bus class for the following reason:
239
+ * + If a base class B has been moved to multi-phase, then it does not
240
+ * override this default reset method and may have defined phase methods.
241
+ * + A child class C (extending class B) which uses
242
+ * bus_class_set_parent_reset() (or similar means) to override the
243
+ * reset method will still work as expected. @bus_phases_reset function
244
+ * will be registered as the parent reset method and effectively call
245
+ * parent reset phases.
246
+ */
247
+ bc->reset = bus_phases_reset;
248
+ rc->get_transitional_function = bus_get_transitional_reset;
249
}
250
251
static void qbus_finalize(Object *obj)
252
@@ -XXX,XX +XXX,XX @@ static const TypeInfo bus_info = {
253
.instance_init = qbus_initfn,
254
.instance_finalize = qbus_finalize,
255
.class_init = bus_class_init,
256
+ .interfaces = (InterfaceInfo[]) {
257
+ { TYPE_RESETTABLE_INTERFACE },
258
+ { }
259
+ },
260
};
261
262
static void bus_register_types(void)
263
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
264
index XXXXXXX..XXXXXXX 100644
265
--- a/hw/core/qdev.c
266
+++ b/hw/core/qdev.c
267
@@ -XXX,XX +XXX,XX @@ void qbus_reset_all_fn(void *opaque)
268
qbus_reset_all(bus);
269
}
270
271
+bool device_is_in_reset(DeviceState *dev)
272
+{
273
+ return resettable_is_in_reset(OBJECT(dev));
274
+}
275
+
276
+static ResettableState *device_get_reset_state(Object *obj)
277
+{
278
+ DeviceState *dev = DEVICE(obj);
279
+ return &dev->reset;
280
+}
281
+
282
+static void device_reset_child_foreach(Object *obj, ResettableChildCallback cb,
283
+ void *opaque, ResetType type)
284
+{
285
+ DeviceState *dev = DEVICE(obj);
286
+ BusState *bus;
287
+
288
+ QLIST_FOREACH(bus, &dev->child_bus, sibling) {
289
+ cb(OBJECT(bus), opaque, type);
290
+ }
291
+}
292
+
293
/* can be used as ->unplug() callback for the simple cases */
294
void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
295
DeviceState *dev, Error **errp)
296
@@ -XXX,XX +XXX,XX @@ device_vmstate_if_get_id(VMStateIf *obj)
297
return qdev_get_dev_path(dev);
298
}
299
300
+/**
301
+ * device_phases_reset:
302
+ * Transition reset method for devices to allow moving
303
+ * smoothly from legacy reset method to multi-phases
304
+ */
305
+static void device_phases_reset(DeviceState *dev)
306
+{
307
+ ResettableClass *rc = RESETTABLE_GET_CLASS(dev);
308
+
309
+ if (rc->phases.enter) {
310
+ rc->phases.enter(OBJECT(dev), RESET_TYPE_COLD);
311
+ }
312
+ if (rc->phases.hold) {
313
+ rc->phases.hold(OBJECT(dev));
314
+ }
315
+ if (rc->phases.exit) {
316
+ rc->phases.exit(OBJECT(dev));
317
+ }
318
+}
319
+
320
+static void device_transitional_reset(Object *obj)
321
+{
322
+ DeviceClass *dc = DEVICE_GET_CLASS(obj);
323
+
324
+ /*
325
+ * This will call either @device_phases_reset (for multi-phases transitioned
326
+ * devices) or a device's specific method for not-yet transitioned devices.
327
+ * In both case, it does not reset children.
328
+ */
329
+ if (dc->reset) {
330
+ dc->reset(DEVICE(obj));
331
+ }
332
+}
333
+
334
+/**
335
+ * device_get_transitional_reset:
336
+ * check if the device's class is ready for multi-phase
337
+ */
338
+static ResettableTrFunction device_get_transitional_reset(Object *obj)
339
+{
340
+ DeviceClass *dc = DEVICE_GET_CLASS(obj);
341
+ if (dc->reset != device_phases_reset) {
342
+ /*
343
+ * dc->reset has been overridden by a subclass,
344
+ * the device is not ready for multi phase yet.
345
+ */
346
+ return device_transitional_reset;
347
+ }
348
+ return NULL;
349
+}
350
+
351
static void device_class_init(ObjectClass *class, void *data)
352
{
353
DeviceClass *dc = DEVICE_CLASS(class);
354
VMStateIfClass *vc = VMSTATE_IF_CLASS(class);
355
+ ResettableClass *rc = RESETTABLE_CLASS(class);
356
357
class->unparent = device_unparent;
358
359
@@ -XXX,XX +XXX,XX @@ static void device_class_init(ObjectClass *class, void *data)
360
dc->hotpluggable = true;
361
dc->user_creatable = true;
362
vc->get_id = device_vmstate_if_get_id;
363
+ rc->get_state = device_get_reset_state;
364
+ rc->child_foreach = device_reset_child_foreach;
365
+
366
+ /*
367
+ * @device_phases_reset is put as the default reset method below, allowing
368
+ * to do the multi-phase transition from base classes to leaf classes. It
369
+ * allows a legacy-reset Device class to extend a multi-phases-reset
370
+ * Device class for the following reason:
371
+ * + If a base class B has been moved to multi-phase, then it does not
372
+ * override this default reset method and may have defined phase methods.
373
+ * + A child class C (extending class B) which uses
374
+ * device_class_set_parent_reset() (or similar means) to override the
375
+ * reset method will still work as expected. @device_phases_reset function
376
+ * will be registered as the parent reset method and effectively call
377
+ * parent reset phases.
378
+ */
379
+ dc->reset = device_phases_reset;
380
+ rc->get_transitional_function = device_get_transitional_reset;
381
382
object_class_property_add_bool(class, "realized",
383
device_get_realized, device_set_realized,
384
@@ -XXX,XX +XXX,XX @@ static const TypeInfo device_type_info = {
385
.class_size = sizeof(DeviceClass),
386
.interfaces = (InterfaceInfo[]) {
387
{ TYPE_VMSTATE_IF },
388
+ { TYPE_RESETTABLE_INTERFACE },
389
{ }
390
}
391
};
392
--
73
--
393
2.20.1
74
2.34.1
394
75
395
76
diff view generated by jsdifflib
1
From: Zenghui Yu <yuzenghui@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
If LPIs are disabled, KVM will just ignore the GICR_PENDBASER.PTZ bit when
3
Assign the pointer return value to 'a' directly,
4
restoring GICR_CTLR. Setting PTZ here makes littlt sense in "reduce GIC
4
rather than going through an intermediary index.
5
initialization time".
6
5
7
And what's worse, PTZ is generally programmed by guest to indicate to the
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Redistributor whether the LPI Pending table is zero when enabling LPIs.
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
If migration is triggered when the PTZ has just been cleared by guest (and
8
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
10
before enabling LPIs), we will see PTZ==1 on the destination side, which
11
is not as expected. Let's just drop this hackish userspace behavior.
12
13
Also take this chance to refine the comment a bit.
14
15
Fixes: 367b9f527bec ("hw/intc/arm_gicv3_kvm: Implement get/put functions")
16
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
17
Message-id: 20200119133051.642-1-yuzenghui@huawei.com
18
Reviewed-by: Peter Maydell <peter.maydell@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
hw/intc/arm_gicv3_kvm.c | 11 ++++-------
11
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
22
1 file changed, 4 insertions(+), 7 deletions(-)
12
1 file changed, 10 insertions(+), 22 deletions(-)
23
13
24
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/intc/arm_gicv3_kvm.c
16
--- a/fpu/softfloat-parts.c.inc
27
+++ b/hw/intc/arm_gicv3_kvm.c
17
+++ b/fpu/softfloat-parts.c.inc
28
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_put(GICv3State *s)
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
29
kvm_gicd_access(s, GICD_CTLR, &reg, true);
19
FloatPartsN *c, float_status *s,
30
20
int ab_mask, int abc_mask)
31
if (redist_typer & GICR_TYPER_PLPIS) {
21
{
32
- /* Set base addresses before LPIs are enabled by GICR_CTLR write */
22
- int which;
33
+ /*
23
bool infzero = (ab_mask == float_cmask_infzero);
34
+ * Restore base addresses before LPIs are potentially enabled by
24
bool have_snan = (abc_mask & float_cmask_snan);
35
+ * GICR_CTLR write
25
+ FloatPartsN *ret;
36
+ */
26
37
for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
27
if (unlikely(have_snan)) {
38
GICv3CPUState *c = &s->cpu[ncpu];
28
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
39
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
40
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_put(GICv3State *s)
30
default:
41
kvm_gicr_access(s, GICR_PROPBASER + 4, ncpu, &regh, true);
31
g_assert_not_reached();
42
32
}
43
reg64 = c->gicr_pendbaser;
33
- which = 2;
44
- if (!(c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS)) {
34
+ ret = c;
45
- /* Setting PTZ is advised if LPIs are disabled, to reduce
35
} else {
46
- * GIC initialization time.
36
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
47
- */
37
+ FloatPartsN *val[3] = { a, b, c };
48
- reg64 |= GICR_PENDBASER_PTZ;
38
Float3NaNPropRule rule = s->float_3nan_prop_rule;
49
- }
39
50
regl = (uint32_t)reg64;
40
assert(rule != float_3nan_prop_none);
51
kvm_gicr_access(s, GICR_PENDBASER, ncpu, &regl, true);
41
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
52
regh = (uint32_t)(reg64 >> 32);
42
/* We have at least one SNaN input and should prefer it */
43
do {
44
- which = rule & R_3NAN_1ST_MASK;
45
+ ret = val[rule & R_3NAN_1ST_MASK];
46
rule >>= R_3NAN_1ST_LENGTH;
47
- } while (!is_snan(cls[which]));
48
+ } while (!is_snan(ret->cls));
49
} else {
50
do {
51
- which = rule & R_3NAN_1ST_MASK;
52
+ ret = val[rule & R_3NAN_1ST_MASK];
53
rule >>= R_3NAN_1ST_LENGTH;
54
- } while (!is_nan(cls[which]));
55
+ } while (!is_nan(ret->cls));
56
}
57
}
58
59
- switch (which) {
60
- case 0:
61
- break;
62
- case 1:
63
- a = b;
64
- break;
65
- case 2:
66
- a = c;
67
- break;
68
- default:
69
- g_assert_not_reached();
70
+ if (is_snan(ret->cls)) {
71
+ parts_silence_nan(ret, s);
72
}
73
- if (is_snan(a->cls)) {
74
- parts_silence_nan(a, s);
75
- }
76
- return a;
77
+ return ret;
78
79
default_nan:
80
parts_default_nan(a, s);
53
--
81
--
54
2.20.1
82
2.34.1
55
83
56
84
diff view generated by jsdifflib
1
The num-lines property of the TYPE_OR_GATE device sets the number
1
From: Richard Henderson <richard.henderson@linaro.org>
2
of input lines it has. An assert() in or_irq_realize() restricts
3
this to the maximum supported by the implementation. However we
4
got the condition in the assert wrong: it should be using <=,
5
because num-lines == MAX_OR_LINES is permitted, and means that
6
all entries from 0 to MAX_OR_LINES-1 in the s->levels[] array
7
are used.
8
2
9
We didn't notice this previously because no user has so far
3
While all indices into val[] should be in [0-2], the mask
10
needed that many input lines.
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.
11
7
12
Reported-by: Guenter Roeck <linux@roeck-us.net>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20241203203949.483774-6-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
16
Message-id: 20200120142235.10432-1-peter.maydell@linaro.org
17
---
12
---
18
hw/core/or-irq.c | 2 +-
13
fpu/softfloat-parts.c.inc | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
20
15
21
diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/core/or-irq.c
18
--- a/fpu/softfloat-parts.c.inc
24
+++ b/hw/core/or-irq.c
19
+++ b/fpu/softfloat-parts.c.inc
25
@@ -XXX,XX +XXX,XX @@ static void or_irq_realize(DeviceState *dev, Error **errp)
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
26
{
21
}
27
qemu_or_irq *s = OR_IRQ(dev);
22
ret = c;
28
23
} else {
29
- assert(s->num_lines < MAX_OR_LINES);
24
- FloatPartsN *val[3] = { a, b, c };
30
+ assert(s->num_lines <= MAX_OR_LINES);
25
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
31
26
Float3NaNPropRule rule = s->float_3nan_prop_rule;
32
qdev_init_gpio_in(dev, or_irq_handler, s->num_lines);
27
33
}
28
assert(rule != float_3nan_prop_none);
34
--
29
--
35
2.20.1
30
2.34.1
36
31
37
32
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
3
This function is part of the public interface and
4
is not "specialized" to any target in any way.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
6
Message-id: 20200123132823.1117486-10-damien.hedde@greensocs.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
docs/devel/index.rst | 1 +
11
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
10
docs/devel/reset.rst | 289 +++++++++++++++++++++++++++++++++++++++++++
12
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
11
2 files changed, 290 insertions(+)
13
2 files changed, 52 insertions(+), 52 deletions(-)
12
create mode 100644 docs/devel/reset.rst
13
14
14
diff --git a/docs/devel/index.rst b/docs/devel/index.rst
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/devel/index.rst
17
--- a/fpu/softfloat.c
17
+++ b/docs/devel/index.rst
18
+++ b/fpu/softfloat.c
18
@@ -XXX,XX +XXX,XX @@ Contents:
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
19
tcg
20
*zExpPtr = 1 - shiftCount;
20
tcg-plugins
21
}
21
bitops
22
22
+ reset
23
+/*----------------------------------------------------------------------------
23
diff --git a/docs/devel/reset.rst b/docs/devel/reset.rst
24
+| Takes two extended double-precision floating-point values `a' and `b', one
24
new file mode 100644
25
+| of which is a NaN, and returns the appropriate NaN result. If either `a' or
25
index XXXXXXX..XXXXXXX
26
+| `b' is a signaling NaN, the invalid exception is raised.
26
--- /dev/null
27
+*----------------------------------------------------------------------------*/
27
+++ b/docs/devel/reset.rst
28
@@ -XXX,XX +XXX,XX @@
29
+
28
+
30
+=======================================
29
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
31
+Reset in QEMU: the Resettable interface
30
+{
32
+=======================================
31
+ bool aIsLargerSignificand;
32
+ FloatClass a_cls, b_cls;
33
+
33
+
34
+The reset of qemu objects is handled using the resettable interface declared
34
+ /* This is not complete, but is good enough for pickNaN. */
35
+in ``include/hw/resettable.h``.
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);
36
+
45
+
37
+This interface allows objects to be grouped (on a tree basis); so that the
46
+ if (is_snan(a_cls) || is_snan(b_cls)) {
38
+whole group can be reset consistently. Each individual member object does not
47
+ float_raise(float_flag_invalid, status);
39
+have to care about others; in particular, problems of order (which object is
40
+reset first) are addressed.
41
+
42
+As of now DeviceClass and BusClass implement this interface.
43
+
44
+
45
+Triggering reset
46
+----------------
47
+
48
+This section documents the APIs which "users" of a resettable object should use
49
+to control it. All resettable control functions must be called while holding
50
+the iothread lock.
51
+
52
+You can apply a reset to an object using ``resettable_assert_reset()``. You need
53
+to call ``resettable_release_reset()`` to release the object from reset. To
54
+instantly reset an object, without keeping it in reset state, just call
55
+``resettable_reset()``. These functions take two parameters: a pointer to the
56
+object to reset and a reset type.
57
+
58
+Several types of reset will be supported. For now only cold reset is defined;
59
+others may be added later. The Resettable interface handles reset types with an
60
+enum:
61
+
62
+``RESET_TYPE_COLD``
63
+ Cold reset is supported by every resettable object. In QEMU, it means we reset
64
+ to the initial state corresponding to the start of QEMU; this might differ
65
+ from what is a real hardware cold reset. It differs from other resets (like
66
+ warm or bus resets) which may keep certain parts untouched.
67
+
68
+Calling ``resettable_reset()`` is equivalent to calling
69
+``resettable_assert_reset()`` then ``resettable_release_reset()``. It is
70
+possible to interleave multiple calls to these three functions. There may
71
+be several reset sources/controllers of a given object. The interface handles
72
+everything and the different reset controllers do not need to know anything
73
+about each others. The object will leave reset state only when each other
74
+controllers end their reset operation. This point is handled internally by
75
+maintaining a count of in-progress resets; it is crucial to call
76
+``resettable_release_reset()`` one time and only one time per
77
+``resettable_assert_reset()`` call.
78
+
79
+For now migration of a device or bus in reset is not supported. Care must be
80
+taken not to delay ``resettable_release_reset()`` after its
81
+``resettable_assert_reset()`` counterpart.
82
+
83
+Note that, since resettable is an interface, the API takes a simple Object as
84
+parameter. Still, it is a programming error to call a resettable function on a
85
+non-resettable object and it will trigger a run time assert error. Since most
86
+calls to resettable interface are done through base class functions, such an
87
+error is not likely to happen.
88
+
89
+For Devices and Buses, the following helper functions exist:
90
+
91
+- ``device_cold_reset()``
92
+- ``bus_cold_reset()``
93
+
94
+These are simple wrappers around resettable_reset() function; they only cast the
95
+Device or Bus into an Object and pass the cold reset type. When possible
96
+prefer to use these functions instead of ``resettable_reset()``.
97
+
98
+Device and bus functions co-exist because there can be semantic differences
99
+between resetting a bus and resetting the controller bridge which owns it.
100
+For example, consider a SCSI controller. Resetting the controller puts all
101
+its registers back to what reset state was as well as reset everything on the
102
+SCSI bus, whereas resetting just the SCSI bus only resets everything that's on
103
+it but not the controller.
104
+
105
+
106
+Multi-phase mechanism
107
+---------------------
108
+
109
+This section documents the internals of the resettable interface.
110
+
111
+The resettable interface uses a multi-phase system to relieve objects and
112
+machines from reset ordering problems. To address this, the reset operation
113
+of an object is split into three well defined phases.
114
+
115
+When resetting several objects (for example the whole machine at simulation
116
+startup), all first phases of all objects are executed, then all second phases
117
+and then all third phases.
118
+
119
+The three phases are:
120
+
121
+1. The **enter** phase is executed when the object enters reset. It resets only
122
+ local state of the object; it must not do anything that has a side-effect
123
+ on other objects, such as raising or lowering a qemu_irq line or reading or
124
+ writing guest memory.
125
+
126
+2. The **hold** phase is executed for entry into reset, once every object in the
127
+ group which is being reset has had its *enter* phase executed. At this point
128
+ devices can do actions that affect other objects.
129
+
130
+3. The **exit** phase is executed when the object leaves the reset state.
131
+ Actions affecting other objects are permitted.
132
+
133
+As said in previous section, the interface maintains a count of reset. This
134
+count is used to ensure phases are executed only when required. *enter* and
135
+*hold* phases are executed only when asserting reset for the first time
136
+(if an object is already in reset state when calling
137
+``resettable_assert_reset()`` or ``resettable_reset()``, they are not
138
+executed).
139
+The *exit* phase is executed only when the last reset operation ends. Therefore
140
+the object does not need to care how many of reset controllers it has and how
141
+many of them have started a reset.
142
+
143
+
144
+Handling reset in a resettable object
145
+-------------------------------------
146
+
147
+This section documents the APIs that an implementation of a resettable object
148
+must provide and what functions it has access to. It is intended for people
149
+who want to implement or convert a class which has the resettable interface;
150
+for example when specializing an existing device or bus.
151
+
152
+Methods to implement
153
+....................
154
+
155
+Three methods should be defined or left empty. Each method corresponds to a
156
+phase of the reset; they are name ``phases.enter()``, ``phases.hold()`` and
157
+``phases.exit()``. They all take the object as parameter. The *enter* method
158
+also take the reset type as second parameter.
159
+
160
+When extending an existing class, these methods may need to be extended too.
161
+The ``resettable_class_set_parent_phases()`` class function may be used to
162
+backup parent class methods.
163
+
164
+Here follows an example to implement reset for a Device which sets an IO while
165
+in reset.
166
+
167
+::
168
+
169
+ static void mydev_reset_enter(Object *obj, ResetType type)
170
+ {
171
+ MyDevClass *myclass = MYDEV_GET_CLASS(obj);
172
+ MyDevState *mydev = MYDEV(obj);
173
+ /* call parent class enter phase */
174
+ if (myclass->parent_phases.enter) {
175
+ myclass->parent_phases.enter(obj, type);
176
+ }
177
+ /* initialize local state only */
178
+ mydev->var = 0;
179
+ }
48
+ }
180
+
49
+
181
+ static void mydev_reset_hold(Object *obj)
50
+ if (status->default_nan_mode) {
182
+ {
51
+ return floatx80_default_nan(status);
183
+ MyDevClass *myclass = MYDEV_GET_CLASS(obj);
184
+ MyDevState *mydev = MYDEV(obj);
185
+ /* call parent class hold phase */
186
+ if (myclass->parent_phases.hold) {
187
+ myclass->parent_phases.hold(obj);
188
+ }
189
+ /* set an IO */
190
+ qemu_set_irq(mydev->irq, 1);
191
+ }
52
+ }
192
+
53
+
193
+ static void mydev_reset_exit(Object *obj)
54
+ if (a.low < b.low) {
194
+ {
55
+ aIsLargerSignificand = 0;
195
+ MyDevClass *myclass = MYDEV_GET_CLASS(obj);
56
+ } else if (b.low < a.low) {
196
+ MyDevState *mydev = MYDEV(obj);
57
+ aIsLargerSignificand = 1;
197
+ /* call parent class exit phase */
58
+ } else {
198
+ if (myclass->parent_phases.exit) {
59
+ aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
199
+ myclass->parent_phases.exit(obj);
200
+ }
201
+ /* clear an IO */
202
+ qemu_set_irq(mydev->irq, 0);
203
+ }
60
+ }
204
+
61
+
205
+ typedef struct MyDevClass {
62
+ if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
206
+ MyParentClass parent_class;
63
+ if (is_snan(b_cls)) {
207
+ /* to store eventual parent reset methods */
64
+ return floatx80_silence_nan(b, status);
208
+ ResettablePhases parent_phases;
65
+ }
209
+ } MyDevClass;
66
+ return b;
67
+ } else {
68
+ if (is_snan(a_cls)) {
69
+ return floatx80_silence_nan(a, status);
70
+ }
71
+ return a;
72
+ }
73
+}
210
+
74
+
211
+ static void mydev_class_init(ObjectClass *class, void *data)
75
/*----------------------------------------------------------------------------
212
+ {
76
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
213
+ MyDevClass *myclass = MYDEV_CLASS(class);
77
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
214
+ ResettableClass *rc = RESETTABLE_CLASS(class);
78
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
215
+ resettable_class_set_parent_reset_phases(rc,
79
index XXXXXXX..XXXXXXX 100644
216
+ mydev_reset_enter,
80
--- a/fpu/softfloat-specialize.c.inc
217
+ mydev_reset_hold,
81
+++ b/fpu/softfloat-specialize.c.inc
218
+ mydev_reset_exit,
82
@@ -XXX,XX +XXX,XX @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
219
+ &myclass->parent_phases);
83
return a;
220
+ }
84
}
221
+
85
222
+In the above example, we override all three phases. It is possible to override
86
-/*----------------------------------------------------------------------------
223
+only some of them by passing NULL instead of a function pointer to
87
-| Takes two extended double-precision floating-point values `a' and `b', one
224
+``resettable_class_set_parent_reset_phases()``. For example, the following will
88
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
225
+only override the *enter* phase and leave *hold* and *exit* untouched::
89
-| `b' is a signaling NaN, the invalid exception is raised.
226
+
90
-*----------------------------------------------------------------------------*/
227
+ resettable_class_set_parent_reset_phases(rc, mydev_reset_enter,
91
-
228
+ NULL, NULL,
92
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
229
+ &myclass->parent_phases);
93
-{
230
+
94
- bool aIsLargerSignificand;
231
+This is equivalent to providing a trivial implementation of the hold and exit
95
- FloatClass a_cls, b_cls;
232
+phases which does nothing but call the parent class's implementation of the
96
-
233
+phase.
97
- /* This is not complete, but is good enough for pickNaN. */
234
+
98
- a_cls = (!floatx80_is_any_nan(a)
235
+Polling the reset state
99
- ? float_class_normal
236
+.......................
100
- : floatx80_is_signaling_nan(a, status)
237
+
101
- ? float_class_snan
238
+Resettable interface provides the ``resettable_is_in_reset()`` function.
102
- : float_class_qnan);
239
+This function returns true if the object parameter is currently under reset.
103
- b_cls = (!floatx80_is_any_nan(b)
240
+
104
- ? float_class_normal
241
+An object is under reset from the beginning of the *init* phase to the end of
105
- : floatx80_is_signaling_nan(b, status)
242
+the *exit* phase. During all three phases, the function will return that the
106
- ? float_class_snan
243
+object is in reset.
107
- : float_class_qnan);
244
+
108
-
245
+This function may be used if the object behavior has to be adapted
109
- if (is_snan(a_cls) || is_snan(b_cls)) {
246
+while in reset state. For example if a device has an irq input,
110
- float_raise(float_flag_invalid, status);
247
+it will probably need to ignore it while in reset; then it can for
111
- }
248
+example check the reset state at the beginning of the irq callback.
112
-
249
+
113
- if (status->default_nan_mode) {
250
+Note that until migration of the reset state is supported, an object
114
- return floatx80_default_nan(status);
251
+should not be left in reset. So apart from being currently executing
115
- }
252
+one of the reset phases, the only cases when this function will return
116
-
253
+true is if an external interaction (like changing an io) is made during
117
- if (a.low < b.low) {
254
+*hold* or *exit* phase of another object in the same reset group.
118
- aIsLargerSignificand = 0;
255
+
119
- } else if (b.low < a.low) {
256
+Helpers ``device_is_in_reset()`` and ``bus_is_in_reset()`` are also provided
120
- aIsLargerSignificand = 1;
257
+for devices and buses and should be preferred.
121
- } else {
258
+
122
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
259
+
123
- }
260
+Base class handling of reset
124
-
261
+----------------------------
125
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
262
+
126
- if (is_snan(b_cls)) {
263
+This section documents parts of the reset mechanism that you only need to know
127
- return floatx80_silence_nan(b, status);
264
+about if you are extending it to work with a new base class other than
128
- }
265
+DeviceClass or BusClass, or maintaining the existing code in those classes. Most
129
- return b;
266
+people can ignore it.
130
- } else {
267
+
131
- if (is_snan(a_cls)) {
268
+Methods to implement
132
- return floatx80_silence_nan(a, status);
269
+....................
133
- }
270
+
134
- return a;
271
+There are two other methods that need to exist in a class implementing the
135
- }
272
+interface: ``get_state()`` and ``child_foreach()``.
136
-}
273
+
137
-
274
+``get_state()`` is simple. *resettable* is an interface and, as a consequence,
138
/*----------------------------------------------------------------------------
275
+does not have any class state structure. But in order to factorize the code, we
139
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
276
+need one. This method must return a pointer to ``ResettableState`` structure.
140
| NaN; otherwise returns 0.
277
+The structure must be allocated by the base class; preferably it should be
278
+located inside the object instance structure.
279
+
280
+``child_foreach()`` is more complex. It should execute the given callback on
281
+every reset child of the given resettable object. All children must be
282
+resettable too. Additional parameters (a reset type and an opaque pointer) must
283
+be passed to the callback too.
284
+
285
+In ``DeviceClass`` and ``BusClass`` the ``ResettableState`` is located
286
+``DeviceState`` and ``BusState`` structure. ``child_foreach()`` is implemented
287
+to follow the bus hierarchy; for a bus, it calls the function on every child
288
+device; for a device, it calls the function on every bus child. When we reset
289
+the main system bus, we reset the whole machine bus tree.
290
+
291
+Changing a resettable parent
292
+............................
293
+
294
+One thing which should be taken care of by the base class is handling reset
295
+hierarchy changes.
296
+
297
+The reset hierarchy is supposed to be static and built during machine creation.
298
+But there are actually some exceptions. To cope with this, the resettable API
299
+provides ``resettable_change_parent()``. This function allows to set, update or
300
+remove the parent of a resettable object after machine creation is done. As
301
+parameters, it takes the object being moved, the old parent if any and the new
302
+parent if any.
303
+
304
+This function can be used at any time when not in a reset operation. During
305
+a reset operation it must be used only in *hold* phase. Using it in *enter* or
306
+*exit* phase is an error.
307
+Also it should not be used during machine creation, although it is harmless to
308
+do so: the function is a no-op as long as old and new parent are NULL or not
309
+in reset.
310
+
311
+There is currently 2 cases where this function is used:
312
+
313
+1. *device hotplug*; it means a new device is introduced on a live bus.
314
+
315
+2. *hot bus change*; it means an existing live device is added, moved or
316
+ removed in the bus hierarchy. At the moment, it occurs only in the raspi
317
+ machines for changing the sdbus used by sd card.
318
--
141
--
319
2.20.1
142
2.34.1
320
321
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Unpacking and repacking the parts may be slightly more work
4
than we did before, but we get to reuse more code. For a
5
code path handling exceptional values, this is an improvement.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241203203949.483774-8-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
fpu/softfloat.c | 43 +++++--------------------------------------
13
1 file changed, 5 insertions(+), 38 deletions(-)
14
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/fpu/softfloat.c
18
+++ b/fpu/softfloat.c
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
20
21
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
22
{
23
- bool aIsLargerSignificand;
24
- FloatClass a_cls, b_cls;
25
+ FloatParts128 pa, pb, *pr;
26
27
- /* This is not complete, but is good enough for pickNaN. */
28
- a_cls = (!floatx80_is_any_nan(a)
29
- ? float_class_normal
30
- : floatx80_is_signaling_nan(a, status)
31
- ? float_class_snan
32
- : float_class_qnan);
33
- b_cls = (!floatx80_is_any_nan(b)
34
- ? float_class_normal
35
- : floatx80_is_signaling_nan(b, status)
36
- ? float_class_snan
37
- : float_class_qnan);
38
-
39
- if (is_snan(a_cls) || is_snan(b_cls)) {
40
- float_raise(float_flag_invalid, status);
41
- }
42
-
43
- if (status->default_nan_mode) {
44
+ if (!floatx80_unpack_canonical(&pa, a, status) ||
45
+ !floatx80_unpack_canonical(&pb, b, status)) {
46
return floatx80_default_nan(status);
47
}
48
49
- if (a.low < b.low) {
50
- aIsLargerSignificand = 0;
51
- } else if (b.low < a.low) {
52
- aIsLargerSignificand = 1;
53
- } else {
54
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
55
- }
56
-
57
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
58
- if (is_snan(b_cls)) {
59
- return floatx80_silence_nan(b, status);
60
- }
61
- return b;
62
- } else {
63
- if (is_snan(a_cls)) {
64
- return floatx80_silence_nan(a, status);
65
- }
66
- return a;
67
- }
68
+ pr = parts_pick_nan(&pa, &pb, status);
69
+ return floatx80_round_pack_canonical(pr, status);
70
}
71
72
/*----------------------------------------------------------------------------
73
--
74
2.34.1
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Provide a temporary device_legacy_reset function doing what
3
Inline pickNaN into its only caller. This makes one assert
4
device_reset does to prepare for the transition with Resettable
4
redundant with the immediately preceding IF.
5
API.
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
All occurrence of device_reset in the code tree are also replaced
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
by device_legacy_reset.
8
Message-id: 20241203203949.483774-9-richard.henderson@linaro.org
9
10
The new resettable API has different prototype and semantics
11
(resetting child buses as well as the specified device). Subsequent
12
commits will make the changeover for each call site individually; once
13
that is complete device_legacy_reset() will be removed.
14
15
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Acked-by: David Gibson <david@gibson.dropbear.id.au>
19
Acked-by: Cornelia Huck <cohuck@redhat.com>
20
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
22
Message-id: 20200123132823.1117486-2-damien.hedde@greensocs.com
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
10
---
25
include/hw/qdev-core.h | 4 ++--
11
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
26
hw/audio/intel-hda.c | 2 +-
12
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
27
hw/core/qdev.c | 6 +++---
13
2 files changed, 73 insertions(+), 105 deletions(-)
28
hw/hyperv/hyperv.c | 2 +-
14
29
hw/i386/microvm.c | 2 +-
15
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
30
hw/i386/pc.c | 2 +-
31
hw/ide/microdrive.c | 8 ++++----
32
hw/intc/spapr_xive.c | 2 +-
33
hw/ppc/pnv_psi.c | 4 ++--
34
hw/ppc/spapr_pci.c | 2 +-
35
hw/ppc/spapr_vio.c | 2 +-
36
hw/s390x/s390-pci-inst.c | 2 +-
37
hw/scsi/vmw_pvscsi.c | 2 +-
38
hw/sd/omap_mmc.c | 2 +-
39
hw/sd/pl181.c | 2 +-
40
15 files changed, 22 insertions(+), 22 deletions(-)
41
42
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
43
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
44
--- a/include/hw/qdev-core.h
17
--- a/fpu/softfloat-parts.c.inc
45
+++ b/include/hw/qdev-core.h
18
+++ b/fpu/softfloat-parts.c.inc
46
@@ -XXX,XX +XXX,XX @@ char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev);
19
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
47
void qdev_machine_init(void);
20
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
48
21
float_status *s)
49
/**
22
{
50
- * @device_reset
23
+ int cmp, which;
51
+ * device_legacy_reset:
24
+
52
*
25
if (is_snan(a->cls) || is_snan(b->cls)) {
53
* Reset a single device (by calling the reset method).
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
54
*/
27
}
55
-void device_reset(DeviceState *dev);
28
56
+void device_legacy_reset(DeviceState *dev);
29
if (s->default_nan_mode) {
57
30
parts_default_nan(a, s);
58
void device_class_set_props(DeviceClass *dc, Property *props);
31
- } else {
59
32
- int cmp = frac_cmp(a, b);
60
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
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
61
index XXXXXXX..XXXXXXX 100644
118
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/audio/intel-hda.c
119
--- a/fpu/softfloat-specialize.c.inc
63
+++ b/hw/audio/intel-hda.c
120
+++ b/fpu/softfloat-specialize.c.inc
64
@@ -XXX,XX +XXX,XX @@ static void intel_hda_reset(DeviceState *dev)
121
@@ -XXX,XX +XXX,XX @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
65
QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) {
66
DeviceState *qdev = kid->child;
67
cdev = HDA_CODEC_DEVICE(qdev);
68
- device_reset(DEVICE(cdev));
69
+ device_legacy_reset(DEVICE(cdev));
70
d->state_sts |= (1 << cdev->cad);
71
}
72
intel_hda_update_irq(d);
73
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/core/qdev.c
76
+++ b/hw/core/qdev.c
77
@@ -XXX,XX +XXX,XX @@ HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
78
79
static int qdev_reset_one(DeviceState *dev, void *opaque)
80
{
81
- device_reset(dev);
82
+ device_legacy_reset(dev);
83
84
return 0;
85
}
86
@@ -XXX,XX +XXX,XX @@ static void device_set_realized(Object *obj, bool value, Error **errp)
87
}
88
}
89
if (dev->hotplugged) {
90
- device_reset(dev);
91
+ device_legacy_reset(dev);
92
}
93
dev->pending_deleted_event = false;
94
95
@@ -XXX,XX +XXX,XX @@ void device_class_set_parent_unrealize(DeviceClass *dc,
96
dc->unrealize = dev_unrealize;
97
}
98
99
-void device_reset(DeviceState *dev)
100
+void device_legacy_reset(DeviceState *dev)
101
{
102
DeviceClass *klass = DEVICE_GET_CLASS(dev);
103
104
diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/hyperv/hyperv.c
107
+++ b/hw/hyperv/hyperv.c
108
@@ -XXX,XX +XXX,XX @@ void hyperv_synic_reset(CPUState *cs)
109
SynICState *synic = get_synic(cs);
110
111
if (synic) {
112
- device_reset(DEVICE(synic));
113
+ device_legacy_reset(DEVICE(synic));
114
}
122
}
115
}
123
}
116
124
117
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
125
-/*----------------------------------------------------------------------------
118
index XXXXXXX..XXXXXXX 100644
126
-| Select which NaN to propagate for a two-input operation.
119
--- a/hw/i386/microvm.c
127
-| IEEE754 doesn't specify all the details of this, so the
120
+++ b/hw/i386/microvm.c
128
-| algorithm is target-specific.
121
@@ -XXX,XX +XXX,XX @@ static void microvm_machine_reset(MachineState *machine)
129
-| The routine is passed various bits of information about the
122
cpu = X86_CPU(cs);
130
-| two NaNs and should return 0 to select NaN a and 1 for NaN b.
123
131
-| Note that signalling NaNs are always squashed to quiet NaNs
124
if (cpu->apic_state) {
132
-| by the caller, by calling floatXX_silence_nan() before
125
- device_reset(cpu->apic_state);
133
-| returning them.
126
+ device_legacy_reset(cpu->apic_state);
134
-|
127
}
135
-| aIsLargerSignificand is only valid if both a and b are NaNs
128
}
136
-| of some kind, and is true if a has the larger significand,
129
}
137
-| or if both a and b have the same significand but a is
130
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
138
-| positive but b is negative. It is only needed for the x87
131
index XXXXXXX..XXXXXXX 100644
139
-| tie-break rule.
132
--- a/hw/i386/pc.c
140
-*----------------------------------------------------------------------------*/
133
+++ b/hw/i386/pc.c
141
-
134
@@ -XXX,XX +XXX,XX @@ static void pc_machine_reset(MachineState *machine)
142
-static int pickNaN(FloatClass a_cls, FloatClass b_cls,
135
cpu = X86_CPU(cs);
143
- bool aIsLargerSignificand, float_status *status)
136
144
-{
137
if (cpu->apic_state) {
145
- /*
138
- device_reset(cpu->apic_state);
146
- * We guarantee not to require the target to tell us how to
139
+ device_legacy_reset(cpu->apic_state);
147
- * pick a NaN if we're always returning the default NaN.
140
}
148
- * But if we're not in default-NaN mode then the target must
141
}
149
- * specify via set_float_2nan_prop_rule().
142
}
150
- */
143
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
151
- assert(!status->default_nan_mode);
144
index XXXXXXX..XXXXXXX 100644
152
-
145
--- a/hw/ide/microdrive.c
153
- switch (status->float_2nan_prop_rule) {
146
+++ b/hw/ide/microdrive.c
154
- case float_2nan_prop_s_ab:
147
@@ -XXX,XX +XXX,XX @@ static void md_attr_write(PCMCIACardState *card, uint32_t at, uint8_t value)
155
- if (is_snan(a_cls)) {
148
case 0x00:    /* Configuration Option Register */
156
- return 0;
149
s->opt = value & 0xcf;
157
- } else if (is_snan(b_cls)) {
150
if (value & OPT_SRESET) {
158
- return 1;
151
- device_reset(DEVICE(s));
159
- } else if (is_qnan(a_cls)) {
152
+ device_legacy_reset(DEVICE(s));
160
- return 0;
153
}
161
- } else {
154
md_interrupt_update(s);
162
- return 1;
155
break;
163
- }
156
@@ -XXX,XX +XXX,XX @@ static void md_common_write(PCMCIACardState *card, uint32_t at, uint16_t value)
164
- break;
157
case 0xe:    /* Device Control */
165
- case float_2nan_prop_s_ba:
158
s->ctrl = value;
166
- if (is_snan(b_cls)) {
159
if (value & CTRL_SRST) {
167
- return 1;
160
- device_reset(DEVICE(s));
168
- } else if (is_snan(a_cls)) {
161
+ device_legacy_reset(DEVICE(s));
169
- return 0;
162
}
170
- } else if (is_qnan(b_cls)) {
163
md_interrupt_update(s);
171
- return 1;
164
break;
172
- } else {
165
@@ -XXX,XX +XXX,XX @@ static int dscm1xxxx_attach(PCMCIACardState *card)
173
- return 0;
166
md->attr_base = pcc->cis[0x74] | (pcc->cis[0x76] << 8);
174
- }
167
md->io_base = 0x0;
175
- break;
168
176
- case float_2nan_prop_ab:
169
- device_reset(DEVICE(md));
177
- if (is_nan(a_cls)) {
170
+ device_legacy_reset(DEVICE(md));
178
- return 0;
171
md_interrupt_update(md);
179
- } else {
172
180
- return 1;
173
return 0;
181
- }
174
@@ -XXX,XX +XXX,XX @@ static int dscm1xxxx_detach(PCMCIACardState *card)
182
- break;
175
{
183
- case float_2nan_prop_ba:
176
MicroDriveState *md = MICRODRIVE(card);
184
- if (is_nan(b_cls)) {
177
185
- return 1;
178
- device_reset(DEVICE(md));
186
- } else {
179
+ device_legacy_reset(DEVICE(md));
187
- return 0;
180
return 0;
188
- }
181
}
189
- break;
182
190
- case float_2nan_prop_x87:
183
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
191
- /*
184
index XXXXXXX..XXXXXXX 100644
192
- * This implements x87 NaN propagation rules:
185
--- a/hw/intc/spapr_xive.c
193
- * SNaN + QNaN => return the QNaN
186
+++ b/hw/intc/spapr_xive.c
194
- * two SNaNs => return the one with the larger significand, silenced
187
@@ -XXX,XX +XXX,XX @@ static target_ulong h_int_reset(PowerPCCPU *cpu,
195
- * two QNaNs => return the one with the larger significand
188
return H_PARAMETER;
196
- * SNaN and a non-NaN => return the SNaN, silenced
189
}
197
- * QNaN and a non-NaN => return the QNaN
190
198
- *
191
- device_reset(DEVICE(xive));
199
- * If we get down to comparing significands and they are the same,
192
+ device_legacy_reset(DEVICE(xive));
200
- * return the NaN with the positive sign bit (if any).
193
201
- */
194
if (kvm_irqchip_in_kernel()) {
202
- if (is_snan(a_cls)) {
195
Error *local_err = NULL;
203
- if (is_snan(b_cls)) {
196
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
204
- return aIsLargerSignificand ? 0 : 1;
197
index XXXXXXX..XXXXXXX 100644
205
- }
198
--- a/hw/ppc/pnv_psi.c
206
- return is_qnan(b_cls) ? 1 : 0;
199
+++ b/hw/ppc/pnv_psi.c
207
- } else if (is_qnan(a_cls)) {
200
@@ -XXX,XX +XXX,XX @@ static void pnv_psi_reset(DeviceState *dev)
208
- if (is_snan(b_cls) || !is_qnan(b_cls)) {
201
209
- return 0;
202
static void pnv_psi_reset_handler(void *dev)
210
- } else {
203
{
211
- return aIsLargerSignificand ? 0 : 1;
204
- device_reset(DEVICE(dev));
212
- }
205
+ device_legacy_reset(DEVICE(dev));
213
- } else {
206
}
214
- return 1;
207
215
- }
208
static void pnv_psi_realize(DeviceState *dev, Error **errp)
216
- default:
209
@@ -XXX,XX +XXX,XX @@ static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr,
217
- g_assert_not_reached();
210
break;
218
- }
211
case PSIHB9_INTERRUPT_CONTROL:
219
-}
212
if (val & PSIHB9_IRQ_RESET) {
220
-
213
- device_reset(DEVICE(&psi9->source));
221
/*----------------------------------------------------------------------------
214
+ device_legacy_reset(DEVICE(&psi9->source));
222
| Returns 1 if the double-precision floating-point value `a' is a quiet
215
}
223
| NaN; otherwise returns 0.
216
psi->regs[reg] = val;
217
break;
218
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/ppc/spapr_pci.c
221
+++ b/hw/ppc/spapr_pci.c
222
@@ -XXX,XX +XXX,XX @@ static int spapr_phb_children_reset(Object *child, void *opaque)
223
DeviceState *dev = (DeviceState *) object_dynamic_cast(child, TYPE_DEVICE);
224
225
if (dev) {
226
- device_reset(dev);
227
+ device_legacy_reset(dev);
228
}
229
230
return 0;
231
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
232
index XXXXXXX..XXXXXXX 100644
233
--- a/hw/ppc/spapr_vio.c
234
+++ b/hw/ppc/spapr_vio.c
235
@@ -XXX,XX +XXX,XX @@ int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq)
236
static void spapr_vio_quiesce_one(SpaprVioDevice *dev)
237
{
238
if (dev->tcet) {
239
- device_reset(DEVICE(dev->tcet));
240
+ device_legacy_reset(DEVICE(dev->tcet));
241
}
242
free_crq(dev);
243
}
244
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
245
index XXXXXXX..XXXXXXX 100644
246
--- a/hw/s390x/s390-pci-inst.c
247
+++ b/hw/s390x/s390-pci-inst.c
248
@@ -XXX,XX +XXX,XX @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
249
stw_p(&ressetpci->hdr.rsp, CLP_RC_SETPCIFN_FHOP);
250
goto out;
251
}
252
- device_reset(DEVICE(pbdev));
253
+ device_legacy_reset(DEVICE(pbdev));
254
pbdev->fh &= ~FH_MASK_ENABLE;
255
pbdev->state = ZPCI_FS_DISABLED;
256
stl_p(&ressetpci->fh, pbdev->fh);
257
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
258
index XXXXXXX..XXXXXXX 100644
259
--- a/hw/scsi/vmw_pvscsi.c
260
+++ b/hw/scsi/vmw_pvscsi.c
261
@@ -XXX,XX +XXX,XX @@ pvscsi_on_cmd_reset_device(PVSCSIState *s)
262
263
if (sdev != NULL) {
264
s->resetting++;
265
- device_reset(&sdev->qdev);
266
+ device_legacy_reset(&sdev->qdev);
267
s->resetting--;
268
return PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
269
}
270
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
271
index XXXXXXX..XXXXXXX 100644
272
--- a/hw/sd/omap_mmc.c
273
+++ b/hw/sd/omap_mmc.c
274
@@ -XXX,XX +XXX,XX @@ void omap_mmc_reset(struct omap_mmc_s *host)
275
* into any bus, and we must reset it manually. When omap_mmc is
276
* QOMified this must move into the QOM reset function.
277
*/
278
- device_reset(DEVICE(host->card));
279
+ device_legacy_reset(DEVICE(host->card));
280
}
281
282
static uint64_t omap_mmc_read(void *opaque, hwaddr offset,
283
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
284
index XXXXXXX..XXXXXXX 100644
285
--- a/hw/sd/pl181.c
286
+++ b/hw/sd/pl181.c
287
@@ -XXX,XX +XXX,XX @@ static void pl181_reset(DeviceState *d)
288
/* Since we're still using the legacy SD API the card is not plugged
289
* into any bus, and we must reset it manually.
290
*/
291
- device_reset(DEVICE(s->card));
292
+ device_legacy_reset(DEVICE(s->card));
293
}
294
295
static void pl181_init(Object *obj)
296
--
224
--
297
2.20.1
225
2.34.1
298
226
299
227
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
These buffers should be aligned on 16 bytes.
3
Remember if there was an SNaN, and use that to simplify
4
float_2nan_prop_s_{ab,ba} to only the snan component.
5
Then, fall through to the corresponding
6
float_2nan_prop_{ab,ba} case to handle any remaining
7
nans, which must be quiet.
4
8
5
Ignore invalid RX and TX buffer addresses and log an error. All
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
incoming and outgoing traffic will be dropped because no valid RX or
7
TX descriptors will be available.
8
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 20200114103433.30534-4-clg@kaod.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20241203203949.483774-10-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
hw/net/ftgmac100.c | 13 +++++++++++++
14
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
15
1 file changed, 13 insertions(+)
15
1 file changed, 12 insertions(+), 20 deletions(-)
16
16
17
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.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/hw/net/ftgmac100.c
19
--- a/fpu/softfloat-parts.c.inc
20
+++ b/hw/net/ftgmac100.c
20
+++ b/fpu/softfloat-parts.c.inc
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
21
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
22
uint32_t des3;
22
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
23
} FTGMAC100Desc;
23
float_status *s)
24
24
{
25
+#define FTGMAC100_DESC_ALIGNMENT 16
25
+ bool have_snan = false;
26
+
26
int cmp, which;
27
/*
27
28
* Specific RTL8211E MII Registers
28
if (is_snan(a->cls) || is_snan(b->cls)) {
29
*/
29
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
30
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_write(void *opaque, hwaddr addr,
30
+ have_snan = true;
31
s->itc = value;
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;
32
break;
65
break;
33
case FTGMAC100_RXR_BADR: /* Ring buffer address */
66
+ case float_2nan_prop_s_ba:
34
+ if (!QEMU_IS_ALIGNED(value, FTGMAC100_DESC_ALIGNMENT)) {
67
+ if (have_snan) {
35
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad RX buffer alignment 0x%"
68
+ which = is_snan(b->cls) ? 1 : 0;
36
+ HWADDR_PRIx "\n", __func__, value);
69
+ break;
37
+ return;
38
+ }
70
+ }
39
+
71
+ /* fall through */
40
s->rx_ring = value;
72
case float_2nan_prop_ba:
41
s->rx_descriptor = s->rx_ring;
73
which = is_nan(b->cls) ? 1 : 0;
42
break;
43
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_write(void *opaque, hwaddr addr,
44
break;
45
46
case FTGMAC100_NPTXR_BADR: /* Transmit buffer address */
47
+ if (!QEMU_IS_ALIGNED(value, FTGMAC100_DESC_ALIGNMENT)) {
48
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad TX buffer alignment 0x%"
49
+ HWADDR_PRIx "\n", __func__, value);
50
+ return;
51
+ }
52
s->tx_ring = value;
53
s->tx_descriptor = s->tx_ring;
54
break;
74
break;
55
--
75
--
56
2.20.1
76
2.34.1
57
58
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Replace deprecated qbus_reset_all by resettable_cold_reset_fn for
3
Move the fractional comparison to the end of the
4
the sysbus reset registration.
4
float_2nan_prop_x87 case. This is not required for
5
any other 2nan propagation rule. Reorganize the
6
x87 case itself to break out of the switch when the
7
fractional comparison is not required.
5
8
6
Apart for the raspi machines, this does not impact the behavior
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
because:
8
+ at this point resettable just calls the old reset methods of devices
9
and buses in the same order as qdev/qbus.
10
+ resettable handlers registered with qemu_register_reset are
11
serialized; there is no interleaving.
12
+ eventual explicit calls to legacy reset API (device_reset or
13
qdev/qbus_reset) inside this reset handler will not be masked out
14
by resettable mechanism; they do not go through resettable api.
15
16
For the raspi machines, during the sysbus reset the sd-card is not
17
reset twice anymore but only once. This is a consequence of switching
18
both sysbus reset and changing parent to resettable; it detects the
19
second reset is not needed. This has no impact on the state after
20
reset; the sd-card reset method only reset local state and query
21
information from the block backend.
22
23
The raspi reset change can be observed by using the following command
24
(reset will occurs, then do Ctrl-C to end qemu; no firmware is
25
given here).
26
qemu-system-aarch64 -M raspi3 \
27
-trace resettable_phase_hold_exec \
28
-trace qdev_update_parent_bus \
29
-trace resettable_change_parent \
30
-trace qdev_reset -trace qbus_reset
31
32
Before the patch, the qdev/qbus_reset traces show when reset method are
33
called. After the patch, the resettable_phase_hold_exec show when reset
34
method are called.
35
36
The traced reset order of the raspi3 is listed below. I've added empty
37
lines and the tree structure.
38
39
+->bcm2835-peripherals reset
40
|
41
| +->sd-card reset
42
| +->sd-bus reset
43
+->bcm2835_gpio reset
44
| -> dev_update_parent_bus (move the sd-card on the sdhci-bus)
45
| -> resettable_change_parent
46
|
47
+->bcm2835-dma reset
48
|
49
| +->bcm2835-sdhost-bus reset
50
+->bcm2835-sdhost reset
51
|
52
| +->sd-card (reset ONLY BEFORE BEFORE THE PATCH)
53
| +->sdhci-bus reset
54
+->generic-sdhci reset
55
|
56
+->bcm2835-rng reset
57
+->bcm2835-property reset
58
+->bcm2835-fb reset
59
+->bcm2835-mbox reset
60
+->bcm2835-aux reset
61
+->pl011 reset
62
+->bcm2835-ic reset
63
+->bcm2836-control reset
64
System reset
65
66
In both case, the sd-card is reset (being on bcm2835_gpio/sd-bus) then moved
67
to generic-sdhci/sdhci-bus by the bcm2835_gpio reset method.
68
69
Before the patch, it is then reset again being part of generic-sdhci/sdhci-bus.
70
After the patch, it considered again for reset but its reset method is not
71
called because it is already flagged as reset.
72
73
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
74
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
75
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
76
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
77
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
78
Message-id: 20200123132823.1117486-11-damien.hedde@greensocs.com
79
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
80
---
13
---
81
vl.c | 10 +++++++++-
14
fpu/softfloat-parts.c.inc | 19 +++++++++----------
82
1 file changed, 9 insertions(+), 1 deletion(-)
15
1 file changed, 9 insertions(+), 10 deletions(-)
83
16
84
diff --git a/vl.c b/vl.c
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
85
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
86
--- a/vl.c
19
--- a/fpu/softfloat-parts.c.inc
87
+++ b/vl.c
20
+++ b/fpu/softfloat-parts.c.inc
88
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
21
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
89
22
return a;
90
/* TODO: once all bus devices are qdevified, this should be done
23
}
91
* when bus is created by qdev.c */
24
92
- qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
25
- cmp = frac_cmp(a, b);
93
+ /*
26
- if (cmp == 0) {
94
+ * TODO: If we had a main 'reset container' that the whole system
27
- cmp = a->sign < b->sign;
95
+ * lived in, we could reset that using the multi-phase reset
28
- }
96
+ * APIs. For the moment, we just reset the sysbus, which will cause
29
-
97
+ * all devices hanging off it (and all their child buses, recursively)
30
switch (s->float_2nan_prop_rule) {
98
+ * to be reset. Note that this will *not* reset any Device objects
31
case float_2nan_prop_s_ab:
99
+ * which are not attached to some part of the qbus tree!
32
if (have_snan) {
100
+ */
33
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
101
+ qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
34
* return the NaN with the positive sign bit (if any).
102
qemu_run_machine_init_done_notifiers();
35
*/
103
36
if (is_snan(a->cls)) {
104
if (rom_check_and_register_reset() != 0) {
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();
105
--
63
--
106
2.20.1
64
2.34.1
107
108
diff view generated by jsdifflib
1
From: Andrew Jeffery <andrew@aj.id.au>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The AST2600 includes a second cut-down version of the SD/MMC controller
3
Replace the "index" selecting between A and B with a result variable
4
found in the AST2500, named the eMMC controller. It's cut down in the
4
of the proper type. This improves clarity within the function.
5
sense that it only supports one slot rather than two, but it brings the
6
total number of slots supported by the AST2600 to three.
7
5
8
The existing code assumed that the SD controller always provided two
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
slots. Rework the SDHCI object to expose the number of slots as a
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
property to be set by the SoC configuration.
8
Message-id: 20241203203949.483774-12-richard.henderson@linaro.org
11
12
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Cédric Le Goater <clg@kaod.org>
15
Signed-off-by: Cédric Le Goater <clg@kaod.org>
16
Message-id: 20200114103433.30534-2-clg@kaod.org
17
[PMM: fixed up to use device_class_set_props()]
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
10
---
20
include/hw/sd/aspeed_sdhci.h | 1 +
11
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
21
hw/arm/aspeed.c | 2 +-
12
1 file changed, 13 insertions(+), 15 deletions(-)
22
hw/arm/aspeed_ast2600.c | 2 ++
23
hw/arm/aspeed_soc.c | 2 ++
24
hw/sd/aspeed_sdhci.c | 11 +++++++++--
25
5 files changed, 15 insertions(+), 3 deletions(-)
26
13
27
diff --git a/include/hw/sd/aspeed_sdhci.h b/include/hw/sd/aspeed_sdhci.h
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
28
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
29
--- a/include/hw/sd/aspeed_sdhci.h
16
--- a/fpu/softfloat-parts.c.inc
30
+++ b/include/hw/sd/aspeed_sdhci.h
17
+++ b/fpu/softfloat-parts.c.inc
31
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSDHCIState {
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
32
SysBusDevice parent;
19
float_status *s)
33
20
{
34
SDHCIState slots[ASPEED_SDHCI_NUM_SLOTS];
21
bool have_snan = false;
35
+ uint8_t num_slots;
22
- int cmp, which;
36
23
+ FloatPartsN *ret;
37
MemoryRegion iomem;
24
+ int cmp;
38
qemu_irq irq;
25
39
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
26
if (is_snan(a->cls) || is_snan(b->cls)) {
40
index XXXXXXX..XXXXXXX 100644
27
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
41
--- a/hw/arm/aspeed.c
28
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
42
+++ b/hw/arm/aspeed.c
29
switch (s->float_2nan_prop_rule) {
43
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_init(MachineState *machine)
30
case float_2nan_prop_s_ab:
44
amc->i2c_init(bmc);
31
if (have_snan) {
32
- which = is_snan(a->cls) ? 0 : 1;
33
+ ret = is_snan(a->cls) ? a : b;
34
break;
35
}
36
/* fall through */
37
case float_2nan_prop_ab:
38
- which = is_nan(a->cls) ? 0 : 1;
39
+ ret = is_nan(a->cls) ? a : b;
40
break;
41
case float_2nan_prop_s_ba:
42
if (have_snan) {
43
- which = is_snan(b->cls) ? 1 : 0;
44
+ ret = is_snan(b->cls) ? b : a;
45
break;
46
}
47
/* fall through */
48
case float_2nan_prop_ba:
49
- which = is_nan(b->cls) ? 1 : 0;
50
+ ret = is_nan(b->cls) ? b : a;
51
break;
52
case float_2nan_prop_x87:
53
/*
54
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
55
*/
56
if (is_snan(a->cls)) {
57
if (!is_snan(b->cls)) {
58
- which = is_qnan(b->cls) ? 1 : 0;
59
+ ret = is_qnan(b->cls) ? b : a;
60
break;
61
}
62
} else if (is_qnan(a->cls)) {
63
if (is_snan(b->cls) || !is_qnan(b->cls)) {
64
- which = 0;
65
+ ret = a;
66
break;
67
}
68
} else {
69
- which = 1;
70
+ ret = b;
71
break;
72
}
73
cmp = frac_cmp(a, b);
74
if (cmp == 0) {
75
cmp = a->sign < b->sign;
76
}
77
- which = cmp > 0 ? 0 : 1;
78
+ ret = cmp > 0 ? a : b;
79
break;
80
default:
81
g_assert_not_reached();
45
}
82
}
46
83
47
- for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
84
- if (which) {
48
+ for (i = 0; i < bmc->soc.sdhci.num_slots; i++) {
85
- a = b;
49
SDHCIState *sdhci = &bmc->soc.sdhci.slots[i];
86
+ if (is_snan(ret->cls)) {
50
DriveInfo *dinfo = drive_get_next(IF_SD);
87
+ parts_silence_nan(ret, s);
51
BlockBackend *blk;
88
}
52
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
89
- if (is_snan(a->cls)) {
53
index XXXXXXX..XXXXXXX 100644
90
- parts_silence_nan(a, s);
54
--- a/hw/arm/aspeed_ast2600.c
91
- }
55
+++ b/hw/arm/aspeed_ast2600.c
92
- return a;
56
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
93
+ return ret;
57
sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
58
TYPE_ASPEED_SDHCI);
59
60
+ object_property_set_int(OBJECT(&s->sdhci), 2, "num-slots", &error_abort);
61
+
62
/* Init sd card slot class here so that they're under the correct parent */
63
for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
64
sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
65
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/aspeed_soc.c
68
+++ b/hw/arm/aspeed_soc.c
69
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
70
sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
71
TYPE_ASPEED_SDHCI);
72
73
+ object_property_set_int(OBJECT(&s->sdhci), 2, "num-slots", &error_abort);
74
+
75
/* Init sd card slot class here so that they're under the correct parent */
76
for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
77
sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
78
diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/sd/aspeed_sdhci.c
81
+++ b/hw/sd/aspeed_sdhci.c
82
@@ -XXX,XX +XXX,XX @@
83
#include "qapi/error.h"
84
#include "hw/irq.h"
85
#include "migration/vmstate.h"
86
+#include "hw/qdev-properties.h"
87
88
#define ASPEED_SDHCI_INFO 0x00
89
#define ASPEED_SDHCI_INFO_RESET 0x00030000
90
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdhci_realize(DeviceState *dev, Error **errp)
91
92
/* Create input irqs for the slots */
93
qdev_init_gpio_in_named_with_opaque(DEVICE(sbd), aspeed_sdhci_set_irq,
94
- sdhci, NULL, ASPEED_SDHCI_NUM_SLOTS);
95
+ sdhci, NULL, sdhci->num_slots);
96
97
sysbus_init_irq(sbd, &sdhci->irq);
98
memory_region_init_io(&sdhci->iomem, OBJECT(sdhci), &aspeed_sdhci_ops,
99
sdhci, TYPE_ASPEED_SDHCI, 0x1000);
100
sysbus_init_mmio(sbd, &sdhci->iomem);
101
102
- for (int i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
103
+ for (int i = 0; i < sdhci->num_slots; ++i) {
104
Object *sdhci_slot = OBJECT(&sdhci->slots[i]);
105
SysBusDevice *sbd_slot = SYS_BUS_DEVICE(&sdhci->slots[i]);
106
107
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_sdhci = {
108
},
109
};
110
111
+static Property aspeed_sdhci_properties[] = {
112
+ DEFINE_PROP_UINT8("num-slots", AspeedSDHCIState, num_slots, 0),
113
+ DEFINE_PROP_END_OF_LIST(),
114
+};
115
+
116
static void aspeed_sdhci_class_init(ObjectClass *classp, void *data)
117
{
118
DeviceClass *dc = DEVICE_CLASS(classp);
119
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdhci_class_init(ObjectClass *classp, void *data)
120
dc->realize = aspeed_sdhci_realize;
121
dc->reset = aspeed_sdhci_reset;
122
dc->vmsd = &vmstate_aspeed_sdhci;
123
+ device_class_set_props(dc, aspeed_sdhci_properties);
124
}
94
}
125
95
126
static TypeInfo aspeed_sdhci_info = {
96
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
127
--
97
--
128
2.20.1
98
2.34.1
129
99
130
100
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
Add a function resettable_change_parent() to do the required
3
I'm migrating to Qualcomm's new open source email infrastructure, so
4
plumbing when changing the parent a of Resettable object.
4
update my email address, and update the mailmap to match.
5
5
6
We need to make sure that the reset state of the object remains
6
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
7
coherent with the reset state of the new parent.
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
8
8
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
9
We make the 2 following hypothesis:
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
+ when an object is put in a parent under reset, the object goes in
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
reset.
11
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
12
+ when an object is removed from a parent under reset, the object
13
leaves reset.
14
15
The added function avoids any glitch if both old and new parent are
16
already in reset.
17
18
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
22
Message-id: 20200123132823.1117486-6-damien.hedde@greensocs.com
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
13
---
25
include/hw/resettable.h | 16 +++++++++++
14
MAINTAINERS | 2 +-
26
hw/core/resettable.c | 62 +++++++++++++++++++++++++++++++++++++++--
15
.mailmap | 5 +++--
27
hw/core/trace-events | 1 +
16
2 files changed, 4 insertions(+), 3 deletions(-)
28
3 files changed, 77 insertions(+), 2 deletions(-)
29
17
30
diff --git a/include/hw/resettable.h b/include/hw/resettable.h
18
diff --git a/MAINTAINERS b/MAINTAINERS
31
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
32
--- a/include/hw/resettable.h
20
--- a/MAINTAINERS
33
+++ b/include/hw/resettable.h
21
+++ b/MAINTAINERS
34
@@ -XXX,XX +XXX,XX @@ void resettable_release_reset(Object *obj, ResetType type);
22
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
35
*/
23
SBSA-REF
36
bool resettable_is_in_reset(Object *obj);
24
M: Radoslaw Biernacki <rad@semihalf.com>
37
25
M: Peter Maydell <peter.maydell@linaro.org>
38
+/**
26
-R: Leif Lindholm <quic_llindhol@quicinc.com>
39
+ * resettable_change_parent:
27
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
40
+ * Indicate that the parent of Ressettable @obj is changing from @oldp to @newp.
28
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
41
+ * All 3 objects must implement resettable interface. @oldp or @newp may be
29
L: qemu-arm@nongnu.org
42
+ * NULL.
30
S: Maintained
43
+ *
31
diff --git a/.mailmap b/.mailmap
44
+ * This function will adapt the reset state of @obj so that it is coherent
45
+ * with the reset state of @newp. It may trigger @resettable_assert_reset()
46
+ * or @resettable_release_reset(). It will do such things only if the reset
47
+ * state of @newp and @oldp are different.
48
+ *
49
+ * When using this function during reset, it must only be called during
50
+ * a hold phase method. Calling this during enter or exit phase is an error.
51
+ */
52
+void resettable_change_parent(Object *obj, Object *newp, Object *oldp);
53
+
54
/**
55
* resettable_class_set_parent_phases:
56
*
57
diff --git a/hw/core/resettable.c b/hw/core/resettable.c
58
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/core/resettable.c
33
--- a/.mailmap
60
+++ b/hw/core/resettable.c
34
+++ b/.mailmap
61
@@ -XXX,XX +XXX,XX @@ static void resettable_phase_exit(Object *obj, void *opaque, ResetType type);
35
@@ -XXX,XX +XXX,XX @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
62
* enter_phase_in_progress:
36
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
63
* True if we are currently in reset enter phase.
37
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
64
*
38
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
65
- * Note: This flag is only used to guarantee (using asserts) that the reset
39
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
66
- * API is used correctly. We can use a global variable because we rely on the
40
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
67
+ * exit_phase_in_progress:
41
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
68
+ * count the number of exit phase we are in.
42
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
69
+ *
43
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
70
+ * Note: These flags are only used to guarantee (using asserts) that the reset
44
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
71
+ * API is used correctly. We can use global variables because we rely on the
45
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
72
* iothread mutex to ensure only one reset operation is in a progress at a
46
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
73
* given time.
74
*/
75
static bool enter_phase_in_progress;
76
+static unsigned exit_phase_in_progress;
77
78
void resettable_reset(Object *obj, ResetType type)
79
{
80
@@ -XXX,XX +XXX,XX @@ void resettable_release_reset(Object *obj, ResetType type)
81
trace_resettable_reset_release_begin(obj, type);
82
assert(!enter_phase_in_progress);
83
84
+ exit_phase_in_progress += 1;
85
resettable_phase_exit(obj, NULL, type);
86
+ exit_phase_in_progress -= 1;
87
88
trace_resettable_reset_release_end(obj);
89
}
90
@@ -XXX,XX +XXX,XX @@ static void resettable_phase_exit(Object *obj, void *opaque, ResetType type)
91
trace_resettable_phase_exit_end(obj, obj_typename, s->count);
92
}
93
94
+/*
95
+ * resettable_get_count:
96
+ * Get the count of the Resettable object @obj. Return 0 if @obj is NULL.
97
+ */
98
+static unsigned resettable_get_count(Object *obj)
99
+{
100
+ if (obj) {
101
+ ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
102
+ return rc->get_state(obj)->count;
103
+ }
104
+ return 0;
105
+}
106
+
107
+void resettable_change_parent(Object *obj, Object *newp, Object *oldp)
108
+{
109
+ ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
110
+ ResettableState *s = rc->get_state(obj);
111
+ unsigned newp_count = resettable_get_count(newp);
112
+ unsigned oldp_count = resettable_get_count(oldp);
113
+
114
+ /*
115
+ * Ensure we do not change parent when in enter or exit phase.
116
+ * During these phases, the reset subtree being updated is partly in reset
117
+ * and partly not in reset (it depends on the actual position in
118
+ * resettable_child_foreach()s). We are not able to tell in which part is a
119
+ * leaving or arriving device. Thus we cannot set the reset count of the
120
+ * moving device to the proper value.
121
+ */
122
+ assert(!enter_phase_in_progress && !exit_phase_in_progress);
123
+ trace_resettable_change_parent(obj, oldp, oldp_count, newp, newp_count);
124
+
125
+ /*
126
+ * At most one of the two 'for' loops will be executed below
127
+ * in order to cope with the difference between the two counts.
128
+ */
129
+ /* if newp is more reset than oldp */
130
+ for (unsigned i = oldp_count; i < newp_count; i++) {
131
+ resettable_assert_reset(obj, RESET_TYPE_COLD);
132
+ }
133
+ /*
134
+ * if obj is leaving a bus under reset, we need to ensure
135
+ * hold phase is not pending.
136
+ */
137
+ if (oldp_count && s->hold_phase_pending) {
138
+ resettable_phase_hold(obj, NULL, RESET_TYPE_COLD);
139
+ }
140
+ /* if oldp is more reset than newp */
141
+ for (unsigned i = newp_count; i < oldp_count; i++) {
142
+ resettable_release_reset(obj, RESET_TYPE_COLD);
143
+ }
144
+}
145
+
146
void resettable_class_set_parent_phases(ResettableClass *rc,
147
ResettableEnterPhase enter,
148
ResettableHoldPhase hold,
149
diff --git a/hw/core/trace-events b/hw/core/trace-events
150
index XXXXXXX..XXXXXXX 100644
151
--- a/hw/core/trace-events
152
+++ b/hw/core/trace-events
153
@@ -XXX,XX +XXX,XX @@ resettable_reset_assert_begin(void *obj, int cold) "obj=%p cold=%d"
154
resettable_reset_assert_end(void *obj) "obj=%p"
155
resettable_reset_release_begin(void *obj, int cold) "obj=%p cold=%d"
156
resettable_reset_release_end(void *obj) "obj=%p"
157
+resettable_change_parent(void *obj, void *o, unsigned oc, void *n, unsigned nc) "obj=%p from=%p(%d) to=%p(%d)"
158
resettable_phase_enter_begin(void *obj, const char *objtype, unsigned count, int type) "obj=%p(%s) count=%d type=%d"
159
resettable_phase_enter_exec(void *obj, const char *objtype, int type, int has_method) "obj=%p(%s) type=%d method=%d"
160
resettable_phase_enter_end(void *obj, const char *objtype, unsigned count) "obj=%p(%s) count=%d"
161
--
47
--
162
2.20.1
48
2.34.1
163
49
164
50
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
2
2
3
Since we enabled parallel TCG code generation for softmmu (see
3
Previously, maintainer role was paused due to inactive email id. Commit id:
4
commit 3468b59 "tcg: enable multiple TCG contexts in softmmu")
4
c009d715721861984c4987bcc78b7ee183e86d75.
5
and its subsequent fix (commit 72649619 "add .min_cpus and
6
.default_cpus fields to machine_class"), the raspi machines are
7
restricted to always use their 4 cores:
8
5
9
See in hw/arm/raspi2 (with BCM283X_NCPUS set to 4):
6
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
10
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
11
222 static void raspi2_machine_init(MachineClass *mc)
8
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
12
223 {
13
224 mc->desc = "Raspberry Pi 2";
14
230 mc->max_cpus = BCM283X_NCPUS;
15
231 mc->min_cpus = BCM283X_NCPUS;
16
232 mc->default_cpus = BCM283X_NCPUS;
17
235 };
18
236 DEFINE_MACHINE("raspi2", raspi2_machine_init)
19
20
We can no longer use the -smp option, as we get:
21
22
$ qemu-system-arm -M raspi2 -smp 1
23
qemu-system-arm: Invalid SMP CPUs 1. The min CPUs supported by machine 'raspi2' is 4
24
25
Since we can not set the TYPE_BCM283x SOC "enabled-cpus" with -smp,
26
remove the unuseful code.
27
28
We can achieve the same by using the '-global bcm2836.enabled-cpus=1'
29
option.
30
31
Reported-by: Laurent Bonnans <laurent.bonnans@here.com>
32
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
33
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
34
Message-id: 20200120235159.18510-2-f4bug@amsat.org
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
---
10
---
37
hw/arm/raspi.c | 2 --
11
MAINTAINERS | 2 ++
38
1 file changed, 2 deletions(-)
12
1 file changed, 2 insertions(+)
39
13
40
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
14
diff --git a/MAINTAINERS b/MAINTAINERS
41
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/raspi.c
16
--- a/MAINTAINERS
43
+++ b/hw/arm/raspi.c
17
+++ b/MAINTAINERS
44
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
18
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-sb16-test.c
45
/* Setup the SOC */
19
46
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
20
Xilinx CAN
47
&error_abort);
21
M: Francisco Iglesias <francisco.iglesias@amd.com>
48
- object_property_set_int(OBJECT(&s->soc), machine->smp.cpus, "enabled-cpus",
22
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
49
- &error_abort);
23
S: Maintained
50
int board_rev = version == 3 ? 0xa02082 : 0xa21041;
24
F: hw/net/can/xlnx-*
51
object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev",
25
F: include/hw/net/xlnx-*
52
&error_abort);
26
@@ -XXX,XX +XXX,XX @@ F: include/hw/rx/
27
CAN bus subsystem and hardware
28
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
29
M: Francisco Iglesias <francisco.iglesias@amd.com>
30
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
31
S: Maintained
32
W: https://canbus.pages.fel.cvut.cz/
33
F: net/can/*
53
--
34
--
54
2.20.1
35
2.34.1
55
56
diff view generated by jsdifflib