1
The following changes since commit c3709fde5955d13f6d4f86ab46ef3cc2288ca65e:
1
First arm pullreq of the cycle; this is mostly my softfloat NaN
2
handling series. (Lots more in my to-review queue, but I don't
3
like pullreqs growing too close to a hundred patches at a time :-))
2
4
3
Merge tag 'pull-aspeed-20240201' of https://github.com/legoater/qemu into staging (2024-02-01 14:42:11 +0000)
5
thanks
6
-- PMM
7
8
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
9
10
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240202
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
8
15
9
for you to fetch changes up to f09c2b7ba9908714a3e2f1decd989462536cf731:
16
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
10
17
11
hw/arm: Connect SPI Controller to BCM2835 (2024-02-02 13:51:59 +0000)
18
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
target/arm: fix exception syndrome for AArch32 bkpt insn
21
target-arm queue:
15
pci, vmbus, adb, s390x/css-bridge: Switch buses to 3-phase reset
22
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
16
system/vl.c: Fix handling of '-serial none -serial something'
23
* fpu: Make muladd NaN handling runtime-selected, not compile-time
17
target/arm: Add ID_AA64ZFR0_EL1.B16B16 to the exposed-to-userspace set
24
* fpu: Make default NaN pattern runtime-selected, not compile-time
18
tests/qtest/xlnx-versal-trng-test.c: Drop use of variable length array
25
* fpu: Minor NaN-related cleanups
19
target/arm: Reinstate "vfp" property on AArch32 CPUs
26
* MAINTAINERS: email address updates
20
doc/sphinx/hxtool.py: add optional label argument to SRST directive
21
hw/arm: Check for CPU types in machine_run_board_init() for various boards
22
pci-host: designware: Limit value range of iATU viewport register
23
hw/arm: Convert some DPRINTF macros to trace events and guest errors
24
hw/arm: NPCM7XX SoC: Add GMAC ethernet controller devices
25
hw/arm: Implement BCM2835 SPI Controller
26
27
27
----------------------------------------------------------------
28
----------------------------------------------------------------
28
David Woodhouse (1):
29
Bernhard Beschow (5):
29
doc/sphinx/hxtool.py: add optional label argument to SRST directive
30
hw/net/lan9118: Extract lan9118_phy
31
hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations
32
hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register
33
hw/net/lan9118_phy: Reuse MII constants
34
hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement
30
35
31
Guenter Roeck (1):
36
Leif Lindholm (1):
32
pci-host: designware: Limit value range of iATU viewport register
37
MAINTAINERS: update email address for Leif Lindholm
33
38
34
Hao Wu (2):
39
Peter Maydell (54):
35
hw/net: Add NPCMXXX GMAC device
40
fpu: handle raising Invalid for infzero in pick_nan_muladd
36
hw/arm: Add GMAC devices to NPCM7XX SoC
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
37
94
38
Jan Klötzke (1):
95
Richard Henderson (11):
39
target/arm: fix exception syndrome for AArch32 bkpt insn
96
target/arm: Copy entire float_status in is_ebf
97
softfloat: Inline pickNaNMulAdd
98
softfloat: Use goto for default nan case in pick_nan_muladd
99
softfloat: Remove which from parts_pick_nan_muladd
100
softfloat: Pad array size in pick_nan_muladd
101
softfloat: Move propagateFloatx80NaN to softfloat.c
102
softfloat: Use parts_pick_nan in propagateFloatx80NaN
103
softfloat: Inline pickNaN
104
softfloat: Share code between parts_pick_nan cases
105
softfloat: Sink frac_cmp in parts_pick_nan until needed
106
softfloat: Replace WHICH with RET in parts_pick_nan
40
107
41
Manos Pitsidianakis (6):
108
Vikram Garhwal (1):
42
hw/arm/strongarm.c: convert DPRINTF to trace events and guest errors
109
MAINTAINERS: Add correct email address for Vikram Garhwal
43
hw/arm/z2: convert DPRINTF to trace events and guest errors
44
hw/arm/xen_arm.c: convert DPRINTF to trace events and error/warn reports
45
hw/xen/xen-mapcache.c: convert DPRINTF to tracepoints
46
hw/xen/xen-hvm-common.c: convert DPRINTF to tracepoints
47
hw/xen: convert stderr prints to error/warn reports
48
110
49
Nabih Estefan Diaz (4):
111
MAINTAINERS | 4 +-
50
tests/qtest: Creating qtest for GMAC Module
112
include/fpu/softfloat-helpers.h | 38 +++-
51
hw/net: GMAC Rx Implementation
113
include/fpu/softfloat-types.h | 89 +++++++-
52
hw/net: GMAC Tx Implementation
114
include/hw/net/imx_fec.h | 9 +-
53
tests/qtest: Adding PCS Module test to GMAC Qtest
115
include/hw/net/lan9118_phy.h | 37 ++++
54
116
include/hw/net/mii.h | 6 +
55
Peter Maydell (10):
117
target/mips/fpu_helper.h | 20 ++
56
pci: Switch bus reset to 3-phase-reset
118
target/sparc/helper.h | 4 +-
57
vmbus: Switch bus reset to 3-phase-reset
119
fpu/softfloat.c | 19 ++
58
adb: Switch bus reset to 3-phase-reset
120
hw/net/imx_fec.c | 146 ++------------
59
hw/s390x/css-bridge: switch virtual-css bus to 3-phase-reset
121
hw/net/lan9118.c | 137 ++-----------
60
hw/core: Remove transitional infrastructure from BusClass
122
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
61
system/vl.c: Fix handling of '-serial none -serial something'
123
linux-user/arm/nwfpe/fpa11.c | 5 +
62
qemu-options.hx: Improve -serial option documentation
124
target/alpha/cpu.c | 2 +
63
target/arm: Add ID_AA64ZFR0_EL1.B16B16 to the exposed-to-userspace set
125
target/arm/cpu.c | 10 +
64
tests/qtest/xlnx-versal-trng-test.c: Drop use of variable length array
126
target/arm/tcg/vec_helper.c | 20 +-
65
target/arm: Reinstate "vfp" property on AArch32 CPUs
127
target/hexagon/cpu.c | 2 +
66
128
target/hppa/fpu_helper.c | 12 ++
67
Philippe Mathieu-Daudé (9):
129
target/i386/tcg/fpu_helper.c | 12 ++
68
hw/arm/exynos: Add missing QOM parent for CPU cores
130
target/loongarch/tcg/fpu_helper.c | 14 +-
69
hw/arm/exynos: Check for CPU types in machine_run_board_init()
131
target/m68k/cpu.c | 14 +-
70
hw/arm/highbank: Add missing QOM parent for CPU cores
132
target/m68k/fpu_helper.c | 6 +-
71
hw/arm/highbank: Check for CPU types in machine_run_board_init()
133
target/m68k/helper.c | 6 +-
72
hw/arm/msf2: Simplify setting MachineClass::valid_cpu_types[]
134
target/microblaze/cpu.c | 2 +
73
hw/arm/musca: Simplify setting MachineClass::valid_cpu_types[]
135
target/mips/msa.c | 10 +
74
hw/arm/npcm7xx_boards: Simplify setting MachineClass::valid_cpu_types[]
136
target/openrisc/cpu.c | 2 +
75
hw/arm/vexpress: Check for CPU types in machine_run_board_init()
137
target/ppc/cpu_init.c | 19 ++
76
hw/arm/zynq: Check for CPU types in machine_run_board_init()
138
target/ppc/fpu_helper.c | 3 +-
77
139
target/riscv/cpu.c | 2 +
78
Rayhan Faizel (2):
140
target/rx/cpu.c | 2 +
79
hw/ssi: Implement BCM2835 SPI Controller
141
target/s390x/cpu.c | 5 +
80
hw/arm: Connect SPI Controller to BCM2835
142
target/sh4/cpu.c | 2 +
81
143
target/sparc/cpu.c | 6 +
82
docs/devel/docs.rst | 12 +-
144
target/sparc/fop_helper.c | 8 +-
83
docs/sphinx/hxtool.py | 16 +
145
target/sparc/translate.c | 4 +-
84
docs/system/arm/raspi.rst | 2 +-
146
target/tricore/helper.c | 2 +
85
docs/system/i386/xen.rst | 3 +-
147
target/xtensa/cpu.c | 4 +
86
include/hw/arm/bcm2835_peripherals.h | 3 +-
148
target/xtensa/fpu_helper.c | 3 +-
87
include/hw/arm/msf2-soc.h | 3 -
149
tests/fp/fp-bench.c | 7 +
88
include/hw/arm/npcm7xx.h | 2 +
150
tests/fp/fp-test-log2.c | 1 +
89
include/hw/net/npcm_gmac.h | 343 +++++++++++++
151
tests/fp/fp-test.c | 7 +
90
include/hw/qdev-core.h | 2 -
152
fpu/softfloat-parts.c.inc | 152 +++++++++++---
91
include/hw/ssi/bcm2835_spi.h | 81 +++
153
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
92
target/arm/syndrome.h | 8 +
154
.mailmap | 5 +-
93
hw/arm/bcm2835_peripherals.c | 17 +-
155
hw/net/Kconfig | 5 +
94
hw/arm/exynos4210.c | 1 +
156
hw/net/meson.build | 1 +
95
hw/arm/exynos4_boards.c | 8 +
157
hw/net/trace-events | 10 +-
96
hw/arm/highbank.c | 11 +
158
47 files changed, 778 insertions(+), 730 deletions(-)
97
hw/arm/msf2-soc.c | 3 +-
159
create mode 100644 include/hw/net/lan9118_phy.h
98
hw/arm/msf2-som.c | 4 -
160
create mode 100644 hw/net/lan9118_phy.c
99
hw/arm/musca.c | 1 -
100
hw/arm/npcm7xx.c | 37 +-
101
hw/arm/npcm7xx_boards.c | 1 -
102
hw/arm/strongarm.c | 82 +--
103
hw/arm/vexpress.c | 12 +-
104
hw/arm/xen_arm.c | 23 +-
105
hw/arm/xilinx_zynq.c | 6 +-
106
hw/arm/z2.c | 27 +-
107
hw/core/bus.c | 67 ---
108
hw/hyperv/vmbus.c | 7 +-
109
hw/input/adb.c | 7 +-
110
hw/net/npcm_gmac.c | 942 +++++++++++++++++++++++++++++++++++
111
hw/pci-host/designware.c | 2 +
112
hw/pci/pci.c | 10 +-
113
hw/s390x/css-bridge.c | 5 +-
114
hw/ssi/bcm2835_spi.c | 288 +++++++++++
115
hw/xen/xen-hvm-common.c | 47 +-
116
hw/xen/xen-mapcache.c | 59 +--
117
system/vl.c | 22 +-
118
target/arm/cpu.c | 4 +
119
target/arm/helper.c | 19 +
120
tests/qtest/npcm_gmac-test.c | 344 +++++++++++++
121
tests/qtest/xlnx-versal-trng-test.c | 19 +-
122
tests/tcg/aarch64/sysregs.c | 2 +-
123
hw/arm/Kconfig | 1 +
124
hw/arm/trace-events | 15 +
125
hw/net/meson.build | 2 +-
126
hw/net/trace-events | 19 +
127
hw/ssi/Kconfig | 4 +
128
hw/ssi/meson.build | 1 +
129
hw/xen/trace-events | 21 +-
130
qemu-options.hx | 16 +-
131
tests/qtest/meson.build | 1 +
132
50 files changed, 2388 insertions(+), 244 deletions(-)
133
create mode 100644 include/hw/net/npcm_gmac.h
134
create mode 100644 include/hw/ssi/bcm2835_spi.h
135
create mode 100644 hw/net/npcm_gmac.c
136
create mode 100644 hw/ssi/bcm2835_spi.c
137
create mode 100644 tests/qtest/npcm_gmac-test.c
138
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
This patch implements the basic registers of GMAC device and sets
3
A very similar implementation of the same device exists in imx_fec. Prepare for
4
registers for networking functionalities.
4
a common implementation by extracting a device model into its own files.
5
Squashed IRQ Implementation patch into this one for compliation.
6
Tested:
7
The following message shows up with the change:
8
Broadcom BCM54612E stmmac-0:00: attached PHY driver [Broadcom BCM54612E] (mii_bus:phy_addr=stmmac-0:00, irq=POLL)
9
stmmaceth f0802000.eth eth0: Link is Up - 1Gbps/Full - flow control rx/tx
10
5
11
Change-Id: If71c6d486b95edcccba109ba454870714d7e0940
6
Some migration state has been moved into the new device model which breaks
12
Signed-off-by: Hao Wu <wuhaotsh@google.com>
7
migration compatibility for the following machines:
13
Signed-off-by: Nabih Estefan Diaz <nabihestefan@google.com>
8
* smdkc210
14
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
9
* realview-*
15
Message-id: 20240131002800.989285-2-nabihestefan@google.com
10
* vexpress-*
11
* kzm
12
* mps2-*
13
14
While breaking migration ABI, fix the size of the MII registers to be 16 bit,
15
as defined by IEEE 802.3u.
16
17
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
18
Tested-by: Guenter Roeck <linux@roeck-us.net>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Message-id: 20241102125724.532843-2-shentey@gmail.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
22
---
19
include/hw/net/npcm_gmac.h | 343 +++++++++++++++++++++++++++
23
include/hw/net/lan9118_phy.h | 37 ++++++++
20
hw/net/npcm_gmac.c | 467 +++++++++++++++++++++++++++++++++++++
24
hw/net/lan9118.c | 137 +++++-----------------------
21
hw/net/meson.build | 2 +-
25
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
22
hw/net/trace-events | 12 +
26
hw/net/Kconfig | 4 +
23
4 files changed, 823 insertions(+), 1 deletion(-)
27
hw/net/meson.build | 1 +
24
create mode 100644 include/hw/net/npcm_gmac.h
28
5 files changed, 233 insertions(+), 115 deletions(-)
25
create mode 100644 hw/net/npcm_gmac.c
29
create mode 100644 include/hw/net/lan9118_phy.h
30
create mode 100644 hw/net/lan9118_phy.c
26
31
27
diff --git a/include/hw/net/npcm_gmac.h b/include/hw/net/npcm_gmac.h
32
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
28
new file mode 100644
33
new file mode 100644
29
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
30
--- /dev/null
35
--- /dev/null
31
+++ b/include/hw/net/npcm_gmac.h
36
+++ b/include/hw/net/lan9118_phy.h
32
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
33
+/*
38
+/*
34
+ * Nuvoton NPCM7xx/8xx GMAC Module
39
+ * SMSC LAN9118 PHY emulation
35
+ *
40
+ *
36
+ * Copyright 2024 Google LLC
41
+ * Copyright (c) 2009 CodeSourcery, LLC.
37
+ * Authors:
42
+ * Written by Paul Brook
38
+ * Hao Wu <wuhaotsh@google.com>
39
+ * Nabih Estefan <nabihestefan@google.com>
40
+ *
43
+ *
41
+ * This program is free software; you can redistribute it and/or modify it
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
42
+ * under the terms of the GNU General Public License as published by the
45
+ * See the COPYING file in the top-level directory.
43
+ * Free Software Foundation; either version 2 of the License, or
44
+ * (at your option) any later version.
45
+ *
46
+ * This program is distributed in the hope that it will be useful, but WITHOUT
47
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
48
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
49
+ * for more details.
50
+ */
46
+ */
51
+
47
+
52
+#ifndef NPCM_GMAC_H
48
+#ifndef HW_NET_LAN9118_PHY_H
53
+#define NPCM_GMAC_H
49
+#define HW_NET_LAN9118_PHY_H
54
+
50
+
55
+#include "hw/irq.h"
51
+#include "qom/object.h"
56
+#include "hw/sysbus.h"
52
+#include "hw/sysbus.h"
57
+#include "net/net.h"
53
+
58
+
54
+#define TYPE_LAN9118_PHY "lan9118-phy"
59
+#define NPCM_GMAC_NR_REGS (0x1060 / sizeof(uint32_t))
55
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
60
+
56
+
61
+#define NPCM_GMAC_MAX_PHYS 32
57
+typedef struct Lan9118PhyState {
62
+#define NPCM_GMAC_MAX_PHY_REGS 32
58
+ SysBusDevice parent_obj;
63
+
59
+
64
+struct NPCMGMACRxDesc {
60
+ uint16_t status;
65
+ uint32_t rdes0;
61
+ uint16_t control;
66
+ uint32_t rdes1;
62
+ uint16_t advertise;
67
+ uint32_t rdes2;
63
+ uint16_t ints;
68
+ uint32_t rdes3;
64
+ uint16_t int_mask;
69
+};
70
+
71
+/* NPCMGMACRxDesc.flags values */
72
+/* RDES2 and RDES3 are buffer addresses */
73
+/* Owner: 0 = software, 1 = dma */
74
+#define RX_DESC_RDES0_OWN BIT(31)
75
+/* Destination Address Filter Fail */
76
+#define RX_DESC_RDES0_DEST_ADDR_FILT_FAIL BIT(30)
77
+/* Frame length */
78
+#define RX_DESC_RDES0_FRAME_LEN_MASK(word) extract32(word, 16, 14)
79
+/* Frame length Shift*/
80
+#define RX_DESC_RDES0_FRAME_LEN_SHIFT 16
81
+/* Error Summary */
82
+#define RX_DESC_RDES0_ERR_SUMM_MASK BIT(15)
83
+/* Descriptor Error */
84
+#define RX_DESC_RDES0_DESC_ERR_MASK BIT(14)
85
+/* Source Address Filter Fail */
86
+#define RX_DESC_RDES0_SRC_ADDR_FILT_FAIL_MASK BIT(13)
87
+/* Length Error */
88
+#define RX_DESC_RDES0_LEN_ERR_MASK BIT(12)
89
+/* Overflow Error */
90
+#define RX_DESC_RDES0_OVRFLW_ERR_MASK BIT(11)
91
+/* VLAN Tag */
92
+#define RX_DESC_RDES0_VLAN_TAG_MASK BIT(10)
93
+/* First Descriptor */
94
+#define RX_DESC_RDES0_FIRST_DESC_MASK BIT(9)
95
+/* Last Descriptor */
96
+#define RX_DESC_RDES0_LAST_DESC_MASK BIT(8)
97
+/* IPC Checksum Error/Giant Frame */
98
+#define RX_DESC_RDES0_IPC_CHKSM_ERR_GNT_FRM_MASK BIT(7)
99
+/* Late Collision */
100
+#define RX_DESC_RDES0_LT_COLL_MASK BIT(6)
101
+/* Frame Type */
102
+#define RX_DESC_RDES0_FRM_TYPE_MASK BIT(5)
103
+/* Receive Watchdog Timeout */
104
+#define RX_DESC_RDES0_REC_WTCHDG_TMT_MASK BIT(4)
105
+/* Receive Error */
106
+#define RX_DESC_RDES0_RCV_ERR_MASK BIT(3)
107
+/* Dribble Bit Error */
108
+#define RX_DESC_RDES0_DRBL_BIT_ERR_MASK BIT(2)
109
+/* Cyclcic Redundancy Check Error */
110
+#define RX_DESC_RDES0_CRC_ERR_MASK BIT(1)
111
+/* Rx MAC Address/Payload Checksum Error */
112
+#define RC_DESC_RDES0_RCE_MASK BIT(0)
113
+
114
+/* Disable Interrupt on Completion */
115
+#define RX_DESC_RDES1_DIS_INTR_COMP_MASK BIT(31)
116
+/* Recieve end of ring */
117
+#define RX_DESC_RDES1_RC_END_RING_MASK BIT(25)
118
+/* Second Address Chained */
119
+#define RX_DESC_RDES1_SEC_ADDR_CHND_MASK BIT(24)
120
+/* Receive Buffer 2 Size */
121
+#define RX_DESC_RDES1_BFFR2_SZ_SHIFT 11
122
+#define RX_DESC_RDES1_BFFR2_SZ_MASK(word) extract32(word, \
123
+ RX_DESC_RDES1_BFFR2_SZ_SHIFT, 11)
124
+/* Receive Buffer 1 Size */
125
+#define RX_DESC_RDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 11)
126
+
127
+
128
+struct NPCMGMACTxDesc {
129
+ uint32_t tdes0;
130
+ uint32_t tdes1;
131
+ uint32_t tdes2;
132
+ uint32_t tdes3;
133
+};
134
+
135
+/* NPCMGMACTxDesc.flags values */
136
+/* TDES2 and TDES3 are buffer addresses */
137
+/* Owner: 0 = software, 1 = gmac */
138
+#define TX_DESC_TDES0_OWN BIT(31)
139
+/* Tx Time Stamp Status */
140
+#define TX_DESC_TDES0_TTSS_MASK BIT(17)
141
+/* IP Header Error */
142
+#define TX_DESC_TDES0_IP_HEAD_ERR_MASK BIT(16)
143
+/* Error Summary */
144
+#define TX_DESC_TDES0_ERR_SUMM_MASK BIT(15)
145
+/* Jabber Timeout */
146
+#define TX_DESC_TDES0_JBBR_TMT_MASK BIT(14)
147
+/* Frame Flushed */
148
+#define TX_DESC_TDES0_FRM_FLSHD_MASK BIT(13)
149
+/* Payload Checksum Error */
150
+#define TX_DESC_TDES0_PYLD_CHKSM_ERR_MASK BIT(12)
151
+/* Loss of Carrier */
152
+#define TX_DESC_TDES0_LSS_CARR_MASK BIT(11)
153
+/* No Carrier */
154
+#define TX_DESC_TDES0_NO_CARR_MASK BIT(10)
155
+/* Late Collision */
156
+#define TX_DESC_TDES0_LATE_COLL_MASK BIT(9)
157
+/* Excessive Collision */
158
+#define TX_DESC_TDES0_EXCS_COLL_MASK BIT(8)
159
+/* VLAN Frame */
160
+#define TX_DESC_TDES0_VLAN_FRM_MASK BIT(7)
161
+/* Collision Count */
162
+#define TX_DESC_TDES0_COLL_CNT_MASK(word) extract32(word, 3, 4)
163
+/* Excessive Deferral */
164
+#define TX_DESC_TDES0_EXCS_DEF_MASK BIT(2)
165
+/* Underflow Error */
166
+#define TX_DESC_TDES0_UNDRFLW_ERR_MASK BIT(1)
167
+/* Deferred Bit */
168
+#define TX_DESC_TDES0_DFRD_BIT_MASK BIT(0)
169
+
170
+/* Interrupt of Completion */
171
+#define TX_DESC_TDES1_INTERR_COMP_MASK BIT(31)
172
+/* Last Segment */
173
+#define TX_DESC_TDES1_LAST_SEG_MASK BIT(30)
174
+/* First Segment */
175
+#define TX_DESC_TDES1_FIRST_SEG_MASK BIT(29)
176
+/* Checksum Insertion Control */
177
+#define TX_DESC_TDES1_CHKSM_INS_CTRL_MASK(word) extract32(word, 27, 2)
178
+/* Disable Cyclic Redundancy Check */
179
+#define TX_DESC_TDES1_DIS_CDC_MASK BIT(26)
180
+/* Transmit End of Ring */
181
+#define TX_DESC_TDES1_TX_END_RING_MASK BIT(25)
182
+/* Secondary Address Chained */
183
+#define TX_DESC_TDES1_SEC_ADDR_CHND_MASK BIT(24)
184
+/* Transmit Buffer 2 Size */
185
+#define TX_DESC_TDES1_BFFR2_SZ_MASK(word) extract32(word, 11, 11)
186
+/* Transmit Buffer 1 Size */
187
+#define TX_DESC_TDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 11)
188
+
189
+typedef struct NPCMGMACState {
190
+ SysBusDevice parent;
191
+
192
+ MemoryRegion iomem;
193
+ qemu_irq irq;
65
+ qemu_irq irq;
194
+
66
+ bool link_down;
195
+ NICState *nic;
67
+} Lan9118PhyState;
196
+ NICConf conf;
68
+
197
+
69
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down);
198
+ uint32_t regs[NPCM_GMAC_NR_REGS];
70
+void lan9118_phy_reset(Lan9118PhyState *s);
199
+ uint16_t phy_regs[NPCM_GMAC_MAX_PHYS][NPCM_GMAC_MAX_PHY_REGS];
71
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg);
200
+} NPCMGMACState;
72
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val);
201
+
73
+
202
+#define TYPE_NPCM_GMAC "npcm-gmac"
74
+#endif
203
+OBJECT_DECLARE_SIMPLE_TYPE(NPCMGMACState, NPCM_GMAC)
75
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
204
+
76
index XXXXXXX..XXXXXXX 100644
205
+/* Mask for RO bits in Status */
77
--- a/hw/net/lan9118.c
206
+#define NPCM_DMA_STATUS_RO_MASK(word) (word & 0xfffe0000)
78
+++ b/hw/net/lan9118.c
207
+/* Mask for RO bits in Status */
79
@@ -XXX,XX +XXX,XX @@
208
+#define NPCM_DMA_STATUS_W1C_MASK(word) (word & 0x1e7ff)
80
#include "net/net.h"
209
+
81
#include "net/eth.h"
210
+/* Transmit Process State */
82
#include "hw/irq.h"
211
+#define NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT 20
83
+#include "hw/net/lan9118_phy.h"
212
+/* Transmit States */
84
#include "hw/net/lan9118.h"
213
+#define NPCM_DMA_STATUS_TX_STOPPED_STATE \
85
#include "hw/ptimer.h"
214
+ (0b000)
86
#include "hw/qdev-properties.h"
215
+#define NPCM_DMA_STATUS_TX_RUNNING_FETCHING_STATE \
87
@@ -XXX,XX +XXX,XX @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
216
+ (0b001)
88
#define MAC_CR_RXEN 0x00000004
217
+#define NPCM_DMA_STATUS_TX_RUNNING_WAITING_STATE \
89
#define MAC_CR_RESERVED 0x7f404213
218
+ (0b010)
90
219
+#define NPCM_DMA_STATUS_TX_RUNNING_READ_STATE \
91
-#define PHY_INT_ENERGYON 0x80
220
+ (0b011)
92
-#define PHY_INT_AUTONEG_COMPLETE 0x40
221
+#define NPCM_DMA_STATUS_TX_SUSPENDED_STATE \
93
-#define PHY_INT_FAULT 0x20
222
+ (0b110)
94
-#define PHY_INT_DOWN 0x10
223
+#define NPCM_DMA_STATUS_TX_RUNNING_CLOSING_STATE \
95
-#define PHY_INT_AUTONEG_LP 0x08
224
+ (0b111)
96
-#define PHY_INT_PARFAULT 0x04
225
+/* Transmit Process State */
97
-#define PHY_INT_AUTONEG_PAGE 0x02
226
+#define NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT 17
98
-
227
+/* Receive States */
99
#define GPT_TIMER_EN 0x20000000
228
+#define NPCM_DMA_STATUS_RX_STOPPED_STATE \
100
229
+ (0b000)
101
/*
230
+#define NPCM_DMA_STATUS_RX_RUNNING_FETCHING_STATE \
102
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
231
+ (0b001)
103
uint32_t mac_mii_data;
232
+#define NPCM_DMA_STATUS_RX_RUNNING_WAITING_STATE \
104
uint32_t mac_flow;
233
+ (0b011)
105
234
+#define NPCM_DMA_STATUS_RX_SUSPENDED_STATE \
106
- uint32_t phy_status;
235
+ (0b100)
107
- uint32_t phy_control;
236
+#define NPCM_DMA_STATUS_RX_RUNNING_CLOSING_STATE \
108
- uint32_t phy_advertise;
237
+ (0b101)
109
- uint32_t phy_int;
238
+#define NPCM_DMA_STATUS_RX_RUNNING_TRANSFERRING_STATE \
110
- uint32_t phy_int_mask;
239
+ (0b111)
111
+ Lan9118PhyState mii;
240
+
112
+ IRQState mii_irq;
241
+
113
242
+/* Early Receive Interrupt */
114
int32_t eeprom_writable;
243
+#define NPCM_DMA_STATUS_ERI BIT(14)
115
uint8_t eeprom[128];
244
+/* Fatal Bus Error Interrupt */
116
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
245
+#define NPCM_DMA_STATUS_FBI BIT(13)
117
246
+/* Early transmit Interrupt */
118
static const VMStateDescription vmstate_lan9118 = {
247
+#define NPCM_DMA_STATUS_ETI BIT(10)
119
.name = "lan9118",
248
+/* Receive Watchdog Timout */
120
- .version_id = 2,
249
+#define NPCM_DMA_STATUS_RWT BIT(9)
121
- .minimum_version_id = 1,
250
+/* Receive Process Stopped */
122
+ .version_id = 3,
251
+#define NPCM_DMA_STATUS_RPS BIT(8)
123
+ .minimum_version_id = 3,
252
+/* Receive Buffer Unavailable */
124
.fields = (const VMStateField[]) {
253
+#define NPCM_DMA_STATUS_RU BIT(7)
125
VMSTATE_PTIMER(timer, lan9118_state),
254
+/* Receive Interrupt */
126
VMSTATE_UINT32(irq_cfg, lan9118_state),
255
+#define NPCM_DMA_STATUS_RI BIT(6)
127
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118 = {
256
+/* Transmit Underflow */
128
VMSTATE_UINT32(mac_mii_acc, lan9118_state),
257
+#define NPCM_DMA_STATUS_UNF BIT(5)
129
VMSTATE_UINT32(mac_mii_data, lan9118_state),
258
+/* Receive Overflow */
130
VMSTATE_UINT32(mac_flow, lan9118_state),
259
+#define NPCM_DMA_STATUS_OVF BIT(4)
131
- VMSTATE_UINT32(phy_status, lan9118_state),
260
+/* Transmit Jabber Timeout */
132
- VMSTATE_UINT32(phy_control, lan9118_state),
261
+#define NPCM_DMA_STATUS_TJT BIT(3)
133
- VMSTATE_UINT32(phy_advertise, lan9118_state),
262
+/* Transmit Buffer Unavailable */
134
- VMSTATE_UINT32(phy_int, lan9118_state),
263
+#define NPCM_DMA_STATUS_TU BIT(2)
135
- VMSTATE_UINT32(phy_int_mask, lan9118_state),
264
+/* Transmit Process Stopped */
136
VMSTATE_INT32(eeprom_writable, lan9118_state),
265
+#define NPCM_DMA_STATUS_TPS BIT(1)
137
VMSTATE_UINT8_ARRAY(eeprom, lan9118_state, 128),
266
+/* Transmit Interrupt */
138
VMSTATE_INT32(tx_fifo_size, lan9118_state),
267
+#define NPCM_DMA_STATUS_TI BIT(0)
139
@@ -XXX,XX +XXX,XX @@ static void lan9118_reload_eeprom(lan9118_state *s)
268
+
140
lan9118_mac_changed(s);
269
+/* Normal Interrupt Summary */
141
}
270
+#define NPCM_DMA_STATUS_NIS BIT(16)
142
271
+/* Interrupts enabled by NIE */
143
-static void phy_update_irq(lan9118_state *s)
272
+#define NPCM_DMA_STATUS_NIS_BITS (NPCM_DMA_STATUS_TI | \
144
+static void lan9118_update_irq(void *opaque, int n, int level)
273
+ NPCM_DMA_STATUS_TU | \
145
{
274
+ NPCM_DMA_STATUS_RI | \
146
- if (s->phy_int & s->phy_int_mask) {
275
+ NPCM_DMA_STATUS_ERI)
147
+ lan9118_state *s = opaque;
276
+/* Abnormal Interrupt Summary */
148
+
277
+#define NPCM_DMA_STATUS_AIS BIT(15)
149
+ if (level) {
278
+/* Interrupts enabled by AIE */
150
s->int_sts |= PHY_INT;
279
+#define NPCM_DMA_STATUS_AIS_BITS (NPCM_DMA_STATUS_TPS | \
151
} else {
280
+ NPCM_DMA_STATUS_TJT | \
152
s->int_sts &= ~PHY_INT;
281
+ NPCM_DMA_STATUS_OVF | \
153
@@ -XXX,XX +XXX,XX @@ static void phy_update_irq(lan9118_state *s)
282
+ NPCM_DMA_STATUS_UNF | \
154
lan9118_update(s);
283
+ NPCM_DMA_STATUS_RU | \
155
}
284
+ NPCM_DMA_STATUS_RPS | \
156
285
+ NPCM_DMA_STATUS_RWT | \
157
-static void phy_update_link(lan9118_state *s)
286
+ NPCM_DMA_STATUS_ETI | \
158
-{
287
+ NPCM_DMA_STATUS_FBI)
159
- /* Autonegotiation status mirrors link status. */
288
+
160
- if (qemu_get_queue(s->nic)->link_down) {
289
+/* Early Receive Interrupt Enable */
161
- s->phy_status &= ~0x0024;
290
+#define NPCM_DMA_INTR_ENAB_ERE BIT(14)
162
- s->phy_int |= PHY_INT_DOWN;
291
+/* Fatal Bus Error Interrupt Enable */
163
- } else {
292
+#define NPCM_DMA_INTR_ENAB_FBE BIT(13)
164
- s->phy_status |= 0x0024;
293
+/* Early transmit Interrupt Enable */
165
- s->phy_int |= PHY_INT_ENERGYON;
294
+#define NPCM_DMA_INTR_ENAB_ETE BIT(10)
166
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
295
+/* Receive Watchdog Timout Enable */
167
- }
296
+#define NPCM_DMA_INTR_ENAB_RWE BIT(9)
168
- phy_update_irq(s);
297
+/* Receive Process Stopped Enable */
169
-}
298
+#define NPCM_DMA_INTR_ENAB_RSE BIT(8)
170
-
299
+/* Receive Buffer Unavailable Enable */
171
static void lan9118_set_link(NetClientState *nc)
300
+#define NPCM_DMA_INTR_ENAB_RUE BIT(7)
172
{
301
+/* Receive Interrupt Enable */
173
- phy_update_link(qemu_get_nic_opaque(nc));
302
+#define NPCM_DMA_INTR_ENAB_RIE BIT(6)
174
-}
303
+/* Transmit Underflow Enable */
175
-
304
+#define NPCM_DMA_INTR_ENAB_UNE BIT(5)
176
-static void phy_reset(lan9118_state *s)
305
+/* Receive Overflow Enable */
177
-{
306
+#define NPCM_DMA_INTR_ENAB_OVE BIT(4)
178
- s->phy_status = 0x7809;
307
+/* Transmit Jabber Timeout Enable */
179
- s->phy_control = 0x3000;
308
+#define NPCM_DMA_INTR_ENAB_TJE BIT(3)
180
- s->phy_advertise = 0x01e1;
309
+/* Transmit Buffer Unavailable Enable */
181
- s->phy_int_mask = 0;
310
+#define NPCM_DMA_INTR_ENAB_TUE BIT(2)
182
- s->phy_int = 0;
311
+/* Transmit Process Stopped Enable */
183
- phy_update_link(s);
312
+#define NPCM_DMA_INTR_ENAB_TSE BIT(1)
184
+ lan9118_phy_update_link(&LAN9118(qemu_get_nic_opaque(nc))->mii,
313
+/* Transmit Interrupt Enable */
185
+ nc->link_down);
314
+#define NPCM_DMA_INTR_ENAB_TIE BIT(0)
186
}
315
+
187
316
+/* Normal Interrupt Summary Enable */
188
static void lan9118_reset(DeviceState *d)
317
+#define NPCM_DMA_INTR_ENAB_NIE BIT(16)
189
@@ -XXX,XX +XXX,XX @@ static void lan9118_reset(DeviceState *d)
318
+/* Interrupts enabled by NIE Enable */
190
s->read_word_n = 0;
319
+#define NPCM_DMA_INTR_ENAB_NIE_BITS (NPCM_DMA_INTR_ENAB_TIE | \
191
s->write_word_n = 0;
320
+ NPCM_DMA_INTR_ENAB_TUE | \
192
321
+ NPCM_DMA_INTR_ENAB_RIE | \
193
- phy_reset(s);
322
+ NPCM_DMA_INTR_ENAB_ERE)
194
-
323
+/* Abnormal Interrupt Summary Enable */
195
s->eeprom_writable = 0;
324
+#define NPCM_DMA_INTR_ENAB_AIE BIT(15)
196
lan9118_reload_eeprom(s);
325
+/* Interrupts enabled by AIE Enable */
197
}
326
+#define NPCM_DMA_INTR_ENAB_AIE_BITS (NPCM_DMA_INTR_ENAB_TSE | \
198
@@ -XXX,XX +XXX,XX @@ static void do_tx_packet(lan9118_state *s)
327
+ NPCM_DMA_INTR_ENAB_TJE | \
199
uint32_t status;
328
+ NPCM_DMA_INTR_ENAB_OVE | \
200
329
+ NPCM_DMA_INTR_ENAB_UNE | \
201
/* FIXME: Honor TX disable, and allow queueing of packets. */
330
+ NPCM_DMA_INTR_ENAB_RUE | \
202
- if (s->phy_control & 0x4000) {
331
+ NPCM_DMA_INTR_ENAB_RSE | \
203
+ if (s->mii.control & 0x4000) {
332
+ NPCM_DMA_INTR_ENAB_RWE | \
204
/* This assumes the receive routine doesn't touch the VLANClient. */
333
+ NPCM_DMA_INTR_ENAB_ETE | \
205
qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
334
+ NPCM_DMA_INTR_ENAB_FBE)
206
} else {
335
+
207
@@ -XXX,XX +XXX,XX @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
336
+/* Flushing Disabled */
208
}
337
+#define NPCM_DMA_CONTROL_FLUSH_MASK BIT(24)
209
}
338
+/* Start/stop Transmit */
210
339
+#define NPCM_DMA_CONTROL_START_STOP_TX BIT(13)
211
-static uint32_t do_phy_read(lan9118_state *s, int reg)
340
+/* Start/stop Receive */
212
-{
341
+#define NPCM_DMA_CONTROL_START_STOP_RX BIT(1)
213
- uint32_t val;
342
+/* Next receive descriptor start address */
214
-
343
+#define NPCM_DMA_HOST_RX_DESC_MASK(word) ((uint32_t) (word) & ~3u)
215
- switch (reg) {
344
+/* Next transmit descriptor start address */
216
- case 0: /* Basic Control */
345
+#define NPCM_DMA_HOST_TX_DESC_MASK(word) ((uint32_t) (word) & ~3u)
217
- return s->phy_control;
346
+
218
- case 1: /* Basic Status */
347
+/* Receive enable */
219
- return s->phy_status;
348
+#define NPCM_GMAC_MAC_CONFIG_RX_EN BIT(2)
220
- case 2: /* ID1 */
349
+/* Transmit enable */
221
- return 0x0007;
350
+#define NPCM_GMAC_MAC_CONFIG_TX_EN BIT(3)
222
- case 3: /* ID2 */
351
+
223
- return 0xc0d1;
352
+/* Frame Receive All */
224
- case 4: /* Auto-neg advertisement */
353
+#define NPCM_GMAC_FRAME_FILTER_REC_ALL_MASK BIT(31)
225
- return s->phy_advertise;
354
+/* Frame HPF Filter*/
226
- case 5: /* Auto-neg Link Partner Ability */
355
+#define NPCM_GMAC_FRAME_FILTER_HPF_MASK BIT(10)
227
- return 0x0f71;
356
+/* Frame SAF Filter*/
228
- case 6: /* Auto-neg Expansion */
357
+#define NPCM_GMAC_FRAME_FILTER_SAF_MASK BIT(9)
229
- return 1;
358
+/* Frame SAIF Filter*/
230
- /* TODO 17, 18, 27, 29, 30, 31 */
359
+#define NPCM_GMAC_FRAME_FILTER_SAIF_MASK BIT(8)
231
- case 29: /* Interrupt source. */
360
+/* Frame PCF Filter*/
232
- val = s->phy_int;
361
+#define NPCM_GMAC_FRAME_FILTER_PCF_MASK BIT(word) extract32((word), 6, 2)
233
- s->phy_int = 0;
362
+/* Frame DBF Filter*/
234
- phy_update_irq(s);
363
+#define NPCM_GMAC_FRAME_FILTER_DBF_MASK BIT(5)
235
- return val;
364
+/* Frame PM Filter*/
236
- case 30: /* Interrupt mask */
365
+#define NPCM_GMAC_FRAME_FILTER_PM_MASK BIT(4)
237
- return s->phy_int_mask;
366
+/* Frame DAIF Filter*/
238
- default:
367
+#define NPCM_GMAC_FRAME_FILTER_DAIF_MASK BIT(3)
239
- qemu_log_mask(LOG_GUEST_ERROR,
368
+/* Frame HMC Filter*/
240
- "do_phy_read: PHY read reg %d\n", reg);
369
+#define NPCM_GMAC_FRAME_FILTER_HMC_MASK BIT(2)
241
- return 0;
370
+/* Frame HUC Filter*/
242
- }
371
+#define NPCM_GMAC_FRAME_FILTER_HUC_MASK BIT(1)
243
-}
372
+/* Frame PR Filter*/
244
-
373
+#define NPCM_GMAC_FRAME_FILTER_PR_MASK BIT(0)
245
-static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
374
+
246
-{
375
+#endif /* NPCM_GMAC_H */
247
- switch (reg) {
376
diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
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
377
new file mode 100644
312
new file mode 100644
378
index XXXXXXX..XXXXXXX
313
index XXXXXXX..XXXXXXX
379
--- /dev/null
314
--- /dev/null
380
+++ b/hw/net/npcm_gmac.c
315
+++ b/hw/net/lan9118_phy.c
381
@@ -XXX,XX +XXX,XX @@
316
@@ -XXX,XX +XXX,XX @@
382
+/*
317
+/*
383
+ * Nuvoton NPCM7xx/8xx GMAC Module
318
+ * SMSC LAN9118 PHY emulation
384
+ *
319
+ *
385
+ * Copyright 2024 Google LLC
320
+ * Copyright (c) 2009 CodeSourcery, LLC.
386
+ * Authors:
321
+ * Written by Paul Brook
387
+ * Hao Wu <wuhaotsh@google.com>
388
+ * Nabih Estefan <nabihestefan@google.com>
389
+ *
322
+ *
390
+ * This program is free software; you can redistribute it and/or modify it
323
+ * This code is licensed under the GNU GPL v2
391
+ * under the terms of the GNU General Public License as published by the
392
+ * Free Software Foundation; either version 2 of the License, or
393
+ * (at your option) any later version.
394
+ *
324
+ *
395
+ * This program is distributed in the hope that it will be useful, but WITHOUT
325
+ * Contributions after 2012-01-13 are licensed under the terms of the
396
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
326
+ * GNU GPL, version 2 or (at your option) any later version.
397
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
398
+ * for more details.
399
+ *
400
+ * Unsupported/unimplemented features:
401
+ * - MII is not implemented, MII_ADDR.BUSY and MII_DATA always return zero
402
+ * - Precision timestamp (PTP) is not implemented.
403
+ */
327
+ */
404
+
328
+
405
+#include "qemu/osdep.h"
329
+#include "qemu/osdep.h"
406
+
330
+#include "hw/net/lan9118_phy.h"
407
+#include "hw/registerfields.h"
331
+#include "hw/irq.h"
408
+#include "hw/net/mii.h"
332
+#include "hw/resettable.h"
409
+#include "hw/net/npcm_gmac.h"
410
+#include "migration/vmstate.h"
333
+#include "migration/vmstate.h"
411
+#include "qemu/log.h"
334
+#include "qemu/log.h"
412
+#include "qemu/units.h"
335
+
413
+#include "sysemu/dma.h"
336
+#define PHY_INT_ENERGYON (1 << 7)
414
+#include "trace.h"
337
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
415
+
338
+#define PHY_INT_FAULT (1 << 5)
416
+REG32(NPCM_DMA_BUS_MODE, 0x1000)
339
+#define PHY_INT_DOWN (1 << 4)
417
+REG32(NPCM_DMA_XMT_POLL_DEMAND, 0x1004)
340
+#define PHY_INT_AUTONEG_LP (1 << 3)
418
+REG32(NPCM_DMA_RCV_POLL_DEMAND, 0x1008)
341
+#define PHY_INT_PARFAULT (1 << 2)
419
+REG32(NPCM_DMA_RX_BASE_ADDR, 0x100c)
342
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
420
+REG32(NPCM_DMA_TX_BASE_ADDR, 0x1010)
343
+
421
+REG32(NPCM_DMA_STATUS, 0x1014)
344
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
422
+REG32(NPCM_DMA_CONTROL, 0x1018)
345
+{
423
+REG32(NPCM_DMA_INTR_ENA, 0x101c)
346
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
424
+REG32(NPCM_DMA_MISSED_FRAME_CTR, 0x1020)
347
+}
425
+REG32(NPCM_DMA_HOST_TX_DESC, 0x1048)
348
+
426
+REG32(NPCM_DMA_HOST_RX_DESC, 0x104c)
349
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
427
+REG32(NPCM_DMA_CUR_TX_BUF_ADDR, 0x1050)
350
+{
428
+REG32(NPCM_DMA_CUR_RX_BUF_ADDR, 0x1054)
351
+ uint16_t val;
429
+REG32(NPCM_DMA_HW_FEATURE, 0x1058)
352
+
430
+
353
+ switch (reg) {
431
+REG32(NPCM_GMAC_MAC_CONFIG, 0x0)
354
+ case 0: /* Basic Control */
432
+REG32(NPCM_GMAC_FRAME_FILTER, 0x4)
355
+ return s->control;
433
+REG32(NPCM_GMAC_HASH_HIGH, 0x8)
356
+ case 1: /* Basic Status */
434
+REG32(NPCM_GMAC_HASH_LOW, 0xc)
357
+ return s->status;
435
+REG32(NPCM_GMAC_MII_ADDR, 0x10)
358
+ case 2: /* ID1 */
436
+REG32(NPCM_GMAC_MII_DATA, 0x14)
359
+ return 0x0007;
437
+REG32(NPCM_GMAC_FLOW_CTRL, 0x18)
360
+ case 3: /* ID2 */
438
+REG32(NPCM_GMAC_VLAN_FLAG, 0x1c)
361
+ return 0xc0d1;
439
+REG32(NPCM_GMAC_VERSION, 0x20)
362
+ case 4: /* Auto-neg advertisement */
440
+REG32(NPCM_GMAC_WAKEUP_FILTER, 0x28)
363
+ return s->advertise;
441
+REG32(NPCM_GMAC_PMT, 0x2c)
364
+ case 5: /* Auto-neg Link Partner Ability */
442
+REG32(NPCM_GMAC_LPI_CTRL, 0x30)
365
+ return 0x0f71;
443
+REG32(NPCM_GMAC_TIMER_CTRL, 0x34)
366
+ case 6: /* Auto-neg Expansion */
444
+REG32(NPCM_GMAC_INT_STATUS, 0x38)
367
+ return 1;
445
+REG32(NPCM_GMAC_INT_MASK, 0x3c)
368
+ /* TODO 17, 18, 27, 29, 30, 31 */
446
+REG32(NPCM_GMAC_MAC0_ADDR_HI, 0x40)
369
+ case 29: /* Interrupt source. */
447
+REG32(NPCM_GMAC_MAC0_ADDR_LO, 0x44)
370
+ val = s->ints;
448
+REG32(NPCM_GMAC_MAC1_ADDR_HI, 0x48)
371
+ s->ints = 0;
449
+REG32(NPCM_GMAC_MAC1_ADDR_LO, 0x4c)
372
+ lan9118_phy_update_irq(s);
450
+REG32(NPCM_GMAC_MAC2_ADDR_HI, 0x50)
373
+ return val;
451
+REG32(NPCM_GMAC_MAC2_ADDR_LO, 0x54)
374
+ case 30: /* Interrupt mask */
452
+REG32(NPCM_GMAC_MAC3_ADDR_HI, 0x58)
375
+ return s->int_mask;
453
+REG32(NPCM_GMAC_MAC3_ADDR_LO, 0x5c)
376
+ default:
454
+REG32(NPCM_GMAC_RGMII_STATUS, 0xd8)
377
+ qemu_log_mask(LOG_GUEST_ERROR,
455
+REG32(NPCM_GMAC_WATCHDOG, 0xdc)
378
+ "lan9118_phy_read: PHY read reg %d\n", reg);
456
+REG32(NPCM_GMAC_PTP_TCR, 0x700)
379
+ return 0;
457
+REG32(NPCM_GMAC_PTP_SSIR, 0x704)
458
+REG32(NPCM_GMAC_PTP_STSR, 0x708)
459
+REG32(NPCM_GMAC_PTP_STNSR, 0x70c)
460
+REG32(NPCM_GMAC_PTP_STSUR, 0x710)
461
+REG32(NPCM_GMAC_PTP_STNSUR, 0x714)
462
+REG32(NPCM_GMAC_PTP_TAR, 0x718)
463
+REG32(NPCM_GMAC_PTP_TTSR, 0x71c)
464
+
465
+/* Register Fields */
466
+#define NPCM_GMAC_MII_ADDR_BUSY BIT(0)
467
+#define NPCM_GMAC_MII_ADDR_WRITE BIT(1)
468
+#define NPCM_GMAC_MII_ADDR_GR(rv) extract16((rv), 6, 5)
469
+#define NPCM_GMAC_MII_ADDR_PA(rv) extract16((rv), 11, 5)
470
+
471
+#define NPCM_GMAC_INT_MASK_LPIIM BIT(10)
472
+#define NPCM_GMAC_INT_MASK_PMTM BIT(3)
473
+#define NPCM_GMAC_INT_MASK_RGIM BIT(0)
474
+
475
+#define NPCM_DMA_BUS_MODE_SWR BIT(0)
476
+
477
+static const uint32_t npcm_gmac_cold_reset_values[NPCM_GMAC_NR_REGS] = {
478
+ /* Reduce version to 3.2 so that the kernel can enable interrupt. */
479
+ [R_NPCM_GMAC_VERSION] = 0x00001032,
480
+ [R_NPCM_GMAC_TIMER_CTRL] = 0x03e80000,
481
+ [R_NPCM_GMAC_MAC0_ADDR_HI] = 0x8000ffff,
482
+ [R_NPCM_GMAC_MAC0_ADDR_LO] = 0xffffffff,
483
+ [R_NPCM_GMAC_MAC1_ADDR_HI] = 0x0000ffff,
484
+ [R_NPCM_GMAC_MAC1_ADDR_LO] = 0xffffffff,
485
+ [R_NPCM_GMAC_MAC2_ADDR_HI] = 0x0000ffff,
486
+ [R_NPCM_GMAC_MAC2_ADDR_LO] = 0xffffffff,
487
+ [R_NPCM_GMAC_MAC3_ADDR_HI] = 0x0000ffff,
488
+ [R_NPCM_GMAC_MAC3_ADDR_LO] = 0xffffffff,
489
+ [R_NPCM_GMAC_PTP_TCR] = 0x00002000,
490
+ [R_NPCM_DMA_BUS_MODE] = 0x00020101,
491
+ [R_NPCM_DMA_HW_FEATURE] = 0x100d4f37,
492
+};
493
+
494
+static const uint16_t phy_reg_init[] = {
495
+ [MII_BMCR] = MII_BMCR_AUTOEN | MII_BMCR_FD | MII_BMCR_SPEED1000,
496
+ [MII_BMSR] = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD |
497
+ MII_BMSR_10T_HD | MII_BMSR_EXTSTAT | MII_BMSR_AUTONEG |
498
+ MII_BMSR_LINK_ST | MII_BMSR_EXTCAP,
499
+ [MII_PHYID1] = 0x0362,
500
+ [MII_PHYID2] = 0x5e6a,
501
+ [MII_ANAR] = MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD |
502
+ MII_ANAR_10 | MII_ANAR_CSMACD,
503
+ [MII_ANLPAR] = MII_ANLPAR_ACK | MII_ANLPAR_PAUSE |
504
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
505
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD,
506
+ [MII_ANER] = 0x64 | MII_ANER_NWAY,
507
+ [MII_ANNP] = 0x2001,
508
+ [MII_CTRL1000] = MII_CTRL1000_FULL,
509
+ [MII_STAT1000] = MII_STAT1000_FULL,
510
+ [MII_EXTSTAT] = 0x3000, /* 1000BASTE_T full-duplex capable */
511
+};
512
+
513
+static void npcm_gmac_soft_reset(NPCMGMACState *gmac)
514
+{
515
+ memcpy(gmac->regs, npcm_gmac_cold_reset_values,
516
+ NPCM_GMAC_NR_REGS * sizeof(uint32_t));
517
+ /* Clear reset bits */
518
+ gmac->regs[R_NPCM_DMA_BUS_MODE] &= ~NPCM_DMA_BUS_MODE_SWR;
519
+}
520
+
521
+static void gmac_phy_set_link(NPCMGMACState *gmac, bool active)
522
+{
523
+ /* Autonegotiation status mirrors link status. */
524
+ if (active) {
525
+ gmac->phy_regs[0][MII_BMSR] |= (MII_BMSR_LINK_ST | MII_BMSR_AN_COMP);
526
+ } else {
527
+ gmac->phy_regs[0][MII_BMSR] &= ~(MII_BMSR_LINK_ST | MII_BMSR_AN_COMP);
528
+ }
380
+ }
529
+}
381
+}
530
+
382
+
531
+static bool gmac_can_receive(NetClientState *nc)
383
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
532
+{
384
+{
533
+ return true;
385
+ switch (reg) {
534
+}
386
+ case 0: /* Basic Control */
535
+
387
+ if (val & 0x8000) {
536
+/*
388
+ lan9118_phy_reset(s);
537
+ * Function that updates the GMAC IRQ
389
+ break;
538
+ * It find the logical OR of the enabled bits for NIS (if enabled)
539
+ * It find the logical OR of the enabled bits for AIS (if enabled)
540
+ */
541
+static void gmac_update_irq(NPCMGMACState *gmac)
542
+{
543
+ /*
544
+ * Check if the normal interrupts summary is enabled
545
+ * if so, add the bits for the summary that are enabled
546
+ */
547
+ if (gmac->regs[R_NPCM_DMA_INTR_ENA] & gmac->regs[R_NPCM_DMA_STATUS] &
548
+ (NPCM_DMA_INTR_ENAB_NIE_BITS)) {
549
+ gmac->regs[R_NPCM_DMA_STATUS] |= NPCM_DMA_STATUS_NIS;
550
+ }
551
+ /*
552
+ * Check if the abnormal interrupts summary is enabled
553
+ * if so, add the bits for the summary that are enabled
554
+ */
555
+ if (gmac->regs[R_NPCM_DMA_INTR_ENA] & gmac->regs[R_NPCM_DMA_STATUS] &
556
+ (NPCM_DMA_INTR_ENAB_AIE_BITS)) {
557
+ gmac->regs[R_NPCM_DMA_STATUS] |= NPCM_DMA_STATUS_AIS;
558
+ }
559
+
560
+ /* Get the logical OR of both normal and abnormal interrupts */
561
+ int level = !!((gmac->regs[R_NPCM_DMA_STATUS] &
562
+ gmac->regs[R_NPCM_DMA_INTR_ENA] &
563
+ NPCM_DMA_STATUS_NIS) |
564
+ (gmac->regs[R_NPCM_DMA_STATUS] &
565
+ gmac->regs[R_NPCM_DMA_INTR_ENA] &
566
+ NPCM_DMA_STATUS_AIS));
567
+
568
+ /* Set the IRQ */
569
+ trace_npcm_gmac_update_irq(DEVICE(gmac)->canonical_path,
570
+ gmac->regs[R_NPCM_DMA_STATUS],
571
+ gmac->regs[R_NPCM_DMA_INTR_ENA],
572
+ level);
573
+ qemu_set_irq(gmac->irq, level);
574
+}
575
+
576
+static ssize_t gmac_receive(NetClientState *nc, const uint8_t *buf, size_t len)
577
+{
578
+ /* Placeholder. Function will be filled in following patches */
579
+ return 0;
580
+}
581
+
582
+static void gmac_cleanup(NetClientState *nc)
583
+{
584
+ /* Nothing to do yet. */
585
+}
586
+
587
+static void gmac_set_link(NetClientState *nc)
588
+{
589
+ NPCMGMACState *gmac = qemu_get_nic_opaque(nc);
590
+
591
+ trace_npcm_gmac_set_link(!nc->link_down);
592
+ gmac_phy_set_link(gmac, !nc->link_down);
593
+}
594
+
595
+static void npcm_gmac_mdio_access(NPCMGMACState *gmac, uint16_t v)
596
+{
597
+ bool busy = v & NPCM_GMAC_MII_ADDR_BUSY;
598
+ uint8_t is_write;
599
+ uint8_t pa, gr;
600
+ uint16_t data;
601
+
602
+ if (busy) {
603
+ is_write = v & NPCM_GMAC_MII_ADDR_WRITE;
604
+ pa = NPCM_GMAC_MII_ADDR_PA(v);
605
+ gr = NPCM_GMAC_MII_ADDR_GR(v);
606
+ /* Both pa and gr are 5 bits, so they are less than 32. */
607
+ g_assert(pa < NPCM_GMAC_MAX_PHYS);
608
+ g_assert(gr < NPCM_GMAC_MAX_PHY_REGS);
609
+
610
+
611
+ if (v & NPCM_GMAC_MII_ADDR_WRITE) {
612
+ data = gmac->regs[R_NPCM_GMAC_MII_DATA];
613
+ /* Clear reset bit for BMCR register */
614
+ switch (gr) {
615
+ case MII_BMCR:
616
+ data &= ~MII_BMCR_RESET;
617
+ /* Autonegotiation is a W1C bit*/
618
+ if (data & MII_BMCR_ANRESTART) {
619
+ /* Tells autonegotiation to not restart again */
620
+ data &= ~MII_BMCR_ANRESTART;
621
+ }
622
+ if ((data & MII_BMCR_AUTOEN) &&
623
+ !(gmac->phy_regs[pa][MII_BMSR] & MII_BMSR_AN_COMP)) {
624
+ /* sets autonegotiation as complete */
625
+ gmac->phy_regs[pa][MII_BMSR] |= MII_BMSR_AN_COMP;
626
+ /* Resolve AN automatically->need to set this */
627
+ gmac->phy_regs[0][MII_ANLPAR] = 0x0000;
628
+ }
629
+ }
630
+ gmac->phy_regs[pa][gr] = data;
631
+ } else {
632
+ data = gmac->phy_regs[pa][gr];
633
+ gmac->regs[R_NPCM_GMAC_MII_DATA] = data;
634
+ }
390
+ }
635
+ trace_npcm_gmac_mdio_access(DEVICE(gmac)->canonical_path, is_write, pa,
391
+ s->control = val & 0x7980;
636
+ gr, data);
392
+ /* Complete autonegotiation immediately. */
637
+ }
393
+ if (val & 0x1000) {
638
+ gmac->regs[R_NPCM_GMAC_MII_ADDR] = v & ~NPCM_GMAC_MII_ADDR_BUSY;
394
+ s->status |= 0x0020;
639
+}
640
+
641
+static uint64_t npcm_gmac_read(void *opaque, hwaddr offset, unsigned size)
642
+{
643
+ NPCMGMACState *gmac = opaque;
644
+ uint32_t v = 0;
645
+
646
+ switch (offset) {
647
+ /* Write only registers */
648
+ case A_NPCM_DMA_XMT_POLL_DEMAND:
649
+ case A_NPCM_DMA_RCV_POLL_DEMAND:
650
+ qemu_log_mask(LOG_GUEST_ERROR,
651
+ "%s: Read of write-only reg: offset: 0x%04" HWADDR_PRIx
652
+ "\n", DEVICE(gmac)->canonical_path, offset);
653
+ break;
654
+
655
+ default:
656
+ v = gmac->regs[offset / sizeof(uint32_t)];
657
+ }
658
+
659
+ trace_npcm_gmac_reg_read(DEVICE(gmac)->canonical_path, offset, v);
660
+ return v;
661
+}
662
+
663
+static void npcm_gmac_write(void *opaque, hwaddr offset,
664
+ uint64_t v, unsigned size)
665
+{
666
+ NPCMGMACState *gmac = opaque;
667
+
668
+ trace_npcm_gmac_reg_write(DEVICE(gmac)->canonical_path, offset, v);
669
+
670
+ switch (offset) {
671
+ /* Read only registers */
672
+ case A_NPCM_GMAC_VERSION:
673
+ case A_NPCM_GMAC_INT_STATUS:
674
+ case A_NPCM_GMAC_RGMII_STATUS:
675
+ case A_NPCM_GMAC_PTP_STSR:
676
+ case A_NPCM_GMAC_PTP_STNSR:
677
+ case A_NPCM_DMA_MISSED_FRAME_CTR:
678
+ case A_NPCM_DMA_HOST_TX_DESC:
679
+ case A_NPCM_DMA_HOST_RX_DESC:
680
+ case A_NPCM_DMA_CUR_TX_BUF_ADDR:
681
+ case A_NPCM_DMA_CUR_RX_BUF_ADDR:
682
+ case A_NPCM_DMA_HW_FEATURE:
683
+ qemu_log_mask(LOG_GUEST_ERROR,
684
+ "%s: Write of read-only reg: offset: 0x%04" HWADDR_PRIx
685
+ ", value: 0x%04" PRIx64 "\n",
686
+ DEVICE(gmac)->canonical_path, offset, v);
687
+ break;
688
+
689
+ case A_NPCM_GMAC_MAC_CONFIG:
690
+ break;
691
+
692
+ case A_NPCM_GMAC_MII_ADDR:
693
+ npcm_gmac_mdio_access(gmac, v);
694
+ break;
695
+
696
+ case A_NPCM_GMAC_MAC0_ADDR_HI:
697
+ gmac->regs[offset / sizeof(uint32_t)] = v;
698
+ gmac->conf.macaddr.a[0] = v >> 8;
699
+ gmac->conf.macaddr.a[1] = v >> 0;
700
+ break;
701
+
702
+ case A_NPCM_GMAC_MAC0_ADDR_LO:
703
+ gmac->regs[offset / sizeof(uint32_t)] = v;
704
+ gmac->conf.macaddr.a[2] = v >> 24;
705
+ gmac->conf.macaddr.a[3] = v >> 16;
706
+ gmac->conf.macaddr.a[4] = v >> 8;
707
+ gmac->conf.macaddr.a[5] = v >> 0;
708
+ break;
709
+
710
+ case A_NPCM_GMAC_MAC1_ADDR_HI:
711
+ case A_NPCM_GMAC_MAC1_ADDR_LO:
712
+ case A_NPCM_GMAC_MAC2_ADDR_HI:
713
+ case A_NPCM_GMAC_MAC2_ADDR_LO:
714
+ case A_NPCM_GMAC_MAC3_ADDR_HI:
715
+ case A_NPCM_GMAC_MAC3_ADDR_LO:
716
+ gmac->regs[offset / sizeof(uint32_t)] = v;
717
+ qemu_log_mask(LOG_UNIMP,
718
+ "%s: Only MAC Address 0 is supported. This request "
719
+ "is ignored.\n", DEVICE(gmac)->canonical_path);
720
+ break;
721
+
722
+ case A_NPCM_DMA_BUS_MODE:
723
+ gmac->regs[offset / sizeof(uint32_t)] = v;
724
+ if (v & NPCM_DMA_BUS_MODE_SWR) {
725
+ npcm_gmac_soft_reset(gmac);
726
+ }
395
+ }
727
+ break;
396
+ break;
728
+
397
+ case 4: /* Auto-neg advertisement */
729
+ case A_NPCM_DMA_RCV_POLL_DEMAND:
398
+ s->advertise = (val & 0x2d7f) | 0x80;
730
+ /* We dont actually care about the value */
731
+ break;
399
+ break;
732
+
400
+ /* TODO 17, 18, 27, 31 */
733
+ case A_NPCM_DMA_STATUS:
401
+ case 30: /* Interrupt mask */
734
+ /* Check that RO bits are not written to */
402
+ s->int_mask = val & 0xff;
735
+ if (NPCM_DMA_STATUS_RO_MASK(v)) {
403
+ lan9118_phy_update_irq(s);
736
+ qemu_log_mask(LOG_GUEST_ERROR,
737
+ "%s: Write of read-only bits of reg: offset: 0x%04"
738
+ HWADDR_PRIx ", value: 0x%04" PRIx64 "\n",
739
+ DEVICE(gmac)->canonical_path, offset, v);
740
+ }
741
+ break;
404
+ break;
742
+
743
+ default:
405
+ default:
744
+ gmac->regs[offset / sizeof(uint32_t)] = v;
406
+ qemu_log_mask(LOG_GUEST_ERROR,
745
+ break;
407
+ "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
746
+ }
408
+ }
747
+
409
+}
748
+ gmac_update_irq(gmac);
410
+
749
+}
411
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
750
+
412
+{
751
+static void npcm_gmac_reset(DeviceState *dev)
413
+ s->link_down = link_down;
752
+{
414
+
753
+ NPCMGMACState *gmac = NPCM_GMAC(dev);
415
+ /* Autonegotiation status mirrors link status. */
754
+
416
+ if (link_down) {
755
+ npcm_gmac_soft_reset(gmac);
417
+ s->status &= ~0x0024;
756
+ memcpy(gmac->phy_regs[0], phy_reg_init, sizeof(phy_reg_init));
418
+ s->ints |= PHY_INT_DOWN;
757
+
419
+ } else {
758
+ trace_npcm_gmac_reset(DEVICE(gmac)->canonical_path,
420
+ s->status |= 0x0024;
759
+ gmac->phy_regs[0][MII_BMSR]);
421
+ s->ints |= PHY_INT_ENERGYON;
760
+}
422
+ s->ints |= PHY_INT_AUTONEG_COMPLETE;
761
+
423
+ }
762
+static NetClientInfo net_npcm_gmac_info = {
424
+ lan9118_phy_update_irq(s);
763
+ .type = NET_CLIENT_DRIVER_NIC,
425
+}
764
+ .size = sizeof(NICState),
426
+
765
+ .can_receive = gmac_can_receive,
427
+void lan9118_phy_reset(Lan9118PhyState *s)
766
+ .receive = gmac_receive,
428
+{
767
+ .cleanup = gmac_cleanup,
429
+ s->control = 0x3000;
768
+ .link_status_changed = gmac_set_link,
430
+ s->status = 0x7809;
431
+ s->advertise = 0x01e1;
432
+ s->int_mask = 0;
433
+ s->ints = 0;
434
+ lan9118_phy_update_link(s, s->link_down);
435
+}
436
+
437
+static void lan9118_phy_reset_hold(Object *obj, ResetType type)
438
+{
439
+ Lan9118PhyState *s = LAN9118_PHY(obj);
440
+
441
+ lan9118_phy_reset(s);
442
+}
443
+
444
+static void lan9118_phy_init(Object *obj)
445
+{
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()
463
+ }
769
+};
464
+};
770
+
465
+
771
+static const struct MemoryRegionOps npcm_gmac_ops = {
466
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
772
+ .read = npcm_gmac_read,
467
+{
773
+ .write = npcm_gmac_write,
468
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
774
+ .endianness = DEVICE_LITTLE_ENDIAN,
469
+ DeviceClass *dc = DEVICE_CLASS(klass);
775
+ .valid = {
470
+
776
+ .min_access_size = 4,
471
+ rc->phases.hold = lan9118_phy_reset_hold;
777
+ .max_access_size = 4,
472
+ dc->vmsd = &vmstate_lan9118_phy;
778
+ .unaligned = false,
473
+}
779
+ },
474
+
475
+static const TypeInfo types[] = {
476
+ {
477
+ .name = TYPE_LAN9118_PHY,
478
+ .parent = TYPE_SYS_BUS_DEVICE,
479
+ .instance_size = sizeof(Lan9118PhyState),
480
+ .instance_init = lan9118_phy_init,
481
+ .class_init = lan9118_phy_class_init,
482
+ }
780
+};
483
+};
781
+
484
+
782
+static void npcm_gmac_realize(DeviceState *dev, Error **errp)
485
+DEFINE_TYPES(types)
783
+{
486
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
784
+ NPCMGMACState *gmac = NPCM_GMAC(dev);
487
index XXXXXXX..XXXXXXX 100644
785
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
488
--- a/hw/net/Kconfig
786
+
489
+++ b/hw/net/Kconfig
787
+ memory_region_init_io(&gmac->iomem, OBJECT(gmac), &npcm_gmac_ops, gmac,
490
@@ -XXX,XX +XXX,XX @@ config VMXNET3_PCI
788
+ TYPE_NPCM_GMAC, 8 * KiB);
491
config SMC91C111
789
+ sysbus_init_mmio(sbd, &gmac->iomem);
492
bool
790
+ sysbus_init_irq(sbd, &gmac->irq);
493
791
+
494
+config LAN9118_PHY
792
+ qemu_macaddr_default_if_unset(&gmac->conf.macaddr);
495
+ bool
793
+
496
+
794
+ gmac->nic = qemu_new_nic(&net_npcm_gmac_info, &gmac->conf, TYPE_NPCM_GMAC,
497
config LAN9118
795
+ dev->id, &dev->mem_reentrancy_guard, gmac);
498
bool
796
+ qemu_format_nic_info_str(qemu_get_queue(gmac->nic), gmac->conf.macaddr.a);
499
+ select LAN9118_PHY
797
+ gmac->regs[R_NPCM_GMAC_MAC0_ADDR_HI] = (gmac->conf.macaddr.a[0] << 8) + \
500
select PTIMER
798
+ gmac->conf.macaddr.a[1];
501
799
+ gmac->regs[R_NPCM_GMAC_MAC0_ADDR_LO] = (gmac->conf.macaddr.a[2] << 24) + \
502
config NE2000_ISA
800
+ (gmac->conf.macaddr.a[3] << 16) + \
801
+ (gmac->conf.macaddr.a[4] << 8) + \
802
+ gmac->conf.macaddr.a[5];
803
+}
804
+
805
+static void npcm_gmac_unrealize(DeviceState *dev)
806
+{
807
+ NPCMGMACState *gmac = NPCM_GMAC(dev);
808
+
809
+ qemu_del_nic(gmac->nic);
810
+}
811
+
812
+static const VMStateDescription vmstate_npcm_gmac = {
813
+ .name = TYPE_NPCM_GMAC,
814
+ .version_id = 0,
815
+ .minimum_version_id = 0,
816
+ .fields = (VMStateField[]) {
817
+ VMSTATE_UINT32_ARRAY(regs, NPCMGMACState, NPCM_GMAC_NR_REGS),
818
+ VMSTATE_END_OF_LIST(),
819
+ },
820
+};
821
+
822
+static Property npcm_gmac_properties[] = {
823
+ DEFINE_NIC_PROPERTIES(NPCMGMACState, conf),
824
+ DEFINE_PROP_END_OF_LIST(),
825
+};
826
+
827
+static void npcm_gmac_class_init(ObjectClass *klass, void *data)
828
+{
829
+ DeviceClass *dc = DEVICE_CLASS(klass);
830
+
831
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
832
+ dc->desc = "NPCM GMAC Controller";
833
+ dc->realize = npcm_gmac_realize;
834
+ dc->unrealize = npcm_gmac_unrealize;
835
+ dc->reset = npcm_gmac_reset;
836
+ dc->vmsd = &vmstate_npcm_gmac;
837
+ device_class_set_props(dc, npcm_gmac_properties);
838
+}
839
+
840
+static const TypeInfo npcm_gmac_types[] = {
841
+ {
842
+ .name = TYPE_NPCM_GMAC,
843
+ .parent = TYPE_SYS_BUS_DEVICE,
844
+ .instance_size = sizeof(NPCMGMACState),
845
+ .class_init = npcm_gmac_class_init,
846
+ },
847
+};
848
+DEFINE_TYPES(npcm_gmac_types)
849
diff --git a/hw/net/meson.build b/hw/net/meson.build
503
diff --git a/hw/net/meson.build b/hw/net/meson.build
850
index XXXXXXX..XXXXXXX 100644
504
index XXXXXXX..XXXXXXX 100644
851
--- a/hw/net/meson.build
505
--- a/hw/net/meson.build
852
+++ b/hw/net/meson.build
506
+++ b/hw/net/meson.build
853
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_I82596_COMMON', if_true: files('i82596.c'))
507
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('vmxnet3.c'))
854
system_ss.add(when: 'CONFIG_SUNHME', if_true: files('sunhme.c'))
508
855
system_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
509
system_ss.add(when: 'CONFIG_SMC91C111', if_true: files('smc91c111.c'))
856
system_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
510
system_ss.add(when: 'CONFIG_LAN9118', if_true: files('lan9118.c'))
857
-system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c'))
511
+system_ss.add(when: 'CONFIG_LAN9118_PHY', if_true: files('lan9118_phy.c'))
858
+system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c', 'npcm_gmac.c'))
512
system_ss.add(when: 'CONFIG_NE2000_ISA', if_true: files('ne2000-isa.c'))
859
513
system_ss.add(when: 'CONFIG_OPENCORES_ETH', if_true: files('opencores_eth.c'))
860
system_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
514
system_ss.add(when: 'CONFIG_XGMAC', if_true: files('xgmac.c'))
861
system_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
862
diff --git a/hw/net/trace-events b/hw/net/trace-events
863
index XXXXXXX..XXXXXXX 100644
864
--- a/hw/net/trace-events
865
+++ b/hw/net/trace-events
866
@@ -XXX,XX +XXX,XX @@ npcm7xx_emc_rx_done(uint32_t crxdsa) "RX done, CRXDSA=0x%x"
867
npcm7xx_emc_reg_read(int emc_num, uint32_t result, const char *name, int regno) "emc%d: 0x%x = reg[%s/%d]"
868
npcm7xx_emc_reg_write(int emc_num, const char *name, int regno, uint32_t value) "emc%d: reg[%s/%d] = 0x%x"
869
870
+# npcm_gmac.c
871
+npcm_gmac_reg_read(const char *name, uint64_t offset, uint32_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx32
872
+npcm_gmac_reg_write(const char *name, uint64_t offset, uint32_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx32
873
+npcm_gmac_mdio_access(const char *name, uint8_t is_write, uint8_t pa, uint8_t gr, uint16_t val) "%s: is_write: %" PRIu8 " pa: %" PRIu8 " gr: %" PRIu8 " val: 0x%04" PRIx16
874
+npcm_gmac_reset(const char *name, uint16_t value) "%s: phy_regs[0][1]: 0x%04" PRIx16
875
+npcm_gmac_set_link(bool active) "Set link: active=%u"
876
+npcm_gmac_update_irq(const char *name, uint32_t status, uint32_t intr_en, int level) "%s: Status Reg: 0x%04" PRIX32 " Interrupt Enable Reg: 0x%04" PRIX32 " IRQ Set: %d"
877
+
878
+# npcm_pcs.c
879
+npcm_pcs_reg_read(const char *name, uint16_t indirect_access_baes, uint64_t offset, uint16_t value) "%s: IND: 0x%02" PRIx16 " offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
880
+npcm_pcs_reg_write(const char *name, uint16_t indirect_access_baes, uint64_t offset, uint16_t value) "%s: IND: 0x%02" PRIx16 " offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
881
+
882
# dp8398x.c
883
dp8393x_raise_irq(int isr) "raise irq, isr is 0x%04x"
884
dp8393x_lower_irq(void) "lower irq"
885
--
515
--
886
2.34.1
516
2.34.1
diff view generated by jsdifflib
1
From: Nabih Estefan Diaz <nabihestefan@google.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
- Implementation of Receive function for packets
3
imx_fec models the same PHY as lan9118_phy. The code is almost the same with
4
- Implementation for reading and writing from and to descriptors in
4
imx_fec having more logging and tracing. Merge these improvements into
5
memory for Rx
5
lan9118_phy and reuse in imx_fec to fix the code duplication.
6
6
7
When RX starts, we need to flush the queued packets so that they
7
Some migration state how resides in the new device model which breaks migration
8
can be received by the GMAC device. Without this it won't work
8
compatibility for the following machines:
9
with TAP NIC device.
9
* imx25-pdk
10
* sabrelite
11
* mcimx7d-sabre
12
* mcimx6ul-evk
10
13
11
When RX descriptor list is full, it returns a DMA_STATUS for
14
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
12
software to handle it. But there's no way to indicate the software has
15
Tested-by: Guenter Roeck <linux@roeck-us.net>
13
handled all RX descriptors and the whole pipeline stalls.
14
15
We do something similar to NPCM7XX EMC to handle this case.
16
17
1. Return packet size when RX descriptor is full, effectively dropping
18
these packets in such a case.
19
2. When software clears RX descriptor full bit, continue receiving
20
further packets by flushing QEMU packet queue.
21
22
Added relevant trace-events
23
24
Change-Id: I132aa254a94cda1a586aba2ea33bbfc74ecdb831
25
Signed-off-by: Hao Wu <wuhaotsh@google.com>
26
Signed-off-by: Nabih Estefan <nabihestefan@google.com>
27
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
28
Message-id: 20240131002800.989285-5-nabihestefan@google.com
29
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20241102125724.532843-3-shentey@gmail.com
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
---
19
---
32
hw/net/npcm_gmac.c | 276 +++++++++++++++++++++++++++++++++++++++++++-
20
include/hw/net/imx_fec.h | 9 ++-
33
hw/net/trace-events | 5 +
21
hw/net/imx_fec.c | 146 ++++-----------------------------------
34
2 files changed, 279 insertions(+), 2 deletions(-)
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(-)
35
26
36
diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
27
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
37
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/net/npcm_gmac.c
29
--- a/include/hw/net/imx_fec.h
39
+++ b/hw/net/npcm_gmac.c
30
+++ b/include/hw/net/imx_fec.h
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
32
#define TYPE_IMX_ENET "imx.enet"
33
34
#include "hw/sysbus.h"
35
+#include "hw/net/lan9118_phy.h"
36
+#include "hw/irq.h"
37
#include "net/net.h"
38
39
#define ENET_EIR 1
40
@@ -XXX,XX +XXX,XX @@ struct IMXFECState {
41
uint32_t tx_descriptor[ENET_TX_RING_NUM];
42
uint32_t tx_ring_num;
43
44
- uint32_t phy_status;
45
- uint32_t phy_control;
46
- uint32_t phy_advertise;
47
- uint32_t phy_int;
48
- uint32_t phy_int_mask;
49
+ Lan9118PhyState mii;
50
+ IRQState mii_irq;
51
uint32_t phy_num;
52
bool phy_connected;
53
struct IMXFECState *phy_consumer;
54
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/net/imx_fec.c
57
+++ b/hw/net/imx_fec.c
58
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth_txdescs = {
59
60
static const VMStateDescription vmstate_imx_eth = {
61
.name = TYPE_IMX_FEC,
62
- .version_id = 2,
63
- .minimum_version_id = 2,
64
+ .version_id = 3,
65
+ .minimum_version_id = 3,
66
.fields = (const VMStateField[]) {
67
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
68
VMSTATE_UINT32(rx_descriptor, IMXFECState),
69
VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
70
- VMSTATE_UINT32(phy_status, IMXFECState),
71
- VMSTATE_UINT32(phy_control, IMXFECState),
72
- VMSTATE_UINT32(phy_advertise, IMXFECState),
73
- VMSTATE_UINT32(phy_int, IMXFECState),
74
- VMSTATE_UINT32(phy_int_mask, IMXFECState),
75
VMSTATE_END_OF_LIST()
76
},
77
.subsections = (const VMStateDescription * const []) {
78
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth = {
79
},
80
};
81
82
-#define PHY_INT_ENERGYON (1 << 7)
83
-#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
84
-#define PHY_INT_FAULT (1 << 5)
85
-#define PHY_INT_DOWN (1 << 4)
86
-#define PHY_INT_AUTONEG_LP (1 << 3)
87
-#define PHY_INT_PARFAULT (1 << 2)
88
-#define PHY_INT_AUTONEG_PAGE (1 << 1)
89
-
90
static void imx_eth_update(IMXFECState *s);
91
92
/*
93
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s);
94
* For now we don't handle any GPIO/interrupt line, so the OS will
95
* have to poll for the PHY status.
96
*/
97
-static void imx_phy_update_irq(IMXFECState *s)
98
+static void imx_phy_update_irq(void *opaque, int n, int level)
99
{
100
- imx_eth_update(s);
101
-}
102
-
103
-static void imx_phy_update_link(IMXFECState *s)
104
-{
105
- /* Autonegotiation status mirrors link status. */
106
- if (qemu_get_queue(s->nic)->link_down) {
107
- trace_imx_phy_update_link("down");
108
- s->phy_status &= ~0x0024;
109
- s->phy_int |= PHY_INT_DOWN;
110
- } else {
111
- trace_imx_phy_update_link("up");
112
- s->phy_status |= 0x0024;
113
- s->phy_int |= PHY_INT_ENERGYON;
114
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
115
- }
116
- imx_phy_update_irq(s);
117
+ imx_eth_update(opaque);
118
}
119
120
static void imx_eth_set_link(NetClientState *nc)
121
{
122
- imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
123
-}
124
-
125
-static void imx_phy_reset(IMXFECState *s)
126
-{
127
- trace_imx_phy_reset();
128
-
129
- s->phy_status = 0x7809;
130
- s->phy_control = 0x3000;
131
- s->phy_advertise = 0x01e1;
132
- s->phy_int_mask = 0;
133
- s->phy_int = 0;
134
- imx_phy_update_link(s);
135
+ lan9118_phy_update_link(&IMX_FEC(qemu_get_nic_opaque(nc))->mii,
136
+ nc->link_down);
137
}
138
139
static uint32_t imx_phy_read(IMXFECState *s, int reg)
140
{
141
- uint32_t val;
142
uint32_t phy = reg / 32;
143
144
if (!s->phy_connected) {
145
@@ -XXX,XX +XXX,XX @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
146
147
reg %= 32;
148
149
- switch (reg) {
150
- case 0: /* Basic Control */
151
- val = s->phy_control;
152
- break;
153
- case 1: /* Basic Status */
154
- val = s->phy_status;
155
- break;
156
- case 2: /* ID1 */
157
- val = 0x0007;
158
- break;
159
- case 3: /* ID2 */
160
- val = 0xc0d1;
161
- break;
162
- case 4: /* Auto-neg advertisement */
163
- val = s->phy_advertise;
164
- break;
165
- case 5: /* Auto-neg Link Partner Ability */
166
- val = 0x0f71;
167
- break;
168
- case 6: /* Auto-neg Expansion */
169
- val = 1;
170
- break;
171
- case 29: /* Interrupt source. */
172
- val = s->phy_int;
173
- s->phy_int = 0;
174
- imx_phy_update_irq(s);
175
- break;
176
- case 30: /* Interrupt mask */
177
- val = s->phy_int_mask;
178
- break;
179
- case 17:
180
- case 18:
181
- case 27:
182
- case 31:
183
- qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
184
- TYPE_IMX_FEC, __func__, reg);
185
- val = 0;
186
- break;
187
- default:
188
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
189
- TYPE_IMX_FEC, __func__, reg);
190
- val = 0;
191
- break;
192
- }
193
-
194
- trace_imx_phy_read(val, phy, reg);
195
-
196
- return val;
197
+ return lan9118_phy_read(&s->mii, reg);
198
}
199
200
static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
201
@@ -XXX,XX +XXX,XX @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
202
203
reg %= 32;
204
205
- trace_imx_phy_write(val, phy, reg);
206
-
207
- switch (reg) {
208
- case 0: /* Basic Control */
209
- if (val & 0x8000) {
210
- imx_phy_reset(s);
211
- } else {
212
- s->phy_control = val & 0x7980;
213
- /* Complete autonegotiation immediately. */
214
- if (val & 0x1000) {
215
- s->phy_status |= 0x0020;
216
- }
217
- }
218
- break;
219
- case 4: /* Auto-neg advertisement */
220
- s->phy_advertise = (val & 0x2d7f) | 0x80;
221
- break;
222
- case 30: /* Interrupt mask */
223
- s->phy_int_mask = val & 0xff;
224
- imx_phy_update_irq(s);
225
- break;
226
- case 17:
227
- case 18:
228
- case 27:
229
- case 31:
230
- qemu_log_mask(LOG_UNIMP, "[%s.phy)%s: reg %d not implemented\n",
231
- TYPE_IMX_FEC, __func__, reg);
232
- break;
233
- default:
234
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
235
- TYPE_IMX_FEC, __func__, reg);
236
- break;
237
- }
238
+ lan9118_phy_write(&s->mii, reg, val);
239
}
240
241
static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
242
@@ -XXX,XX +XXX,XX @@ static void imx_eth_reset(DeviceState *d)
243
244
s->rx_descriptor = 0;
245
memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
246
-
247
- /* We also reset the PHY */
248
- imx_phy_reset(s);
249
}
250
251
static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
252
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
253
sysbus_init_irq(sbd, &s->irq[0]);
254
sysbus_init_irq(sbd, &s->irq[1]);
255
256
+ qemu_init_irq(&s->mii_irq, imx_phy_update_irq, s, 0);
257
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
258
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
259
+ return;
260
+ }
261
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
262
+
263
qemu_macaddr_default_if_unset(&s->conf.macaddr);
264
265
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
266
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
267
index XXXXXXX..XXXXXXX 100644
268
--- a/hw/net/lan9118_phy.c
269
+++ b/hw/net/lan9118_phy.c
40
@@ -XXX,XX +XXX,XX @@
270
@@ -XXX,XX +XXX,XX @@
41
#include "hw/net/mii.h"
271
* Copyright (c) 2009 CodeSourcery, LLC.
42
#include "hw/net/npcm_gmac.h"
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"
43
#include "migration/vmstate.h"
281
#include "migration/vmstate.h"
44
+#include "net/checksum.h"
45
+#include "net/eth.h"
46
+#include "net/net.h"
47
+#include "qemu/cutils.h"
48
#include "qemu/log.h"
282
#include "qemu/log.h"
49
#include "qemu/units.h"
283
+#include "trace.h"
50
#include "sysemu/dma.h"
284
51
@@ -XXX,XX +XXX,XX @@ static void gmac_phy_set_link(NPCMGMACState *gmac, bool active)
285
#define PHY_INT_ENERGYON (1 << 7)
52
286
#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
53
static bool gmac_can_receive(NetClientState *nc)
287
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
288
289
switch (reg) {
290
case 0: /* Basic Control */
291
- return s->control;
292
+ val = s->control;
293
+ break;
294
case 1: /* Basic Status */
295
- return s->status;
296
+ val = s->status;
297
+ break;
298
case 2: /* ID1 */
299
- return 0x0007;
300
+ val = 0x0007;
301
+ break;
302
case 3: /* ID2 */
303
- return 0xc0d1;
304
+ val = 0xc0d1;
305
+ break;
306
case 4: /* Auto-neg advertisement */
307
- return s->advertise;
308
+ val = s->advertise;
309
+ break;
310
case 5: /* Auto-neg Link Partner Ability */
311
- return 0x0f71;
312
+ val = 0x0f71;
313
+ break;
314
case 6: /* Auto-neg Expansion */
315
- return 1;
316
- /* TODO 17, 18, 27, 29, 30, 31 */
317
+ val = 1;
318
+ break;
319
case 29: /* Interrupt source. */
320
val = s->ints;
321
s->ints = 0;
322
lan9118_phy_update_irq(s);
323
- return val;
324
+ break;
325
case 30: /* Interrupt mask */
326
- return s->int_mask;
327
+ val = s->int_mask;
328
+ break;
329
+ case 17:
330
+ case 18:
331
+ case 27:
332
+ case 31:
333
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
334
+ __func__, reg);
335
+ val = 0;
336
+ break;
337
default:
338
- qemu_log_mask(LOG_GUEST_ERROR,
339
- "lan9118_phy_read: PHY read reg %d\n", reg);
340
- return 0;
341
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
342
+ __func__, reg);
343
+ val = 0;
344
+ break;
345
}
346
+
347
+ trace_lan9118_phy_read(val, reg);
348
+
349
+ return val;
350
}
351
352
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
54
{
353
{
55
+ NPCMGMACState *gmac = NPCM_GMAC(qemu_get_nic_opaque(nc));
354
+ trace_lan9118_phy_write(val, reg);
56
+
355
+
57
+ /* If GMAC receive is disabled. */
356
switch (reg) {
58
+ if (!(gmac->regs[R_NPCM_GMAC_MAC_CONFIG] & NPCM_GMAC_MAC_CONFIG_RX_EN)) {
357
case 0: /* Basic Control */
59
+ return false;
358
if (val & 0x8000) {
60
+ }
359
lan9118_phy_reset(s);
61
+
360
- break;
62
+ /* If GMAC DMA RX is stopped. */
361
- }
63
+ if (!(gmac->regs[R_NPCM_DMA_CONTROL] & NPCM_DMA_CONTROL_START_STOP_RX)) {
362
- s->control = val & 0x7980;
64
+ return false;
363
- /* Complete autonegotiation immediately. */
65
+ }
364
- if (val & 0x1000) {
66
return true;
365
- s->status |= 0x0020;
67
}
366
+ } else {
68
367
+ s->control = val & 0x7980;
69
@@ -XXX,XX +XXX,XX @@ static void gmac_update_irq(NPCMGMACState *gmac)
368
+ /* Complete autonegotiation immediately. */
70
qemu_set_irq(gmac->irq, level);
369
+ if (val & 0x1000) {
71
}
370
+ s->status |= 0x0020;
72
371
+ }
73
+static int gmac_read_rx_desc(dma_addr_t addr, struct NPCMGMACRxDesc *desc)
372
}
74
+{
373
break;
75
+ if (dma_memory_read(&address_space_memory, addr, desc,
374
case 4: /* Auto-neg advertisement */
76
+ sizeof(*desc), MEMTXATTRS_UNSPECIFIED)) {
375
s->advertise = (val & 0x2d7f) | 0x80;
77
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
376
break;
78
+ HWADDR_PRIx "\n", __func__, addr);
377
- /* TODO 17, 18, 27, 31 */
79
+ return -1;
378
case 30: /* Interrupt mask */
80
+ }
379
s->int_mask = val & 0xff;
81
+ desc->rdes0 = le32_to_cpu(desc->rdes0);
380
lan9118_phy_update_irq(s);
82
+ desc->rdes1 = le32_to_cpu(desc->rdes1);
381
break;
83
+ desc->rdes2 = le32_to_cpu(desc->rdes2);
382
+ case 17:
84
+ desc->rdes3 = le32_to_cpu(desc->rdes3);
383
+ case 18:
85
+ return 0;
384
+ case 27:
86
+}
385
+ case 31:
87
+
386
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
88
+static int gmac_write_rx_desc(dma_addr_t addr, struct NPCMGMACRxDesc *desc)
387
+ __func__, reg);
89
+{
388
+ break;
90
+ struct NPCMGMACRxDesc le_desc;
389
default:
91
+ le_desc.rdes0 = cpu_to_le32(desc->rdes0);
390
- qemu_log_mask(LOG_GUEST_ERROR,
92
+ le_desc.rdes1 = cpu_to_le32(desc->rdes1);
391
- "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
93
+ le_desc.rdes2 = cpu_to_le32(desc->rdes2);
392
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
94
+ le_desc.rdes3 = cpu_to_le32(desc->rdes3);
393
+ __func__, reg);
95
+ if (dma_memory_write(&address_space_memory, addr, &le_desc,
394
+ break;
96
+ sizeof(le_desc), MEMTXATTRS_UNSPECIFIED)) {
395
}
97
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%"
396
}
98
+ HWADDR_PRIx "\n", __func__, addr);
397
99
+ return -1;
398
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
100
+ }
399
101
+ return 0;
400
/* Autonegotiation status mirrors link status. */
102
+}
401
if (link_down) {
103
+
402
+ trace_lan9118_phy_update_link("down");
104
+static int gmac_rx_transfer_frame_to_buffer(uint32_t rx_buf_len,
403
s->status &= ~0x0024;
105
+ uint32_t *left_frame,
404
s->ints |= PHY_INT_DOWN;
106
+ uint32_t rx_buf_addr,
405
} else {
107
+ bool *eof_transferred,
406
+ trace_lan9118_phy_update_link("up");
108
+ const uint8_t **frame_ptr,
407
s->status |= 0x0024;
109
+ uint16_t *transferred)
408
s->ints |= PHY_INT_ENERGYON;
110
+{
409
s->ints |= PHY_INT_AUTONEG_COMPLETE;
111
+ uint32_t to_transfer;
410
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
112
+ /*
411
113
+ * Check that buffer is bigger than the frame being transfered
412
void lan9118_phy_reset(Lan9118PhyState *s)
114
+ * If bigger then transfer only whats left of frame
115
+ * Else, fill frame with all the content possible
116
+ */
117
+ if (rx_buf_len >= *left_frame) {
118
+ to_transfer = *left_frame;
119
+ *eof_transferred = true;
120
+ } else {
121
+ to_transfer = rx_buf_len;
122
+ }
123
+
124
+ /* write frame part to memory */
125
+ if (dma_memory_write(&address_space_memory, (uint64_t) rx_buf_addr,
126
+ *frame_ptr, to_transfer, MEMTXATTRS_UNSPECIFIED)) {
127
+ return -1;
128
+ }
129
+
130
+ /* update frame pointer and size of whats left of frame */
131
+ *frame_ptr += to_transfer;
132
+ *left_frame -= to_transfer;
133
+ *transferred += to_transfer;
134
+
135
+ return 0;
136
+}
137
+
138
+static void gmac_dma_set_state(NPCMGMACState *gmac, int shift, uint32_t state)
139
+{
140
+ gmac->regs[R_NPCM_DMA_STATUS] = deposit32(gmac->regs[R_NPCM_DMA_STATUS],
141
+ shift, 3, state);
142
+}
143
+
144
static ssize_t gmac_receive(NetClientState *nc, const uint8_t *buf, size_t len)
145
{
413
{
146
- /* Placeholder. Function will be filled in following patches */
414
+ trace_lan9118_phy_reset();
147
- return 0;
415
+
148
+ /*
416
s->control = 0x3000;
149
+ * Comments have steps that relate to the
417
s->status = 0x7809;
150
+ * receiving process steps in pg 386
418
s->advertise = 0x01e1;
151
+ */
419
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_phy = {
152
+ NPCMGMACState *gmac = NPCM_GMAC(qemu_get_nic_opaque(nc));
420
.version_id = 1,
153
+ uint32_t left_frame = len;
421
.minimum_version_id = 1,
154
+ const uint8_t *frame_ptr = buf;
422
.fields = (const VMStateField[]) {
155
+ uint32_t desc_addr;
423
- VMSTATE_UINT16(control, Lan9118PhyState),
156
+ uint32_t rx_buf_len, rx_buf_addr;
424
VMSTATE_UINT16(status, Lan9118PhyState),
157
+ struct NPCMGMACRxDesc rx_desc;
425
+ VMSTATE_UINT16(control, Lan9118PhyState),
158
+ uint16_t transferred = 0;
426
VMSTATE_UINT16(advertise, Lan9118PhyState),
159
+ bool eof_transferred = false;
427
VMSTATE_UINT16(ints, Lan9118PhyState),
160
+
428
VMSTATE_UINT16(int_mask, Lan9118PhyState),
161
+ trace_npcm_gmac_packet_receive(DEVICE(gmac)->canonical_path, len);
429
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
162
+ if (!gmac_can_receive(nc)) {
430
index XXXXXXX..XXXXXXX 100644
163
+ qemu_log_mask(LOG_GUEST_ERROR, "GMAC Currently is not able for Rx");
431
--- a/hw/net/Kconfig
164
+ return -1;
432
+++ b/hw/net/Kconfig
165
+ }
433
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_SUN8I_EMAC
166
+ if (!gmac->regs[R_NPCM_DMA_HOST_RX_DESC]) {
434
167
+ gmac->regs[R_NPCM_DMA_HOST_RX_DESC] =
435
config IMX_FEC
168
+ NPCM_DMA_HOST_RX_DESC_MASK(gmac->regs[R_NPCM_DMA_RX_BASE_ADDR]);
436
bool
169
+ }
437
+ select LAN9118_PHY
170
+ desc_addr = NPCM_DMA_HOST_RX_DESC_MASK(gmac->regs[R_NPCM_DMA_HOST_RX_DESC]);
438
171
+
439
config CADENCE
172
+ /* step 1 */
440
bool
173
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT,
174
+ NPCM_DMA_STATUS_RX_RUNNING_FETCHING_STATE);
175
+ trace_npcm_gmac_packet_desc_read(DEVICE(gmac)->canonical_path, desc_addr);
176
+ if (gmac_read_rx_desc(desc_addr, &rx_desc)) {
177
+ qemu_log_mask(LOG_GUEST_ERROR, "RX Descriptor @ 0x%x cant be read\n",
178
+ desc_addr);
179
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT,
180
+ NPCM_DMA_STATUS_RX_SUSPENDED_STATE);
181
+ return -1;
182
+ }
183
+
184
+ /* step 2 */
185
+ if (!(rx_desc.rdes0 & RX_DESC_RDES0_OWN)) {
186
+ qemu_log_mask(LOG_GUEST_ERROR,
187
+ "RX Descriptor @ 0x%x is owned by software\n",
188
+ desc_addr);
189
+ gmac->regs[R_NPCM_DMA_STATUS] |= NPCM_DMA_STATUS_RU;
190
+ gmac->regs[R_NPCM_DMA_STATUS] |= NPCM_DMA_STATUS_RI;
191
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT,
192
+ NPCM_DMA_STATUS_RX_SUSPENDED_STATE);
193
+ gmac_update_irq(gmac);
194
+ return len;
195
+ }
196
+ /* step 3 */
197
+ /*
198
+ * TODO --
199
+ * Implement all frame filtering and processing (with its own interrupts)
200
+ */
201
+ trace_npcm_gmac_debug_desc_data(DEVICE(gmac)->canonical_path, &rx_desc,
202
+ rx_desc.rdes0, rx_desc.rdes1, rx_desc.rdes2,
203
+ rx_desc.rdes3);
204
+ /* Clear rdes0 for the incoming descriptor and set FS in first descriptor.*/
205
+ rx_desc.rdes0 = RX_DESC_RDES0_FIRST_DESC_MASK;
206
+
207
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT,
208
+ NPCM_DMA_STATUS_RX_RUNNING_TRANSFERRING_STATE);
209
+
210
+ /* Pad the frame with FCS as the kernel driver will strip it away. */
211
+ left_frame += ETH_FCS_LEN;
212
+
213
+ /* repeat while we still have frame to transfer to memory */
214
+ while (!eof_transferred) {
215
+ /* Return descriptor no matter what happens */
216
+ rx_desc.rdes0 &= ~RX_DESC_RDES0_OWN;
217
+ /* Set the frame to be an IPv4/IPv6 frame. */
218
+ rx_desc.rdes0 |= RX_DESC_RDES0_FRM_TYPE_MASK;
219
+
220
+ /* step 4 */
221
+ rx_buf_len = RX_DESC_RDES1_BFFR1_SZ_MASK(rx_desc.rdes1);
222
+ rx_buf_addr = rx_desc.rdes2;
223
+ gmac->regs[R_NPCM_DMA_CUR_RX_BUF_ADDR] = rx_buf_addr;
224
+ gmac_rx_transfer_frame_to_buffer(rx_buf_len, &left_frame, rx_buf_addr,
225
+ &eof_transferred, &frame_ptr,
226
+ &transferred);
227
+
228
+ trace_npcm_gmac_packet_receiving_buffer(DEVICE(gmac)->canonical_path,
229
+ rx_buf_len, rx_buf_addr);
230
+ /* if we still have frame left and the second buffer is not chained */
231
+ if (!(rx_desc.rdes1 & RX_DESC_RDES1_SEC_ADDR_CHND_MASK) && \
232
+ !eof_transferred) {
233
+ /* repeat process from above on buffer 2 */
234
+ rx_buf_len = RX_DESC_RDES1_BFFR2_SZ_MASK(rx_desc.rdes1);
235
+ rx_buf_addr = rx_desc.rdes3;
236
+ gmac->regs[R_NPCM_DMA_CUR_RX_BUF_ADDR] = rx_buf_addr;
237
+ gmac_rx_transfer_frame_to_buffer(rx_buf_len, &left_frame,
238
+ rx_buf_addr, &eof_transferred,
239
+ &frame_ptr, &transferred);
240
+ trace_npcm_gmac_packet_receiving_buffer( \
241
+ DEVICE(gmac)->canonical_path,
242
+ rx_buf_len, rx_buf_addr);
243
+ }
244
+ /* update address for descriptor */
245
+ gmac->regs[R_NPCM_DMA_HOST_RX_DESC] = rx_buf_addr;
246
+ /* Return descriptor */
247
+ rx_desc.rdes0 &= ~RX_DESC_RDES0_OWN;
248
+ /* Update frame length transferred */
249
+ rx_desc.rdes0 |= ((uint32_t)transferred)
250
+ << RX_DESC_RDES0_FRAME_LEN_SHIFT;
251
+ trace_npcm_gmac_debug_desc_data(DEVICE(gmac)->canonical_path, &rx_desc,
252
+ rx_desc.rdes0, rx_desc.rdes1,
253
+ rx_desc.rdes2, rx_desc.rdes3);
254
+
255
+ /* step 5 */
256
+ gmac_write_rx_desc(desc_addr, &rx_desc);
257
+ trace_npcm_gmac_debug_desc_data(DEVICE(gmac)->canonical_path,
258
+ &rx_desc, rx_desc.rdes0,
259
+ rx_desc.rdes1, rx_desc.rdes2,
260
+ rx_desc.rdes3);
261
+ /* read new descriptor into rx_desc if needed*/
262
+ if (!eof_transferred) {
263
+ /* Get next descriptor address (chained or sequential) */
264
+ if (rx_desc.rdes1 & RX_DESC_RDES1_RC_END_RING_MASK) {
265
+ desc_addr = gmac->regs[R_NPCM_DMA_RX_BASE_ADDR];
266
+ } else if (rx_desc.rdes1 & RX_DESC_RDES1_SEC_ADDR_CHND_MASK) {
267
+ desc_addr = rx_desc.rdes3;
268
+ } else {
269
+ desc_addr += sizeof(rx_desc);
270
+ }
271
+ trace_npcm_gmac_packet_desc_read(DEVICE(gmac)->canonical_path,
272
+ desc_addr);
273
+ if (gmac_read_rx_desc(desc_addr, &rx_desc)) {
274
+ qemu_log_mask(LOG_GUEST_ERROR,
275
+ "RX Descriptor @ 0x%x cant be read\n",
276
+ desc_addr);
277
+ gmac->regs[R_NPCM_DMA_STATUS] |= NPCM_DMA_STATUS_RU;
278
+ gmac_update_irq(gmac);
279
+ return len;
280
+ }
281
+
282
+ /* step 6 */
283
+ if (!(rx_desc.rdes0 & RX_DESC_RDES0_OWN)) {
284
+ if (!(gmac->regs[R_NPCM_DMA_CONTROL] & \
285
+ NPCM_DMA_CONTROL_FLUSH_MASK)) {
286
+ rx_desc.rdes0 |= RX_DESC_RDES0_DESC_ERR_MASK;
287
+ }
288
+ eof_transferred = true;
289
+ }
290
+ /* Clear rdes0 for the incoming descriptor */
291
+ rx_desc.rdes0 = 0;
292
+ }
293
+ }
294
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT,
295
+ NPCM_DMA_STATUS_RX_RUNNING_CLOSING_STATE);
296
+
297
+ rx_desc.rdes0 |= RX_DESC_RDES0_LAST_DESC_MASK;
298
+ if (!(rx_desc.rdes1 & RX_DESC_RDES1_DIS_INTR_COMP_MASK)) {
299
+ gmac->regs[R_NPCM_DMA_STATUS] |= NPCM_DMA_STATUS_RI;
300
+ gmac_update_irq(gmac);
301
+ }
302
+ trace_npcm_gmac_debug_desc_data(DEVICE(gmac)->canonical_path, &rx_desc,
303
+ rx_desc.rdes0, rx_desc.rdes1, rx_desc.rdes2,
304
+ rx_desc.rdes3);
305
+
306
+ /* step 8 */
307
+ gmac->regs[R_NPCM_DMA_CONTROL] |= NPCM_DMA_CONTROL_FLUSH_MASK;
308
+
309
+ /* step 9 */
310
+ trace_npcm_gmac_packet_received(DEVICE(gmac)->canonical_path, left_frame);
311
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT,
312
+ NPCM_DMA_STATUS_RX_RUNNING_WAITING_STATE);
313
+ gmac_write_rx_desc(desc_addr, &rx_desc);
314
+
315
+ /* Get next descriptor address (chained or sequential) */
316
+ if (rx_desc.rdes1 & RX_DESC_RDES1_RC_END_RING_MASK) {
317
+ desc_addr = gmac->regs[R_NPCM_DMA_RX_BASE_ADDR];
318
+ } else if (rx_desc.rdes1 & RX_DESC_RDES1_SEC_ADDR_CHND_MASK) {
319
+ desc_addr = rx_desc.rdes3;
320
+ } else {
321
+ desc_addr += sizeof(rx_desc);
322
+ }
323
+ gmac->regs[R_NPCM_DMA_HOST_RX_DESC] = desc_addr;
324
+ return len;
325
}
326
327
static void gmac_cleanup(NetClientState *nc)
328
@@ -XXX,XX +XXX,XX @@ static void npcm_gmac_write(void *opaque, hwaddr offset,
329
break;
330
331
case A_NPCM_GMAC_MAC_CONFIG:
332
+ gmac->regs[offset / sizeof(uint32_t)] = v;
333
break;
334
335
case A_NPCM_GMAC_MII_ADDR:
336
@@ -XXX,XX +XXX,XX @@ static void npcm_gmac_write(void *opaque, hwaddr offset,
337
338
case A_NPCM_DMA_RCV_POLL_DEMAND:
339
/* We dont actually care about the value */
340
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT,
341
+ NPCM_DMA_STATUS_RX_RUNNING_WAITING_STATE);
342
break;
343
344
case A_NPCM_DMA_STATUS:
345
@@ -XXX,XX +XXX,XX @@ static void npcm_gmac_write(void *opaque, hwaddr offset,
346
HWADDR_PRIx ", value: 0x%04" PRIx64 "\n",
347
DEVICE(gmac)->canonical_path, offset, v);
348
}
349
+ /* for W1C bits, implement W1C */
350
+ gmac->regs[offset / sizeof(uint32_t)] &= ~NPCM_DMA_STATUS_W1C_MASK(v);
351
+ if (v & NPCM_DMA_STATUS_RU) {
352
+ /* Clearing RU bit indicates descriptor is owned by DMA again. */
353
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT,
354
+ NPCM_DMA_STATUS_RX_RUNNING_WAITING_STATE);
355
+ qemu_flush_queued_packets(qemu_get_queue(gmac->nic));
356
+ }
357
break;
358
359
default:
360
diff --git a/hw/net/trace-events b/hw/net/trace-events
441
diff --git a/hw/net/trace-events b/hw/net/trace-events
361
index XXXXXXX..XXXXXXX 100644
442
index XXXXXXX..XXXXXXX 100644
362
--- a/hw/net/trace-events
443
--- a/hw/net/trace-events
363
+++ b/hw/net/trace-events
444
+++ b/hw/net/trace-events
364
@@ -XXX,XX +XXX,XX @@ npcm_gmac_mdio_access(const char *name, uint8_t is_write, uint8_t pa, uint8_t gr
445
@@ -XXX,XX +XXX,XX @@ allwinner_sun8i_emac_set_link(bool active) "Set link: active=%u"
365
npcm_gmac_reset(const char *name, uint16_t value) "%s: phy_regs[0][1]: 0x%04" PRIx16
446
allwinner_sun8i_emac_read(uint64_t offset, uint64_t val) "MMIO read: offset=0x%" PRIx64 " value=0x%" PRIx64
366
npcm_gmac_set_link(bool active) "Set link: active=%u"
447
allwinner_sun8i_emac_write(uint64_t offset, uint64_t val) "MMIO write: offset=0x%" PRIx64 " value=0x%" PRIx64
367
npcm_gmac_update_irq(const char *name, uint32_t status, uint32_t intr_en, int level) "%s: Status Reg: 0x%04" PRIX32 " Interrupt Enable Reg: 0x%04" PRIX32 " IRQ Set: %d"
448
368
+npcm_gmac_packet_desc_read(const char* name, uint32_t desc_addr) "%s: attempting to read descriptor @0x%04" PRIX32
449
+# lan9118_phy.c
369
+npcm_gmac_packet_receive(const char* name, uint32_t len) "%s: RX packet length: 0x%04" PRIX32
450
+lan9118_phy_read(uint16_t val, int reg) "[0x%02x] -> 0x%04" PRIx16
370
+npcm_gmac_packet_receiving_buffer(const char* name, uint32_t buf_len, uint32_t rx_buf_addr) "%s: Receiving into Buffer size: 0x%04" PRIX32 " at address 0x%04" PRIX32
451
+lan9118_phy_write(uint16_t val, int reg) "[0x%02x] <- 0x%04" PRIx16
371
+npcm_gmac_packet_received(const char* name, uint32_t len) "%s: Reception finished, packet left: 0x%04" PRIX32
452
+lan9118_phy_update_link(const char *s) "%s"
372
+npcm_gmac_debug_desc_data(const char* name, void* addr, uint32_t des0, uint32_t des1, uint32_t des2, uint32_t des3)"%s: Address: %p Descriptor 0: 0x%04" PRIX32 " Descriptor 1: 0x%04" PRIX32 "Descriptor 2: 0x%04" PRIX32 " Descriptor 3: 0x%04" PRIX32
453
+lan9118_phy_reset(void) ""
373
454
+
374
# npcm_pcs.c
455
# lance.c
375
npcm_pcs_reg_read(const char *name, uint16_t indirect_access_baes, uint64_t offset, uint16_t value) "%s: IND: 0x%02" PRIx16 " offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
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"
376
--
471
--
377
2.34.1
472
2.34.1
diff view generated by jsdifflib
New patch
1
From: Bernhard Beschow <shentey@gmail.com>
1
2
3
Turns 0x70 into 0xe0 (== 0x70 << 1) which adds the missing MII_ANLPAR_TX and
4
fixes the MSB of selector field to be zero, as specified in the datasheet.
5
6
Fixes: 2a424990170b "LAN9118 emulation"
7
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
8
Tested-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20241102125724.532843-4-shentey@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/net/lan9118_phy.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/lan9118_phy.c
19
+++ b/hw/net/lan9118_phy.c
20
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
21
val = s->advertise;
22
break;
23
case 5: /* Auto-neg Link Partner Ability */
24
- val = 0x0f71;
25
+ val = 0x0fe1;
26
break;
27
case 6: /* Auto-neg Expansion */
28
val = 1;
29
--
30
2.34.1
diff view generated by jsdifflib
New patch
1
From: Bernhard Beschow <shentey@gmail.com>
1
2
3
Prefer named constants over magic values for better readability.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
7
Tested-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20241102125724.532843-5-shentey@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/net/mii.h | 6 +++++
12
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
13
2 files changed, 46 insertions(+), 23 deletions(-)
14
15
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/net/mii.h
18
+++ b/include/hw/net/mii.h
19
@@ -XXX,XX +XXX,XX @@
20
#define MII_BMSR_JABBER (1 << 1) /* Jabber detected */
21
#define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */
22
23
+#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */
24
#define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */
25
#define MII_ANAR_PAUSE (1 << 10) /* Try for pause */
26
#define MII_ANAR_TXFD (1 << 8)
27
@@ -XXX,XX +XXX,XX @@
28
#define MII_ANAR_10FD (1 << 6)
29
#define MII_ANAR_10 (1 << 5)
30
#define MII_ANAR_CSMACD (1 << 0)
31
+#define MII_ANAR_SELECT (0x001f) /* Selector bits */
32
33
#define MII_ANLPAR_ACK (1 << 14)
34
#define MII_ANLPAR_PAUSEASY (1 << 11) /* can pause asymmetrically */
35
@@ -XXX,XX +XXX,XX @@
36
#define RTL8201CP_PHYID1 0x0000
37
#define RTL8201CP_PHYID2 0x8201
38
39
+/* SMSC LAN9118 */
40
+#define SMSCLAN9118_PHYID1 0x0007
41
+#define SMSCLAN9118_PHYID2 0xc0d1
42
+
43
/* RealTek 8211E */
44
#define RTL8211E_PHYID1 0x001c
45
#define RTL8211E_PHYID2 0xc915
46
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/net/lan9118_phy.c
49
+++ b/hw/net/lan9118_phy.c
50
@@ -XXX,XX +XXX,XX @@
51
52
#include "qemu/osdep.h"
53
#include "hw/net/lan9118_phy.h"
54
+#include "hw/net/mii.h"
55
#include "hw/irq.h"
56
#include "hw/resettable.h"
57
#include "migration/vmstate.h"
58
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
59
uint16_t val;
60
61
switch (reg) {
62
- case 0: /* Basic Control */
63
+ case MII_BMCR:
64
val = s->control;
65
break;
66
- case 1: /* Basic Status */
67
+ case MII_BMSR:
68
val = s->status;
69
break;
70
- case 2: /* ID1 */
71
- val = 0x0007;
72
+ case MII_PHYID1:
73
+ val = SMSCLAN9118_PHYID1;
74
break;
75
- case 3: /* ID2 */
76
- val = 0xc0d1;
77
+ case MII_PHYID2:
78
+ val = SMSCLAN9118_PHYID2;
79
break;
80
- case 4: /* Auto-neg advertisement */
81
+ case MII_ANAR:
82
val = s->advertise;
83
break;
84
- case 5: /* Auto-neg Link Partner Ability */
85
- val = 0x0fe1;
86
+ case MII_ANLPAR:
87
+ val = MII_ANLPAR_PAUSEASY | MII_ANLPAR_PAUSE | MII_ANLPAR_T4 |
88
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
89
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
90
break;
91
- case 6: /* Auto-neg Expansion */
92
- val = 1;
93
+ case MII_ANER:
94
+ val = MII_ANER_NWAY;
95
break;
96
case 29: /* Interrupt source. */
97
val = s->ints;
98
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
99
trace_lan9118_phy_write(val, reg);
100
101
switch (reg) {
102
- case 0: /* Basic Control */
103
- if (val & 0x8000) {
104
+ case MII_BMCR:
105
+ if (val & MII_BMCR_RESET) {
106
lan9118_phy_reset(s);
107
} else {
108
- s->control = val & 0x7980;
109
+ s->control = val & (MII_BMCR_LOOPBACK | MII_BMCR_SPEED100 |
110
+ MII_BMCR_AUTOEN | MII_BMCR_PDOWN | MII_BMCR_FD |
111
+ MII_BMCR_CTST);
112
/* Complete autonegotiation immediately. */
113
- if (val & 0x1000) {
114
- s->status |= 0x0020;
115
+ if (val & MII_BMCR_AUTOEN) {
116
+ s->status |= MII_BMSR_AN_COMP;
117
}
118
}
119
break;
120
- case 4: /* Auto-neg advertisement */
121
- s->advertise = (val & 0x2d7f) | 0x80;
122
+ case MII_ANAR:
123
+ s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
124
+ MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
125
+ MII_ANAR_SELECT))
126
+ | MII_ANAR_TX;
127
break;
128
case 30: /* Interrupt mask */
129
s->int_mask = val & 0xff;
130
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
131
/* Autonegotiation status mirrors link status. */
132
if (link_down) {
133
trace_lan9118_phy_update_link("down");
134
- s->status &= ~0x0024;
135
+ s->status &= ~(MII_BMSR_AN_COMP | MII_BMSR_LINK_ST);
136
s->ints |= PHY_INT_DOWN;
137
} else {
138
trace_lan9118_phy_update_link("up");
139
- s->status |= 0x0024;
140
+ s->status |= MII_BMSR_AN_COMP | MII_BMSR_LINK_ST;
141
s->ints |= PHY_INT_ENERGYON;
142
s->ints |= PHY_INT_AUTONEG_COMPLETE;
143
}
144
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_reset(Lan9118PhyState *s)
145
{
146
trace_lan9118_phy_reset();
147
148
- s->control = 0x3000;
149
- s->status = 0x7809;
150
- s->advertise = 0x01e1;
151
+ s->control = MII_BMCR_AUTOEN | MII_BMCR_SPEED100;
152
+ s->status = MII_BMSR_100TX_FD
153
+ | MII_BMSR_100TX_HD
154
+ | MII_BMSR_10T_FD
155
+ | MII_BMSR_10T_HD
156
+ | MII_BMSR_AUTONEG
157
+ | MII_BMSR_EXTCAP;
158
+ s->advertise = MII_ANAR_TXFD
159
+ | MII_ANAR_TX
160
+ | MII_ANAR_10FD
161
+ | MII_ANAR_10
162
+ | MII_ANAR_CSMACD;
163
s->int_mask = 0;
164
s->ints = 0;
165
lan9118_phy_update_link(s, s->link_down);
166
--
167
2.34.1
diff view generated by jsdifflib
1
From: David Woodhouse <dwmw@amazon.co.uk>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
We can't just embed labels directly into files like qemu-options.hx which
3
The real device advertises this mode and the device model already advertises
4
are included from multiple top-level rST files, because Sphinx sees the
4
100 mbps half duplex and 10 mbps full+half duplex. So advertise this mode to
5
labels as duplicate: https://github.com/sphinx-doc/sphinx/issues/9707
5
make the model more realistic.
6
6
7
So add an optional argument to the SRST directive which causes a label
8
of the form '.. _DOCNAME-HXFILE-LABEL:' to be emitted, where 'DOCNAME'
9
is the name of the top level rST file, 'HXFILE' is the filename of the
10
.hx file, and 'LABEL' is the text provided within the 'SRST()' directive.
11
Using the DOCNAME of the top-level rST document means that it is unique
12
even when the .hx file is included from two different documents, as is
13
the case for qemu-options.hx
14
15
Now where the Xen PV documentation refers to the documentation for the
16
-initrd command line option, it can emit a link directly to it as
17
'<system/invocation-qemu-options-initrd>'.
18
19
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
20
Reviewed-by: Paul Durrant <paul@xen.org>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20240130190348.682912-1-dwmw2@infradead.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
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
12
---
25
docs/devel/docs.rst | 12 ++++++++++--
13
hw/net/lan9118_phy.c | 4 ++--
26
docs/sphinx/hxtool.py | 16 ++++++++++++++++
14
1 file changed, 2 insertions(+), 2 deletions(-)
27
docs/system/i386/xen.rst | 3 ++-
28
qemu-options.hx | 2 +-
29
4 files changed, 29 insertions(+), 4 deletions(-)
30
15
31
diff --git a/docs/devel/docs.rst b/docs/devel/docs.rst
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
32
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
33
--- a/docs/devel/docs.rst
18
--- a/hw/net/lan9118_phy.c
34
+++ b/docs/devel/docs.rst
19
+++ b/hw/net/lan9118_phy.c
35
@@ -XXX,XX +XXX,XX @@ nor the documentation output.
20
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
36
21
break;
37
``SRST`` starts a reStructuredText section. Following lines
22
case MII_ANAR:
38
are put into the documentation verbatim, and discarded from the C output.
23
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
39
+The alternative form ``SRST()`` is used to define a label which can be
24
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
40
+referenced from elsewhere in the rST documentation. The label will take
25
- MII_ANAR_SELECT))
41
+the form ``<DOCNAME-HXFILE-LABEL>``, where ``DOCNAME`` is the name of the
26
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
42
+top level rST file, ``HXFILE`` is the filename of the .hx file without
27
+ MII_ANAR_10 | MII_ANAR_SELECT))
43
+the ``.hx`` extension, and ``LABEL`` is the text provided within the
28
| MII_ANAR_TX;
44
+``SRST()`` directive. For example,
29
break;
45
+``<system/invocation-qemu-options-initrd>``.
30
case 30: /* Interrupt mask */
46
47
``ERST`` ends the documentation section started with ``SRST``,
48
and switches back to a C code section.
49
@@ -XXX,XX +XXX,XX @@ text, but in ``hmp-commands.hx`` the C code sections are elements
50
of an array of structs of type ``HMPCommand`` which define the
51
name, behaviour and help text for each monitor command.
52
53
-In the file ``qemu-options.hx``, do not try to define a
54
+In the file ``qemu-options.hx``, do not try to explicitly define a
55
reStructuredText label within a documentation section. This file
56
is included into two separate Sphinx documents, and some
57
versions of Sphinx will complain about the duplicate label
58
-that results.
59
+that results. Use the ``SRST()`` directive documented above, to
60
+emit an unambiguous label.
61
diff --git a/docs/sphinx/hxtool.py b/docs/sphinx/hxtool.py
62
index XXXXXXX..XXXXXXX 100644
63
--- a/docs/sphinx/hxtool.py
64
+++ b/docs/sphinx/hxtool.py
65
@@ -XXX,XX +XXX,XX @@ def parse_archheading(file, lnum, line):
66
serror(file, lnum, "Invalid ARCHHEADING line")
67
return match.group(1)
68
69
+def parse_srst(file, lnum, line):
70
+ """Handle an SRST directive"""
71
+ # The input should be either "SRST", or "SRST(label)".
72
+ match = re.match(r'SRST(\((.*?)\))?', line)
73
+ if match is None:
74
+ serror(file, lnum, "Invalid SRST line")
75
+ return match.group(2)
76
+
77
class HxtoolDocDirective(Directive):
78
"""Extract rST fragments from the specified .hx file"""
79
required_argument = 1
80
@@ -XXX,XX +XXX,XX @@ def run(self):
81
serror(hxfile, lnum, 'expected ERST, found SRST')
82
else:
83
state = HxState.RST
84
+ label = parse_srst(hxfile, lnum, line)
85
+ if label:
86
+ rstlist.append("", hxfile, lnum - 1)
87
+ # Build label as _DOCNAME-HXNAME-LABEL
88
+ hx = os.path.splitext(os.path.basename(hxfile))[0]
89
+ refline = ".. _" + env.docname + "-" + hx + \
90
+ "-" + label + ":"
91
+ rstlist.append(refline, hxfile, lnum - 1)
92
elif directive == 'ERST':
93
if state == HxState.CTEXT:
94
serror(hxfile, lnum, 'expected SRST, found ERST')
95
diff --git a/docs/system/i386/xen.rst b/docs/system/i386/xen.rst
96
index XXXXXXX..XXXXXXX 100644
97
--- a/docs/system/i386/xen.rst
98
+++ b/docs/system/i386/xen.rst
99
@@ -XXX,XX +XXX,XX @@ The example above provides the guest kernel command line after a separator
100
(" ``--`` ") on the Xen command line, and does not provide the guest kernel
101
with an actual initramfs, which would need to listed as a second multiboot
102
module. For more complicated alternatives, see the command line
103
-documentation for the ``-initrd`` option.
104
+:ref:`documentation <system/invocation-qemu-options-initrd>` for the
105
+``-initrd`` option.
106
107
Host OS requirements
108
--------------------
109
diff --git a/qemu-options.hx b/qemu-options.hx
110
index XXXXXXX..XXXXXXX 100644
111
--- a/qemu-options.hx
112
+++ b/qemu-options.hx
113
@@ -XXX,XX +XXX,XX @@ ERST
114
115
DEF("initrd", HAS_ARG, QEMU_OPTION_initrd, \
116
"-initrd file use 'file' as initial ram disk\n", QEMU_ARCH_ALL)
117
-SRST
118
+SRST(initrd)
119
120
``-initrd file``
121
Use file as initial ram disk.
122
--
31
--
123
2.34.1
32
2.34.1
diff view generated by jsdifflib
New patch
1
For IEEE fused multiply-add, the (0 * inf) + NaN case should raise
2
Invalid for the multiplication of 0 by infinity. Currently we handle
3
this in the per-architecture ifdef ladder in pickNaNMulAdd().
4
However, since this isn't really architecture specific we can hoist
5
it up to the generic code.
1
6
7
For the cases where the infzero test in pickNaNMulAdd was
8
returning 2, we can delete the check entirely and allow the
9
code to fall into the normal pick-a-NaN handling, because this
10
will return 2 anyway (input 'c' being the only NaN in this case).
11
For the cases where infzero was returning 3 to indicate "return
12
the default NaN", we must retain that "return 3".
13
14
For Arm, this looks like it might be a behaviour change because we
15
used to set float_flag_invalid | float_flag_invalid_imz only if C is
16
a quiet NaN. However, it is not, because Arm target code never looks
17
at float_flag_invalid_imz, and for the (0 * inf) + SNaN case we
18
already raised float_flag_invalid via the "abc_mask &
19
float_cmask_snan" check in pick_nan_muladd.
20
21
For any target architecture using the "default implementation" at the
22
bottom of the ifdef, this is a behaviour change but will be fixing a
23
bug (where we failed to raise the Invalid exception for (0 * inf +
24
QNaN). The architectures using the default case are:
25
* hppa
26
* i386
27
* sh4
28
* tricore
29
30
The x86, Tricore and SH4 CPU architecture manuals are clear that this
31
should have raised Invalid; HPPA is a bit vaguer but still seems
32
clear enough.
33
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
36
Message-id: 20241202131347.498124-2-peter.maydell@linaro.org
37
---
38
fpu/softfloat-parts.c.inc | 13 +++++++------
39
fpu/softfloat-specialize.c.inc | 29 +----------------------------
40
2 files changed, 8 insertions(+), 34 deletions(-)
41
42
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
43
index XXXXXXX..XXXXXXX 100644
44
--- a/fpu/softfloat-parts.c.inc
45
+++ b/fpu/softfloat-parts.c.inc
46
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
47
int ab_mask, int abc_mask)
48
{
49
int which;
50
+ bool infzero = (ab_mask == float_cmask_infzero);
51
52
if (unlikely(abc_mask & float_cmask_snan)) {
53
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
54
}
55
56
- which = pickNaNMulAdd(a->cls, b->cls, c->cls,
57
- ab_mask == float_cmask_infzero, s);
58
+ if (infzero) {
59
+ /* This is (0 * inf) + NaN or (inf * 0) + NaN */
60
+ float_raise(float_flag_invalid | float_flag_invalid_imz, s);
61
+ }
62
+
63
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
64
65
if (s->default_nan_mode || which == 3) {
66
- /*
67
- * Note that this check is after pickNaNMulAdd so that function
68
- * has an opportunity to set the Invalid flag for infzero.
69
- */
70
parts_default_nan(a, s);
71
return a;
72
}
73
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
74
index XXXXXXX..XXXXXXX 100644
75
--- a/fpu/softfloat-specialize.c.inc
76
+++ b/fpu/softfloat-specialize.c.inc
77
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
78
* the default NaN
79
*/
80
if (infzero && is_qnan(c_cls)) {
81
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
82
return 3;
83
}
84
85
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
86
* case sets InvalidOp and returns the default NaN
87
*/
88
if (infzero) {
89
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
90
return 3;
91
}
92
/* Prefer sNaN over qNaN, in the a, b, c order. */
93
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
94
* For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
95
* case sets InvalidOp and returns the input value 'c'
96
*/
97
- if (infzero) {
98
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
99
- return 2;
100
- }
101
/* Prefer sNaN over qNaN, in the c, a, b order. */
102
if (is_snan(c_cls)) {
103
return 2;
104
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
105
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
106
* case sets InvalidOp and returns the input value 'c'
107
*/
108
- if (infzero) {
109
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
110
- return 2;
111
- }
112
+
113
/* Prefer sNaN over qNaN, in the c, a, b order. */
114
if (is_snan(c_cls)) {
115
return 2;
116
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
117
* to return an input NaN if we have one (ie c) rather than generating
118
* a default NaN
119
*/
120
- if (infzero) {
121
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
122
- return 2;
123
- }
124
125
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
126
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
127
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
128
return 1;
129
}
130
#elif defined(TARGET_RISCV)
131
- /* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */
132
- if (infzero) {
133
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
134
- }
135
return 3; /* default NaN */
136
#elif defined(TARGET_S390X)
137
if (infzero) {
138
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
139
return 3;
140
}
141
142
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
143
return 2;
144
}
145
#elif defined(TARGET_SPARC)
146
- /* For (inf,0,nan) return c. */
147
- if (infzero) {
148
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
149
- return 2;
150
- }
151
/* Prefer SNaN over QNaN, order C, B, A. */
152
if (is_snan(c_cls)) {
153
return 2;
154
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
155
* For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
156
* an input NaN if we have one (ie c).
157
*/
158
- if (infzero) {
159
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
160
- return 2;
161
- }
162
if (status->use_first_nan) {
163
if (is_nan(a_cls)) {
164
return 0;
165
--
166
2.34.1
diff view generated by jsdifflib
New patch
1
If the target sets default_nan_mode then we're always going to return
2
the default NaN, and pickNaNMulAdd() no longer has any side effects.
3
For consistency with pickNaN(), check for default_nan_mode before
4
calling pickNaNMulAdd().
1
5
6
When we convert pickNaNMulAdd() to allow runtime selection of the NaN
7
propagation rule, this means we won't have to make the targets which
8
use default_nan_mode also set a propagation rule.
9
10
Since RiscV always uses default_nan_mode, this allows us to remove
11
its ifdef case from pickNaNMulAdd().
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-3-peter.maydell@linaro.org
16
---
17
fpu/softfloat-parts.c.inc | 8 ++++++--
18
fpu/softfloat-specialize.c.inc | 9 +++++++--
19
2 files changed, 13 insertions(+), 4 deletions(-)
20
21
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
index XXXXXXX..XXXXXXX 100644
23
--- a/fpu/softfloat-parts.c.inc
24
+++ b/fpu/softfloat-parts.c.inc
25
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
26
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
27
}
28
29
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
30
+ if (s->default_nan_mode) {
31
+ which = 3;
32
+ } else {
33
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ }
35
36
- if (s->default_nan_mode || which == 3) {
37
+ if (which == 3) {
38
parts_default_nan(a, s);
39
return a;
40
}
41
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
42
index XXXXXXX..XXXXXXX 100644
43
--- a/fpu/softfloat-specialize.c.inc
44
+++ b/fpu/softfloat-specialize.c.inc
45
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
46
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
47
bool infzero, float_status *status)
48
{
49
+ /*
50
+ * We guarantee not to require the target to tell us how to
51
+ * pick a NaN if we're always returning the default NaN.
52
+ * But if we're not in default-NaN mode then the target must
53
+ * specify.
54
+ */
55
+ assert(!status->default_nan_mode);
56
#if defined(TARGET_ARM)
57
/* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
58
* the default NaN
59
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
60
} else {
61
return 1;
62
}
63
-#elif defined(TARGET_RISCV)
64
- return 3; /* default NaN */
65
#elif defined(TARGET_S390X)
66
if (infzero) {
67
return 3;
68
--
69
2.34.1
diff view generated by jsdifflib
1
From: Nabih Estefan Diaz <nabihestefan@google.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
- Implementation of Transmit function for packets
3
architectures thus do different things:
4
- Implementation for reading and writing from and to descriptors in
4
* some return the default NaN
5
memory for Tx
5
* some return the input NaN
6
6
* Arm returns the default NaN if the input NaN is quiet,
7
Added relevant trace-events
7
and the input NaN if it is signalling
8
8
9
NOTE: This function implements the steps detailed in the datasheet for
9
We want to make this logic be runtime selected rather than
10
transmitting messages from the GMAC.
10
hardcoded into the binary, because:
11
11
* this will let us have multiple targets in one QEMU binary
12
Change-Id: Icf14f9fcc6cc7808a41acd872bca67c9832087e6
12
* the Arm FEAT_AFP architectural feature includes letting
13
Signed-off-by: Nabih Estefan <nabihestefan@google.com>
13
the guest select a NaN propagation rule at runtime
14
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
14
15
Message-id: 20240131002800.989285-6-nabihestefan@google.com
15
In this commit we add an enum for the propagation rule, the field in
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
18
---
33
---
19
hw/net/npcm_gmac.c | 203 ++++++++++++++++++++++++++++++++++++++++++++
34
include/fpu/softfloat-helpers.h | 11 ++++
20
hw/net/trace-events | 2 +
35
include/fpu/softfloat-types.h | 23 +++++++++
21
2 files changed, 205 insertions(+)
36
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
22
37
3 files changed, 95 insertions(+), 30 deletions(-)
23
diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
38
39
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
24
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/net/npcm_gmac.c
41
--- a/include/fpu/softfloat-helpers.h
26
+++ b/hw/net/npcm_gmac.c
42
+++ b/include/fpu/softfloat-helpers.h
27
@@ -XXX,XX +XXX,XX @@ static int gmac_write_rx_desc(dma_addr_t addr, struct NPCMGMACRxDesc *desc)
43
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
28
return 0;
44
status->float_2nan_prop_rule = rule;
29
}
45
}
30
46
31
+static int gmac_read_tx_desc(dma_addr_t addr, struct NPCMGMACTxDesc *desc)
47
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
+ float_status *status)
32
+{
49
+{
33
+ if (dma_memory_read(&address_space_memory, addr, desc,
50
+ status->float_infzeronan_rule = rule;
34
+ sizeof(*desc), MEMTXATTRS_UNSPECIFIED)) {
35
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
36
+ HWADDR_PRIx "\n", __func__, addr);
37
+ return -1;
38
+ }
39
+ desc->tdes0 = le32_to_cpu(desc->tdes0);
40
+ desc->tdes1 = le32_to_cpu(desc->tdes1);
41
+ desc->tdes2 = le32_to_cpu(desc->tdes2);
42
+ desc->tdes3 = le32_to_cpu(desc->tdes3);
43
+ return 0;
44
+}
51
+}
45
+
52
+
46
+static int gmac_write_tx_desc(dma_addr_t addr, struct NPCMGMACTxDesc *desc)
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)
47
+{
61
+{
48
+ struct NPCMGMACTxDesc le_desc;
62
+ return status->float_infzeronan_rule;
49
+ le_desc.tdes0 = cpu_to_le32(desc->tdes0);
50
+ le_desc.tdes1 = cpu_to_le32(desc->tdes1);
51
+ le_desc.tdes2 = cpu_to_le32(desc->tdes2);
52
+ le_desc.tdes3 = cpu_to_le32(desc->tdes3);
53
+ if (dma_memory_write(&address_space_memory, addr, &le_desc,
54
+ sizeof(le_desc), MEMTXATTRS_UNSPECIFIED)) {
55
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%"
56
+ HWADDR_PRIx "\n", __func__, addr);
57
+ return -1;
58
+ }
59
+ return 0;
60
+}
63
+}
61
+
64
+
62
static int gmac_rx_transfer_frame_to_buffer(uint32_t rx_buf_len,
65
static inline bool get_flush_to_zero(float_status *status)
63
uint32_t *left_frame,
66
{
64
uint32_t rx_buf_addr,
67
return status->flush_to_zero;
65
@@ -XXX,XX +XXX,XX @@ static ssize_t gmac_receive(NetClientState *nc, const uint8_t *buf, size_t len)
68
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
66
return len;
69
index XXXXXXX..XXXXXXX 100644
67
}
70
--- a/include/fpu/softfloat-types.h
68
71
+++ b/include/fpu/softfloat-types.h
69
+static int gmac_tx_get_csum(uint32_t tdes1)
72
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
70
+{
73
float_2nan_prop_x87,
71
+ uint32_t mask = TX_DESC_TDES1_CHKSM_INS_CTRL_MASK(tdes1);
74
} Float2NaNPropRule;
72
+ int csum = 0;
75
73
+
76
+/*
74
+ if (likely(mask > 0)) {
77
+ * Rule for result of fused multiply-add 0 * Inf + NaN.
75
+ csum |= CSUM_IP;
78
+ * This must be a NaN, but implementations differ on whether this
76
+ }
79
+ * is the input NaN or the default NaN.
77
+ if (likely(mask > 1)) {
80
+ *
78
+ csum |= CSUM_TCP | CSUM_UDP;
81
+ * You don't need to set this if default_nan_mode is enabled.
79
+ }
82
+ * When not in default-NaN mode, it is an error for the target
80
+
83
+ * not to set the rule in float_status if it uses muladd, and we
81
+ return csum;
84
+ * will assert if we need to handle an input NaN and no rule was
82
+}
85
+ * selected.
83
+
86
+ */
84
+static void gmac_try_send_next_packet(NPCMGMACState *gmac)
87
+typedef enum __attribute__((__packed__)) {
85
+{
88
+ /* No propagation rule specified */
86
+ /*
89
+ float_infzeronan_none = 0,
87
+ * Comments about steps refer to steps for
90
+ /* Result is never the default NaN (so always the input NaN) */
88
+ * transmitting in page 384 of datasheet
91
+ float_infzeronan_dnan_never,
89
+ */
92
+ /* Result is always the default NaN */
90
+ uint16_t tx_buffer_size = 2048;
93
+ float_infzeronan_dnan_always,
91
+ g_autofree uint8_t *tx_send_buffer = g_malloc(tx_buffer_size);
94
+ /* Result is the default NaN if the input NaN is quiet */
92
+ uint32_t desc_addr;
95
+ float_infzeronan_dnan_if_qnan,
93
+ struct NPCMGMACTxDesc tx_desc;
96
+} FloatInfZeroNaNRule;
94
+ uint32_t tx_buf_addr, tx_buf_len;
97
+
95
+ uint16_t length = 0;
98
/*
96
+ uint8_t *buf = tx_send_buffer;
99
* Floating Point Status. Individual architectures may maintain
97
+ uint32_t prev_buf_size = 0;
100
* several versions of float_status for different functions. The
98
+ int csum = 0;
101
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
99
+
102
FloatRoundMode float_rounding_mode;
100
+ /* steps 1&2 */
103
FloatX80RoundPrec floatx80_rounding_precision;
101
+ if (!gmac->regs[R_NPCM_DMA_HOST_TX_DESC]) {
104
Float2NaNPropRule float_2nan_prop_rule;
102
+ gmac->regs[R_NPCM_DMA_HOST_TX_DESC] =
105
+ FloatInfZeroNaNRule float_infzeronan_rule;
103
+ NPCM_DMA_HOST_TX_DESC_MASK(gmac->regs[R_NPCM_DMA_TX_BASE_ADDR]);
106
bool tininess_before_rounding;
104
+ }
107
/* should denormalised results go to zero and set the inexact flag? */
105
+ desc_addr = gmac->regs[R_NPCM_DMA_HOST_TX_DESC];
108
bool flush_to_zero;
106
+
109
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
107
+ while (true) {
110
index XXXXXXX..XXXXXXX 100644
108
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
111
--- a/fpu/softfloat-specialize.c.inc
109
+ NPCM_DMA_STATUS_TX_RUNNING_FETCHING_STATE);
112
+++ b/fpu/softfloat-specialize.c.inc
110
+ if (gmac_read_tx_desc(desc_addr, &tx_desc)) {
113
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
111
+ qemu_log_mask(LOG_GUEST_ERROR,
114
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
112
+ "TX Descriptor @ 0x%x can't be read\n",
115
bool infzero, float_status *status)
113
+ desc_addr);
116
{
114
+ return;
117
+ FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
118
+
119
/*
120
* We guarantee not to require the target to tell us how to
121
* pick a NaN if we're always returning the default NaN.
122
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
123
* specify.
124
*/
125
assert(!status->default_nan_mode);
126
+
127
+ if (rule == float_infzeronan_none) {
128
+ /*
129
+ * Temporarily fall back to ifdef ladder
130
+ */
131
#if defined(TARGET_ARM)
132
- /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
133
- * the default NaN
134
- */
135
- if (infzero && is_qnan(c_cls)) {
136
- return 3;
137
+ /*
138
+ * For ARM, the (inf,zero,qnan) case returns the default NaN,
139
+ * but (inf,zero,snan) returns the input NaN.
140
+ */
141
+ rule = float_infzeronan_dnan_if_qnan;
142
+#elif defined(TARGET_MIPS)
143
+ if (snan_bit_is_one(status)) {
144
+ /*
145
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
146
+ * case sets InvalidOp and returns the default NaN
147
+ */
148
+ rule = float_infzeronan_dnan_always;
149
+ } else {
150
+ /*
151
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
152
+ * case sets InvalidOp and returns the input value 'c'
153
+ */
154
+ rule = float_infzeronan_dnan_never;
115
+ }
155
+ }
116
+ /* step 3 */
156
+#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
117
+
157
+ defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
118
+ trace_npcm_gmac_packet_desc_read(DEVICE(gmac)->canonical_path,
158
+ defined(TARGET_I386) || defined(TARGET_LOONGARCH)
119
+ desc_addr);
159
+ /*
120
+ trace_npcm_gmac_debug_desc_data(DEVICE(gmac)->canonical_path, &tx_desc,
160
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
121
+ tx_desc.tdes0, tx_desc.tdes1, tx_desc.tdes2, tx_desc.tdes3);
161
+ * case sets InvalidOp and returns the input value 'c'
122
+
162
+ */
123
+ /* 1 = DMA Owned, 0 = Software Owned */
163
+ /*
124
+ if (!(tx_desc.tdes0 & TX_DESC_TDES0_OWN)) {
164
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
125
+ qemu_log_mask(LOG_GUEST_ERROR,
165
+ * to return an input NaN if we have one (ie c) rather than generating
126
+ "TX Descriptor @ 0x%x is owned by software\n",
166
+ * a default NaN
127
+ desc_addr);
167
+ */
128
+ gmac->regs[R_NPCM_DMA_STATUS] |= NPCM_DMA_STATUS_TU;
168
+ rule = float_infzeronan_dnan_never;
129
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
169
+#elif defined(TARGET_S390X)
130
+ NPCM_DMA_STATUS_TX_SUSPENDED_STATE);
170
+ rule = float_infzeronan_dnan_always;
131
+ gmac_update_irq(gmac);
171
+#endif
132
+ return;
172
}
133
+ }
173
134
+
174
+ if (infzero) {
135
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
175
+ /*
136
+ NPCM_DMA_STATUS_TX_RUNNING_READ_STATE);
176
+ * Inf * 0 + NaN -- some implementations return the default NaN here,
137
+ /* Give the descriptor back regardless of what happens. */
177
+ * and some return the input NaN.
138
+ tx_desc.tdes0 &= ~TX_DESC_TDES0_OWN;
178
+ */
139
+
179
+ switch (rule) {
140
+ if (tx_desc.tdes1 & TX_DESC_TDES1_FIRST_SEG_MASK) {
180
+ case float_infzeronan_dnan_never:
141
+ csum = gmac_tx_get_csum(tx_desc.tdes1);
181
+ return 2;
142
+ }
182
+ case float_infzeronan_dnan_always:
143
+
183
+ return 3;
144
+ /* step 4 */
184
+ case float_infzeronan_dnan_if_qnan:
145
+ tx_buf_addr = tx_desc.tdes2;
185
+ return is_qnan(c_cls) ? 3 : 2;
146
+ gmac->regs[R_NPCM_DMA_CUR_TX_BUF_ADDR] = tx_buf_addr;
186
+ default:
147
+ tx_buf_len = TX_DESC_TDES1_BFFR1_SZ_MASK(tx_desc.tdes1);
187
+ g_assert_not_reached();
148
+ buf = &tx_send_buffer[prev_buf_size];
149
+
150
+ if ((prev_buf_size + tx_buf_len) > sizeof(buf)) {
151
+ tx_buffer_size = prev_buf_size + tx_buf_len;
152
+ tx_send_buffer = g_realloc(tx_send_buffer, tx_buffer_size);
153
+ buf = &tx_send_buffer[prev_buf_size];
154
+ }
155
+
156
+ /* step 5 */
157
+ if (dma_memory_read(&address_space_memory, tx_buf_addr, buf,
158
+ tx_buf_len, MEMTXATTRS_UNSPECIFIED)) {
159
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read packet @ 0x%x\n",
160
+ __func__, tx_buf_addr);
161
+ return;
162
+ }
163
+ length += tx_buf_len;
164
+ prev_buf_size += tx_buf_len;
165
+
166
+ /* If not chained we'll have a second buffer. */
167
+ if (!(tx_desc.tdes1 & TX_DESC_TDES1_SEC_ADDR_CHND_MASK)) {
168
+ tx_buf_addr = tx_desc.tdes3;
169
+ gmac->regs[R_NPCM_DMA_CUR_TX_BUF_ADDR] = tx_buf_addr;
170
+ tx_buf_len = TX_DESC_TDES1_BFFR2_SZ_MASK(tx_desc.tdes1);
171
+ buf = &tx_send_buffer[prev_buf_size];
172
+
173
+ if ((prev_buf_size + tx_buf_len) > sizeof(buf)) {
174
+ tx_buffer_size = prev_buf_size + tx_buf_len;
175
+ tx_send_buffer = g_realloc(tx_send_buffer, tx_buffer_size);
176
+ buf = &tx_send_buffer[prev_buf_size];
177
+ }
178
+
179
+ if (dma_memory_read(&address_space_memory, tx_buf_addr, buf,
180
+ tx_buf_len, MEMTXATTRS_UNSPECIFIED)) {
181
+ qemu_log_mask(LOG_GUEST_ERROR,
182
+ "%s: Failed to read packet @ 0x%x\n",
183
+ __func__, tx_buf_addr);
184
+ return;
185
+ }
186
+ length += tx_buf_len;
187
+ prev_buf_size += tx_buf_len;
188
+ }
189
+ if (tx_desc.tdes1 & TX_DESC_TDES1_LAST_SEG_MASK) {
190
+ net_checksum_calculate(tx_send_buffer, length, csum);
191
+ qemu_send_packet(qemu_get_queue(gmac->nic), tx_send_buffer, length);
192
+ trace_npcm_gmac_packet_sent(DEVICE(gmac)->canonical_path, length);
193
+ buf = tx_send_buffer;
194
+ length = 0;
195
+ }
196
+
197
+ /* step 6 */
198
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
199
+ NPCM_DMA_STATUS_TX_RUNNING_CLOSING_STATE);
200
+ gmac_write_tx_desc(desc_addr, &tx_desc);
201
+ if (tx_desc.tdes1 & TX_DESC_TDES1_TX_END_RING_MASK) {
202
+ desc_addr = gmac->regs[R_NPCM_DMA_TX_BASE_ADDR];
203
+ } else if (tx_desc.tdes1 & TX_DESC_TDES1_SEC_ADDR_CHND_MASK) {
204
+ desc_addr = tx_desc.tdes3;
205
+ } else {
206
+ desc_addr += sizeof(tx_desc);
207
+ }
208
+ gmac->regs[R_NPCM_DMA_HOST_TX_DESC] = desc_addr;
209
+
210
+ /* step 7 */
211
+ if (tx_desc.tdes1 & TX_DESC_TDES1_INTERR_COMP_MASK) {
212
+ gmac->regs[R_NPCM_DMA_STATUS] |= NPCM_DMA_STATUS_TI;
213
+ gmac_update_irq(gmac);
214
+ }
188
+ }
215
+ }
189
+ }
216
+}
190
+
217
+
191
+#if defined(TARGET_ARM)
218
static void gmac_cleanup(NetClientState *nc)
192
+
219
{
193
/* This looks different from the ARM ARM pseudocode, because the ARM ARM
220
/* Nothing to do yet. */
194
* puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
221
@@ -XXX,XX +XXX,XX @@ static void npcm_gmac_write(void *opaque, hwaddr offset,
195
*/
222
NPCM_DMA_STATUS_RX_RUNNING_WAITING_STATE);
196
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
223
break;
197
}
224
198
#elif defined(TARGET_MIPS)
225
+ case A_NPCM_DMA_XMT_POLL_DEMAND:
199
if (snan_bit_is_one(status)) {
226
+ /* We dont actually care about the value */
200
- /*
227
+ gmac_try_send_next_packet(gmac);
201
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
228
+ break;
202
- * case sets InvalidOp and returns the default NaN
229
+
203
- */
230
+ case A_NPCM_DMA_CONTROL:
204
- if (infzero) {
231
+ gmac->regs[offset / sizeof(uint32_t)] = v;
205
- return 3;
232
+ if (v & NPCM_DMA_CONTROL_START_STOP_TX) {
206
- }
233
+ gmac_try_send_next_packet(gmac);
207
/* Prefer sNaN over qNaN, in the a, b, c order. */
234
+ } else {
208
if (is_snan(a_cls)) {
235
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
209
return 0;
236
+ NPCM_DMA_STATUS_TX_STOPPED_STATE);
210
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
237
+ }
211
return 2;
238
+ if (v & NPCM_DMA_CONTROL_START_STOP_RX) {
212
}
239
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT,
213
} else {
240
+ NPCM_DMA_STATUS_RX_RUNNING_WAITING_STATE);
214
- /*
241
+ qemu_flush_queued_packets(qemu_get_queue(gmac->nic));
215
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
242
+ } else {
216
- * case sets InvalidOp and returns the input value 'c'
243
+ gmac_dma_set_state(gmac, NPCM_DMA_STATUS_RX_PROCESS_STATE_SHIFT,
217
- */
244
+ NPCM_DMA_STATUS_RX_STOPPED_STATE);
218
/* Prefer sNaN over qNaN, in the c, a, b order. */
245
+ }
219
if (is_snan(c_cls)) {
246
+ break;
220
return 2;
247
+
221
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
248
case A_NPCM_DMA_STATUS:
222
}
249
/* Check that RO bits are not written to */
223
}
250
if (NPCM_DMA_STATUS_RO_MASK(v)) {
224
#elif defined(TARGET_LOONGARCH64)
251
diff --git a/hw/net/trace-events b/hw/net/trace-events
225
- /*
252
index XXXXXXX..XXXXXXX 100644
226
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
253
--- a/hw/net/trace-events
227
- * case sets InvalidOp and returns the input value 'c'
254
+++ b/hw/net/trace-events
228
- */
255
@@ -XXX,XX +XXX,XX @@ npcm_gmac_packet_desc_read(const char* name, uint32_t desc_addr) "%s: attempting
229
-
256
npcm_gmac_packet_receive(const char* name, uint32_t len) "%s: RX packet length: 0x%04" PRIX32
230
/* Prefer sNaN over qNaN, in the c, a, b order. */
257
npcm_gmac_packet_receiving_buffer(const char* name, uint32_t buf_len, uint32_t rx_buf_addr) "%s: Receiving into Buffer size: 0x%04" PRIX32 " at address 0x%04" PRIX32
231
if (is_snan(c_cls)) {
258
npcm_gmac_packet_received(const char* name, uint32_t len) "%s: Reception finished, packet left: 0x%04" PRIX32
232
return 2;
259
+npcm_gmac_packet_sent(const char* name, uint16_t len) "%s: TX packet sent!, length: 0x%04" PRIX16
233
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
260
npcm_gmac_debug_desc_data(const char* name, void* addr, uint32_t des0, uint32_t des1, uint32_t des2, uint32_t des3)"%s: Address: %p Descriptor 0: 0x%04" PRIX32 " Descriptor 1: 0x%04" PRIX32 "Descriptor 2: 0x%04" PRIX32 " Descriptor 3: 0x%04" PRIX32
234
return 1;
261
+npcm_gmac_packet_tx_desc_data(const char* name, uint32_t tdes0, uint32_t tdes1) "%s: Tdes0: 0x%04" PRIX32 " Tdes1: 0x%04" PRIX32
235
}
262
236
#elif defined(TARGET_PPC)
263
# npcm_pcs.c
237
- /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
264
npcm_pcs_reg_read(const char *name, uint16_t indirect_access_baes, uint64_t offset, uint16_t value) "%s: IND: 0x%02" PRIx16 " offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
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)) {
265
--
256
--
266
2.34.1
257
2.34.1
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for the inf-zero-nan
2
muladd special case. In meson.build we put -DTARGET_ARM in fpcflags,
3
and so we should select here the Arm rule of
4
float_infzeronan_dnan_if_qnan.
1
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241202131347.498124-5-peter.maydell@linaro.org
9
---
10
tests/fp/fp-bench.c | 5 +++++
11
tests/fp/fp-test.c | 5 +++++
12
2 files changed, 10 insertions(+)
13
14
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/fp/fp-bench.c
17
+++ b/tests/fp/fp-bench.c
18
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
19
{
20
bench_func_t f;
21
22
+ /*
23
+ * These implementation-defined choices for various things IEEE
24
+ * doesn't specify match those used by the Arm architecture.
25
+ */
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
28
29
f = bench_funcs[operation][precision];
30
g_assert(f);
31
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/tests/fp/fp-test.c
34
+++ b/tests/fp/fp-test.c
35
@@ -XXX,XX +XXX,XX @@ void run_test(void)
36
{
37
unsigned int i;
38
39
+ /*
40
+ * These implementation-defined choices for various things IEEE
41
+ * doesn't specify match those used by the Arm architecture.
42
+ */
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
44
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
45
46
genCases_setLevel(test_level);
47
verCases_maxErrorCount = n_max_errors;
48
--
49
2.34.1
diff view generated by jsdifflib
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: Nabih Estefan Diaz <nabihestefan@google.com>
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
- Add PCS Register check to npcm_gmac-test
3
are NaNs. As a result different architectures have ended up with
4
4
different rules for propagating NaNs.
5
Change-Id: I34821beb5e0b1e89e2be576ab58eabe41545af12
5
6
Signed-off-by: Nabih Estefan <nabihestefan@google.com>
6
QEMU currently hardcodes the NaN propagation logic into the binary
7
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
7
because pickNaNMulAdd() has an ifdef ladder for different targets.
8
Message-id: 20240131002800.989285-7-nabihestefan@google.com
8
We want to make the propagation rule instead be selectable at
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
runtime, because:
10
* this will let us have multiple targets in one QEMU binary
11
* the Arm FEAT_AFP architectural feature includes letting
12
the guest select a NaN propagation rule at runtime
13
14
In this commit we add an enum for the propagation rule, the field in
15
float_status, and the corresponding getters and setters. We change
16
pickNaNMulAdd to honour this, but because all targets still leave
17
this field at its default 0 value, the fallback logic will pick the
18
rule type with the old ifdef ladder.
19
20
It's valid not to set a propagation rule if default_nan_mode is
21
enabled, because in that case there's no need to pick a NaN; all the
22
callers of pickNaNMulAdd() catch this case and skip calling it.
23
10
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
11
---
27
---
12
tests/qtest/npcm_gmac-test.c | 132 +++++++++++++++++++++++++++++++++++
28
include/fpu/softfloat-helpers.h | 11 +++
13
1 file changed, 132 insertions(+)
29
include/fpu/softfloat-types.h | 55 +++++++++++
14
30
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
15
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.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
16
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/qtest/npcm_gmac-test.c
35
--- a/include/fpu/softfloat-helpers.h
18
+++ b/tests/qtest/npcm_gmac-test.c
36
+++ b/include/fpu/softfloat-helpers.h
19
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
20
/* Name of the GMAC Device */
38
status->float_2nan_prop_rule = rule;
21
#define TYPE_NPCM_GMAC "npcm-gmac"
22
23
+/* Address of the PCS Module */
24
+#define PCS_BASE_ADDRESS 0xf0780000
25
+#define NPCM_PCS_IND_AC_BA 0x1fe
26
+
27
typedef struct GMACModule {
28
int irq;
29
uint64_t base_addr;
30
@@ -XXX,XX +XXX,XX @@ typedef enum NPCMRegister {
31
NPCM_GMAC_PTP_STNSUR = 0x714,
32
NPCM_GMAC_PTP_TAR = 0x718,
33
NPCM_GMAC_PTP_TTSR = 0x71c,
34
+
35
+ /* PCS Registers */
36
+ NPCM_PCS_SR_CTL_ID1 = 0x3c0008,
37
+ NPCM_PCS_SR_CTL_ID2 = 0x3c000a,
38
+ NPCM_PCS_SR_CTL_STS = 0x3c0010,
39
+
40
+ NPCM_PCS_SR_MII_CTRL = 0x3e0000,
41
+ NPCM_PCS_SR_MII_STS = 0x3e0002,
42
+ NPCM_PCS_SR_MII_DEV_ID1 = 0x3e0004,
43
+ NPCM_PCS_SR_MII_DEV_ID2 = 0x3e0006,
44
+ NPCM_PCS_SR_MII_AN_ADV = 0x3e0008,
45
+ NPCM_PCS_SR_MII_LP_BABL = 0x3e000a,
46
+ NPCM_PCS_SR_MII_AN_EXPN = 0x3e000c,
47
+ NPCM_PCS_SR_MII_EXT_STS = 0x3e001e,
48
+
49
+ NPCM_PCS_SR_TIM_SYNC_ABL = 0x3e0e10,
50
+ NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR = 0x3e0e12,
51
+ NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR = 0x3e0e14,
52
+ NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR = 0x3e0e16,
53
+ NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR = 0x3e0e18,
54
+ NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR = 0x3e0e1a,
55
+ NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR = 0x3e0e1c,
56
+ NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR = 0x3e0e1e,
57
+ NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR = 0x3e0e20,
58
+
59
+ NPCM_PCS_VR_MII_MMD_DIG_CTRL1 = 0x3f0000,
60
+ NPCM_PCS_VR_MII_AN_CTRL = 0x3f0002,
61
+ NPCM_PCS_VR_MII_AN_INTR_STS = 0x3f0004,
62
+ NPCM_PCS_VR_MII_TC = 0x3f0006,
63
+ NPCM_PCS_VR_MII_DBG_CTRL = 0x3f000a,
64
+ NPCM_PCS_VR_MII_EEE_MCTRL0 = 0x3f000c,
65
+ NPCM_PCS_VR_MII_EEE_TXTIMER = 0x3f0010,
66
+ NPCM_PCS_VR_MII_EEE_RXTIMER = 0x3f0012,
67
+ NPCM_PCS_VR_MII_LINK_TIMER_CTRL = 0x3f0014,
68
+ NPCM_PCS_VR_MII_EEE_MCTRL1 = 0x3f0016,
69
+ NPCM_PCS_VR_MII_DIG_STS = 0x3f0020,
70
+ NPCM_PCS_VR_MII_ICG_ERRCNT1 = 0x3f0022,
71
+ NPCM_PCS_VR_MII_MISC_STS = 0x3f0030,
72
+ NPCM_PCS_VR_MII_RX_LSTS = 0x3f0040,
73
+ NPCM_PCS_VR_MII_MP_TX_BSTCTRL0 = 0x3f0070,
74
+ NPCM_PCS_VR_MII_MP_TX_LVLCTRL0 = 0x3f0074,
75
+ NPCM_PCS_VR_MII_MP_TX_GENCTRL0 = 0x3f007a,
76
+ NPCM_PCS_VR_MII_MP_TX_GENCTRL1 = 0x3f007c,
77
+ NPCM_PCS_VR_MII_MP_TX_STS = 0x3f0090,
78
+ NPCM_PCS_VR_MII_MP_RX_GENCTRL0 = 0x3f00b0,
79
+ NPCM_PCS_VR_MII_MP_RX_GENCTRL1 = 0x3f00b2,
80
+ NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0 = 0x3f00ba,
81
+ NPCM_PCS_VR_MII_MP_MPLL_CTRL0 = 0x3f00f0,
82
+ NPCM_PCS_VR_MII_MP_MPLL_CTRL1 = 0x3f00f2,
83
+ NPCM_PCS_VR_MII_MP_MPLL_STS = 0x3f0110,
84
+ NPCM_PCS_VR_MII_MP_MISC_CTRL2 = 0x3f0126,
85
+ NPCM_PCS_VR_MII_MP_LVL_CTRL = 0x3f0130,
86
+ NPCM_PCS_VR_MII_MP_MISC_CTRL0 = 0x3f0132,
87
+ NPCM_PCS_VR_MII_MP_MISC_CTRL1 = 0x3f0134,
88
+ NPCM_PCS_VR_MII_DIG_CTRL2 = 0x3f01c2,
89
+ NPCM_PCS_VR_MII_DIG_ERRCNT_SEL = 0x3f01c4,
90
} NPCMRegister;
91
92
static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
93
@@ -XXX,XX +XXX,XX @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
94
return qtest_readl(qts, mod->base_addr + regno);
95
}
39
}
96
40
97
+static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
41
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
98
+ NPCMRegister regno)
42
+ float_status *status)
99
+{
43
+{
100
+ uint32_t write_value = (regno & 0x3ffe00) >> 9;
44
+ status->float_3nan_prop_rule = rule;
101
+ qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
102
+ uint32_t read_offset = regno & 0x1ff;
103
+ return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
104
+}
45
+}
105
+
46
+
106
/* Check that GMAC registers are reset to default value */
47
static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
107
static void test_init(gconstpointer test_data)
48
float_status *status)
108
{
49
{
109
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
50
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
110
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
51
return status->float_2nan_prop_rule;
111
} while (0)
52
}
112
53
113
+#define CHECK_REG_PCS(regno, value) \
54
+static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
114
+ do { \
55
+{
115
+ g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
56
+ return status->float_3nan_prop_rule;
116
+ } while (0)
57
+}
117
+
58
+
118
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
59
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
119
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
60
{
120
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
61
return status->float_infzeronan_rule;
121
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
62
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
122
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
63
index XXXXXXX..XXXXXXX 100644
123
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
64
--- a/include/fpu/softfloat-types.h
124
65
+++ b/include/fpu/softfloat-types.h
125
+ /* TODO Add registers PCS */
66
@@ -XXX,XX +XXX,XX @@ this code that are retained.
126
+ if (mod->base_addr == 0xf0802000) {
67
#ifndef SOFTFLOAT_TYPES_H
127
+ CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
68
#define SOFTFLOAT_TYPES_H
128
+ CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
69
129
+ CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
70
+#include "hw/registerfields.h"
130
+
71
+
131
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
72
/*
132
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109);
73
* Software IEC/IEEE floating-point types.
133
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID1, 0x699e);
74
*/
134
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID2, 0x0ced0);
75
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
135
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_ADV, 0x0020);
76
float_2nan_prop_x87,
136
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_LP_BABL, 0);
77
} Float2NaNPropRule;
137
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_EXPN, 0);
78
138
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_EXT_STS, 0xc000);
79
+/*
139
+
80
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
140
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_ABL, 0x0003);
81
+ * architectures have different rules for which input NaN is
141
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x0038);
82
+ * propagated to the output when there is more than one NaN on the
142
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0);
83
+ * input.
143
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x0038);
84
+ *
144
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0);
85
+ * If default_nan_mode is enabled then it is valid not to set a NaN
145
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x0058);
86
+ * propagation rule, because the softfloat code guarantees not to try
146
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR, 0);
87
+ * to pick a NaN to propagate in default NaN mode. When not in
147
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR, 0x0048);
88
+ * default-NaN mode, it is an error for the target not to set the rule
148
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR, 0);
89
+ * in float_status if it uses a muladd, and we will assert if we need
149
+
90
+ * to handle an input NaN and no rule was selected.
150
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x2400);
91
+ *
151
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_CTRL, 0);
92
+ * The naming scheme for Float3NaNPropRule values is:
152
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_INTR_STS, 0x000a);
93
+ * float_3nan_prop_s_abc:
153
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_TC, 0);
94
+ * = "Prefer SNaN over QNaN, then operand A over B over C"
154
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_DBG_CTRL, 0);
95
+ * float_3nan_prop_abc:
155
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x899c);
96
+ * = "Prefer A over B over C regardless of SNaN vs QNAN"
156
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_TXTIMER, 0);
97
+ *
157
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_RXTIMER, 0);
98
+ * For QEMU, the multiply-add operation is A * B + C.
158
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_LINK_TIMER_CTRL, 0);
99
+ */
159
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL1, 0);
100
+
160
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_STS, 0x0010);
101
+/*
161
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_ICG_ERRCNT1, 0);
102
+ * We set the Float3NaNPropRule enum values up so we can select the
162
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MISC_STS, 0);
103
+ * right value in pickNaNMulAdd in a data driven way.
163
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_RX_LSTS, 0);
104
+ */
164
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_BSTCTRL0, 0x00a);
105
+FIELD(3NAN, 1ST, 0, 2) /* which operand is most preferred ? */
165
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_LVLCTRL0, 0x007f);
106
+FIELD(3NAN, 2ND, 2, 2) /* which operand is next most preferred ? */
166
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL0, 0x0001);
107
+FIELD(3NAN, 3RD, 4, 2) /* which operand is least preferred ? */
167
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL1, 0);
108
+FIELD(3NAN, SNAN, 6, 1) /* do we prefer SNaN over QNaN ? */
168
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_STS, 0);
109
+
169
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL0, 0x0100);
110
+#define PROPRULE(X, Y, Z) \
170
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL1, 0x1100);
111
+ ((X << R_3NAN_1ST_SHIFT) | (Y << R_3NAN_2ND_SHIFT) | (Z << R_3NAN_3RD_SHIFT))
171
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0, 0x000e);
112
+
172
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL0, 0x0100);
113
+typedef enum __attribute__((__packed__)) {
173
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL1, 0x0032);
114
+ float_3nan_prop_none = 0, /* No propagation rule specified */
174
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_STS, 0x0001);
115
+ float_3nan_prop_abc = PROPRULE(0, 1, 2),
175
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL2, 0);
116
+ float_3nan_prop_acb = PROPRULE(0, 2, 1),
176
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_LVL_CTRL, 0x0019);
117
+ float_3nan_prop_bac = PROPRULE(1, 0, 2),
177
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL0, 0);
118
+ float_3nan_prop_bca = PROPRULE(1, 2, 0),
178
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL1, 0);
119
+ float_3nan_prop_cab = PROPRULE(2, 0, 1),
179
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_CTRL2, 0);
120
+ float_3nan_prop_cba = PROPRULE(2, 1, 0),
180
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_ERRCNT_SEL, 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
181
+ }
321
+ }
182
+
322
+
183
qtest_quit(qts);
323
+ assert(rule != float_3nan_prop_none);
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]));
335
+ }
336
+ return which;
184
}
337
}
185
338
339
/*----------------------------------------------------------------------------
186
--
340
--
187
2.34.1
341
2.34.1
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for propagating NaNs in
2
the muladd case. In meson.build we put -DTARGET_ARM in fpcflags, and
3
so we should select here the Arm rule of float_3nan_prop_s_cab.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-17-peter.maydell@linaro.org
8
---
9
tests/fp/fp-bench.c | 1 +
10
tests/fp/fp-test.c | 1 +
11
2 files changed, 2 insertions(+)
12
13
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/fp/fp-bench.c
16
+++ b/tests/fp/fp-bench.c
17
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
18
* doesn't specify match those used by the Arm architecture.
19
*/
20
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
22
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
23
24
f = bench_funcs[operation][precision];
25
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/fp/fp-test.c
28
+++ b/tests/fp/fp-test.c
29
@@ -XXX,XX +XXX,XX @@ void run_test(void)
30
* doesn't specify match those used by the Arm architecture.
31
*/
32
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
33
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
34
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
35
36
genCases_setLevel(test_level);
37
--
38
2.34.1
diff view generated by jsdifflib
1
In commit 4315f7c614743 we restructured the logic for creating the
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
VFP related properties to avoid testing the aa32_simd_r32 feature on
2
ifdef from pickNaNMulAdd().
3
AArch64 CPUs. However in the process we accidentally stopped
4
exposing the "vfp" QOM property on AArch32 TCG CPUs.
5
3
6
This mostly hasn't had any ill effects because not many people want
7
to disable VFP, but it wasn't intentional. Reinstate the property.
8
9
Cc: qemu-stable@nongnu.org
10
Fixes: 4315f7c614743 ("target/arm: Restructure has_vfp_d32 test")
11
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2098
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20240126193432.2210558-1-peter.maydell@linaro.org
6
Message-id: 20241202131347.498124-18-peter.maydell@linaro.org
15
---
7
---
16
target/arm/cpu.c | 4 ++++
8
target/arm/cpu.c | 5 +++++
17
1 file changed, 4 insertions(+)
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 6 insertions(+), 7 deletions(-)
18
11
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
14
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
24
}
17
* * tininess-before-rounding
25
} else if (cpu_isar_feature(aa32_vfp, cpu)) {
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
26
cpu->has_vfp = true;
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
27
+ if (tcg_enabled() || qtest_enabled()) {
20
+ * * 3-input NaN propagation prefers SNaN over QNaN, and then
28
+ qdev_property_add_static(DEVICE(obj),
21
+ * operand C over A over B (see FPProcessNaNs3() pseudocode,
29
+ &arm_cpu_has_vfp_property);
22
+ * but note that for QEMU muladd is a * b + c, whereas for
30
+ }
23
+ * the pseudocode function the arguments are in the order c, a, b.
31
if (cpu_isar_feature(aa32_simd_r32, cpu)) {
24
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
32
cpu->has_vfp_d32 = true;
25
* and the input NaN if it is signalling
33
/*
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 {
34
--
54
--
35
2.34.1
55
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for loongarch, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-19-peter.maydell@linaro.org
7
---
8
target/loongarch/tcg/fpu_helper.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/loongarch/tcg/fpu_helper.c
15
+++ b/target/loongarch/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
17
* case sets InvalidOp and returns the input value 'c'
18
*/
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
21
}
22
23
int ieee_ex_to_loongarch(int xcpt)
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_LOONGARCH64)
33
- rule = float_3nan_prop_s_cab;
34
#elif defined(TARGET_PPC)
35
/*
36
* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for PPC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-20-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 8 ++++++++
9
fpu/softfloat-specialize.c.inc | 6 ------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * NaN propagation for fused multiply-add:
22
+ * if fRA is a NaN return it; otherwise if fRB is a NaN return it;
23
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
24
+ * whereas QEMU labels the operands as (a * b) + c.
25
+ */
26
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->fp_status);
27
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->vec_status);
28
/*
29
* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
30
* to return an input NaN if we have one (ie c) rather than generating
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
} else {
37
rule = float_3nan_prop_s_cab;
38
}
39
-#elif defined(TARGET_PPC)
40
- /*
41
- * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
42
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
43
- */
44
- rule = float_3nan_prop_acb;
45
#elif defined(TARGET_S390X)
46
rule = float_3nan_prop_s_abc;
47
#elif defined(TARGET_SPARC)
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for s390x, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-21-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
21
set_float_infzeronan_rule(float_infzeronan_dnan_always,
22
&env->fpu_status);
23
/* fall through */
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_S390X)
33
- rule = float_3nan_prop_s_abc;
34
#elif defined(TARGET_SPARC)
35
rule = float_3nan_prop_s_cba;
36
#elif defined(TARGET_XTENSA)
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for SPARC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-22-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For fused-multiply add, prefer SNaN over QNaN, then C->B->A */
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
22
/* For inf * 0 + NaN, return the input NaN */
23
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
} else {
31
rule = float_3nan_prop_s_cab;
32
}
33
-#elif defined(TARGET_SPARC)
34
- rule = float_3nan_prop_s_cba;
35
#elif defined(TARGET_XTENSA)
36
if (status->use_first_nan) {
37
rule = float_3nan_prop_abc;
38
--
39
2.34.1
diff view generated by jsdifflib
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: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
1
Set the Float3NaNPropRule explicitly for xtensa, and remove the
2
ifdef from pickNaNMulAdd().
2
3
3
Tracing DPRINTFs to stderr might not be desired. A developer that relies
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
on tracepoints should be able to opt-in to each tracepoint and rely on
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
QEMU's log redirection, instead of stderr by default.
6
Message-id: 20241202131347.498124-24-peter.maydell@linaro.org
7
---
8
target/xtensa/fpu_helper.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 8 --------
10
2 files changed, 2 insertions(+), 8 deletions(-)
6
11
7
This commit converts DPRINTFs in this file that are used for tracing
12
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
8
into tracepoints.
9
10
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Message-id: b000ab73022dfeb7a7ab0ee8fd0f41fb208adaf0.1706544115.git.manos.pitsidianakis@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/xen/xen-hvm-common.c | 35 ++++++++++++++++++-----------------
16
hw/xen/trace-events | 10 +++++++++-
17
2 files changed, 27 insertions(+), 18 deletions(-)
18
19
diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/xen/xen-hvm-common.c
14
--- a/target/xtensa/fpu_helper.c
22
+++ b/hw/xen/xen-hvm-common.c
15
+++ b/target/xtensa/fpu_helper.c
23
@@ -XXX,XX +XXX,XX @@ static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu)
16
@@ -XXX,XX +XXX,XX @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
24
ioreq_t *req = xen_vcpu_ioreq(state->shared_page, vcpu);
17
set_use_first_nan(use_first, &env->fp_status);
25
18
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
26
if (req->state != STATE_IOREQ_READY) {
19
&env->fp_status);
27
- DPRINTF("I/O request not ready: "
20
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
28
- "%x, ptr: %x, port: %"PRIx64", "
21
+ &env->fp_status);
29
- "data: %"PRIx64", count: %u, size: %u\n",
22
}
30
- req->state, req->data_is_ptr, req->addr,
23
31
- req->data, req->count, req->size);
24
void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
32
+ trace_cpu_get_ioreq_from_shared_memory_req_not_ready(req->state,
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
33
+ req->data_is_ptr,
26
index XXXXXXX..XXXXXXX 100644
34
+ req->addr,
27
--- a/fpu/softfloat-specialize.c.inc
35
+ req->data,
28
+++ b/fpu/softfloat-specialize.c.inc
36
+ req->count,
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
37
+ req->size);
38
return NULL;
39
}
30
}
40
31
41
@@ -XXX,XX +XXX,XX @@ static void xen_main_loop_prepare(XenIOState *state)
32
if (rule == float_3nan_prop_none) {
42
if (evtchn_fd != -1) {
33
-#if defined(TARGET_XTENSA)
43
CPUState *cpu_state;
34
- if (status->use_first_nan) {
44
35
- rule = float_3nan_prop_abc;
45
- DPRINTF("%s: Init cpu_by_vcpu_id\n", __func__);
36
- } else {
46
CPU_FOREACH(cpu_state) {
37
- rule = float_3nan_prop_cba;
47
- DPRINTF("%s: cpu_by_vcpu_id[%d]=%p\n",
38
- }
48
- __func__, cpu_state->cpu_index, cpu_state);
39
-#else
49
+ trace_xen_main_loop_prepare_init_cpu(cpu_state->cpu_index,
40
rule = float_3nan_prop_abc;
50
+ cpu_state);
41
-#endif
51
state->cpu_by_vcpu_id[cpu_state->cpu_index] = cpu_state;
52
}
53
qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
54
@@ -XXX,XX +XXX,XX @@ static int xen_map_ioreq_server(XenIOState *state)
55
}
42
}
56
43
57
if (state->shared_page == NULL) {
44
assert(rule != float_3nan_prop_none);
58
- DPRINTF("shared page at pfn %lx\n", ioreq_pfn);
59
+ trace_xen_map_ioreq_server_shared_page(ioreq_pfn);
60
61
state->shared_page = xenforeignmemory_map(xen_fmem, xen_domid,
62
PROT_READ | PROT_WRITE,
63
@@ -XXX,XX +XXX,XX @@ static int xen_map_ioreq_server(XenIOState *state)
64
}
65
66
if (state->buffered_io_page == NULL) {
67
- DPRINTF("buffered io page at pfn %lx\n", bufioreq_pfn);
68
+ trace_xen_map_ioreq_server_buffered_io_page(bufioreq_pfn);
69
70
state->buffered_io_page = xenforeignmemory_map(xen_fmem, xen_domid,
71
PROT_READ | PROT_WRITE,
72
@@ -XXX,XX +XXX,XX @@ static int xen_map_ioreq_server(XenIOState *state)
73
return -1;
74
}
75
76
- DPRINTF("buffered io evtchn is %x\n", bufioreq_evtchn);
77
+ trace_xen_map_ioreq_server_buffered_io_evtchn(bufioreq_evtchn);
78
79
state->bufioreq_remote_port = bufioreq_evtchn;
80
81
@@ -XXX,XX +XXX,XX @@ void destroy_hvm_domain(bool reboot)
82
83
xc_handle = xc_interface_open(0, 0, 0);
84
if (xc_handle == NULL) {
85
- fprintf(stderr, "Cannot acquire xenctrl handle\n");
86
+ trace_destroy_hvm_domain_cannot_acquire_handle();
87
} else {
88
sts = xc_domain_shutdown(xc_handle, xen_domid, reason);
89
if (sts != 0) {
90
- fprintf(stderr, "xc_domain_shutdown failed to issue %s, "
91
- "sts %d, %s\n", reboot ? "reboot" : "poweroff",
92
- sts, strerror(errno));
93
+ trace_destroy_hvm_domain_failed_action(
94
+ reboot ? "reboot" : "poweroff", sts, strerror(errno)
95
+ );
96
} else {
97
- fprintf(stderr, "Issued domain %d %s\n", xen_domid,
98
- reboot ? "reboot" : "poweroff");
99
+ trace_destroy_hvm_domain_action(
100
+ xen_domid, reboot ? "reboot" : "poweroff"
101
+ );
102
}
103
xc_interface_close(xc_handle);
104
}
105
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
106
index XXXXXXX..XXXXXXX 100644
107
--- a/hw/xen/trace-events
108
+++ b/hw/xen/trace-events
109
@@ -XXX,XX +XXX,XX @@ xs_node_vscanf(char *path, char *value) "%s %s"
110
xs_node_watch(char *path) "%s"
111
xs_node_unwatch(char *path) "%s"
112
113
-# xen-hvm.c
114
+# xen-hvm-common.c
115
xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: 0x%lx, size 0x%lx"
116
xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty) "0x%"PRIx64" size 0x%lx, log_dirty %i"
117
handle_ioreq(void *req, uint32_t type, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p type=%d dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
118
@@ -XXX,XX +XXX,XX @@ cpu_ioreq_move(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint6
119
xen_map_resource_ioreq(uint32_t id, void *addr) "id: %u addr: %p"
120
cpu_ioreq_config_read(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
121
cpu_ioreq_config_write(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
122
+cpu_get_ioreq_from_shared_memory_req_not_ready(int state, int data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O request not ready: 0x%x, ptr: 0x%x, port: 0x%"PRIx64", data: 0x%"PRIx64", count: %u, size: %u"
123
+xen_main_loop_prepare_init_cpu(int id, void *cpu) "cpu_by_vcpu_id[%d]=%p"
124
+xen_map_ioreq_server_shared_page(long unsigned int ioreq_pfn) "shared page at pfn 0x%lx"
125
+xen_map_ioreq_server_buffered_io_page(long unsigned int ioreq_pfn) "buffered io page at pfn 0x%lx"
126
+xen_map_ioreq_server_buffered_io_evtchn(int bufioreq_evtchn) "buffered io evtchn is 0x%x"
127
+destroy_hvm_domain_cannot_acquire_handle(void) "Cannot acquire xenctrl handle"
128
+destroy_hvm_domain_failed_action(const char *action, int sts, char *errno_s) "xc_domain_shutdown failed to issue %s, sts %d, %s"
129
+destroy_hvm_domain_action(int xen_domid, const char *action) "Issued domain %d %s"
130
131
# xen-mapcache.c
132
xen_map_cache(uint64_t phys_addr) "want 0x%"PRIx64
133
--
45
--
134
2.34.1
46
2.34.1
135
136
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
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
QDev objects created with qdev_new() need to manually add
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
their parent relationship with object_property_add_child().
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Gavin Shan <gshan@redhat.com>
8
Message-id: 20241202131347.498124-25-peter.maydell@linaro.org
9
Message-id: 20240129151828.59544-2-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
hw/arm/exynos4210.c | 1 +
10
target/i386/tcg/fpu_helper.c | 1 +
13
1 file changed, 1 insertion(+)
11
1 file changed, 1 insertion(+)
14
12
15
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
13
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/exynos4210.c
15
--- a/target/i386/tcg/fpu_helper.c
18
+++ b/hw/arm/exynos4210.c
16
+++ b/target/i386/tcg/fpu_helper.c
19
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
20
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
18
* there are multiple input NaNs they are selected in the order a, b, c.
21
Object *cpuobj = object_new(ARM_CPU_TYPE_NAME("cortex-a9"));
19
*/
22
20
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
23
+ object_property_add_child(OBJECT(s), "cpu[*]", cpuobj);
21
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
24
/* By default A9 CPUs have EL3 enabled. This board does not currently
22
}
25
* support EL3 so the CPU EL3 property is disabled before realization.
23
26
*/
24
static inline uint8_t save_exception_flags(CPUX86State *env)
27
--
25
--
28
2.34.1
26
2.34.1
29
30
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
1
BusClass currently has transitional infrastructure to support
1
The use_first_nan field in float_status was an xtensa-specific way to
2
subclasses which implement the legacy BusClass::reset method rather
2
select at runtime from two different NaN propagation rules. Now that
3
than the Resettable interface. We have now removed all the users of
3
xtensa is using the target-agnostic NaN propagation rule selection
4
BusClass::reset in the tree, so we can remove the transitional
4
that we've just added, we can remove use_first_nan, because there is
5
infrastructure.
5
no longer any code that reads it.
6
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Acked-by: Michael S. Tsirkin <mst@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Acked-by: Cédric Le Goater <clg@redhat.com>
9
Message-id: 20241202131347.498124-27-peter.maydell@linaro.org
10
Acked-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
11
Tested-by: Cédric Le Goater <clg@redhat.com>
12
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
13
Message-id: 20240119163512.3810301-6-peter.maydell@linaro.org
14
---
10
---
15
include/hw/qdev-core.h | 2 --
11
include/fpu/softfloat-helpers.h | 5 -----
16
hw/core/bus.c | 67 ------------------------------------------
12
include/fpu/softfloat-types.h | 1 -
17
2 files changed, 69 deletions(-)
13
target/xtensa/fpu_helper.c | 1 -
14
3 files changed, 7 deletions(-)
18
15
19
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
16
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/qdev-core.h
18
--- a/include/fpu/softfloat-helpers.h
22
+++ b/include/hw/qdev-core.h
19
+++ b/include/fpu/softfloat-helpers.h
23
@@ -XXX,XX +XXX,XX @@ struct BusClass {
20
@@ -XXX,XX +XXX,XX @@ static inline void set_snan_bit_is_one(bool val, float_status *status)
24
*/
21
status->snan_bit_is_one = val;
25
char *(*get_fw_dev_path)(DeviceState *dev);
26
27
- void (*reset)(BusState *bus);
28
-
29
/*
30
* Return whether the device can be added to @bus,
31
* based on the address that was set (via device properties)
32
diff --git a/hw/core/bus.c b/hw/core/bus.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/core/bus.c
35
+++ b/hw/core/bus.c
36
@@ -XXX,XX +XXX,XX @@ static char *default_bus_get_fw_dev_path(DeviceState *dev)
37
return g_strdup(object_get_typename(OBJECT(dev)));
38
}
22
}
39
23
40
-/**
24
-static inline void set_use_first_nan(bool val, float_status *status)
41
- * bus_phases_reset:
42
- * Transition reset method for buses to allow moving
43
- * smoothly from legacy reset method to multi-phases
44
- */
45
-static void bus_phases_reset(BusState *bus)
46
-{
25
-{
47
- ResettableClass *rc = RESETTABLE_GET_CLASS(bus);
26
- status->use_first_nan = val;
48
-
49
- if (rc->phases.enter) {
50
- rc->phases.enter(OBJECT(bus), RESET_TYPE_COLD);
51
- }
52
- if (rc->phases.hold) {
53
- rc->phases.hold(OBJECT(bus));
54
- }
55
- if (rc->phases.exit) {
56
- rc->phases.exit(OBJECT(bus));
57
- }
58
-}
27
-}
59
-
28
-
60
-static void bus_transitional_reset(Object *obj)
29
static inline void set_no_signaling_nans(bool val, float_status *status)
61
-{
62
- BusClass *bc = BUS_GET_CLASS(obj);
63
-
64
- /*
65
- * This will call either @bus_phases_reset (for multi-phases transitioned
66
- * buses) or a bus's specific method for not-yet transitioned buses.
67
- * In both case, it does not reset children.
68
- */
69
- if (bc->reset) {
70
- bc->reset(BUS(obj));
71
- }
72
-}
73
-
74
-/**
75
- * bus_get_transitional_reset:
76
- * check if the bus's class is ready for multi-phase
77
- */
78
-static ResettableTrFunction bus_get_transitional_reset(Object *obj)
79
-{
80
- BusClass *dc = BUS_GET_CLASS(obj);
81
- if (dc->reset != bus_phases_reset) {
82
- /*
83
- * dc->reset has been overridden by a subclass,
84
- * the bus is not ready for multi phase yet.
85
- */
86
- return bus_transitional_reset;
87
- }
88
- return NULL;
89
-}
90
-
91
static void bus_class_init(ObjectClass *class, void *data)
92
{
30
{
93
BusClass *bc = BUS_CLASS(class);
31
status->no_signaling_nans = val;
94
@@ -XXX,XX +XXX,XX @@ static void bus_class_init(ObjectClass *class, void *data)
32
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
95
33
index XXXXXXX..XXXXXXX 100644
96
rc->get_state = bus_get_reset_state;
34
--- a/include/fpu/softfloat-types.h
97
rc->child_foreach = bus_reset_child_foreach;
35
+++ b/include/fpu/softfloat-types.h
98
-
36
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
99
- /*
37
* softfloat-specialize.inc.c)
100
- * @bus_phases_reset is put as the default reset method below, allowing
38
*/
101
- * to do the multi-phase transition from base classes to leaf classes. It
39
bool snan_bit_is_one;
102
- * allows a legacy-reset Bus class to extend a multi-phases-reset
40
- bool use_first_nan;
103
- * Bus class for the following reason:
41
bool no_signaling_nans;
104
- * + If a base class B has been moved to multi-phase, then it does not
42
/* should overflowed results subtract re_bias to its exponent? */
105
- * override this default reset method and may have defined phase methods.
43
bool rebias_overflow;
106
- * + A child class C (extending class B) which uses
44
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
107
- * bus_class_set_parent_reset() (or similar means) to override the
45
index XXXXXXX..XXXXXXX 100644
108
- * reset method will still work as expected. @bus_phases_reset function
46
--- a/target/xtensa/fpu_helper.c
109
- * will be registered as the parent reset method and effectively call
47
+++ b/target/xtensa/fpu_helper.c
110
- * parent reset phases.
48
@@ -XXX,XX +XXX,XX @@ static const struct {
111
- */
49
112
- bc->reset = bus_phases_reset;
50
void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
113
- rc->get_transitional_function = bus_get_transitional_reset;
51
{
114
}
52
- set_use_first_nan(use_first, &env->fp_status);
115
53
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
116
static void qbus_finalize(Object *obj)
54
&env->fp_status);
55
set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
117
--
56
--
118
2.34.1
57
2.34.1
119
120
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
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
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.
2
4
3
Leverage the common code introduced in commit c9cf636d48 ("machine:
5
floatx80 is used only by:
4
Add a valid_cpu_types property") to check for the single valid CPU
6
i386
5
type. Remove the now unused MachineClass::default_cpu_type field.
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)
6
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>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
38
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Gavin Shan <gshan@redhat.com>
39
Message-id: 20241202131347.498124-29-peter.maydell@linaro.org
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20240129151828.59544-10-philmd@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
40
---
13
hw/arm/xilinx_zynq.c | 6 +++++-
41
fpu/softfloat-specialize.c.inc | 20 ++++++++++----------
14
1 file changed, 5 insertions(+), 1 deletion(-)
42
1 file changed, 10 insertions(+), 10 deletions(-)
15
43
16
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
44
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
17
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/xilinx_zynq.c
46
--- a/fpu/softfloat-specialize.c.inc
19
+++ b/hw/arm/xilinx_zynq.c
47
+++ b/fpu/softfloat-specialize.c.inc
20
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
48
@@ -XXX,XX +XXX,XX @@ static void parts128_silence_nan(FloatParts128 *p, float_status *status)
21
49
floatx80 floatx80_default_nan(float_status *status)
22
static void zynq_machine_class_init(ObjectClass *oc, void *data)
23
{
50
{
24
+ static const char * const valid_cpu_types[] = {
51
floatx80 r;
25
+ ARM_CPU_TYPE_NAME("cortex-a9"),
52
+ /*
26
+ NULL
53
+ * Extrapolate from the choices made by parts64_default_nan to fill
27
+ };
54
+ * in the floatx80 format. We assume that floatx80's explicit
28
MachineClass *mc = MACHINE_CLASS(oc);
55
+ * integer bit is always set (this is true for i386 and m68k,
29
mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
56
+ * which are the only real users of this format).
30
mc->init = zynq_init;
57
+ */
31
mc->max_cpus = 1;
58
+ FloatParts64 p64;
32
mc->no_sdcard = 1;
59
+ parts64_default_nan(&p64, status);
33
mc->ignore_memory_transaction_failures = true;
60
34
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
61
- /* None of the targets that have snan_bit_is_one use floatx80. */
35
+ mc->valid_cpu_types = valid_cpu_types;
62
- assert(!snan_bit_is_one(status));
36
mc->default_ram_id = "zynq.ext_ram";
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;
37
}
74
}
38
75
39
--
76
--
40
2.34.1
77
2.34.1
41
42
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
Switch vmbus from using BusClass::reset to the Resettable interface.
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
This has no behavioural change, because the BusClass code to support
8
To do this we need to pass the CPU env pointer in to the helper.
4
subclasses that use the legacy BusClass::reset will call that method
5
in the hold phase of 3-phase reset.
6
9
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Acked-by: Michael S. Tsirkin <mst@redhat.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Acked-by: Cédric Le Goater <clg@redhat.com>
12
Message-id: 20241202131347.498124-33-peter.maydell@linaro.org
10
Acked-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
11
Tested-by: Cédric Le Goater <clg@redhat.com>
12
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
13
Message-id: 20240119163512.3810301-3-peter.maydell@linaro.org
14
---
13
---
15
hw/hyperv/vmbus.c | 7 ++++---
14
target/sparc/helper.h | 4 ++--
16
1 file changed, 4 insertions(+), 3 deletions(-)
15
target/sparc/fop_helper.c | 8 ++++----
16
target/sparc/translate.c | 4 ++--
17
3 files changed, 8 insertions(+), 8 deletions(-)
17
18
18
diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c
19
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/hyperv/vmbus.c
21
--- a/target/sparc/helper.h
21
+++ b/hw/hyperv/vmbus.c
22
+++ b/target/sparc/helper.h
22
@@ -XXX,XX +XXX,XX @@ static void vmbus_unrealize(BusState *bus)
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
23
qemu_mutex_destroy(&vmbus->rx_queue_lock);
24
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
25
DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
26
DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
27
-DEF_HELPER_FLAGS_2(flcmps, TCG_CALL_NO_RWG_SE, i32, f32, f32)
28
-DEF_HELPER_FLAGS_2(flcmpd, TCG_CALL_NO_RWG_SE, i32, f64, f64)
29
+DEF_HELPER_FLAGS_3(flcmps, TCG_CALL_NO_RWG_SE, i32, env, f32, f32)
30
+DEF_HELPER_FLAGS_3(flcmpd, TCG_CALL_NO_RWG_SE, i32, env, f64, f64)
31
DEF_HELPER_2(raise_exception, noreturn, env, int)
32
33
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
34
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/sparc/fop_helper.c
37
+++ b/target/sparc/fop_helper.c
38
@@ -XXX,XX +XXX,XX @@ uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
39
return finish_fcmp(env, r, GETPC());
24
}
40
}
25
41
26
-static void vmbus_reset(BusState *bus)
42
-uint32_t helper_flcmps(float32 src1, float32 src2)
27
+static void vmbus_reset_hold(Object *obj)
43
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
28
{
44
{
29
- vmbus_deinit(VMBUS(bus));
45
/*
30
+ vmbus_deinit(VMBUS(obj));
46
* FLCMP never raises an exception nor modifies any FSR fields.
47
* Perform the comparison with a dummy fp environment.
48
*/
49
- float_status discard = { };
50
+ float_status discard = env->fp_status;
51
FloatRelation r;
52
53
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
54
@@ -XXX,XX +XXX,XX @@ uint32_t helper_flcmps(float32 src1, float32 src2)
55
g_assert_not_reached();
31
}
56
}
32
57
33
static char *vmbus_get_dev_path(DeviceState *dev)
58
-uint32_t helper_flcmpd(float64 src1, float64 src2)
34
@@ -XXX,XX +XXX,XX @@ static char *vmbus_get_fw_dev_path(DeviceState *dev)
59
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
35
static void vmbus_class_init(ObjectClass *klass, void *data)
36
{
60
{
37
BusClass *k = BUS_CLASS(klass);
61
- float_status discard = { };
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
62
+ float_status discard = env->fp_status;
39
63
FloatRelation r;
40
k->get_dev_path = vmbus_get_dev_path;
64
41
k->get_fw_dev_path = vmbus_get_fw_dev_path;
65
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
42
k->realize = vmbus_realize;
66
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
43
k->unrealize = vmbus_unrealize;
67
index XXXXXXX..XXXXXXX 100644
44
- k->reset = vmbus_reset;
68
--- a/target/sparc/translate.c
45
+ rc->phases.hold = vmbus_reset_hold;
69
+++ b/target/sparc/translate.c
70
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPs(DisasContext *dc, arg_FLCMPs *a)
71
72
src1 = gen_load_fpr_F(dc, a->rs1);
73
src2 = gen_load_fpr_F(dc, a->rs2);
74
- gen_helper_flcmps(cpu_fcc[a->cc], src1, src2);
75
+ gen_helper_flcmps(cpu_fcc[a->cc], tcg_env, src1, src2);
76
return advance_pc(dc);
46
}
77
}
47
78
48
static int vmbus_pre_load(void *opaque)
79
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPd(DisasContext *dc, arg_FLCMPd *a)
80
81
src1 = gen_load_fpr_D(dc, a->rs1);
82
src2 = gen_load_fpr_D(dc, a->rs2);
83
- gen_helper_flcmpd(cpu_fcc[a->cc], src1, src2);
84
+ gen_helper_flcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
85
return advance_pc(dc);
86
}
87
49
--
88
--
50
2.34.1
89
2.34.1
51
52
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: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The npcm7xx Soc is created with a Cortex-A9 core, see in
3
Now that float_status has a bunch of fp parameters,
4
hw/arm/npcm7xx.c:
4
it is easier to copy an existing structure than create
5
one from scratch. Begin by copying the structure that
6
corresponds to the FPSR and make only the adjustments
7
required for BFloat16 semantics.
5
8
6
static void npcm7xx_init(Object *obj)
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
{
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
NPCM7xxState *s = NPCM7XX(obj);
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
12
Message-id: 20241203203949.483774-2-richard.henderson@linaro.org
10
for (int i = 0; i < NPCM7XX_MAX_NUM_CPUS; i++) {
11
object_initialize_child(obj, "cpu[*]", &s->cpu[i],
12
ARM_CPU_TYPE_NAME("cortex-a9"));
13
}
14
15
The MachineClass::default_cpu_type field is ignored: delete it.
16
17
Use the common code introduced in commit c9cf636d48 ("machine: Add
18
a valid_cpu_types property") to check for valid CPU type at the
19
board level.
20
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
23
Message-id: 20240129151828.59544-8-philmd@linaro.org
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
14
---
26
hw/arm/npcm7xx_boards.c | 1 -
15
target/arm/tcg/vec_helper.c | 20 +++++++-------------
27
1 file changed, 1 deletion(-)
16
1 file changed, 7 insertions(+), 13 deletions(-)
28
17
29
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
18
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
30
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/npcm7xx_boards.c
20
--- a/target/arm/tcg/vec_helper.c
32
+++ b/hw/arm/npcm7xx_boards.c
21
+++ b/target/arm/tcg/vec_helper.c
33
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_machine_class_init(ObjectClass *oc, void *data)
22
@@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
34
mc->no_cdrom = 1;
23
* no effect on AArch32 instructions.
35
mc->no_parallel = 1;
24
*/
36
mc->default_ram_id = "ram";
25
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
37
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
26
- *statusp = (float_status){
38
mc->valid_cpu_types = valid_cpu_types;
27
- .tininess_before_rounding = float_tininess_before_rounding,
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;
39
}
53
}
40
54
41
--
55
--
42
2.34.1
56
2.34.1
43
57
44
58
diff view generated by jsdifflib
1
From: Nabih Estefan Diaz <nabihestefan@google.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
- Created qtest to check initialization of registers in GMAC Module.
7
Add a field to float_status to specify the default NaN value; fall
4
- Implemented test into Build File.
8
back to the old ifdef behaviour if these are not set.
5
9
6
Change-Id: I8b2fe152d3987a7eec4cf6a1d25ba92e75a5391d
10
The default NaN value is specified by setting a uint8_t to a
7
Signed-off-by: Nabih Estefan <nabihestefan@google.com>
11
pattern corresponding to the sign and upper fraction parts of
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
12
the NaN; the lower bits of the fraction are set from bit 0 of
9
Message-id: 20240131002800.989285-4-nabihestefan@google.com
13
the pattern.
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
12
---
18
---
13
tests/qtest/npcm_gmac-test.c | 212 +++++++++++++++++++++++++++++++++++
19
include/fpu/softfloat-helpers.h | 11 +++++++
14
tests/qtest/meson.build | 1 +
20
include/fpu/softfloat-types.h | 10 ++++++
15
2 files changed, 213 insertions(+)
21
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
16
create mode 100644 tests/qtest/npcm_gmac-test.c
22
3 files changed, 54 insertions(+), 22 deletions(-)
17
23
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
24
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
19
new file mode 100644
25
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX
26
--- a/include/fpu/softfloat-helpers.h
21
--- /dev/null
27
+++ b/include/fpu/softfloat-helpers.h
22
+++ b/tests/qtest/npcm_gmac-test.c
28
@@ -XXX,XX +XXX,XX @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
23
@@ -XXX,XX +XXX,XX @@
29
status->float_infzeronan_rule = rule;
24
+/*
30
}
25
+ * QTests for Nuvoton NPCM7xx/8xx GMAC Modules.
31
26
+ *
32
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
27
+ * Copyright 2024 Google LLC
33
+ float_status *status)
28
+ * Authors:
29
+ * Hao Wu <wuhaotsh@google.com>
30
+ * Nabih Estefan <nabihestefan@google.com>
31
+ *
32
+ * This program is free software; you can redistribute it and/or modify it
33
+ * under the terms of the GNU General Public License as published by the
34
+ * Free Software Foundation; either version 2 of the License, or
35
+ * (at your option) any later version.
36
+ *
37
+ * This program is distributed in the hope that it will be useful, but WITHOUT
38
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
39
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
40
+ * for more details.
41
+ */
42
+
43
+#include "qemu/osdep.h"
44
+#include "libqos/libqos.h"
45
+
46
+/* Name of the GMAC Device */
47
+#define TYPE_NPCM_GMAC "npcm-gmac"
48
+
49
+typedef struct GMACModule {
50
+ int irq;
51
+ uint64_t base_addr;
52
+} GMACModule;
53
+
54
+typedef struct TestData {
55
+ const GMACModule *module;
56
+} TestData;
57
+
58
+/* Values extracted from hw/arm/npcm8xx.c */
59
+static const GMACModule gmac_module_list[] = {
60
+ {
61
+ .irq = 14,
62
+ .base_addr = 0xf0802000
63
+ },
64
+ {
65
+ .irq = 15,
66
+ .base_addr = 0xf0804000
67
+ },
68
+ {
69
+ .irq = 16,
70
+ .base_addr = 0xf0806000
71
+ },
72
+ {
73
+ .irq = 17,
74
+ .base_addr = 0xf0808000
75
+ }
76
+};
77
+
78
+/* Returns the index of the GMAC module. */
79
+static int gmac_module_index(const GMACModule *mod)
80
+{
34
+{
81
+ ptrdiff_t diff = mod - gmac_module_list;
35
+ status->default_nan_pattern = dnan_pattern;
82
+
83
+ g_assert_true(diff >= 0 && diff < ARRAY_SIZE(gmac_module_list));
84
+
85
+ return diff;
86
+}
36
+}
87
+
37
+
88
+/* 32-bit register indices. Taken from npcm_gmac.c */
38
static inline void set_flush_to_zero(bool val, float_status *status)
89
+typedef enum NPCMRegister {
39
{
90
+ /* DMA Registers */
40
status->flush_to_zero = val;
91
+ NPCM_DMA_BUS_MODE = 0x1000,
41
@@ -XXX,XX +XXX,XX @@ static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status
92
+ NPCM_DMA_XMT_POLL_DEMAND = 0x1004,
42
return status->float_infzeronan_rule;
93
+ NPCM_DMA_RCV_POLL_DEMAND = 0x1008,
43
}
94
+ NPCM_DMA_RCV_BASE_ADDR = 0x100c,
44
95
+ NPCM_DMA_TX_BASE_ADDR = 0x1010,
45
+static inline uint8_t get_float_default_nan_pattern(float_status *status)
96
+ NPCM_DMA_STATUS = 0x1014,
97
+ NPCM_DMA_CONTROL = 0x1018,
98
+ NPCM_DMA_INTR_ENA = 0x101c,
99
+ NPCM_DMA_MISSED_FRAME_CTR = 0x1020,
100
+ NPCM_DMA_HOST_TX_DESC = 0x1048,
101
+ NPCM_DMA_HOST_RX_DESC = 0x104c,
102
+ NPCM_DMA_CUR_TX_BUF_ADDR = 0x1050,
103
+ NPCM_DMA_CUR_RX_BUF_ADDR = 0x1054,
104
+ NPCM_DMA_HW_FEATURE = 0x1058,
105
+
106
+ /* GMAC Registers */
107
+ NPCM_GMAC_MAC_CONFIG = 0x0,
108
+ NPCM_GMAC_FRAME_FILTER = 0x4,
109
+ NPCM_GMAC_HASH_HIGH = 0x8,
110
+ NPCM_GMAC_HASH_LOW = 0xc,
111
+ NPCM_GMAC_MII_ADDR = 0x10,
112
+ NPCM_GMAC_MII_DATA = 0x14,
113
+ NPCM_GMAC_FLOW_CTRL = 0x18,
114
+ NPCM_GMAC_VLAN_FLAG = 0x1c,
115
+ NPCM_GMAC_VERSION = 0x20,
116
+ NPCM_GMAC_WAKEUP_FILTER = 0x28,
117
+ NPCM_GMAC_PMT = 0x2c,
118
+ NPCM_GMAC_LPI_CTRL = 0x30,
119
+ NPCM_GMAC_TIMER_CTRL = 0x34,
120
+ NPCM_GMAC_INT_STATUS = 0x38,
121
+ NPCM_GMAC_INT_MASK = 0x3c,
122
+ NPCM_GMAC_MAC0_ADDR_HI = 0x40,
123
+ NPCM_GMAC_MAC0_ADDR_LO = 0x44,
124
+ NPCM_GMAC_MAC1_ADDR_HI = 0x48,
125
+ NPCM_GMAC_MAC1_ADDR_LO = 0x4c,
126
+ NPCM_GMAC_MAC2_ADDR_HI = 0x50,
127
+ NPCM_GMAC_MAC2_ADDR_LO = 0x54,
128
+ NPCM_GMAC_MAC3_ADDR_HI = 0x58,
129
+ NPCM_GMAC_MAC3_ADDR_LO = 0x5c,
130
+ NPCM_GMAC_RGMII_STATUS = 0xd8,
131
+ NPCM_GMAC_WATCHDOG = 0xdc,
132
+ NPCM_GMAC_PTP_TCR = 0x700,
133
+ NPCM_GMAC_PTP_SSIR = 0x704,
134
+ NPCM_GMAC_PTP_STSR = 0x708,
135
+ NPCM_GMAC_PTP_STNSR = 0x70c,
136
+ NPCM_GMAC_PTP_STSUR = 0x710,
137
+ NPCM_GMAC_PTP_STNSUR = 0x714,
138
+ NPCM_GMAC_PTP_TAR = 0x718,
139
+ NPCM_GMAC_PTP_TTSR = 0x71c,
140
+} NPCMRegister;
141
+
142
+static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
143
+ NPCMRegister regno)
144
+{
46
+{
145
+ return qtest_readl(qts, mod->base_addr + regno);
47
+ return status->default_nan_pattern;
146
+}
48
+}
147
+
49
+
148
+/* Check that GMAC registers are reset to default value */
50
static inline bool get_flush_to_zero(float_status *status)
149
+static void test_init(gconstpointer test_data)
51
{
150
+{
52
return status->flush_to_zero;
151
+ const TestData *td = test_data;
53
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
152
+ const GMACModule *mod = td->module;
54
index XXXXXXX..XXXXXXX 100644
153
+ QTestState *qts = qtest_init("-machine npcm845-evb");
55
--- a/include/fpu/softfloat-types.h
56
+++ b/include/fpu/softfloat-types.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
58
/* should denormalised inputs go to zero and set the input_denormal flag? */
59
bool flush_inputs_to_zero;
60
bool default_nan_mode;
61
+ /*
62
+ * The pattern to use for the default NaN. Here the high bit specifies
63
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
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);
154
+
136
+
155
+#define CHECK_REG32(regno, value) \
137
+ sign = dnan_pattern >> 7;
156
+ do { \
138
+ /*
157
+ g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
139
+ * Place default_nan_pattern [6:0] into bits [62:56],
158
+ } while (0)
140
+ * and replecate bit [0] down into [55:0]
159
+
141
+ */
160
+ CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
142
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
161
+ CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
143
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
162
+ CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
144
163
+ CHECK_REG32(NPCM_DMA_RCV_BASE_ADDR, 0);
145
*p = (FloatParts64) {
164
+ CHECK_REG32(NPCM_DMA_TX_BASE_ADDR, 0);
146
.cls = float_class_qnan,
165
+ CHECK_REG32(NPCM_DMA_STATUS, 0);
166
+ CHECK_REG32(NPCM_DMA_CONTROL, 0);
167
+ CHECK_REG32(NPCM_DMA_INTR_ENA, 0);
168
+ CHECK_REG32(NPCM_DMA_MISSED_FRAME_CTR, 0);
169
+ CHECK_REG32(NPCM_DMA_HOST_TX_DESC, 0);
170
+ CHECK_REG32(NPCM_DMA_HOST_RX_DESC, 0);
171
+ CHECK_REG32(NPCM_DMA_CUR_TX_BUF_ADDR, 0);
172
+ CHECK_REG32(NPCM_DMA_CUR_RX_BUF_ADDR, 0);
173
+ CHECK_REG32(NPCM_DMA_HW_FEATURE, 0x100d4f37);
174
+
175
+ CHECK_REG32(NPCM_GMAC_MAC_CONFIG, 0);
176
+ CHECK_REG32(NPCM_GMAC_FRAME_FILTER, 0);
177
+ CHECK_REG32(NPCM_GMAC_HASH_HIGH, 0);
178
+ CHECK_REG32(NPCM_GMAC_HASH_LOW, 0);
179
+ CHECK_REG32(NPCM_GMAC_MII_ADDR, 0);
180
+ CHECK_REG32(NPCM_GMAC_MII_DATA, 0);
181
+ CHECK_REG32(NPCM_GMAC_FLOW_CTRL, 0);
182
+ CHECK_REG32(NPCM_GMAC_VLAN_FLAG, 0);
183
+ CHECK_REG32(NPCM_GMAC_VERSION, 0x00001032);
184
+ CHECK_REG32(NPCM_GMAC_WAKEUP_FILTER, 0);
185
+ CHECK_REG32(NPCM_GMAC_PMT, 0);
186
+ CHECK_REG32(NPCM_GMAC_LPI_CTRL, 0);
187
+ CHECK_REG32(NPCM_GMAC_TIMER_CTRL, 0x03e80000);
188
+ CHECK_REG32(NPCM_GMAC_INT_STATUS, 0);
189
+ CHECK_REG32(NPCM_GMAC_INT_MASK, 0);
190
+ CHECK_REG32(NPCM_GMAC_MAC0_ADDR_HI, 0x8000ffff);
191
+ CHECK_REG32(NPCM_GMAC_MAC0_ADDR_LO, 0xffffffff);
192
+ CHECK_REG32(NPCM_GMAC_MAC1_ADDR_HI, 0x0000ffff);
193
+ CHECK_REG32(NPCM_GMAC_MAC1_ADDR_LO, 0xffffffff);
194
+ CHECK_REG32(NPCM_GMAC_MAC2_ADDR_HI, 0x0000ffff);
195
+ CHECK_REG32(NPCM_GMAC_MAC2_ADDR_LO, 0xffffffff);
196
+ CHECK_REG32(NPCM_GMAC_MAC3_ADDR_HI, 0x0000ffff);
197
+ CHECK_REG32(NPCM_GMAC_MAC3_ADDR_LO, 0xffffffff);
198
+ CHECK_REG32(NPCM_GMAC_RGMII_STATUS, 0);
199
+ CHECK_REG32(NPCM_GMAC_WATCHDOG, 0);
200
+ CHECK_REG32(NPCM_GMAC_PTP_TCR, 0x00002000);
201
+ CHECK_REG32(NPCM_GMAC_PTP_SSIR, 0);
202
+ CHECK_REG32(NPCM_GMAC_PTP_STSR, 0);
203
+ CHECK_REG32(NPCM_GMAC_PTP_STNSR, 0);
204
+ CHECK_REG32(NPCM_GMAC_PTP_STSUR, 0);
205
+ CHECK_REG32(NPCM_GMAC_PTP_STNSUR, 0);
206
+ CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
207
+ CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
208
+
209
+ qtest_quit(qts);
210
+}
211
+
212
+static void gmac_add_test(const char *name, const TestData* td,
213
+ GTestDataFunc fn)
214
+{
215
+ g_autofree char *full_name = g_strdup_printf(
216
+ "npcm7xx_gmac/gmac[%d]/%s", gmac_module_index(td->module), name);
217
+ qtest_add_data_func(full_name, td, fn);
218
+}
219
+
220
+int main(int argc, char **argv)
221
+{
222
+ TestData test_data_list[ARRAY_SIZE(gmac_module_list)];
223
+
224
+ g_test_init(&argc, &argv, NULL);
225
+
226
+ for (int i = 0; i < ARRAY_SIZE(gmac_module_list); ++i) {
227
+ TestData *td = &test_data_list[i];
228
+
229
+ td->module = &gmac_module_list[i];
230
+
231
+ gmac_add_test("init", td, test_init);
232
+ }
233
+
234
+ return g_test_run();
235
+}
236
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
237
index XXXXXXX..XXXXXXX 100644
238
--- a/tests/qtest/meson.build
239
+++ b/tests/qtest/meson.build
240
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
241
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
242
(config_all_accel.has_key('CONFIG_TCG') and \
243
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
244
+ (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
245
['arm-cpu-features',
246
'numa-test',
247
'boot-serial-test',
248
--
147
--
249
2.34.1
148
2.34.1
diff view generated by jsdifflib
1
Switch the PCI bus from using BusClass::reset to the Resettable
1
Set the default NaN pattern explicitly for the tests/fp code.
2
interface.
3
4
This has no behavioural change, because the BusClass code to support
5
subclasses that use the legacy BusClass::reset will call that method
6
in the hold phase of 3-phase reset.
7
2
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Acked-by: Michael S. Tsirkin <mst@redhat.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Acked-by: Cédric Le Goater <clg@redhat.com>
5
Message-id: 20241202131347.498124-36-peter.maydell@linaro.org
11
Tested-by: Cédric Le Goater <clg@redhat.com>
12
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
13
Message-id: 20240119163512.3810301-2-peter.maydell@linaro.org
14
---
6
---
15
hw/pci/pci.c | 10 ++++++----
7
tests/fp/fp-bench.c | 1 +
16
1 file changed, 6 insertions(+), 4 deletions(-)
8
tests/fp/fp-test-log2.c | 1 +
9
tests/fp/fp-test.c | 1 +
10
3 files changed, 3 insertions(+)
17
11
18
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
12
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/pci/pci.c
14
--- a/tests/fp/fp-bench.c
21
+++ b/hw/pci/pci.c
15
+++ b/tests/fp/fp-bench.c
22
@@ -XXX,XX +XXX,XX @@ bool pci_available = true;
16
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
23
17
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
24
static char *pcibus_get_dev_path(DeviceState *dev);
18
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
25
static char *pcibus_get_fw_dev_path(DeviceState *dev);
19
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
26
-static void pcibus_reset(BusState *qbus);
20
+ set_float_default_nan_pattern(0b01000000, &soft_status);
27
+static void pcibus_reset_hold(Object *obj);
21
28
static bool pcie_has_upstream_port(PCIDevice *dev);
22
f = bench_funcs[operation][precision];
29
23
g_assert(f);
30
static Property pci_props[] = {
24
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c
31
@@ -XXX,XX +XXX,XX @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
25
index XXXXXXX..XXXXXXX 100644
32
{
26
--- a/tests/fp/fp-test-log2.c
33
BusClass *k = BUS_CLASS(klass);
27
+++ b/tests/fp/fp-test-log2.c
34
PCIBusClass *pbc = PCI_BUS_CLASS(klass);
28
@@ -XXX,XX +XXX,XX @@ int main(int ac, char **av)
35
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
36
37
k->print_dev = pcibus_dev_print;
38
k->get_dev_path = pcibus_get_dev_path;
39
k->get_fw_dev_path = pcibus_get_fw_dev_path;
40
k->realize = pci_bus_realize;
41
k->unrealize = pci_bus_unrealize;
42
- k->reset = pcibus_reset;
43
+
44
+ rc->phases.hold = pcibus_reset_hold;
45
46
pbc->bus_num = pcibus_num;
47
pbc->numa_node = pcibus_numa_node;
48
@@ -XXX,XX +XXX,XX @@ void pci_device_reset(PCIDevice *dev)
49
* Called via bus_cold_reset on RST# assert, after the devices
50
* have been reset device_cold_reset-ed already.
51
*/
52
-static void pcibus_reset(BusState *qbus)
53
+static void pcibus_reset_hold(Object *obj)
54
{
55
- PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
56
+ PCIBus *bus = PCI_BUS(obj);
57
int i;
29
int i;
58
30
59
for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
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);
60
--
48
--
61
2.34.1
49
2.34.1
62
63
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
Switch the s390x virtual-css bus from using BusClass::reset to the
1
Set the default NaN pattern explicitly for the arm target.
2
Resettable interface.
2
This includes setting it for the old linux-user nwfpe emulation.
3
3
For nwfpe, our default doesn't match the real kernel, but we
4
This has no behavioural change, because the BusClass code to support
4
avoid making a behaviour change in this commit.
5
subclasses that use the legacy BusClass::reset will call that method
6
in the hold phase of 3-phase reset.
7
5
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Acked-by: Michael S. Tsirkin <mst@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Acked-by: Cédric Le Goater <clg@redhat.com>
8
Message-id: 20241202131347.498124-41-peter.maydell@linaro.org
11
Acked-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
12
Tested-by: Cédric Le Goater <clg@redhat.com>
13
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
14
Reviewed-by: Eric Farman <farman@linux.ibm.com>
15
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
16
Message-id: 20240119163512.3810301-5-peter.maydell@linaro.org
17
---
9
---
18
hw/s390x/css-bridge.c | 5 +++--
10
linux-user/arm/nwfpe/fpa11.c | 5 +++++
19
1 file changed, 3 insertions(+), 2 deletions(-)
11
target/arm/cpu.c | 2 ++
12
2 files changed, 7 insertions(+)
20
13
21
diff --git a/hw/s390x/css-bridge.c b/hw/s390x/css-bridge.c
14
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
22
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/s390x/css-bridge.c
16
--- a/linux-user/arm/nwfpe/fpa11.c
24
+++ b/hw/s390x/css-bridge.c
17
+++ b/linux-user/arm/nwfpe/fpa11.c
25
@@ -XXX,XX +XXX,XX @@ static void ccw_device_unplug(HotplugHandler *hotplug_dev,
18
@@ -XXX,XX +XXX,XX @@ void resetFPA11(void)
26
qdev_unrealize(dev);
19
* this late date.
20
*/
21
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
22
+ /*
23
+ * Use the same default NaN value as Arm VFP. This doesn't match
24
+ * the Linux kernel's nwfpe emulation, which uses an all-1s value.
25
+ */
26
+ set_float_default_nan_pattern(0b01000000, &fpa11->fp_status);
27
}
27
}
28
28
29
-static void virtual_css_bus_reset(BusState *qbus)
29
void SetRoundingMode(const unsigned int opcode)
30
+static void virtual_css_bus_reset_hold(Object *obj)
30
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu.c
33
+++ b/target/arm/cpu.c
34
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
35
* the pseudocode function the arguments are in the order c, a, b.
36
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
37
* and the input NaN if it is signalling
38
+ * * Default NaN has sign bit clear, msb frac bit set
39
*/
40
static void arm_set_default_fp_behaviours(float_status *s)
31
{
41
{
32
/* This should actually be modelled via the generic css */
42
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
33
css_reset();
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
34
@@ -XXX,XX +XXX,XX @@ static char *virtual_css_bus_get_dev_path(DeviceState *dev)
44
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
35
static void virtual_css_bus_class_init(ObjectClass *klass, void *data)
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
36
{
46
+ set_float_default_nan_pattern(0b01000000, s);
37
BusClass *k = BUS_CLASS(klass);
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
39
40
- k->reset = virtual_css_bus_reset;
41
+ rc->phases.hold = virtual_css_bus_reset_hold;
42
k->get_dev_path = virtual_css_bus_get_dev_path;
43
}
47
}
44
48
49
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
45
--
50
--
46
2.34.1
51
2.34.1
47
48
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: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Set the default NaN pattern explicitly for MIPS. Note that this
2
is our only target which currently changes the default NaN
3
at runtime (which it was previously doing indirectly when it
4
changed the snan_bit_is_one setting).
2
5
3
Musca boards use the embedded subsystems (SSE) tied to a specific
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Cortex core. Our models only use the Cortex-M33.
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
Use the common code introduced in commit c9cf636d48 ("machine: Add
14
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
7
a valid_cpu_types property") to check for valid CPU type at the
8
board level.
9
10
Remove the now unused MachineClass::default_cpu_type field.
11
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Message-id: 20240129151828.59544-7-philmd@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/musca.c | 1 -
18
1 file changed, 1 deletion(-)
19
20
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/musca.c
16
--- a/target/mips/fpu_helper.h
23
+++ b/hw/arm/musca.c
17
+++ b/target/mips/fpu_helper.h
24
@@ -XXX,XX +XXX,XX @@ static void musca_class_init(ObjectClass *oc, void *data)
18
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
25
mc->default_cpus = 2;
19
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
26
mc->min_cpus = mc->default_cpus;
20
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
27
mc->max_cpus = mc->default_cpus;
21
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
28
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
22
+ /*
29
mc->valid_cpu_types = valid_cpu_types;
23
+ * With nan2008, the default NaN value has the sign bit clear and the
30
mc->init = musca_init;
24
+ * frac msb set; with the older mode, the sign bit is clear, and all
25
+ * frac bits except the msb are set.
26
+ */
27
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
28
+ &env->active_fpu.fp_status);
29
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);
31
}
43
}
32
--
44
--
33
2.34.1
45
2.34.1
34
35
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for openrisc.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-45-peter.maydell@linaro.org
6
---
7
target/openrisc/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/openrisc/cpu.c
13
+++ b/target/openrisc/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
15
*/
16
set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
17
18
+ /* Default NaN: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
20
21
#ifndef CONFIG_USER_ONLY
22
cpu->env.picmr = 0x00000000;
23
--
24
2.34.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Set the default NaN pattern explicitly for ppc.
2
2
3
QDev objects created with qdev_new() need to manually add
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
their parent relationship with object_property_add_child().
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(+)
5
9
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Gavin Shan <gshan@redhat.com>
9
Message-id: 20240129151828.59544-4-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/highbank.c | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/highbank.c
12
--- a/target/ppc/cpu_init.c
18
+++ b/hw/arm/highbank.c
13
+++ b/target/ppc/cpu_init.c
19
@@ -XXX,XX +XXX,XX @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
14
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
20
cpuobj = object_new(machine->cpu_type);
15
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
21
cpu = ARM_CPU(cpuobj);
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
22
17
23
+ object_property_add_child(OBJECT(machine), "cpu[*]", cpuobj);
18
+ /* Default NaN: sign bit clear, set frac msb */
24
object_property_set_int(cpuobj, "psci-conduit", QEMU_PSCI_CONDUIT_SMC,
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
25
&error_abort);
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];
26
24
27
--
25
--
28
2.34.1
26
2.34.1
29
30
diff view generated by jsdifflib
1
From: Rayhan Faizel <rayhan.faizel@gmail.com>
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.
2
4
3
This patch will allow the SPI controller to be accessible from BCM2835 based
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
boards as SPI0. SPI driver is usually disabled by default and config.txt does
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
not work.
7
Message-id: 20241202131347.498124-47-peter.maydell@linaro.org
8
---
9
target/sh4/cpu.c | 2 ++
10
1 file changed, 2 insertions(+)
6
11
7
Instead, dtmerge can be used to apply spi=on on a bcm2835 dtb file.
12
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
8
9
Signed-off-by: Rayhan Faizel <rayhan.faizel@gmail.com>
10
Message-id: 20240129221807.2983148-3-rayhan.faizel@gmail.com
11
[PMM: indent tweak]
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/hw/arm/bcm2835_peripherals.h | 3 ++-
16
hw/arm/bcm2835_peripherals.c | 17 ++++++++++++++++-
17
hw/arm/Kconfig | 1 +
18
3 files changed, 19 insertions(+), 2 deletions(-)
19
20
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/bcm2835_peripherals.h
14
--- a/target/sh4/cpu.c
23
+++ b/include/hw/arm/bcm2835_peripherals.h
15
+++ b/target/sh4/cpu.c
24
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_reset_hold(Object *obj, ResetType type)
25
#include "hw/gpio/bcm2835_gpio.h"
17
set_flush_to_zero(1, &env->fp_status);
26
#include "hw/timer/bcm2835_systmr.h"
18
#endif
27
#include "hw/usb/hcd-dwc2.h"
19
set_default_nan_mode(1, &env->fp_status);
28
+#include "hw/ssi/bcm2835_spi.h"
20
+ /* sign bit clear, set all frac bits other than msb */
29
#include "hw/misc/unimp.h"
21
+ set_float_default_nan_pattern(0b00111111, &env->fp_status);
30
#include "qom/object.h"
31
32
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
33
BCM2835GpioState gpio;
34
Bcm2835ThermalState thermal;
35
UnimplementedDeviceState i2s;
36
- UnimplementedDeviceState spi[1];
37
+ BCM2835SPIState spi[1];
38
UnimplementedDeviceState i2c[3];
39
UnimplementedDeviceState otp;
40
UnimplementedDeviceState dbus;
41
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/bcm2835_peripherals.c
44
+++ b/hw/arm/bcm2835_peripherals.c
45
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
46
/* Power Management */
47
object_initialize_child(obj, "powermgt", &s->powermgt,
48
TYPE_BCM2835_POWERMGT);
49
+
50
+ /* SPI */
51
+ object_initialize_child(obj, "bcm2835-spi0", &s->spi[0],
52
+ TYPE_BCM2835_SPI);
53
}
22
}
54
23
55
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
24
static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
56
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
57
memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
58
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
59
60
+ /* SPI */
61
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[0]), errp)) {
62
+ return;
63
+ }
64
+
65
+ memory_region_add_subregion(&s->peri_mr, SPI0_OFFSET,
66
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->spi[0]), 0));
67
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[0]), 0,
68
+ qdev_get_gpio_in_named(DEVICE(&s->ic),
69
+ BCM2835_IC_GPU_IRQ,
70
+ INTERRUPT_SPI));
71
+
72
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
73
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
74
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
75
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
76
- create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
77
create_unimp(s, &s->bscsl, "bcm2835-spis", BSC_SL_OFFSET, 0x100);
78
create_unimp(s, &s->i2c[0], "bcm2835-i2c0", BSC0_OFFSET, 0x20);
79
create_unimp(s, &s->i2c[1], "bcm2835-i2c1", BSC1_OFFSET, 0x20);
80
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
81
index XXXXXXX..XXXXXXX 100644
82
--- a/hw/arm/Kconfig
83
+++ b/hw/arm/Kconfig
84
@@ -XXX,XX +XXX,XX @@ config RASPI
85
select PL011 # UART
86
select SDHCI
87
select USB_DWC2
88
+ select BCM2835_SPI
89
90
config STM32F100_SOC
91
bool
92
--
25
--
93
2.34.1
26
2.34.1
diff view generated by jsdifflib
1
This test program is the last use of any variable length array in the
1
Set the default NaN pattern explicitly for rx.
2
codebase. If we can get rid of all uses of VLAs we can make the
3
compiler error on new additions. This is a defensive measure against
4
security bugs where an on-stack dynamic allocation isn't correctly
5
size-checked (e.g. CVE-2021-3527).
6
7
In this case the test code didn't even want a variable-sized
8
array, it was just accidentally using syntax that gave it one.
9
(The array size for C has to be an actual constant expression,
10
not just something that happens to be known to be constant...)
11
12
Remove the VLA usage.
13
2
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20241202131347.498124-48-peter.maydell@linaro.org
17
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
18
Message-id: 20240125173211.1786196-2-peter.maydell@linaro.org
19
---
6
---
20
tests/qtest/xlnx-versal-trng-test.c | 19 +++++++++++--------
7
target/rx/cpu.c | 2 ++
21
1 file changed, 11 insertions(+), 8 deletions(-)
8
1 file changed, 2 insertions(+)
22
9
23
diff --git a/tests/qtest/xlnx-versal-trng-test.c b/tests/qtest/xlnx-versal-trng-test.c
10
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
24
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
25
--- a/tests/qtest/xlnx-versal-trng-test.c
12
--- a/target/rx/cpu.c
26
+++ b/tests/qtest/xlnx-versal-trng-test.c
13
+++ b/target/rx/cpu.c
27
@@ -XXX,XX +XXX,XX @@ static size_t trng_collect(uint32_t *rnd, size_t cnt)
14
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_reset_hold(Object *obj, ResetType type)
28
return i;
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);
29
}
20
}
30
21
31
+/* These tests all generate 512 bits of random data with the device */
22
static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
32
+#define TEST_DATA_WORDS (512 / 32)
33
+
34
static void trng_test_autogen(void)
35
{
36
- const size_t cnt = 512 / 32;
37
- uint32_t rng[cnt], prng[cnt];
38
+ const size_t cnt = TEST_DATA_WORDS;
39
+ uint32_t rng[TEST_DATA_WORDS], prng[TEST_DATA_WORDS];
40
size_t n;
41
42
trng_reset();
43
@@ -XXX,XX +XXX,XX @@ static void trng_test_autogen(void)
44
45
static void trng_test_oneshot(void)
46
{
47
- const size_t cnt = 512 / 32;
48
- uint32_t rng[cnt];
49
+ const size_t cnt = TEST_DATA_WORDS;
50
+ uint32_t rng[TEST_DATA_WORDS];
51
size_t n;
52
53
trng_reset();
54
@@ -XXX,XX +XXX,XX @@ static void trng_test_oneshot(void)
55
56
static void trng_test_per_str(void)
57
{
58
- const size_t cnt = 512 / 32;
59
- uint32_t rng[cnt], prng[cnt];
60
+ const size_t cnt = TEST_DATA_WORDS;
61
+ uint32_t rng[TEST_DATA_WORDS], prng[TEST_DATA_WORDS];
62
size_t n;
63
64
trng_reset();
65
@@ -XXX,XX +XXX,XX @@ static void trng_test_forced_prng(void)
66
const char *prop = "forced-prng";
67
const uint64_t seed = 0xdeadbeefbad1bad0ULL;
68
69
- const size_t cnt = 512 / 32;
70
- uint32_t rng[cnt], prng[cnt];
71
+ const size_t cnt = TEST_DATA_WORDS;
72
+ uint32_t rng[TEST_DATA_WORDS], prng[TEST_DATA_WORDS];
73
size_t n;
74
75
trng_reset();
76
--
23
--
77
2.34.1
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for s390x.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-49-peter.maydell@linaro.org
6
---
7
target/s390x/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/s390x/cpu.c
13
+++ b/target/s390x/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
15
set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
16
set_float_infzeronan_rule(float_infzeronan_dnan_always,
17
&env->fpu_status);
18
+ /* Default NaN value: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fpu_status);
20
/* fall through */
21
case RESET_TYPE_S390_CPU_NORMAL:
22
env->psw.mask &= ~PSW_MASK_RI;
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for SPARC, and remove
2
the ifdef from parts64_default_nan.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-50-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 5 +----
10
2 files changed, 3 insertions(+), 4 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
18
/* For inf * 0 + NaN, return the input NaN */
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ /* Default NaN value: sign bit clear, all frac bits set */
21
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
22
23
cpu_exec_realizefn(cs, &local_err);
24
if (local_err != NULL) {
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
uint8_t dnan_pattern = status->default_nan_pattern;
31
32
if (dnan_pattern == 0) {
33
-#if defined(TARGET_SPARC)
34
- /* Sign bit clear, all frac bits set */
35
- dnan_pattern = 0b01111111;
36
-#elif defined(TARGET_HEXAGON)
37
+#if defined(TARGET_HEXAGON)
38
/* Sign bit set, all frac bits set. */
39
dnan_pattern = 0b11111111;
40
#else
41
--
42
2.34.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Set the default NaN pattern explicitly for xtensa.
2
2
3
The M2Sxxx SoC family can only be used with Cortex-M3.
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Propagating the CPU type from the board level is pointless.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-51-peter.maydell@linaro.org
6
---
7
target/xtensa/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
5
9
6
Hard-code the CPU type at the SoC level.
10
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
7
Remove the now ignored MachineClass::default_cpu_type field.
8
9
Use the common code introduced in commit c9cf636d48 ("machine: Add
10
a valid_cpu_types property") to check for valid CPU type at the
11
board level.
12
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Message-id: 20240129151828.59544-6-philmd@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
include/hw/arm/msf2-soc.h | 3 ---
19
hw/arm/msf2-soc.c | 3 +--
20
hw/arm/msf2-som.c | 4 ----
21
3 files changed, 1 insertion(+), 9 deletions(-)
22
23
diff --git a/include/hw/arm/msf2-soc.h b/include/hw/arm/msf2-soc.h
24
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/msf2-soc.h
12
--- a/target/xtensa/cpu.c
26
+++ b/include/hw/arm/msf2-soc.h
13
+++ b/target/xtensa/cpu.c
27
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(MSF2State, MSF2_SOC)
14
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
28
#define MSF2_NUM_TIMERS 2
15
/* For inf * 0 + NaN, return the input NaN */
29
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
30
struct MSF2State {
17
set_no_signaling_nans(!dfpu, &env->fp_status);
31
- /*< private >*/
18
+ /* Default NaN value: sign bit clear, set frac msb */
32
SysBusDevice parent_obj;
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
33
- /*< public >*/
20
xtensa_use_first_nan(env, !dfpu);
34
35
ARMv7MState armv7m;
36
37
- char *cpu_type;
38
char *part_name;
39
uint64_t envm_size;
40
uint64_t esram_size;
41
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/msf2-soc.c
44
+++ b/hw/arm/msf2-soc.c
45
@@ -XXX,XX +XXX,XX @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
46
47
armv7m = DEVICE(&s->armv7m);
48
qdev_prop_set_uint32(armv7m, "num-irq", 81);
49
- qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
50
+ qdev_prop_set_string(armv7m, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
51
qdev_prop_set_bit(armv7m, "enable-bitband", true);
52
qdev_connect_clock_in(armv7m, "cpuclk", s->m3clk);
53
qdev_connect_clock_in(armv7m, "refclk", s->refclk);
54
@@ -XXX,XX +XXX,XX @@ static Property m2sxxx_soc_properties[] = {
55
* part name specifies the type of SmartFusion2 device variant(this
56
* property is for information purpose only.
57
*/
58
- DEFINE_PROP_STRING("cpu-type", MSF2State, cpu_type),
59
DEFINE_PROP_STRING("part-name", MSF2State, part_name),
60
DEFINE_PROP_UINT64("eNVM-size", MSF2State, envm_size, MSF2_ENVM_MAX_SIZE),
61
DEFINE_PROP_UINT64("eSRAM-size", MSF2State, esram_size,
62
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/arm/msf2-som.c
65
+++ b/hw/arm/msf2-som.c
66
@@ -XXX,XX +XXX,XX @@ static void emcraft_sf2_s2s010_init(MachineState *machine)
67
DeviceState *dev;
68
DeviceState *spi_flash;
69
MSF2State *soc;
70
- MachineClass *mc = MACHINE_GET_CLASS(machine);
71
DriveInfo *dinfo = drive_get(IF_MTD, 0, 0);
72
qemu_irq cs_line;
73
BusState *spi_bus;
74
@@ -XXX,XX +XXX,XX @@ static void emcraft_sf2_s2s010_init(MachineState *machine)
75
dev = qdev_new(TYPE_MSF2_SOC);
76
object_property_add_child(OBJECT(machine), "soc", OBJECT(dev));
77
qdev_prop_set_string(dev, "part-name", "M2S010");
78
- qdev_prop_set_string(dev, "cpu-type", mc->default_cpu_type);
79
-
80
qdev_prop_set_uint64(dev, "eNVM-size", M2S010_ENVM_SIZE);
81
qdev_prop_set_uint64(dev, "eSRAM-size", M2S010_ESRAM_SIZE);
82
83
@@ -XXX,XX +XXX,XX @@ static void emcraft_sf2_machine_init(MachineClass *mc)
84
85
mc->desc = "SmartFusion2 SOM kit from Emcraft (M2S010)";
86
mc->init = emcraft_sf2_s2s010_init;
87
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
88
mc->valid_cpu_types = valid_cpu_types;
89
}
21
}
90
22
91
--
23
--
92
2.34.1
24
2.34.1
93
94
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
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.
2
4
3
Leverage the common code introduced in commit c9cf636d48 ("machine:
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Add a valid_cpu_types property") to check for the single valid CPU
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
type. Remove the now unused MachineClass::default_cpu_type field.
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(-)
6
12
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
8
Reviewed-by: Gavin Shan <gshan@redhat.com>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20240129151828.59544-9-philmd@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/vexpress.c | 12 ++++++++++--
14
1 file changed, 10 insertions(+), 2 deletions(-)
15
16
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/vexpress.c
15
--- a/target/hexagon/cpu.c
19
+++ b/hw/arm/vexpress.c
16
+++ b/target/hexagon/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void vexpress_class_init(ObjectClass *oc, void *data)
17
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
21
18
22
static void vexpress_a9_class_init(ObjectClass *oc, void *data)
19
set_default_nan_mode(1, &env->fp_status);
23
{
20
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
24
+ static const char * const valid_cpu_types[] = {
21
+ /* Default NaN value: sign bit set, all frac bits set */
25
+ ARM_CPU_TYPE_NAME("cortex-a9"),
22
+ set_float_default_nan_pattern(0b11111111, &env->fp_status);
26
+ NULL
27
+ };
28
MachineClass *mc = MACHINE_CLASS(oc);
29
VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc);
30
31
mc->desc = "ARM Versatile Express for Cortex-A9";
32
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
33
+ mc->valid_cpu_types = valid_cpu_types;
34
35
vmc->daughterboard = &a9_daughterboard;
36
}
23
}
37
24
38
static void vexpress_a15_class_init(ObjectClass *oc, void *data)
25
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
39
{
26
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
40
+ static const char * const valid_cpu_types[] = {
27
index XXXXXXX..XXXXXXX 100644
41
+ ARM_CPU_TYPE_NAME("cortex-a15"),
28
--- a/fpu/softfloat-specialize.c.inc
42
+ NULL
29
+++ b/fpu/softfloat-specialize.c.inc
43
+ };
30
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
44
MachineClass *mc = MACHINE_CLASS(oc);
31
uint8_t dnan_pattern = status->default_nan_pattern;
45
VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc);
32
46
33
if (dnan_pattern == 0) {
47
mc->desc = "ARM Versatile Express for Cortex-A15";
34
-#if defined(TARGET_HEXAGON)
48
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
35
- /* Sign bit set, all frac bits set. */
49
+ mc->valid_cpu_types = valid_cpu_types;
36
- dnan_pattern = 0b11111111;
50
37
-#else
51
vmc->daughterboard = &a15_daughterboard;
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);
52
48
53
--
49
--
54
2.34.1
50
2.34.1
55
56
diff view generated by jsdifflib
1
In kernel commit 5d5b4e8c2d9ec ("arm64/sve: Report FEAT_SVE_B16B16 to
1
Set the default NaN pattern explicitly for riscv.
2
userspace") Linux added ID_AA64ZFR0_el1.B16B16 to the set of ID
3
register fields which it exposes to userspace. Update our
4
exported_bits mask to include this.
5
6
(This doesn't yet change any behaviour for us, because we don't yet
7
have any CPUs that implement this feature, which is part of SVE2.)
8
2
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20240125134304.1470404-1-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-53-peter.maydell@linaro.org
12
---
6
---
13
target/arm/helper.c | 1 +
7
target/riscv/cpu.c | 2 ++
14
tests/tcg/aarch64/sysregs.c | 2 +-
8
1 file changed, 2 insertions(+)
15
2 files changed, 2 insertions(+), 1 deletion(-)
16
9
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
10
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
12
--- a/target/riscv/cpu.c
20
+++ b/target/arm/helper.c
13
+++ b/target/riscv/cpu.c
21
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
14
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
22
R_ID_AA64ZFR0_AES_MASK |
15
cs->exception_index = RISCV_EXCP_NONE;
23
R_ID_AA64ZFR0_BITPERM_MASK |
16
env->load_res = -1;
24
R_ID_AA64ZFR0_BFLOAT16_MASK |
17
set_default_nan_mode(1, &env->fp_status);
25
+ R_ID_AA64ZFR0_B16B16_MASK |
18
+ /* Default NaN value: sign bit clear, frac msb set */
26
R_ID_AA64ZFR0_SHA3_MASK |
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
27
R_ID_AA64ZFR0_SM4_MASK |
20
env->vill = true;
28
R_ID_AA64ZFR0_I8MM_MASK |
21
29
diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c
22
#ifndef CONFIG_USER_ONLY
30
index XXXXXXX..XXXXXXX 100644
31
--- a/tests/tcg/aarch64/sysregs.c
32
+++ b/tests/tcg/aarch64/sysregs.c
33
@@ -XXX,XX +XXX,XX @@ int main(void)
34
/* all hidden, DebugVer fixed to 0x6 (ARMv8 debug architecture) */
35
get_cpu_reg_check_mask(id_aa64dfr0_el1, _m(0000,0000,0000,0006));
36
get_cpu_reg_check_zero(id_aa64dfr1_el1);
37
- get_cpu_reg_check_mask(SYS_ID_AA64ZFR0_EL1, _m(0ff0,ff0f,00ff,00ff));
38
+ get_cpu_reg_check_mask(SYS_ID_AA64ZFR0_EL1, _m(0ff0,ff0f,0fff,00ff));
39
get_cpu_reg_check_mask(SYS_ID_AA64SMFR0_EL1, _m(8ff1,fcff,0000,0000));
40
41
get_cpu_reg_check_zero(id_aa64afr0_el1);
42
--
23
--
43
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
Switch the ADB bus from using BusClass::reset to the Resettable
1
Set the default NaN pattern explicitly for tricore.
2
interface.
3
4
This has no behavioural change, because the BusClass code to support
5
subclasses that use the legacy BusClass::reset will call that method
6
in the hold phase of 3-phase reset.
7
2
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Acked-by: Michael S. Tsirkin <mst@redhat.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Acked-by: Cédric Le Goater <clg@redhat.com>
5
Message-id: 20241202131347.498124-54-peter.maydell@linaro.org
11
Acked-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
12
Tested-by: Cédric Le Goater <clg@redhat.com>
13
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
14
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
15
Message-id: 20240119163512.3810301-4-peter.maydell@linaro.org
16
---
6
---
17
hw/input/adb.c | 7 ++++---
7
target/tricore/helper.c | 2 ++
18
1 file changed, 4 insertions(+), 3 deletions(-)
8
1 file changed, 2 insertions(+)
19
9
20
diff --git a/hw/input/adb.c b/hw/input/adb.c
10
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
21
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/input/adb.c
12
--- a/target/tricore/helper.c
23
+++ b/hw/input/adb.c
13
+++ b/target/tricore/helper.c
24
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_adb_bus = {
14
@@ -XXX,XX +XXX,XX @@ void fpu_set_state(CPUTriCoreState *env)
25
}
15
set_flush_to_zero(1, &env->fp_status);
26
};
16
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
27
17
set_default_nan_mode(1, &env->fp_status);
28
-static void adb_bus_reset(BusState *qbus)
18
+ /* Default NaN pattern: sign bit clear, frac msb set */
29
+static void adb_bus_reset_hold(Object *obj)
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
30
{
31
- ADBBusState *adb_bus = ADB_BUS(qbus);
32
+ ADBBusState *adb_bus = ADB_BUS(obj);
33
34
adb_bus->autopoll_enabled = false;
35
adb_bus->autopoll_mask = 0xffff;
36
@@ -XXX,XX +XXX,XX @@ static void adb_bus_unrealize(BusState *qbus)
37
static void adb_bus_class_init(ObjectClass *klass, void *data)
38
{
39
BusClass *k = BUS_CLASS(klass);
40
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
41
42
k->realize = adb_bus_realize;
43
k->unrealize = adb_bus_unrealize;
44
- k->reset = adb_bus_reset;
45
+ rc->phases.hold = adb_bus_reset_hold;
46
}
20
}
47
21
48
static const TypeInfo adb_bus_type_info = {
22
uint32_t psw_read(CPUTriCoreState *env)
49
--
23
--
50
2.34.1
24
2.34.1
51
52
diff view generated by jsdifflib
1
The -serial option documentation is a bit brief about '-serial none'
1
Now that all our targets have bene converted to explicitly specify
2
and '-serial null'. In particular it's not very clear about the
2
their pattern for the default NaN value we can remove the remaining
3
difference between them, and it doesn't mention that it's up to
3
fallback code in parts64_default_nan().
4
the machine model whether '-serial none' means "don't create the
5
serial port" or "don't wire the serial port up to anything".
6
7
Expand on these points.
8
4
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20241202131347.498124-55-peter.maydell@linaro.org
12
Message-id: 20240122163607.459769-3-peter.maydell@linaro.org
13
---
8
---
14
qemu-options.hx | 14 +++++++++++---
9
fpu/softfloat-specialize.c.inc | 14 --------------
15
1 file changed, 11 insertions(+), 3 deletions(-)
10
1 file changed, 14 deletions(-)
16
11
17
diff --git a/qemu-options.hx b/qemu-options.hx
12
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/qemu-options.hx
14
--- a/fpu/softfloat-specialize.c.inc
20
+++ b/qemu-options.hx
15
+++ b/fpu/softfloat-specialize.c.inc
21
@@ -XXX,XX +XXX,XX @@ SRST
16
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
22
This option can be used several times to simulate up to 4 serial
17
uint64_t frac;
23
ports.
18
uint8_t dnan_pattern = status->default_nan_pattern;
24
19
25
- Use ``-serial none`` to disable all serial ports.
20
- if (dnan_pattern == 0) {
26
+ You can use ``-serial none`` to suppress the creation of default
21
- /*
27
+ serial devices.
22
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
28
23
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
29
Available character devices are:
24
- * do not have floating-point.
30
25
- */
31
@@ -XXX,XX +XXX,XX @@ SRST
26
- if (snan_bit_is_one(status)) {
32
[Linux only] Pseudo TTY (a new PTY is automatically allocated)
27
- /* sign bit clear, set all frac bits other than msb */
33
28
- dnan_pattern = 0b00111111;
34
``none``
29
- } else {
35
- No device is allocated.
30
- /* sign bit clear, set frac msb */
36
+ No device is allocated. Note that for machine types which
31
- dnan_pattern = 0b01000000;
37
+ emulate systems where a serial device is always present in
32
- }
38
+ real hardware, this may be equivalent to the ``null`` option,
33
- }
39
+ in that the serial device is still present but all output
34
assert(dnan_pattern != 0);
40
+ is discarded. For boards where the number of serial ports is
35
41
+ truly variable, this suppresses the creation of the device.
36
sign = dnan_pattern >> 7;
42
43
``null``
44
- void device
45
+ A guest will see the UART or serial device as present in the
46
+ machine, but all output is discarded, and there is no input.
47
+ Conceptually equivalent to redirecting the output to ``/dev/null``.
48
49
``chardev:id``
50
Use a named character device defined with the ``-chardev``
51
--
37
--
52
2.34.1
38
2.34.1
53
54
diff view generated by jsdifflib
1
Currently if the user passes multiple -serial options on the command
1
From: Richard Henderson <richard.henderson@linaro.org>
2
line, we mostly treat those as applying to the different serial
3
devices in order, so that for example
4
-serial stdio -serial file:filename
5
will connect the first serial port to stdio and the second to the
6
named file.
7
2
8
The exception to this is the '-serial none' serial device type. This
3
Inline pickNaNMulAdd into its only caller. This makes
9
means "don't allocate this serial device", but a bug means that
4
one assert redundant with the immediately preceding IF.
10
following -serial options are not correctly handled, so that
11
-serial none -serial stdio
12
has the unexpected effect that stdio is connected to the first serial
13
port, not the second.
14
5
15
This is a very long-standing bug that dates back at least as far as
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
commit 998bbd74b9d81 from 2009.
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
8
Message-id: 20241203203949.483774-3-richard.henderson@linaro.org
18
Make the 'none' serial type move forward in the indexing of serial
9
[PMM: keep comment from old code in new location]
19
devices like all the other serial types, so that any subsequent
20
-serial options are correctly handled.
21
22
Note that if your commandline mistakenly had a '-serial none' that
23
was being overridden by a following '-serial something' option, you
24
should delete the unnecessary '-serial none'. This will give you the
25
same behaviour as before, on QEMU versions both with and without this
26
bug fix.
27
28
Cc: qemu-stable@nongnu.org
29
Reported-by: Bohdan Kostiv <bohdan.kostiv@tii.ae>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
32
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Message-id: 20240122163607.459769-2-peter.maydell@linaro.org
34
Fixes: 998bbd74b9d81 ("default devices: core code & serial lines")
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
---
11
---
37
system/vl.c | 22 +++++++++++++---------
12
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
38
1 file changed, 13 insertions(+), 9 deletions(-)
13
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
14
2 files changed, 40 insertions(+), 55 deletions(-)
39
15
40
diff --git a/system/vl.c b/system/vl.c
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
41
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
42
--- a/system/vl.c
18
--- a/fpu/softfloat-parts.c.inc
43
+++ b/system/vl.c
19
+++ b/fpu/softfloat-parts.c.inc
44
@@ -XXX,XX +XXX,XX @@ static void qemu_create_default_devices(void)
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
45
static int serial_parse(const char *devname)
21
}
46
{
22
47
int index = num_serial_hds;
23
if (s->default_nan_mode) {
48
- char label[32];
24
+ /*
49
25
+ * We guarantee not to require the target to tell us how to
50
- if (strcmp(devname, "none") == 0)
26
+ * pick a NaN if we're always returning the default NaN.
51
- return 0;
27
+ * But if we're not in default-NaN mode then the target must
52
- snprintf(label, sizeof(label), "serial%d", index);
28
+ * specify.
53
serial_hds = g_renew(Chardev *, serial_hds, index + 1);
29
+ */
54
30
which = 3;
55
- serial_hds[index] = qemu_chr_new_mux_mon(label, devname, NULL);
31
+ } else if (infzero) {
56
- if (!serial_hds[index]) {
32
+ /*
57
- error_report("could not connect serial device"
33
+ * Inf * 0 + NaN -- some implementations return the
58
- " to character backend '%s'", devname);
34
+ * default NaN here, and some return the input NaN.
59
- return -1;
35
+ */
60
+ if (strcmp(devname, "none") == 0) {
36
+ switch (s->float_infzeronan_rule) {
61
+ /* Don't allocate a serial device for this index */
37
+ case float_infzeronan_dnan_never:
62
+ serial_hds[index] = NULL;
38
+ which = 2;
63
+ } else {
39
+ break;
64
+ char label[32];
40
+ case float_infzeronan_dnan_always:
65
+ snprintf(label, sizeof(label), "serial%d", index);
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;
66
+
53
+
67
+ serial_hds[index] = qemu_chr_new_mux_mon(label, devname, NULL);
54
+ assert(rule != float_3nan_prop_none);
68
+ if (!serial_hds[index]) {
55
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
69
+ error_report("could not connect serial device"
56
+ /* We have at least one SNaN input and should prefer it */
70
+ " to character backend '%s'", devname);
57
+ do {
71
+ return -1;
58
+ which = rule & R_3NAN_1ST_MASK;
59
+ rule >>= R_3NAN_1ST_LENGTH;
60
+ } while (!is_snan(cls[which]));
61
+ } else {
62
+ do {
63
+ which = rule & R_3NAN_1ST_MASK;
64
+ rule >>= R_3NAN_1ST_LENGTH;
65
+ } while (!is_nan(cls[which]));
72
+ }
66
+ }
73
}
67
}
74
num_serial_hds++;
68
75
return 0;
69
if (which == 3) {
70
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
71
index XXXXXXX..XXXXXXX 100644
72
--- a/fpu/softfloat-specialize.c.inc
73
+++ b/fpu/softfloat-specialize.c.inc
74
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
75
}
76
}
77
78
-/*----------------------------------------------------------------------------
79
-| Select which NaN to propagate for a three-input operation.
80
-| For the moment we assume that no CPU needs the 'larger significand'
81
-| information.
82
-| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
83
-*----------------------------------------------------------------------------*/
84
-static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
85
- bool infzero, bool have_snan, float_status *status)
86
-{
87
- FloatClass cls[3] = { a_cls, b_cls, c_cls };
88
- Float3NaNPropRule rule = status->float_3nan_prop_rule;
89
- int which;
90
-
91
- /*
92
- * We guarantee not to require the target to tell us how to
93
- * pick a NaN if we're always returning the default NaN.
94
- * But if we're not in default-NaN mode then the target must
95
- * specify.
96
- */
97
- assert(!status->default_nan_mode);
98
-
99
- if (infzero) {
100
- /*
101
- * Inf * 0 + NaN -- some implementations return the default NaN here,
102
- * and some return the input NaN.
103
- */
104
- switch (status->float_infzeronan_rule) {
105
- case float_infzeronan_dnan_never:
106
- return 2;
107
- case float_infzeronan_dnan_always:
108
- return 3;
109
- case float_infzeronan_dnan_if_qnan:
110
- return is_qnan(c_cls) ? 3 : 2;
111
- default:
112
- g_assert_not_reached();
113
- }
114
- }
115
-
116
- assert(rule != float_3nan_prop_none);
117
- if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
118
- /* We have at least one SNaN input and should prefer it */
119
- do {
120
- which = rule & R_3NAN_1ST_MASK;
121
- rule >>= R_3NAN_1ST_LENGTH;
122
- } while (!is_snan(cls[which]));
123
- } else {
124
- do {
125
- which = rule & R_3NAN_1ST_MASK;
126
- rule >>= R_3NAN_1ST_LENGTH;
127
- } while (!is_nan(cls[which]));
128
- }
129
- return which;
130
-}
131
-
132
/*----------------------------------------------------------------------------
133
| Returns 1 if the double-precision floating-point value `a' is a quiet
134
| NaN; otherwise returns 0.
76
--
135
--
77
2.34.1
136
2.34.1
78
137
79
138
diff view generated by jsdifflib
1
From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Tracing DPRINTFs to stderr might not be desired. A developer that relies
3
Remove "3" as a special case for which and simply
4
on trace events should be able to opt-in to each trace event and rely on
4
branch to return the desired value.
5
QEMU's log redirection, instead of stderr by default.
6
5
7
This commit converts DPRINTFs in this file that are used for tracing
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
into trace events. DPRINTFs that report guest errors are logged with
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
LOG_GUEST_ERROR.
8
Message-id: 20241203203949.483774-4-richard.henderson@linaro.org
10
11
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-id: 799c5141c5751cf2341e1d095349612e046424a8.1706544115.git.manos.pitsidianakis@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
hw/arm/z2.c | 27 ++++++++-------------------
11
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
17
hw/arm/trace-events | 7 +++++++
12
1 file changed, 10 insertions(+), 10 deletions(-)
18
2 files changed, 15 insertions(+), 19 deletions(-)
19
13
20
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/z2.c
16
--- a/fpu/softfloat-parts.c.inc
23
+++ b/hw/arm/z2.c
17
+++ b/fpu/softfloat-parts.c.inc
24
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
25
#include "exec/address-spaces.h"
19
* But if we're not in default-NaN mode then the target must
26
#include "qom/object.h"
20
* specify.
27
#include "qapi/error.h"
21
*/
28
-
22
- which = 3;
29
-#ifdef DEBUG_Z2
23
+ goto default_nan;
30
-#define DPRINTF(fmt, ...) \
24
} else if (infzero) {
31
- printf(fmt, ## __VA_ARGS__)
25
/*
32
-#else
26
* Inf * 0 + NaN -- some implementations return the
33
-#define DPRINTF(fmt, ...)
27
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
34
-#endif
28
*/
35
+#include "trace.h"
29
switch (s->float_infzeronan_rule) {
36
30
case float_infzeronan_dnan_never:
37
static const struct keymap map[0x100] = {
31
- which = 2;
38
[0 ... 0xff] = { -1, -1 },
39
@@ -XXX,XX +XXX,XX @@ static uint32_t zipit_lcd_transfer(SSIPeripheral *dev, uint32_t value)
40
{
41
ZipitLCD *z = ZIPIT_LCD(dev);
42
uint16_t val;
43
+
44
+ trace_z2_lcd_reg_update(z->cur_reg, z->buf[0], z->buf[1], z->buf[2], value);
45
if (z->selected) {
46
z->buf[z->pos] = value & 0xff;
47
z->pos++;
48
@@ -XXX,XX +XXX,XX @@ static uint32_t zipit_lcd_transfer(SSIPeripheral *dev, uint32_t value)
49
if (z->pos == 3) {
50
switch (z->buf[0]) {
51
case 0x74:
52
- DPRINTF("%s: reg: 0x%.2x\n", __func__, z->buf[2]);
53
z->cur_reg = z->buf[2];
54
break;
32
break;
55
case 0x76:
33
case float_infzeronan_dnan_always:
56
val = z->buf[1] << 8 | z->buf[2];
34
- which = 3;
57
- DPRINTF("%s: value: 0x%.4x\n", __func__, val);
35
- break;
58
if (z->cur_reg == 0x22 && val == 0x0000) {
36
+ goto default_nan;
59
z->enabled = 1;
37
case float_infzeronan_dnan_if_qnan:
60
- printf("%s: LCD enabled\n", __func__);
38
- which = is_qnan(c->cls) ? 3 : 2;
61
+ trace_z2_lcd_enable_disable_result("enabled");
39
+ if (is_qnan(c->cls)) {
62
} else if (z->cur_reg == 0x10 && val == 0x0000) {
40
+ goto default_nan;
63
z->enabled = 0;
41
+ }
64
- printf("%s: LCD disabled\n", __func__);
65
+ trace_z2_lcd_enable_disable_result("disabled");
66
}
67
break;
42
break;
68
default:
43
default:
69
- DPRINTF("%s: unknown command!\n", __func__);
44
g_assert_not_reached();
70
break;
71
}
45
}
72
z->pos = 0;
46
+ which = 2;
73
@@ -XXX,XX +XXX,XX @@ static int aer915_send(I2CSlave *i2c, uint8_t data)
47
} else {
74
48
FloatClass cls[3] = { a->cls, b->cls, c->cls };
75
s->buf[s->len] = data;
49
Float3NaNPropRule rule = s->float_3nan_prop_rule;
76
if (s->len++ > 2) {
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
77
- DPRINTF("%s: message too long (%i bytes)\n",
51
}
78
- __func__, s->len);
79
+ trace_z2_aer915_send_too_long(s->len);
80
return 1;
81
}
52
}
82
53
83
if (s->len == 2) {
54
- if (which == 3) {
84
- DPRINTF("%s: reg %d value 0x%02x\n", __func__,
55
- parts_default_nan(a, s);
85
- s->buf[0], s->buf[1]);
56
- return a;
86
+ trace_z2_aer915_send(s->buf[0], s->buf[1]);
57
- }
58
-
59
switch (which) {
60
case 0:
61
break;
62
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
63
parts_silence_nan(a, s);
87
}
64
}
88
65
return a;
89
return 0;
90
@@ -XXX,XX +XXX,XX @@ static int aer915_event(I2CSlave *i2c, enum i2c_event event)
91
{
92
AER915State *s = AER915(i2c);
93
94
+ trace_z2_aer915_event(s->len, event);
95
switch (event) {
96
case I2C_START_SEND:
97
s->len = 0;
98
break;
99
case I2C_START_RECV:
100
- if (s->len != 1) {
101
- DPRINTF("%s: short message!?\n", __func__);
102
- }
103
break;
104
case I2C_FINISH:
105
break;
106
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/trace-events
109
+++ b/hw/arm/trace-events
110
@@ -XXX,XX +XXX,XX @@ smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint16_t vmid, uint64
111
# strongarm.c
112
strongarm_uart_update_parameters(const char *label, int speed, char parity, int data_bits, int stop_bits) "%s speed=%d parity=%c data=%d stop=%d"
113
strongarm_ssp_read_underrun(void) "SSP rx underrun"
114
+
66
+
115
+# z2.c
67
+ default_nan:
116
+z2_lcd_reg_update(uint8_t cur, uint8_t i_0, uint8_t i_1, uint8_t i_2, uint32_t value) "cur_reg = 0x%x, buf = [0x%x, 0x%x, 0x%x], value = 0x%x"
68
+ parts_default_nan(a, s);
117
+z2_lcd_enable_disable_result(const char *result) "LCD %s"
69
+ return a;
118
+z2_aer915_send_too_long(int8_t msg) "message too long (%i bytes)"
70
}
119
+z2_aer915_send(uint8_t reg, uint8_t value) "reg %d value 0x%02x"
71
120
+z2_aer915_event(int8_t event, int8_t len) "i2c event =0x%x len=%d bytes"
72
/*
121
--
73
--
122
2.34.1
74
2.34.1
123
75
124
76
diff view generated by jsdifflib
1
From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Tracing DPRINTFs to stderr might not be desired. A developer that relies
3
Assign the pointer return value to 'a' directly,
4
on tracepoints should be able to opt-in to each tracepoint and rely on
4
rather than going through an intermediary index.
5
QEMU's log redirection, instead of stderr by default.
6
5
7
This commit converts DPRINTFs in this file that are used for tracing
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
into tracepoints.
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
8
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
10
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Message-id: 2fbe1fbc59078e384761c932e97cfa4276a53d75.1706544115.git.manos.pitsidianakis@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
hw/xen/xen-mapcache.c | 54 +++++++++++++++++++------------------------
11
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
16
hw/xen/trace-events | 11 +++++++++
12
1 file changed, 10 insertions(+), 22 deletions(-)
17
2 files changed, 35 insertions(+), 30 deletions(-)
18
13
19
diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/xen/xen-mapcache.c
16
--- a/fpu/softfloat-parts.c.inc
22
+++ b/hw/xen/xen-mapcache.c
17
+++ b/fpu/softfloat-parts.c.inc
23
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
24
#include "trace.h"
19
FloatPartsN *c, float_status *s,
25
20
int ab_mask, int abc_mask)
26
21
{
27
-//#define MAPCACHE_DEBUG
22
- int which;
28
-
23
bool infzero = (ab_mask == float_cmask_infzero);
29
-#ifdef MAPCACHE_DEBUG
24
bool have_snan = (abc_mask & float_cmask_snan);
30
-# define DPRINTF(fmt, ...) do { \
25
+ FloatPartsN *ret;
31
- fprintf(stderr, "xen_mapcache: " fmt, ## __VA_ARGS__); \
26
32
-} while (0)
27
if (unlikely(have_snan)) {
33
-#else
28
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
34
-# define DPRINTF(fmt, ...) do { } while (0)
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
35
-#endif
30
default:
36
-
31
g_assert_not_reached();
37
#if HOST_LONG_BITS == 32
32
}
38
# define MCACHE_BUCKET_SHIFT 16
33
- which = 2;
39
# define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */
34
+ ret = c;
40
@@ -XXX,XX +XXX,XX @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
35
} else {
41
36
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
42
size = mapcache->nr_buckets * sizeof (MapCacheEntry);
37
+ FloatPartsN *val[3] = { a, b, c };
43
size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
38
Float3NaNPropRule rule = s->float_3nan_prop_rule;
44
- DPRINTF("%s, nr_buckets = %lx size %lu\n", __func__,
39
45
- mapcache->nr_buckets, size);
40
assert(rule != float_3nan_prop_none);
46
+ trace_xen_map_cache_init(mapcache->nr_buckets, size);
41
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
47
mapcache->entry = g_malloc0(size);
42
/* We have at least one SNaN input and should prefer it */
48
}
43
do {
49
44
- which = rule & R_3NAN_1ST_MASK;
50
@@ -XXX,XX +XXX,XX @@ tryagain:
45
+ ret = val[rule & R_3NAN_1ST_MASK];
51
test_bits(address_offset >> XC_PAGE_SHIFT,
46
rule >>= R_3NAN_1ST_LENGTH;
52
test_bit_size >> XC_PAGE_SHIFT,
47
- } while (!is_snan(cls[which]));
53
mapcache->last_entry->valid_mapping)) {
48
+ } while (!is_snan(ret->cls));
54
- trace_xen_map_cache_return(mapcache->last_entry->vaddr_base + address_offset);
49
} else {
55
+ trace_xen_map_cache_return(
50
do {
56
+ mapcache->last_entry->vaddr_base + address_offset
51
- which = rule & R_3NAN_1ST_MASK;
57
+ );
52
+ ret = val[rule & R_3NAN_1ST_MASK];
58
return mapcache->last_entry->vaddr_base + address_offset;
53
rule >>= R_3NAN_1ST_LENGTH;
59
}
54
- } while (!is_nan(cls[which]));
60
55
+ } while (!is_nan(ret->cls));
61
@@ -XXX,XX +XXX,XX @@ tryagain:
62
QTAILQ_INSERT_HEAD(&mapcache->locked_entries, reventry, next);
63
}
64
65
- trace_xen_map_cache_return(mapcache->last_entry->vaddr_base + address_offset);
66
+ trace_xen_map_cache_return(
67
+ mapcache->last_entry->vaddr_base + address_offset
68
+ );
69
return mapcache->last_entry->vaddr_base + address_offset;
70
}
71
72
@@ -XXX,XX +XXX,XX @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
73
}
56
}
74
}
57
}
75
if (!found) {
58
76
- fprintf(stderr, "%s, could not find %p\n", __func__, ptr);
59
- switch (which) {
77
+ trace_xen_ram_addr_from_mapcache_not_found(ptr);
60
- case 0:
78
QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
61
- break;
79
- DPRINTF(" "HWADDR_FMT_plx" -> %p is present\n", reventry->paddr_index,
62
- case 1:
80
- reventry->vaddr_req);
63
- a = b;
81
+ trace_xen_ram_addr_from_mapcache_found(reventry->paddr_index,
64
- break;
82
+ reventry->vaddr_req);
65
- case 2:
83
}
66
- a = c;
84
abort();
67
- break;
85
return 0;
68
- default:
86
@@ -XXX,XX +XXX,XX @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
69
- g_assert_not_reached();
87
entry = entry->next;
70
+ if (is_snan(ret->cls)) {
71
+ parts_silence_nan(ret, s);
88
}
72
}
89
if (!entry) {
73
- if (is_snan(a->cls)) {
90
- DPRINTF("Trying to find address %p that is not in the mapcache!\n", ptr);
74
- parts_silence_nan(a, s);
91
+ trace_xen_ram_addr_from_mapcache_not_in_cache(ptr);
75
- }
92
raddr = 0;
76
- return a;
93
} else {
77
+ return ret;
94
raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
78
95
@@ -XXX,XX +XXX,XX @@ static void xen_invalidate_map_cache_entry_unlocked(uint8_t *buffer)
79
default_nan:
96
}
80
parts_default_nan(a, s);
97
}
98
if (!found) {
99
- DPRINTF("%s, could not find %p\n", __func__, buffer);
100
+ trace_xen_invalidate_map_cache_entry_unlocked_not_found(buffer);
101
QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
102
- DPRINTF(" "HWADDR_FMT_plx" -> %p is present\n", reventry->paddr_index, reventry->vaddr_req);
103
+ trace_xen_invalidate_map_cache_entry_unlocked_found(
104
+ reventry->paddr_index,
105
+ reventry->vaddr_req
106
+ );
107
}
108
return;
109
}
110
@@ -XXX,XX +XXX,XX @@ static void xen_invalidate_map_cache_entry_unlocked(uint8_t *buffer)
111
entry = entry->next;
112
}
113
if (!entry) {
114
- DPRINTF("Trying to unmap address %p that is not in the mapcache!\n", buffer);
115
+ trace_xen_invalidate_map_cache_entry_unlocked_miss(buffer);
116
return;
117
}
118
entry->lock--;
119
@@ -XXX,XX +XXX,XX @@ void xen_invalidate_map_cache(void)
120
if (!reventry->dma) {
121
continue;
122
}
123
- fprintf(stderr, "Locked DMA mapping while invalidating mapcache!"
124
- " "HWADDR_FMT_plx" -> %p is present\n",
125
- reventry->paddr_index, reventry->vaddr_req);
126
+ trace_xen_invalidate_map_cache(reventry->paddr_index,
127
+ reventry->vaddr_req);
128
}
129
130
for (i = 0; i < mapcache->nr_buckets; i++) {
131
@@ -XXX,XX +XXX,XX @@ static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
132
entry = entry->next;
133
}
134
if (!entry) {
135
- DPRINTF("Trying to update an entry for "HWADDR_FMT_plx \
136
- "that is not in the mapcache!\n", old_phys_addr);
137
+ trace_xen_replace_cache_entry_unlocked(old_phys_addr);
138
return NULL;
139
}
140
141
address_index = new_phys_addr >> MCACHE_BUCKET_SHIFT;
142
address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
143
144
- fprintf(stderr, "Replacing a dummy mapcache entry for "HWADDR_FMT_plx \
145
- " with "HWADDR_FMT_plx"\n", old_phys_addr, new_phys_addr);
146
+ trace_xen_replace_cache_entry_dummy(old_phys_addr, new_phys_addr);
147
148
xen_remap_bucket(entry, entry->vaddr_base,
149
cache_size, address_index, false);
150
if (!test_bits(address_offset >> XC_PAGE_SHIFT,
151
test_bit_size >> XC_PAGE_SHIFT,
152
entry->valid_mapping)) {
153
- DPRINTF("Unable to update a mapcache entry for "HWADDR_FMT_plx"!\n",
154
- old_phys_addr);
155
+ trace_xen_replace_cache_entry_unlocked_could_not_update_entry(
156
+ old_phys_addr
157
+ );
158
return NULL;
159
}
160
161
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
162
index XXXXXXX..XXXXXXX 100644
163
--- a/hw/xen/trace-events
164
+++ b/hw/xen/trace-events
165
@@ -XXX,XX +XXX,XX @@ cpu_ioreq_config_write(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, ui
166
xen_map_cache(uint64_t phys_addr) "want 0x%"PRIx64
167
xen_remap_bucket(uint64_t index) "index 0x%"PRIx64
168
xen_map_cache_return(void* ptr) "%p"
169
+xen_map_cache_init(uint64_t nr_buckets, uint64_t size) "nr_buckets = 0x%"PRIx64" size 0x%"PRIx64
170
+xen_replace_cache_entry_dummy(uint64_t old_phys_addr, uint64_t new_phys_addr) "Replacing a dummy mapcache entry for 0x%"PRIx64" with 0x%"PRIx64
171
+xen_invalidate_map_cache_entry_unlocked_not_found(void *p) "could not find %p"
172
+xen_invalidate_map_cache_entry_unlocked_found(uint64_t addr, void *p) " 0x%"PRIx64" -> %p is present"
173
+xen_invalidate_map_cache_entry_unlocked_miss(void *buffer) "Trying to unmap address %p that is not in the mapcache"
174
+xen_replace_cache_entry_unlocked_could_not_update_entry(uint64_t old_phys_addr) "Unable to update a mapcache entry for 0x%"PRIx64
175
+xen_ram_addr_from_mapcache_not_found(void *p) "could not find %p"
176
+xen_ram_addr_from_mapcache_found(uint64_t addr, void *p) " 0x%"PRIx64" -> %p is present"
177
+xen_ram_addr_from_mapcache_not_in_cache(void *p) "Trying to find address %p that is not in the mapcache"
178
+xen_replace_cache_entry_unlocked(uint64_t old_phys_addr) "Trying to update an entry for 0x%"PRIx64" that is not in the mapcache"
179
+xen_invalidate_map_cache(uint64_t paddr_index, void *vaddr_req) "Locked DMA mapping while invalidating mapcache 0x%"PRIx64" -> %p is present"
180
--
81
--
181
2.34.1
82
2.34.1
182
83
183
84
diff view generated by jsdifflib
1
From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
According to the QEMU Coding Style document:
3
While all indices into val[] should be in [0-2], the mask
4
applied is two bits. To help static analysis see there is
5
no possibility of read beyond the end of the array, pad the
6
array to 4 entries, with the final being (implicitly) NULL.
4
7
5
> Do not use printf(), fprintf() or monitor_printf(). Instead, use
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
> error_report() or error_vreport() from error-report.h. This ensures the
7
> error is reported in the right place (current monitor or stderr), and in
8
> a uniform format.
9
> Use error_printf() & friends to print additional information.
10
11
This commit changes fprintfs that report warnings and errors to the
12
appropriate report functions.
13
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
10
Message-id: 20241203203949.483774-6-richard.henderson@linaro.org
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Message-id: 42a8953553cf68e8bacada966f93af4fbce45919.1706544115.git.manos.pitsidianakis@linaro.org
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
12
---
20
hw/xen/xen-hvm-common.c | 12 ++++++------
13
fpu/softfloat-parts.c.inc | 2 +-
21
hw/xen/xen-mapcache.c | 5 ++---
14
1 file changed, 1 insertion(+), 1 deletion(-)
22
2 files changed, 8 insertions(+), 9 deletions(-)
23
15
24
diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/xen/xen-hvm-common.c
18
--- a/fpu/softfloat-parts.c.inc
27
+++ b/hw/xen/xen-hvm-common.c
19
+++ b/fpu/softfloat-parts.c.inc
28
@@ -XXX,XX +XXX,XX @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
29
30
if (runstate_check(RUN_STATE_INMIGRATE)) {
31
/* RAM already populated in Xen */
32
- fprintf(stderr, "%s: do not alloc "RAM_ADDR_FMT
33
- " bytes of ram at "RAM_ADDR_FMT" when runstate is INMIGRATE\n",
34
+ warn_report("%s: do not alloc "RAM_ADDR_FMT
35
+ " bytes of ram at "RAM_ADDR_FMT" when runstate is INMIGRATE",
36
__func__, size, ram_addr);
37
return;
38
}
39
@@ -XXX,XX +XXX,XX @@ static void cpu_handle_ioreq(void *opaque)
40
req->data = copy.data;
41
42
if (req->state != STATE_IOREQ_INPROCESS) {
43
- fprintf(stderr, "Badness in I/O request ... not in service?!: "
44
+ warn_report("Badness in I/O request ... not in service?!: "
45
"%x, ptr: %x, port: %"PRIx64", "
46
- "data: %"PRIx64", count: %u, size: %u, type: %u\n",
47
+ "data: %"PRIx64", count: %u, size: %u, type: %u",
48
req->state, req->data_is_ptr, req->addr,
49
req->data, req->count, req->size, req->type);
50
destroy_hvm_domain(false);
51
@@ -XXX,XX +XXX,XX @@ void xen_shutdown_fatal_error(const char *fmt, ...)
52
va_list ap;
53
54
va_start(ap, fmt);
55
- vfprintf(stderr, fmt, ap);
56
+ error_vreport(fmt, ap);
57
va_end(ap);
58
- fprintf(stderr, "Will destroy the domain.\n");
59
+ error_report("Will destroy the domain.");
60
/* destroy the domain */
61
qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_ERROR);
62
}
63
diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/xen/xen-mapcache.c
66
+++ b/hw/xen/xen-mapcache.c
67
@@ -XXX,XX +XXX,XX @@ tryagain:
68
MapCacheRev *reventry = g_new0(MapCacheRev, 1);
69
entry->lock++;
70
if (entry->lock == 0) {
71
- fprintf(stderr,
72
- "mapcache entry lock overflow: "HWADDR_FMT_plx" -> %p\n",
73
- entry->paddr_index, entry->vaddr_base);
74
+ error_report("mapcache entry lock overflow: "HWADDR_FMT_plx" -> %p",
75
+ entry->paddr_index, entry->vaddr_base);
76
abort();
77
}
21
}
78
reventry->dma = dma;
22
ret = c;
23
} else {
24
- FloatPartsN *val[3] = { a, b, c };
25
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
26
Float3NaNPropRule rule = s->float_3nan_prop_rule;
27
28
assert(rule != float_3nan_prop_none);
79
--
29
--
80
2.34.1
30
2.34.1
81
31
82
32
diff view generated by jsdifflib
1
From: Rayhan Faizel <rayhan.faizel@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This patch adds the SPI controller for the BCM2835. Polling and interrupt modes
3
This function is part of the public interface and
4
of transfer are supported. DMA and LoSSI modes are currently unimplemented.
4
is not "specialized" to any target in any way.
5
5
6
Signed-off-by: Rayhan Faizel <rayhan.faizel@gmail.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20240129221807.2983148-2-rayhan.faizel@gmail.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
docs/system/arm/raspi.rst | 2 +-
11
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
12
include/hw/ssi/bcm2835_spi.h | 81 ++++++++++
12
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
13
hw/ssi/bcm2835_spi.c | 288 +++++++++++++++++++++++++++++++++++
13
2 files changed, 52 insertions(+), 52 deletions(-)
14
hw/ssi/Kconfig | 4 +
15
hw/ssi/meson.build | 1 +
16
5 files changed, 375 insertions(+), 1 deletion(-)
17
create mode 100644 include/hw/ssi/bcm2835_spi.h
18
create mode 100644 hw/ssi/bcm2835_spi.c
19
14
20
diff --git a/docs/system/arm/raspi.rst b/docs/system/arm/raspi.rst
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/docs/system/arm/raspi.rst
17
--- a/fpu/softfloat.c
23
+++ b/docs/system/arm/raspi.rst
18
+++ b/fpu/softfloat.c
24
@@ -XXX,XX +XXX,XX @@ Implemented devices
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
25
* USB2 host controller (DWC2 and MPHI)
20
*zExpPtr = 1 - shiftCount;
26
* MailBox controller (MBOX)
21
}
27
* VideoCore firmware (property)
22
28
+ * Peripheral SPI controller (SPI)
23
+/*----------------------------------------------------------------------------
29
24
+| Takes two extended double-precision floating-point values `a' and `b', one
30
25
+| of which is a NaN, and returns the appropriate NaN result. If either `a' or
31
Missing devices
26
+| `b' is a signaling NaN, the invalid exception is raised.
32
---------------
27
+*----------------------------------------------------------------------------*/
33
34
- * Peripheral SPI controller (SPI)
35
* Analog to Digital Converter (ADC)
36
* Pulse Width Modulation (PWM)
37
diff --git a/include/hw/ssi/bcm2835_spi.h b/include/hw/ssi/bcm2835_spi.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/ssi/bcm2835_spi.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * BCM2835 SPI Master Controller
45
+ *
46
+ * Copyright (c) 2024 Rayhan Faizel <rayhan.faizel@gmail.com>
47
+ *
48
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
49
+ * of this software and associated documentation files (the "Software"), to deal
50
+ * in the Software without restriction, including without limitation the rights
51
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
52
+ * copies of the Software, and to permit persons to whom the Software is
53
+ * furnished to do so, subject to the following conditions:
54
+ *
55
+ * The above copyright notice and this permission notice shall be included in
56
+ * all copies or substantial portions of the Software.
57
+ *
58
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
61
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
62
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
63
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64
+ * THE SOFTWARE.
65
+ */
66
+
28
+
67
+#include "hw/sysbus.h"
29
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
68
+#include "hw/ssi/ssi.h"
30
+{
69
+#include "qom/object.h"
31
+ bool aIsLargerSignificand;
70
+#include "qemu/fifo8.h"
32
+ FloatClass a_cls, b_cls;
71
+
33
+
72
+#define TYPE_BCM2835_SPI "bcm2835-spi"
34
+ /* This is not complete, but is good enough for pickNaN. */
73
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835SPIState, BCM2835_SPI)
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);
74
+
45
+
75
+/*
46
+ if (is_snan(a_cls) || is_snan(b_cls)) {
76
+ * Though BCM2835 documentation says FIFOs have a capacity of 16,
47
+ float_raise(float_flag_invalid, status);
77
+ * FIFOs are actually 16 words in size or effectively 64 bytes when operating
78
+ * in non DMA mode.
79
+ */
80
+#define FIFO_SIZE 64
81
+#define FIFO_SIZE_3_4 48
82
+
83
+#define RO_MASK 0x1f0000
84
+
85
+#define BCM2835_SPI_CS 0x00
86
+#define BCM2835_SPI_FIFO 0x04
87
+#define BCM2835_SPI_CLK 0x08
88
+#define BCM2835_SPI_DLEN 0x0c
89
+#define BCM2835_SPI_LTOH 0x10
90
+#define BCM2835_SPI_DC 0x14
91
+
92
+#define BCM2835_SPI_CS_RXF BIT(20)
93
+#define BCM2835_SPI_CS_RXR BIT(19)
94
+#define BCM2835_SPI_CS_TXD BIT(18)
95
+#define BCM2835_SPI_CS_RXD BIT(17)
96
+#define BCM2835_SPI_CS_DONE BIT(16)
97
+#define BCM2835_SPI_CS_LEN BIT(13)
98
+#define BCM2835_SPI_CS_REN BIT(12)
99
+#define BCM2835_SPI_CS_INTR BIT(10)
100
+#define BCM2835_SPI_CS_INTD BIT(9)
101
+#define BCM2835_SPI_CS_DMAEN BIT(8)
102
+#define BCM2835_SPI_CS_TA BIT(7)
103
+#define BCM2835_SPI_CLEAR_RX BIT(5)
104
+#define BCM2835_SPI_CLEAR_TX BIT(4)
105
+
106
+struct BCM2835SPIState {
107
+ /* <private> */
108
+ SysBusDevice parent_obj;
109
+
110
+ /* <public> */
111
+ SSIBus *bus;
112
+ MemoryRegion iomem;
113
+ qemu_irq irq;
114
+
115
+ uint32_t cs;
116
+ uint32_t clk;
117
+ uint32_t dlen;
118
+ uint32_t ltoh;
119
+ uint32_t dc;
120
+
121
+ Fifo8 tx_fifo;
122
+ Fifo8 rx_fifo;
123
+};
124
diff --git a/hw/ssi/bcm2835_spi.c b/hw/ssi/bcm2835_spi.c
125
new file mode 100644
126
index XXXXXXX..XXXXXXX
127
--- /dev/null
128
+++ b/hw/ssi/bcm2835_spi.c
129
@@ -XXX,XX +XXX,XX @@
130
+/*
131
+ * BCM2835 SPI Master Controller
132
+ *
133
+ * Copyright (c) 2024 Rayhan Faizel <rayhan.faizel@gmail.com>
134
+ *
135
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
136
+ * of this software and associated documentation files (the "Software"), to deal
137
+ * in the Software without restriction, including without limitation the rights
138
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
139
+ * copies of the Software, and to permit persons to whom the Software is
140
+ * furnished to do so, subject to the following conditions:
141
+ *
142
+ * The above copyright notice and this permission notice shall be included in
143
+ * all copies or substantial portions of the Software.
144
+ *
145
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
146
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
147
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
148
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
149
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
150
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
151
+ * THE SOFTWARE.
152
+ */
153
+
154
+#include "qemu/osdep.h"
155
+#include "qemu/log.h"
156
+#include "qemu/fifo8.h"
157
+#include "hw/ssi/bcm2835_spi.h"
158
+#include "hw/irq.h"
159
+#include "migration/vmstate.h"
160
+
161
+static void bcm2835_spi_update_int(BCM2835SPIState *s)
162
+{
163
+ int do_interrupt = 0;
164
+
165
+ /* Interrupt on DONE */
166
+ if (s->cs & BCM2835_SPI_CS_INTD && s->cs & BCM2835_SPI_CS_DONE) {
167
+ do_interrupt = 1;
168
+ }
169
+ /* Interrupt on RXR */
170
+ if (s->cs & BCM2835_SPI_CS_INTR && s->cs & BCM2835_SPI_CS_RXR) {
171
+ do_interrupt = 1;
172
+ }
173
+ qemu_set_irq(s->irq, do_interrupt);
174
+}
175
+
176
+static void bcm2835_spi_update_rx_flags(BCM2835SPIState *s)
177
+{
178
+ /* Set RXD if RX FIFO is non empty */
179
+ if (!fifo8_is_empty(&s->rx_fifo)) {
180
+ s->cs |= BCM2835_SPI_CS_RXD;
181
+ } else {
182
+ s->cs &= ~BCM2835_SPI_CS_RXD;
183
+ }
48
+ }
184
+
49
+
185
+ /* Set RXF if RX FIFO is full */
50
+ if (status->default_nan_mode) {
186
+ if (fifo8_is_full(&s->rx_fifo)) {
51
+ return floatx80_default_nan(status);
187
+ s->cs |= BCM2835_SPI_CS_RXF;
188
+ } else {
189
+ s->cs &= ~BCM2835_SPI_CS_RXF;
190
+ }
52
+ }
191
+
53
+
192
+ /* Set RXR if RX FIFO is 3/4th used or above */
54
+ if (a.low < b.low) {
193
+ if (fifo8_num_used(&s->rx_fifo) >= FIFO_SIZE_3_4) {
55
+ aIsLargerSignificand = 0;
194
+ s->cs |= BCM2835_SPI_CS_RXR;
56
+ } else if (b.low < a.low) {
57
+ aIsLargerSignificand = 1;
195
+ } else {
58
+ } else {
196
+ s->cs &= ~BCM2835_SPI_CS_RXR;
59
+ aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
60
+ }
61
+
62
+ if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
63
+ if (is_snan(b_cls)) {
64
+ return floatx80_silence_nan(b, status);
65
+ }
66
+ return b;
67
+ } else {
68
+ if (is_snan(a_cls)) {
69
+ return floatx80_silence_nan(a, status);
70
+ }
71
+ return a;
197
+ }
72
+ }
198
+}
73
+}
199
+
74
+
200
+static void bcm2835_spi_update_tx_flags(BCM2835SPIState *s)
75
/*----------------------------------------------------------------------------
201
+{
76
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
202
+ /* Set TXD if TX FIFO is not full */
77
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
203
+ if (fifo8_is_full(&s->tx_fifo)) {
78
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
204
+ s->cs &= ~BCM2835_SPI_CS_TXD;
205
+ } else {
206
+ s->cs |= BCM2835_SPI_CS_TXD;
207
+ }
208
+
209
+ /* Set DONE if in TA mode and TX FIFO is empty */
210
+ if (fifo8_is_empty(&s->tx_fifo) && s->cs & BCM2835_SPI_CS_TA) {
211
+ s->cs |= BCM2835_SPI_CS_DONE;
212
+ } else {
213
+ s->cs &= ~BCM2835_SPI_CS_DONE;
214
+ }
215
+}
216
+
217
+static void bcm2835_spi_flush_tx_fifo(BCM2835SPIState *s)
218
+{
219
+ uint8_t tx_byte, rx_byte;
220
+
221
+ while (!fifo8_is_empty(&s->tx_fifo) && !fifo8_is_full(&s->rx_fifo)) {
222
+ tx_byte = fifo8_pop(&s->tx_fifo);
223
+ rx_byte = ssi_transfer(s->bus, tx_byte);
224
+ fifo8_push(&s->rx_fifo, rx_byte);
225
+ }
226
+
227
+ bcm2835_spi_update_tx_flags(s);
228
+ bcm2835_spi_update_rx_flags(s);
229
+}
230
+
231
+static uint64_t bcm2835_spi_read(void *opaque, hwaddr addr, unsigned size)
232
+{
233
+ BCM2835SPIState *s = opaque;
234
+ uint32_t readval = 0;
235
+
236
+ switch (addr) {
237
+ case BCM2835_SPI_CS:
238
+ readval = s->cs & 0xffffffff;
239
+ break;
240
+ case BCM2835_SPI_FIFO:
241
+ bcm2835_spi_flush_tx_fifo(s);
242
+ if (s->cs & BCM2835_SPI_CS_RXD) {
243
+ readval = fifo8_pop(&s->rx_fifo);
244
+ bcm2835_spi_update_rx_flags(s);
245
+ }
246
+
247
+ bcm2835_spi_update_int(s);
248
+ break;
249
+ case BCM2835_SPI_CLK:
250
+ readval = s->clk & 0xffff;
251
+ break;
252
+ case BCM2835_SPI_DLEN:
253
+ readval = s->dlen & 0xffff;
254
+ break;
255
+ case BCM2835_SPI_LTOH:
256
+ readval = s->ltoh & 0xf;
257
+ break;
258
+ case BCM2835_SPI_DC:
259
+ readval = s->dc & 0xffffffff;
260
+ break;
261
+ default:
262
+ qemu_log_mask(LOG_GUEST_ERROR,
263
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
264
+ }
265
+ return readval;
266
+}
267
+
268
+static void bcm2835_spi_write(void *opaque, hwaddr addr,
269
+ uint64_t value, unsigned int size)
270
+{
271
+ BCM2835SPIState *s = opaque;
272
+
273
+ switch (addr) {
274
+ case BCM2835_SPI_CS:
275
+ s->cs = (value & ~RO_MASK) | (s->cs & RO_MASK);
276
+ if (!(s->cs & BCM2835_SPI_CS_TA)) {
277
+ /* Clear DONE and RXR if TA is off */
278
+ s->cs &= ~(BCM2835_SPI_CS_DONE);
279
+ s->cs &= ~(BCM2835_SPI_CS_RXR);
280
+ }
281
+
282
+ /* Clear RX FIFO */
283
+ if (s->cs & BCM2835_SPI_CLEAR_RX) {
284
+ fifo8_reset(&s->rx_fifo);
285
+ bcm2835_spi_update_rx_flags(s);
286
+ }
287
+
288
+ /* Clear TX FIFO*/
289
+ if (s->cs & BCM2835_SPI_CLEAR_TX) {
290
+ fifo8_reset(&s->tx_fifo);
291
+ bcm2835_spi_update_tx_flags(s);
292
+ }
293
+
294
+ /* Set Transfer Active */
295
+ if (s->cs & BCM2835_SPI_CS_TA) {
296
+ bcm2835_spi_update_tx_flags(s);
297
+ }
298
+
299
+ if (s->cs & BCM2835_SPI_CS_DMAEN) {
300
+ qemu_log_mask(LOG_UNIMP, "%s: " \
301
+ "DMA not supported\n", __func__);
302
+ }
303
+
304
+ if (s->cs & BCM2835_SPI_CS_LEN) {
305
+ qemu_log_mask(LOG_UNIMP, "%s: " \
306
+ "LoSSI not supported\n", __func__);
307
+ }
308
+
309
+ bcm2835_spi_update_int(s);
310
+ break;
311
+ case BCM2835_SPI_FIFO:
312
+ /*
313
+ * According to documentation, writes to FIFO without TA controls
314
+ * CS and DLEN registers. This is supposed to be used in DMA mode
315
+ * which is currently unimplemented. Moreover, Linux does not make
316
+ * use of this and directly modifies the CS and DLEN registers.
317
+ */
318
+ if (s->cs & BCM2835_SPI_CS_TA) {
319
+ if (s->cs & BCM2835_SPI_CS_TXD) {
320
+ fifo8_push(&s->tx_fifo, value & 0xff);
321
+ bcm2835_spi_update_tx_flags(s);
322
+ }
323
+
324
+ bcm2835_spi_flush_tx_fifo(s);
325
+ bcm2835_spi_update_int(s);
326
+ }
327
+ break;
328
+ case BCM2835_SPI_CLK:
329
+ s->clk = value & 0xffff;
330
+ break;
331
+ case BCM2835_SPI_DLEN:
332
+ s->dlen = value & 0xffff;
333
+ break;
334
+ case BCM2835_SPI_LTOH:
335
+ s->ltoh = value & 0xf;
336
+ break;
337
+ case BCM2835_SPI_DC:
338
+ s->dc = value & 0xffffffff;
339
+ break;
340
+ default:
341
+ qemu_log_mask(LOG_GUEST_ERROR,
342
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
343
+ }
344
+}
345
+
346
+static const MemoryRegionOps bcm2835_spi_ops = {
347
+ .read = bcm2835_spi_read,
348
+ .write = bcm2835_spi_write,
349
+ .endianness = DEVICE_NATIVE_ENDIAN,
350
+};
351
+
352
+static void bcm2835_spi_realize(DeviceState *dev, Error **errp)
353
+{
354
+ BCM2835SPIState *s = BCM2835_SPI(dev);
355
+ s->bus = ssi_create_bus(dev, "spi");
356
+
357
+ memory_region_init_io(&s->iomem, OBJECT(dev), &bcm2835_spi_ops, s,
358
+ TYPE_BCM2835_SPI, 0x18);
359
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
360
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
361
+
362
+ fifo8_create(&s->tx_fifo, FIFO_SIZE);
363
+ fifo8_create(&s->rx_fifo, FIFO_SIZE);
364
+}
365
+static void bcm2835_spi_reset(DeviceState *dev)
366
+{
367
+ BCM2835SPIState *s = BCM2835_SPI(dev);
368
+
369
+ fifo8_reset(&s->tx_fifo);
370
+ fifo8_reset(&s->rx_fifo);
371
+
372
+ /* Reset values according to BCM2835 Peripheral Documentation */
373
+ s->cs = BCM2835_SPI_CS_TXD | BCM2835_SPI_CS_REN;
374
+ s->clk = 0;
375
+ s->dlen = 0;
376
+ s->ltoh = 0x1;
377
+ s->dc = 0x30201020;
378
+}
379
+
380
+static const VMStateDescription vmstate_bcm2835_spi = {
381
+ .name = TYPE_BCM2835_SPI,
382
+ .version_id = 1,
383
+ .minimum_version_id = 1,
384
+ .fields = (const VMStateField[]) {
385
+ VMSTATE_FIFO8(tx_fifo, BCM2835SPIState),
386
+ VMSTATE_FIFO8(rx_fifo, BCM2835SPIState),
387
+ VMSTATE_UINT32(cs, BCM2835SPIState),
388
+ VMSTATE_UINT32(clk, BCM2835SPIState),
389
+ VMSTATE_UINT32(dlen, BCM2835SPIState),
390
+ VMSTATE_UINT32(ltoh, BCM2835SPIState),
391
+ VMSTATE_UINT32(dc, BCM2835SPIState),
392
+ VMSTATE_END_OF_LIST()
393
+ }
394
+};
395
+
396
+static void bcm2835_spi_class_init(ObjectClass *klass, void *data)
397
+{
398
+ DeviceClass *dc = DEVICE_CLASS(klass);
399
+
400
+ dc->reset = bcm2835_spi_reset;
401
+ dc->realize = bcm2835_spi_realize;
402
+ dc->vmsd = &vmstate_bcm2835_spi;
403
+}
404
+
405
+static const TypeInfo bcm2835_spi_info = {
406
+ .name = TYPE_BCM2835_SPI,
407
+ .parent = TYPE_SYS_BUS_DEVICE,
408
+ .instance_size = sizeof(BCM2835SPIState),
409
+ .class_init = bcm2835_spi_class_init,
410
+};
411
+
412
+static void bcm2835_spi_register_types(void)
413
+{
414
+ type_register_static(&bcm2835_spi_info);
415
+}
416
+
417
+type_init(bcm2835_spi_register_types)
418
diff --git a/hw/ssi/Kconfig b/hw/ssi/Kconfig
419
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
420
--- a/hw/ssi/Kconfig
80
--- a/fpu/softfloat-specialize.c.inc
421
+++ b/hw/ssi/Kconfig
81
+++ b/fpu/softfloat-specialize.c.inc
422
@@ -XXX,XX +XXX,XX @@ config XILINX_SPIPS
82
@@ -XXX,XX +XXX,XX @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
423
config STM32F2XX_SPI
83
return a;
424
bool
84
}
425
select SSI
85
426
+
86
-/*----------------------------------------------------------------------------
427
+config BCM2835_SPI
87
-| Takes two extended double-precision floating-point values `a' and `b', one
428
+ bool
88
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
429
+ select SSI
89
-| `b' is a signaling NaN, the invalid exception is raised.
430
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
90
-*----------------------------------------------------------------------------*/
431
index XXXXXXX..XXXXXXX 100644
91
-
432
--- a/hw/ssi/meson.build
92
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
433
+++ b/hw/ssi/meson.build
93
-{
434
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-ospi.c'))
94
- bool aIsLargerSignificand;
435
system_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
95
- FloatClass a_cls, b_cls;
436
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
96
-
437
system_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_spi_host.c'))
97
- /* This is not complete, but is good enough for pickNaN. */
438
+system_ss.add(when: 'CONFIG_BCM2835_SPI', if_true: files('bcm2835_spi.c'))
98
- a_cls = (!floatx80_is_any_nan(a)
99
- ? float_class_normal
100
- : floatx80_is_signaling_nan(a, status)
101
- ? float_class_snan
102
- : float_class_qnan);
103
- b_cls = (!floatx80_is_any_nan(b)
104
- ? float_class_normal
105
- : floatx80_is_signaling_nan(b, status)
106
- ? float_class_snan
107
- : float_class_qnan);
108
-
109
- if (is_snan(a_cls) || is_snan(b_cls)) {
110
- float_raise(float_flag_invalid, status);
111
- }
112
-
113
- if (status->default_nan_mode) {
114
- return floatx80_default_nan(status);
115
- }
116
-
117
- if (a.low < b.low) {
118
- aIsLargerSignificand = 0;
119
- } else if (b.low < a.low) {
120
- aIsLargerSignificand = 1;
121
- } else {
122
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
123
- }
124
-
125
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
126
- if (is_snan(b_cls)) {
127
- return floatx80_silence_nan(b, status);
128
- }
129
- return b;
130
- } else {
131
- if (is_snan(a_cls)) {
132
- return floatx80_silence_nan(a, status);
133
- }
134
- return a;
135
- }
136
-}
137
-
138
/*----------------------------------------------------------------------------
139
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
140
| NaN; otherwise returns 0.
439
--
141
--
440
2.34.1
142
2.34.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Change-Id: Id8a3461fb5042adc4c3fd6f4fbd1ca0d33e22565
3
Unpacking and repacking the parts may be slightly more work
4
Signed-off-by: Hao Wu <wuhaotsh@google.com>
4
than we did before, but we get to reuse more code. For a
5
Signed-off-by: Nabih Estefan <nabihestefan@google.com>
5
code path handling exceptional values, this is an improvement.
6
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
6
7
Message-id: 20240131002800.989285-3-nabihestefan@google.com
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>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
include/hw/arm/npcm7xx.h | 2 ++
12
fpu/softfloat.c | 43 +++++--------------------------------------
12
hw/arm/npcm7xx.c | 37 +++++++++++++++++++++++++++++++++++--
13
1 file changed, 5 insertions(+), 38 deletions(-)
13
2 files changed, 37 insertions(+), 2 deletions(-)
14
14
15
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/npcm7xx.h
17
--- a/fpu/softfloat.c
18
+++ b/include/hw/arm/npcm7xx.h
18
+++ b/fpu/softfloat.c
19
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
20
#include "hw/misc/npcm7xx_pwm.h"
20
21
#include "hw/misc/npcm7xx_rng.h"
21
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
22
#include "hw/net/npcm7xx_emc.h"
22
{
23
+#include "hw/net/npcm_gmac.h"
23
- bool aIsLargerSignificand;
24
#include "hw/nvram/npcm7xx_otp.h"
24
- FloatClass a_cls, b_cls;
25
#include "hw/timer/npcm7xx_timer.h"
25
+ FloatParts128 pa, pb, *pr;
26
#include "hw/ssi/npcm7xx_fiu.h"
26
27
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxState {
27
- /* This is not complete, but is good enough for pickNaN. */
28
OHCISysBusState ohci;
28
- a_cls = (!floatx80_is_any_nan(a)
29
NPCM7xxFIUState fiu[2];
29
- ? float_class_normal
30
NPCM7xxEMCState emc[2];
30
- : floatx80_is_signaling_nan(a, status)
31
+ NPCMGMACState gmac[2];
31
- ? float_class_snan
32
NPCM7xxSDHCIState mmc;
32
- : float_class_qnan);
33
NPCMPSPIState pspi[2];
33
- b_cls = (!floatx80_is_any_nan(b)
34
};
34
- ? float_class_normal
35
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
35
- : floatx80_is_signaling_nan(b, status)
36
index XXXXXXX..XXXXXXX 100644
36
- ? float_class_snan
37
--- a/hw/arm/npcm7xx.c
37
- : float_class_qnan);
38
+++ b/hw/arm/npcm7xx.c
38
-
39
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
39
- if (is_snan(a_cls) || is_snan(b_cls)) {
40
NPCM7XX_UART1_IRQ,
40
- float_raise(float_flag_invalid, status);
41
NPCM7XX_UART2_IRQ,
41
- }
42
NPCM7XX_UART3_IRQ,
42
-
43
+ NPCM7XX_GMAC1_IRQ = 14,
43
- if (status->default_nan_mode) {
44
NPCM7XX_EMC1RX_IRQ = 15,
44
+ if (!floatx80_unpack_canonical(&pa, a, status) ||
45
NPCM7XX_EMC1TX_IRQ,
45
+ !floatx80_unpack_canonical(&pb, b, status)) {
46
+ NPCM7XX_GMAC2_IRQ,
46
return floatx80_default_nan(status);
47
NPCM7XX_MMC_IRQ = 26,
48
NPCM7XX_PSPI2_IRQ = 28,
49
NPCM7XX_PSPI1_IRQ = 31,
50
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_pspi_addr[] = {
51
0xf0201000,
52
};
53
54
+/* Register base address for each GMAC Module */
55
+static const hwaddr npcm7xx_gmac_addr[] = {
56
+ 0xf0802000,
57
+ 0xf0804000,
58
+};
59
+
60
static const struct {
61
hwaddr regs_addr;
62
uint32_t unconnected_pins;
63
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
64
object_initialize_child(obj, "pspi[*]", &s->pspi[i], TYPE_NPCM_PSPI);
65
}
47
}
66
48
67
+ for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
49
- if (a.low < b.low) {
68
+ object_initialize_child(obj, "gmac[*]", &s->gmac[i], TYPE_NPCM_GMAC);
50
- aIsLargerSignificand = 0;
69
+ }
51
- } else if (b.low < a.low) {
70
+
52
- aIsLargerSignificand = 1;
71
object_initialize_child(obj, "mmc", &s->mmc, TYPE_NPCM7XX_SDHCI);
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);
72
}
70
}
73
71
74
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
72
/*----------------------------------------------------------------------------
75
sysbus_connect_irq(sbd, 1, npcm7xx_irq(s, rx_irq));
76
}
77
78
+ /*
79
+ * GMAC Modules. Cannot fail.
80
+ */
81
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_gmac_addr) != ARRAY_SIZE(s->gmac));
82
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->gmac) != 2);
83
+ for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
84
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->gmac[i]);
85
+
86
+ /*
87
+ * The device exists regardless of whether it's connected to a QEMU
88
+ * netdev backend. So always instantiate it even if there is no
89
+ * backend.
90
+ */
91
+ sysbus_realize(sbd, &error_abort);
92
+ sysbus_mmio_map(sbd, 0, npcm7xx_gmac_addr[i]);
93
+ int irq = i == 0 ? NPCM7XX_GMAC1_IRQ : NPCM7XX_GMAC2_IRQ;
94
+ /*
95
+ * N.B. The values for the second argument sysbus_connect_irq are
96
+ * chosen to match the registration order in npcm7xx_emc_realize.
97
+ */
98
+ sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, irq));
99
+ }
100
+
101
/*
102
* Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
103
* specified, but this is a programming error.
104
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
105
create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB);
106
create_unimplemented_device("npcm7xx.ahbpci", 0xf0400000, 1 * MiB);
107
create_unimplemented_device("npcm7xx.mcphy", 0xf05f0000, 64 * KiB);
108
- create_unimplemented_device("npcm7xx.gmac1", 0xf0802000, 8 * KiB);
109
- create_unimplemented_device("npcm7xx.gmac2", 0xf0804000, 8 * KiB);
110
create_unimplemented_device("npcm7xx.vcd", 0xf0810000, 64 * KiB);
111
create_unimplemented_device("npcm7xx.ece", 0xf0820000, 8 * KiB);
112
create_unimplemented_device("npcm7xx.vdma", 0xf0822000, 8 * KiB);
113
--
73
--
114
2.34.1
74
2.34.1
diff view generated by jsdifflib
1
From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Tracing DPRINTFs to stderr might not be desired. A developer that relies
3
Inline pickNaN into its only caller. This makes one assert
4
on trace events should be able to opt-in to each trace event and rely on
4
redundant with the immediately preceding IF.
5
QEMU's log redirection, instead of stderr by default.
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
This commit converts DPRINTFs in this file that are used for tracing
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
into trace events. Errors or warnings are converted to error_report and
8
Message-id: 20241203203949.483774-9-richard.henderson@linaro.org
9
warn_report calls.
10
11
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-id: fe5e3bd54231abe933f95a24e0e88208cd8cfd8f.1706544115.git.manos.pitsidianakis@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
hw/arm/xen_arm.c | 23 +++++++++++------------
11
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
17
hw/arm/trace-events | 5 +++++
12
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
18
2 files changed, 16 insertions(+), 12 deletions(-)
13
2 files changed, 73 insertions(+), 105 deletions(-)
19
14
20
diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
15
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/xen_arm.c
17
--- a/fpu/softfloat-parts.c.inc
23
+++ b/hw/arm/xen_arm.c
18
+++ b/fpu/softfloat-parts.c.inc
24
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
25
#include "hw/xen/xen-hvm-common.h"
20
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
26
#include "sysemu/tpm.h"
21
float_status *s)
27
#include "hw/xen/arch_hvm.h"
22
{
28
+#include "trace.h"
23
+ int cmp, which;
29
24
+
30
#define TYPE_XEN_ARM MACHINE_TYPE_NAME("xenpvh")
25
if (is_snan(a->cls) || is_snan(b->cls)) {
31
OBJECT_DECLARE_SIMPLE_TYPE(XenArmState, XEN_ARM)
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
32
@@ -XXX,XX +XXX,XX @@ static void xen_create_virtio_mmio_devices(XenArmState *xam)
27
}
33
28
34
sysbus_create_simple("virtio-mmio", base, irq);
29
if (s->default_nan_mode) {
35
30
parts_default_nan(a, s);
36
- DPRINTF("Created virtio-mmio device %d: irq %d base 0x%lx\n",
31
- } else {
37
- i, GUEST_VIRTIO_MMIO_SPI_FIRST + i, base);
32
- int cmp = frac_cmp(a, b);
38
+ trace_xen_create_virtio_mmio_devices(i,
33
- if (cmp == 0) {
39
+ GUEST_VIRTIO_MMIO_SPI_FIRST + i,
34
- cmp = a->sign < b->sign;
40
+ base);
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
118
index XXXXXXX..XXXXXXX 100644
119
--- a/fpu/softfloat-specialize.c.inc
120
+++ b/fpu/softfloat-specialize.c.inc
121
@@ -XXX,XX +XXX,XX @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
41
}
122
}
42
}
123
}
43
124
44
@@ -XXX,XX +XXX,XX @@ static void xen_init_ram(MachineState *machine)
125
-/*----------------------------------------------------------------------------
45
MemoryRegion *sysmem = get_system_memory();
126
-| Select which NaN to propagate for a two-input operation.
46
ram_addr_t block_len, ram_size[GUEST_RAM_BANKS];
127
-| IEEE754 doesn't specify all the details of this, so the
47
128
-| algorithm is target-specific.
48
+ trace_xen_init_ram(machine->ram_size);
129
-| The routine is passed various bits of information about the
49
if (machine->ram_size <= GUEST_RAM0_SIZE) {
130
-| two NaNs and should return 0 to select NaN a and 1 for NaN b.
50
ram_size[0] = machine->ram_size;
131
-| Note that signalling NaNs are always squashed to quiet NaNs
51
ram_size[1] = 0;
132
-| by the caller, by calling floatXX_silence_nan() before
52
@@ -XXX,XX +XXX,XX @@ static void xen_init_ram(MachineState *machine)
133
-| returning them.
53
memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo", &ram_memory,
134
-|
54
GUEST_RAM0_BASE, ram_size[0]);
135
-| aIsLargerSignificand is only valid if both a and b are NaNs
55
memory_region_add_subregion(sysmem, GUEST_RAM0_BASE, &ram_lo);
136
-| of some kind, and is true if a has the larger significand,
56
- DPRINTF("Initialized region xen.ram.lo: base 0x%llx size 0x%lx\n",
137
-| or if both a and b have the same significand but a is
57
- GUEST_RAM0_BASE, ram_size[0]);
138
-| positive but b is negative. It is only needed for the x87
139
-| tie-break rule.
140
-*----------------------------------------------------------------------------*/
58
-
141
-
59
if (ram_size[1] > 0) {
142
-static int pickNaN(FloatClass a_cls, FloatClass b_cls,
60
memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi", &ram_memory,
143
- bool aIsLargerSignificand, float_status *status)
61
GUEST_RAM1_BASE, ram_size[1]);
144
-{
62
memory_region_add_subregion(sysmem, GUEST_RAM1_BASE, &ram_hi);
145
- /*
63
- DPRINTF("Initialized region xen.ram.hi: base 0x%llx size 0x%lx\n",
146
- * We guarantee not to require the target to tell us how to
64
- GUEST_RAM1_BASE, ram_size[1]);
147
- * pick a NaN if we're always returning the default NaN.
65
}
148
- * But if we're not in default-NaN mode then the target must
66
}
149
- * specify via set_float_2nan_prop_rule().
67
150
- */
68
@@ -XXX,XX +XXX,XX @@ static void xen_enable_tpm(XenArmState *xam)
151
- assert(!status->default_nan_mode);
69
152
-
70
TPMBackend *be = qemu_find_tpm_be("tpm0");
153
- switch (status->float_2nan_prop_rule) {
71
if (be == NULL) {
154
- case float_2nan_prop_s_ab:
72
- DPRINTF("Couldn't fine the backend for tpm0\n");
155
- if (is_snan(a_cls)) {
73
+ error_report("Couldn't find tmp0 backend");
156
- return 0;
74
return;
157
- } else if (is_snan(b_cls)) {
75
}
158
- return 1;
76
dev = qdev_new(TYPE_TPM_TIS_SYSBUS);
159
- } else if (is_qnan(a_cls)) {
77
@@ -XXX,XX +XXX,XX @@ static void xen_enable_tpm(XenArmState *xam)
160
- return 0;
78
sysbus_realize_and_unref(busdev, &error_fatal);
161
- } else {
79
sysbus_mmio_map(busdev, 0, xam->cfg.tpm_base_addr);
162
- return 1;
80
163
- }
81
- DPRINTF("Connected tpmdev at address 0x%lx\n", xam->cfg.tpm_base_addr);
164
- break;
82
+ trace_xen_enable_tpm(xam->cfg.tpm_base_addr);
165
- case float_2nan_prop_s_ba:
83
}
166
- if (is_snan(b_cls)) {
84
#endif
167
- return 1;
85
168
- } else if (is_snan(a_cls)) {
86
@@ -XXX,XX +XXX,XX @@ static void xen_arm_init(MachineState *machine)
169
- return 0;
87
xam->state = g_new0(XenIOState, 1);
170
- } else if (is_qnan(b_cls)) {
88
171
- return 1;
89
if (machine->ram_size == 0) {
172
- } else {
90
- DPRINTF("ram_size not specified. QEMU machine started without IOREQ"
173
- return 0;
91
- "(no emulated devices including Virtio)\n");
174
- }
92
+ warn_report("%s non-zero ram size not specified. QEMU machine started"
175
- break;
93
+ " without IOREQ (no emulated devices including virtio)",
176
- case float_2nan_prop_ab:
94
+ MACHINE_CLASS(object_get_class(OBJECT(machine)))->desc);
177
- if (is_nan(a_cls)) {
95
return;
178
- return 0;
96
}
179
- } else {
97
180
- return 1;
98
@@ -XXX,XX +XXX,XX @@ static void xen_arm_init(MachineState *machine)
181
- }
99
if (xam->cfg.tpm_base_addr) {
182
- break;
100
xen_enable_tpm(xam);
183
- case float_2nan_prop_ba:
101
} else {
184
- if (is_nan(b_cls)) {
102
- DPRINTF("tpm-base-addr is not provided. TPM will not be enabled\n");
185
- return 1;
103
+ warn_report("tpm-base-addr is not provided. TPM will not be enabled");
186
- } else {
104
}
187
- return 0;
105
#endif
188
- }
106
}
189
- break;
107
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
190
- case float_2nan_prop_x87:
108
index XXXXXXX..XXXXXXX 100644
191
- /*
109
--- a/hw/arm/trace-events
192
- * This implements x87 NaN propagation rules:
110
+++ b/hw/arm/trace-events
193
- * SNaN + QNaN => return the QNaN
111
@@ -XXX,XX +XXX,XX @@ z2_lcd_enable_disable_result(const char *result) "LCD %s"
194
- * two SNaNs => return the one with the larger significand, silenced
112
z2_aer915_send_too_long(int8_t msg) "message too long (%i bytes)"
195
- * two QNaNs => return the one with the larger significand
113
z2_aer915_send(uint8_t reg, uint8_t value) "reg %d value 0x%02x"
196
- * SNaN and a non-NaN => return the SNaN, silenced
114
z2_aer915_event(int8_t event, int8_t len) "i2c event =0x%x len=%d bytes"
197
- * QNaN and a non-NaN => return the QNaN
115
+
198
- *
116
+# xen_arm.c
199
- * If we get down to comparing significands and they are the same,
117
+xen_create_virtio_mmio_devices(int i, int irq, uint64_t base) "Created virtio-mmio device %d: irq %d base 0x%"PRIx64
200
- * return the NaN with the positive sign bit (if any).
118
+xen_init_ram(uint64_t machine_ram_size) "Initialized xen ram with size 0x%"PRIx64
201
- */
119
+xen_enable_tpm(uint64_t addr) "Connected tpmdev at address 0x%"PRIx64
202
- if (is_snan(a_cls)) {
203
- if (is_snan(b_cls)) {
204
- return aIsLargerSignificand ? 0 : 1;
205
- }
206
- return is_qnan(b_cls) ? 1 : 0;
207
- } else if (is_qnan(a_cls)) {
208
- if (is_snan(b_cls) || !is_qnan(b_cls)) {
209
- return 0;
210
- } else {
211
- return aIsLargerSignificand ? 0 : 1;
212
- }
213
- } else {
214
- return 1;
215
- }
216
- default:
217
- g_assert_not_reached();
218
- }
219
-}
220
-
221
/*----------------------------------------------------------------------------
222
| Returns 1 if the double-precision floating-point value `a' is a quiet
223
| NaN; otherwise returns 0.
120
--
224
--
121
2.34.1
225
2.34.1
122
226
123
227
diff view generated by jsdifflib
1
From: Jan Klötzke <jan.kloetzke@kernkonzept.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Debug exceptions that target AArch32 Hyp mode are reported differently
3
Remember if there was an SNaN, and use that to simplify
4
than on AAarch64. Internally, Qemu uses the AArch64 syndromes. Therefore
4
float_2nan_prop_s_{ab,ba} to only the snan component.
5
such exceptions need to be either converted to a prefetch abort
5
Then, fall through to the corresponding
6
(breakpoints, vector catch) or a data abort (watchpoints).
6
float_2nan_prop_{ab,ba} case to handle any remaining
7
nans, which must be quiet.
7
8
8
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Jan Klötzke <jan.kloetzke@kernkonzept.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20241203203949.483774-10-richard.henderson@linaro.org
11
Message-id: 20240127202758.3326381-1-jan.kloetzke@kernkonzept.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
target/arm/syndrome.h | 8 ++++++++
14
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
15
target/arm/helper.c | 18 ++++++++++++++++++
15
1 file changed, 12 insertions(+), 20 deletions(-)
16
2 files changed, 26 insertions(+)
17
16
18
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/syndrome.h
19
--- a/fpu/softfloat-parts.c.inc
21
+++ b/target/arm/syndrome.h
20
+++ b/fpu/softfloat-parts.c.inc
22
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
23
#ifndef TARGET_ARM_SYNDROME_H
22
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
24
#define TARGET_ARM_SYNDROME_H
23
float_status *s)
25
24
{
26
+#include "qemu/bitops.h"
25
+ bool have_snan = false;
27
+
26
int cmp, which;
28
/* Valid Syndrome Register EC field values */
27
29
enum arm_exception_class {
28
if (is_snan(a->cls) || is_snan(b->cls)) {
30
EC_UNCATEGORIZED = 0x00,
29
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
31
@@ -XXX,XX +XXX,XX @@ typedef enum {
30
+ have_snan = true;
32
SME_ET_InactiveZA,
33
} SMEExceptionType;
34
35
+#define ARM_EL_EC_LENGTH 6
36
#define ARM_EL_EC_SHIFT 26
37
#define ARM_EL_IL_SHIFT 25
38
#define ARM_EL_ISV_SHIFT 24
39
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_get_ec(uint32_t syn)
40
return syn >> ARM_EL_EC_SHIFT;
41
}
42
43
+static inline uint32_t syn_set_ec(uint32_t syn, uint32_t ec)
44
+{
45
+ return deposit32(syn, ARM_EL_EC_SHIFT, ARM_EL_EC_LENGTH, ec);
46
+}
47
+
48
/*
49
* Utility functions for constructing various kinds of syndrome value.
50
* Note that in general we follow the AArch64 syndrome values; in a
51
diff --git a/target/arm/helper.c b/target/arm/helper.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/helper.c
54
+++ b/target/arm/helper.c
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
56
}
31
}
57
32
58
if (env->exception.target_el == 2) {
33
if (s->default_nan_mode) {
59
+ /* Debug exceptions are reported differently on AArch32 */
34
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
60
+ switch (syn_get_ec(env->exception.syndrome)) {
35
61
+ case EC_BREAKPOINT:
36
switch (s->float_2nan_prop_rule) {
62
+ case EC_BREAKPOINT_SAME_EL:
37
case float_2nan_prop_s_ab:
63
+ case EC_AA32_BKPT:
38
- if (is_snan(a->cls)) {
64
+ case EC_VECTORCATCH:
39
- which = 0;
65
+ env->exception.syndrome = syn_insn_abort(arm_current_el(env) == 2,
40
- } else if (is_snan(b->cls)) {
66
+ 0, 0, 0x22);
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;
67
+ break;
48
+ break;
68
+ case EC_WATCHPOINT:
49
}
69
+ env->exception.syndrome = syn_set_ec(env->exception.syndrome,
50
- break;
70
+ EC_DATAABORT);
51
- case float_2nan_prop_s_ba:
71
+ break;
52
- if (is_snan(b->cls)) {
72
+ case EC_WATCHPOINT_SAME_EL:
53
- which = 1;
73
+ env->exception.syndrome = syn_set_ec(env->exception.syndrome,
54
- } else if (is_snan(a->cls)) {
74
+ EC_DATAABORT_SAME_EL);
55
- which = 0;
56
- } else if (is_qnan(b->cls)) {
57
- which = 1;
58
- } else {
59
- which = 0;
60
- }
61
- break;
62
+ /* fall through */
63
case float_2nan_prop_ab:
64
which = is_nan(a->cls) ? 0 : 1;
65
break;
66
+ case float_2nan_prop_s_ba:
67
+ if (have_snan) {
68
+ which = is_snan(b->cls) ? 1 : 0;
75
+ break;
69
+ break;
76
+ }
70
+ }
77
arm_cpu_do_interrupt_aarch32_hyp(cs);
71
+ /* fall through */
78
return;
72
case float_2nan_prop_ba:
79
}
73
which = is_nan(b->cls) ? 1 : 0;
74
break;
80
--
75
--
81
2.34.1
76
2.34.1
82
83
diff view generated by jsdifflib
1
From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Tracing DPRINTFs to stderr might not be desired. A developer that relies
3
Move the fractional comparison to the end of the
4
on trace events should be able to opt-in to each trace event and rely on
4
float_2nan_prop_x87 case. This is not required for
5
QEMU's log redirection, instead of stderr by default.
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.
6
8
7
This commit converts DPRINTFs in this file that are used for tracing
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
into trace events. DPRINTFs that report guest errors are logged with
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
LOG_GUEST_ERROR.#
11
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
10
11
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-id: 39db71dd87bf2007cf7812f3d91dde53887f1f2f.1706544115.git.manos.pitsidianakis@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
hw/arm/strongarm.c | 82 ++++++++++++++++++++++++++++-----------------
14
fpu/softfloat-parts.c.inc | 19 +++++++++----------
17
hw/arm/trace-events | 3 ++
15
1 file changed, 9 insertions(+), 10 deletions(-)
18
2 files changed, 55 insertions(+), 30 deletions(-)
19
16
20
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/strongarm.c
19
--- a/fpu/softfloat-parts.c.inc
23
+++ b/hw/arm/strongarm.c
20
+++ b/fpu/softfloat-parts.c.inc
24
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
25
#include "qemu/log.h"
22
return a;
26
#include "qom/object.h"
23
}
27
#include "target/arm/cpu-qom.h"
24
25
- cmp = frac_cmp(a, b);
26
- if (cmp == 0) {
27
- cmp = a->sign < b->sign;
28
- }
28
-
29
-
29
-//#define DEBUG
30
switch (s->float_2nan_prop_rule) {
30
+#include "trace.h"
31
case float_2nan_prop_s_ab:
31
32
if (have_snan) {
32
/*
33
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
33
TODO
34
* return the NaN with the positive sign bit (if any).
34
@@ -XXX,XX +XXX,XX @@
35
*/
35
- Enhance UART with modem signals
36
if (is_snan(a->cls)) {
36
*/
37
- if (is_snan(b->cls)) {
37
38
- which = cmp > 0 ? 0 : 1;
38
-#ifdef DEBUG
39
- } else {
39
-# define DPRINTF(format, ...) printf(format , ## __VA_ARGS__)
40
+ if (!is_snan(b->cls)) {
40
-#else
41
which = is_qnan(b->cls) ? 1 : 0;
41
-# define DPRINTF(format, ...) do { } while (0)
42
+ break;
42
-#endif
43
}
43
-
44
} else if (is_qnan(a->cls)) {
44
static struct {
45
if (is_snan(b->cls) || !is_qnan(b->cls)) {
45
hwaddr io_base;
46
which = 0;
46
int irq;
47
- } else {
47
@@ -XXX,XX +XXX,XX @@ static uint64_t strongarm_pic_mem_read(void *opaque, hwaddr offset,
48
- which = cmp > 0 ? 0 : 1;
48
case ICPR:
49
+ break;
49
return s->pending;
50
}
50
default:
51
} else {
51
- printf("%s: Bad register offset 0x" HWADDR_FMT_plx "\n",
52
which = 1;
52
- __func__, offset);
53
+ break;
53
+ qemu_log_mask(LOG_GUEST_ERROR,
54
}
54
+ "%s: Bad register offset 0x"HWADDR_FMT_plx"\n",
55
+ cmp = frac_cmp(a, b);
55
+ __func__, offset);
56
+ if (cmp == 0) {
56
return 0;
57
+ cmp = a->sign < b->sign;
57
}
58
+ }
58
}
59
+ which = cmp > 0 ? 0 : 1;
59
@@ -XXX,XX +XXX,XX @@ static void strongarm_pic_mem_write(void *opaque, hwaddr offset,
60
s->int_idle = (value & 1) ? 0 : ~0;
61
break;
60
break;
62
default:
61
default:
63
- printf("%s: Bad register offset 0x" HWADDR_FMT_plx "\n",
62
g_assert_not_reached();
64
- __func__, offset);
65
+ qemu_log_mask(LOG_GUEST_ERROR,
66
+ "%s: Bad register offset 0x"HWADDR_FMT_plx"\n",
67
+ __func__, offset);
68
break;
69
}
70
strongarm_pic_update(s);
71
@@ -XXX,XX +XXX,XX @@ static uint64_t strongarm_rtc_read(void *opaque, hwaddr addr,
72
((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
73
(1000 * ((s->rttr & 0xffff) + 1));
74
default:
75
- printf("%s: Bad register 0x" HWADDR_FMT_plx "\n", __func__, addr);
76
+ qemu_log_mask(LOG_GUEST_ERROR,
77
+ "%s: Bad rtc register read 0x"HWADDR_FMT_plx"\n",
78
+ __func__, addr);
79
return 0;
80
}
81
}
82
@@ -XXX,XX +XXX,XX @@ static void strongarm_rtc_write(void *opaque, hwaddr addr,
83
break;
84
85
default:
86
- printf("%s: Bad register 0x" HWADDR_FMT_plx "\n", __func__, addr);
87
+ qemu_log_mask(LOG_GUEST_ERROR,
88
+ "%s: Bad rtc register write 0x"HWADDR_FMT_plx"\n",
89
+ __func__, addr);
90
}
91
}
92
93
@@ -XXX,XX +XXX,XX @@ static uint64_t strongarm_gpio_read(void *opaque, hwaddr offset,
94
95
case GPSR: /* GPIO Pin-Output Set registers */
96
qemu_log_mask(LOG_GUEST_ERROR,
97
- "strongarm GPIO: read from write only register GPSR\n");
98
+ "%s: read from write only register GPSR\n", __func__);
99
return 0;
100
101
case GPCR: /* GPIO Pin-Output Clear registers */
102
qemu_log_mask(LOG_GUEST_ERROR,
103
- "strongarm GPIO: read from write only register GPCR\n");
104
+ "%s: read from write only register GPCR\n", __func__);
105
return 0;
106
107
case GRER: /* GPIO Rising-Edge Detect Enable registers */
108
@@ -XXX,XX +XXX,XX @@ static uint64_t strongarm_gpio_read(void *opaque, hwaddr offset,
109
return s->status;
110
111
default:
112
- printf("%s: Bad offset 0x" HWADDR_FMT_plx "\n", __func__, offset);
113
+ qemu_log_mask(LOG_GUEST_ERROR,
114
+ "%s: Bad gpio read offset 0x"HWADDR_FMT_plx"\n",
115
+ __func__, offset);
116
}
117
118
return 0;
119
@@ -XXX,XX +XXX,XX @@ static void strongarm_gpio_write(void *opaque, hwaddr offset,
120
break;
121
122
default:
123
- printf("%s: Bad offset 0x" HWADDR_FMT_plx "\n", __func__, offset);
124
+ qemu_log_mask(LOG_GUEST_ERROR,
125
+ "%s: Bad write offset 0x"HWADDR_FMT_plx"\n",
126
+ __func__, offset);
127
}
128
}
129
130
@@ -XXX,XX +XXX,XX @@ static uint64_t strongarm_ppc_read(void *opaque, hwaddr offset,
131
return s->ppfr | ~0x7f001;
132
133
default:
134
- printf("%s: Bad offset 0x" HWADDR_FMT_plx "\n", __func__, offset);
135
+ qemu_log_mask(LOG_GUEST_ERROR,
136
+ "%s: Bad ppc read offset 0x"HWADDR_FMT_plx "\n",
137
+ __func__, offset);
138
}
139
140
return 0;
141
@@ -XXX,XX +XXX,XX @@ static void strongarm_ppc_write(void *opaque, hwaddr offset,
142
break;
143
144
default:
145
- printf("%s: Bad offset 0x" HWADDR_FMT_plx "\n", __func__, offset);
146
+ qemu_log_mask(LOG_GUEST_ERROR,
147
+ "%s: Bad ppc write offset 0x"HWADDR_FMT_plx"\n",
148
+ __func__, offset);
149
}
150
}
151
152
@@ -XXX,XX +XXX,XX @@ static void strongarm_uart_update_parameters(StrongARMUARTState *s)
153
s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size;
154
qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
155
156
- DPRINTF(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label,
157
- speed, parity, data_bits, stop_bits);
158
+ trace_strongarm_uart_update_parameters((s->chr.chr ?
159
+ s->chr.chr->label : "NULL") ?:
160
+ "NULL",
161
+ speed,
162
+ parity,
163
+ data_bits,
164
+ stop_bits);
165
}
166
167
static void strongarm_uart_rx_to(void *opaque)
168
@@ -XXX,XX +XXX,XX @@ static uint64_t strongarm_uart_read(void *opaque, hwaddr addr,
169
return s->utsr1;
170
171
default:
172
- printf("%s: Bad register 0x" HWADDR_FMT_plx "\n", __func__, addr);
173
+ qemu_log_mask(LOG_GUEST_ERROR,
174
+ "%s: Bad uart register read 0x"HWADDR_FMT_plx"\n",
175
+ __func__, addr);
176
return 0;
177
}
178
}
179
@@ -XXX,XX +XXX,XX @@ static void strongarm_uart_write(void *opaque, hwaddr addr,
180
break;
181
182
default:
183
- printf("%s: Bad register 0x" HWADDR_FMT_plx "\n", __func__, addr);
184
+ qemu_log_mask(LOG_GUEST_ERROR,
185
+ "%s: Bad uart register write 0x"HWADDR_FMT_plx"\n",
186
+ __func__, addr);
187
}
188
}
189
190
@@ -XXX,XX +XXX,XX @@ static uint64_t strongarm_ssp_read(void *opaque, hwaddr addr,
191
return 0xffffffff;
192
}
193
if (s->rx_level < 1) {
194
- printf("%s: SSP Rx Underrun\n", __func__);
195
+ trace_strongarm_ssp_read_underrun();
196
return 0xffffffff;
197
}
198
s->rx_level--;
199
@@ -XXX,XX +XXX,XX @@ static uint64_t strongarm_ssp_read(void *opaque, hwaddr addr,
200
strongarm_ssp_fifo_update(s);
201
return retval;
202
default:
203
- printf("%s: Bad register 0x" HWADDR_FMT_plx "\n", __func__, addr);
204
+ qemu_log_mask(LOG_GUEST_ERROR,
205
+ "%s: Bad ssp register read 0x"HWADDR_FMT_plx"\n",
206
+ __func__, addr);
207
break;
208
}
209
return 0;
210
@@ -XXX,XX +XXX,XX @@ static void strongarm_ssp_write(void *opaque, hwaddr addr,
211
case SSCR0:
212
s->sscr[0] = value & 0xffbf;
213
if ((s->sscr[0] & SSCR0_SSE) && SSCR0_DSS(value) < 4) {
214
- printf("%s: Wrong data size: %i bits\n", __func__,
215
- (int)SSCR0_DSS(value));
216
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Wrong data size: %i bits\n",
217
+ __func__, (int)SSCR0_DSS(value));
218
}
219
if (!(value & SSCR0_SSE)) {
220
s->sssr = 0;
221
@@ -XXX,XX +XXX,XX @@ static void strongarm_ssp_write(void *opaque, hwaddr addr,
222
case SSCR1:
223
s->sscr[1] = value & 0x2f;
224
if (value & SSCR1_LBM) {
225
- printf("%s: Attempt to use SSP LBM mode\n", __func__);
226
+ qemu_log_mask(LOG_GUEST_ERROR,
227
+ "%s: Attempt to use SSP LBM mode\n",
228
+ __func__);
229
}
230
strongarm_ssp_fifo_update(s);
231
break;
232
@@ -XXX,XX +XXX,XX @@ static void strongarm_ssp_write(void *opaque, hwaddr addr,
233
break;
234
235
default:
236
- printf("%s: Bad register 0x" HWADDR_FMT_plx "\n", __func__, addr);
237
+ qemu_log_mask(LOG_GUEST_ERROR,
238
+ "%s: Bad ssp register write 0x"HWADDR_FMT_plx"\n",
239
+ __func__, addr);
240
break;
241
}
242
}
243
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
244
index XXXXXXX..XXXXXXX 100644
245
--- a/hw/arm/trace-events
246
+++ b/hw/arm/trace-events
247
@@ -XXX,XX +XXX,XX @@ smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s
248
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
249
smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint16_t vmid, uint64_t iova, uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d vmid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64
250
251
+# strongarm.c
252
+strongarm_uart_update_parameters(const char *label, int speed, char parity, int data_bits, int stop_bits) "%s speed=%d parity=%c data=%d stop=%d"
253
+strongarm_ssp_read_underrun(void) "SSP rx underrun"
254
--
63
--
255
2.34.1
64
2.34.1
256
257
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Restrict MachineClass::valid_cpu_types[] to the single
3
Replace the "index" selecting between A and B with a result variable
4
valid CPU type.
4
of the proper type. This improves clarity within the function.
5
5
6
Instead of ignoring invalid CPU type requested by the user:
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
$ qemu-system-arm -M nuri -cpu cortex-a7 -S -monitor stdio
8
Message-id: 20241203203949.483774-12-richard.henderson@linaro.org
9
QEMU 8.2.50 monitor - type 'help' for more information
10
(qemu) info qom-tree
11
/machine (nuri-machine)
12
/soc (exynos4210)
13
/cpu[0] (cortex-a9-arm-cpu)
14
...
15
16
We now display an error:
17
18
$ qemu-system-arm -M nuri -cpu cortex-a7
19
qemu-system-arm: Invalid CPU model: cortex-a7
20
The only valid type is: cortex-a9
21
22
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Gavin Shan <gshan@redhat.com>
25
Message-id: 20240129151828.59544-3-philmd@linaro.org
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
10
---
28
hw/arm/exynos4_boards.c | 8 ++++++++
11
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
29
1 file changed, 8 insertions(+)
12
1 file changed, 13 insertions(+), 15 deletions(-)
30
13
31
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
32
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/exynos4_boards.c
16
--- a/fpu/softfloat-parts.c.inc
34
+++ b/hw/arm/exynos4_boards.c
17
+++ b/fpu/softfloat-parts.c.inc
35
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
36
#include "hw/qdev-properties.h"
19
float_status *s)
37
#include "hw/boards.h"
20
{
38
#include "hw/irq.h"
21
bool have_snan = false;
39
+#include "target/arm/cpu-qom.h"
22
- int cmp, which;
40
23
+ FloatPartsN *ret;
41
#define SMDK_LAN9118_BASE_ADDR 0x05000000
24
+ int cmp;
42
25
43
@@ -XXX,XX +XXX,XX @@ static void smdkc210_init(MachineState *machine)
26
if (is_snan(a->cls) || is_snan(b->cls)) {
44
arm_load_kernel(s->soc.cpu[0], machine, &exynos4_board_binfo);
27
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
28
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
29
switch (s->float_2nan_prop_rule) {
30
case float_2nan_prop_s_ab:
31
if (have_snan) {
32
- which = is_snan(a->cls) ? 0 : 1;
33
+ ret = is_snan(a->cls) ? a : b;
34
break;
35
}
36
/* fall through */
37
case float_2nan_prop_ab:
38
- which = is_nan(a->cls) ? 0 : 1;
39
+ ret = is_nan(a->cls) ? a : b;
40
break;
41
case float_2nan_prop_s_ba:
42
if (have_snan) {
43
- which = is_snan(b->cls) ? 1 : 0;
44
+ ret = is_snan(b->cls) ? b : a;
45
break;
46
}
47
/* fall through */
48
case float_2nan_prop_ba:
49
- which = is_nan(b->cls) ? 1 : 0;
50
+ ret = is_nan(b->cls) ? b : a;
51
break;
52
case float_2nan_prop_x87:
53
/*
54
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
55
*/
56
if (is_snan(a->cls)) {
57
if (!is_snan(b->cls)) {
58
- which = is_qnan(b->cls) ? 1 : 0;
59
+ ret = is_qnan(b->cls) ? b : a;
60
break;
61
}
62
} else if (is_qnan(a->cls)) {
63
if (is_snan(b->cls) || !is_qnan(b->cls)) {
64
- which = 0;
65
+ ret = a;
66
break;
67
}
68
} else {
69
- which = 1;
70
+ ret = b;
71
break;
72
}
73
cmp = frac_cmp(a, b);
74
if (cmp == 0) {
75
cmp = a->sign < b->sign;
76
}
77
- which = cmp > 0 ? 0 : 1;
78
+ ret = cmp > 0 ? a : b;
79
break;
80
default:
81
g_assert_not_reached();
82
}
83
84
- if (which) {
85
- a = b;
86
+ if (is_snan(ret->cls)) {
87
+ parts_silence_nan(ret, s);
88
}
89
- if (is_snan(a->cls)) {
90
- parts_silence_nan(a, s);
91
- }
92
- return a;
93
+ return ret;
45
}
94
}
46
95
47
+static const char * const valid_cpu_types[] = {
96
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
48
+ ARM_CPU_TYPE_NAME("cortex-a9"),
49
+ NULL
50
+};
51
+
52
static void nuri_class_init(ObjectClass *oc, void *data)
53
{
54
MachineClass *mc = MACHINE_CLASS(oc);
55
56
mc->desc = "Samsung NURI board (Exynos4210)";
57
mc->init = nuri_init;
58
+ mc->valid_cpu_types = valid_cpu_types;
59
mc->max_cpus = EXYNOS4210_NCPUS;
60
mc->min_cpus = EXYNOS4210_NCPUS;
61
mc->default_cpus = EXYNOS4210_NCPUS;
62
@@ -XXX,XX +XXX,XX @@ static void smdkc210_class_init(ObjectClass *oc, void *data)
63
64
mc->desc = "Samsung SMDKC210 board (Exynos4210)";
65
mc->init = smdkc210_init;
66
+ mc->valid_cpu_types = valid_cpu_types;
67
mc->max_cpus = EXYNOS4210_NCPUS;
68
mc->min_cpus = EXYNOS4210_NCPUS;
69
mc->default_cpus = EXYNOS4210_NCPUS;
70
--
97
--
71
2.34.1
98
2.34.1
72
99
73
100
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
Restrict MachineClass::valid_cpu_types[] to the single
3
I'm migrating to Qualcomm's new open source email infrastructure, so
4
valid CPU types.
4
update my email address, and update the mailmap to match.
5
5
6
Instead of ignoring invalid CPU type requested by the user:
6
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
7
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
8
$ qemu-system-arm -M midway -cpu cortex-a7 -S -monitor stdio
8
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
9
QEMU 8.2.50 monitor - type 'help' for more information
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
(qemu) info qom-tree
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
/machine (midway-machine)
11
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
12
/cpu[0] (cortex-a15-arm-cpu)
13
...
14
15
we now display an error:
16
17
$ qemu-system-arm -M midway -cpu cortex-a7
18
qemu-system-arm: Invalid CPU model: cortex-a7
19
The only valid type is: cortex-a15
20
21
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Reviewed-by: Gavin Shan <gshan@redhat.com>
24
Message-id: 20240129151828.59544-5-philmd@linaro.org
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
13
---
27
hw/arm/highbank.c | 10 ++++++++++
14
MAINTAINERS | 2 +-
28
1 file changed, 10 insertions(+)
15
.mailmap | 5 +++--
16
2 files changed, 4 insertions(+), 3 deletions(-)
29
17
30
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
18
diff --git a/MAINTAINERS b/MAINTAINERS
31
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/highbank.c
20
--- a/MAINTAINERS
33
+++ b/hw/arm/highbank.c
21
+++ b/MAINTAINERS
34
@@ -XXX,XX +XXX,XX @@ static void midway_init(MachineState *machine)
22
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
35
23
SBSA-REF
36
static void highbank_class_init(ObjectClass *oc, void *data)
24
M: Radoslaw Biernacki <rad@semihalf.com>
37
{
25
M: Peter Maydell <peter.maydell@linaro.org>
38
+ static const char * const valid_cpu_types[] = {
26
-R: Leif Lindholm <quic_llindhol@quicinc.com>
39
+ ARM_CPU_TYPE_NAME("cortex-a9"),
27
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
40
+ NULL
28
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
41
+ };
29
L: qemu-arm@nongnu.org
42
MachineClass *mc = MACHINE_CLASS(oc);
30
S: Maintained
43
31
diff --git a/.mailmap b/.mailmap
44
mc->desc = "Calxeda Highbank (ECX-1000)";
32
index XXXXXXX..XXXXXXX 100644
45
mc->init = highbank_init;
33
--- a/.mailmap
46
+ mc->valid_cpu_types = valid_cpu_types;
34
+++ b/.mailmap
47
mc->block_default_type = IF_IDE;
35
@@ -XXX,XX +XXX,XX @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
48
mc->units_per_default_bus = 1;
36
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
49
mc->max_cpus = 4;
37
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
50
@@ -XXX,XX +XXX,XX @@ static const TypeInfo highbank_type = {
38
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
51
39
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
52
static void midway_class_init(ObjectClass *oc, void *data)
40
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
53
{
41
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
54
+ static const char * const valid_cpu_types[] = {
42
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
55
+ ARM_CPU_TYPE_NAME("cortex-a15"),
43
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
56
+ NULL
44
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
57
+ };
45
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
58
MachineClass *mc = MACHINE_CLASS(oc);
46
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
59
60
mc->desc = "Calxeda Midway (ECX-2000)";
61
mc->init = midway_init;
62
+ mc->valid_cpu_types = valid_cpu_types;
63
mc->block_default_type = IF_IDE;
64
mc->units_per_default_bus = 1;
65
mc->max_cpus = 4;
66
--
47
--
67
2.34.1
48
2.34.1
68
49
69
50
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
2
2
3
The latest version of qemu (v8.2.0-869-g7a1dc45af5) crashes when booting
3
Previously, maintainer role was paused due to inactive email id. Commit id:
4
the mcimx7d-sabre emulation with Linux v5.11 and later.
4
c009d715721861984c4987bcc78b7ee183e86d75.
5
5
6
qemu-system-arm: ../system/memory.c:2750: memory_region_set_alias_offset: Assertion `mr->alias' failed.
6
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
7
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Problem is that the Designware PCIe emulation accepts the full value range
8
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
9
for the iATU Viewport Register. However, both hardware and emulation only
10
support four inbound and four outbound viewports.
11
12
The Linux kernel determines the number of supported viewports by writing
13
0xff into the viewport register and reading the value back. The expected
14
value when reading the register is the highest supported viewport index.
15
Match that code by masking the supported viewport value range when the
16
register is written. With this change, the Linux kernel reports
17
18
imx6q-pcie 33800000.pcie: iATU: unroll F, 4 ob, 4 ib, align 0K, limit 4G
19
20
as expected and supported.
21
22
Fixes: d64e5eabc4c7 ("pci: Add support for Designware IP block")
23
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
24
Cc: Nikita Ostrenkov <n.ostrenkov@gmail.com>
25
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
26
Message-id: 20240129060055.2616989-1-linux@roeck-us.net
27
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
10
---
30
hw/pci-host/designware.c | 2 ++
11
MAINTAINERS | 2 ++
31
1 file changed, 2 insertions(+)
12
1 file changed, 2 insertions(+)
32
13
33
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
14
diff --git a/MAINTAINERS b/MAINTAINERS
34
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/pci-host/designware.c
16
--- a/MAINTAINERS
36
+++ b/hw/pci-host/designware.c
17
+++ b/MAINTAINERS
37
@@ -XXX,XX +XXX,XX @@ static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address,
18
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-sb16-test.c
38
break;
19
39
20
Xilinx CAN
40
case DESIGNWARE_PCIE_ATU_VIEWPORT:
21
M: Francisco Iglesias <francisco.iglesias@amd.com>
41
+ val &= DESIGNWARE_PCIE_ATU_REGION_INBOUND |
22
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
42
+ (DESIGNWARE_PCIE_NUM_VIEWPORTS - 1);
23
S: Maintained
43
root->atu_viewport = val;
24
F: hw/net/can/xlnx-*
44
break;
25
F: include/hw/net/xlnx-*
45
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/*
46
--
34
--
47
2.34.1
35
2.34.1
diff view generated by jsdifflib