1
First arm pullreq for 7.1. The bulk of this is the qemu_split_irq
1
First arm pullreq of the cycle; this is mostly my softfloat NaN
2
removal.
2
handling series. (Lots more in my to-review queue, but I don't
3
3
like pullreqs growing too close to a hundred patches at a time :-))
4
I have enough stuff in my to-review queue that I expect to do another
5
pullreq early next week, but 31 patches is enough to not hang on to.
6
4
7
thanks
5
thanks
8
-- PMM
6
-- PMM
9
7
10
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
8
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
11
9
12
Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700)
10
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
13
11
14
are available in the Git repository at:
12
are available in the Git repository at:
15
13
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220421
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
17
15
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
16
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
19
17
20
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs (2022-04-21 11:37:05 +0100)
18
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
21
19
22
----------------------------------------------------------------
20
----------------------------------------------------------------
23
target-arm queue:
21
target-arm queue:
24
* hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
22
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
23
* fpu: Make muladd NaN handling runtime-selected, not compile-time
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
24
* fpu: Make default NaN pattern runtime-selected, not compile-time
27
* xlnx-zynqmp: Connect 4 TTC timers
25
* fpu: Minor NaN-related cleanups
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
26
* MAINTAINERS: email address updates
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
30
* stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
31
* hw/core/irq: remove unused 'qemu_irq_split' function
32
* npcm7xx: use symbolic constants for PWRON STRAP bit fields
33
* virt: document impact of gic-version on max CPUs
34
27
35
----------------------------------------------------------------
28
----------------------------------------------------------------
36
Edgar E. Iglesias (6):
29
Bernhard Beschow (5):
37
timer: cadence_ttc: Break out header file to allow embedding
30
hw/net/lan9118: Extract lan9118_phy
38
hw/arm/xlnx-zynqmp: Connect 4 TTC timers
31
hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations
39
hw/arm: versal: Create an APU CPU Cluster
32
hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register
40
hw/arm: versal: Add the Cortex-R5Fs
33
hw/net/lan9118_phy: Reuse MII constants
41
hw/misc: Add a model of the Xilinx Versal CRL
34
hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement
42
hw/arm: versal: Connect the CRL
43
35
44
Hao Wu (2):
36
Leif Lindholm (1):
45
hw/misc: Add PWRON STRAP bit fields in GCR module
37
MAINTAINERS: update email address for Leif Lindholm
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
47
38
48
Heinrich Schuchardt (1):
39
Peter Maydell (54):
49
hw/arm/virt: impact of gic-version on max CPUs
40
fpu: handle raising Invalid for infzero in pick_nan_muladd
41
fpu: Check for default_nan_mode before calling pickNaNMulAdd
42
softfloat: Allow runtime choice of inf * 0 + NaN result
43
tests/fp: Explicitly set inf-zero-nan rule
44
target/arm: Set FloatInfZeroNaNRule explicitly
45
target/s390: Set FloatInfZeroNaNRule explicitly
46
target/ppc: Set FloatInfZeroNaNRule explicitly
47
target/mips: Set FloatInfZeroNaNRule explicitly
48
target/sparc: Set FloatInfZeroNaNRule explicitly
49
target/xtensa: Set FloatInfZeroNaNRule explicitly
50
target/x86: Set FloatInfZeroNaNRule explicitly
51
target/loongarch: Set FloatInfZeroNaNRule explicitly
52
target/hppa: Set FloatInfZeroNaNRule explicitly
53
softfloat: Pass have_snan to pickNaNMulAdd
54
softfloat: Allow runtime choice of NaN propagation for muladd
55
tests/fp: Explicitly set 3-NaN propagation rule
56
target/arm: Set Float3NaNPropRule explicitly
57
target/loongarch: Set Float3NaNPropRule explicitly
58
target/ppc: Set Float3NaNPropRule explicitly
59
target/s390x: Set Float3NaNPropRule explicitly
60
target/sparc: Set Float3NaNPropRule explicitly
61
target/mips: Set Float3NaNPropRule explicitly
62
target/xtensa: Set Float3NaNPropRule explicitly
63
target/i386: Set Float3NaNPropRule explicitly
64
target/hppa: Set Float3NaNPropRule explicitly
65
fpu: Remove use_first_nan field from float_status
66
target/m68k: Don't pass NULL float_status to floatx80_default_nan()
67
softfloat: Create floatx80 default NaN from parts64_default_nan
68
target/loongarch: Use normal float_status in fclass_s and fclass_d helpers
69
target/m68k: In frem helper, initialize local float_status from env->fp_status
70
target/m68k: Init local float_status from env fp_status in gdb get/set reg
71
target/sparc: Initialize local scratch float_status from env->fp_status
72
target/ppc: Use env->fp_status in helper_compute_fprf functions
73
fpu: Allow runtime choice of default NaN value
74
tests/fp: Set default NaN pattern explicitly
75
target/microblaze: Set default NaN pattern explicitly
76
target/i386: Set default NaN pattern explicitly
77
target/hppa: Set default NaN pattern explicitly
78
target/alpha: Set default NaN pattern explicitly
79
target/arm: Set default NaN pattern explicitly
80
target/loongarch: Set default NaN pattern explicitly
81
target/m68k: Set default NaN pattern explicitly
82
target/mips: Set default NaN pattern explicitly
83
target/openrisc: Set default NaN pattern explicitly
84
target/ppc: Set default NaN pattern explicitly
85
target/sh4: Set default NaN pattern explicitly
86
target/rx: Set default NaN pattern explicitly
87
target/s390x: Set default NaN pattern explicitly
88
target/sparc: Set default NaN pattern explicitly
89
target/xtensa: Set default NaN pattern explicitly
90
target/hexagon: Set default NaN pattern explicitly
91
target/riscv: Set default NaN pattern explicitly
92
target/tricore: Set default NaN pattern explicitly
93
fpu: Remove default handling for dnan_pattern
50
94
51
Peter Maydell (19):
95
Richard Henderson (11):
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
96
target/arm: Copy entire float_status in is_ebf
53
hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device
97
softfloat: Inline pickNaNMulAdd
54
hw/intc/exynos4210_gic: Remove unused TYPE_EXYNOS4210_IRQ_GATE
98
softfloat: Use goto for default nan case in pick_nan_muladd
55
hw/arm/exynos4210: Put a9mpcore device into state struct
99
softfloat: Remove which from parts_pick_nan_muladd
56
hw/arm/exynos4210: Drop int_gic_irq[] from Exynos4210Irq struct
100
softfloat: Pad array size in pick_nan_muladd
57
hw/arm/exynos4210: Coalesce board_irqs and irq_table
101
softfloat: Move propagateFloatx80NaN to softfloat.c
58
hw/arm/exynos4210: Fix code style nit in combiner_grp_to_gic_id[]
102
softfloat: Use parts_pick_nan in propagateFloatx80NaN
59
hw/arm/exynos4210: Move exynos4210_init_board_irqs() into exynos4210.c
103
softfloat: Inline pickNaN
60
hw/arm/exynos4210: Put external GIC into state struct
104
softfloat: Share code between parts_pick_nan cases
61
hw/arm/exynos4210: Drop ext_gic_irq[] from Exynos4210Irq struct
105
softfloat: Sink frac_cmp in parts_pick_nan until needed
62
hw/arm/exynos4210: Move exynos4210_combiner_get_gpioin() into exynos4210.c
106
softfloat: Replace WHICH with RET in parts_pick_nan
63
hw/arm/exynos4210: Delete unused macro definitions
64
hw/arm/exynos4210: Use TYPE_SPLIT_IRQ in exynos4210_init_board_irqs()
65
hw/arm/exynos4210: Fill in irq_table[] for internal-combiner-only IRQ lines
66
hw/arm/exynos4210: Connect MCT_G0 and MCT_G1 to both combiners
67
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
68
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
69
hw/arm/exynos4210: Put combiners into state struct
70
hw/arm/exynos4210: Drop Exynos4210Irq struct
71
107
72
Zongyuan Li (3):
108
Vikram Garhwal (1):
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
109
MAINTAINERS: Add correct email address for Vikram Garhwal
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
75
hw/core/irq: remove unused 'qemu_irq_split' function
76
110
77
docs/system/arm/virt.rst | 4 +-
111
MAINTAINERS | 4 +-
78
include/hw/arm/exynos4210.h | 50 ++--
112
include/fpu/softfloat-helpers.h | 38 +++-
79
include/hw/arm/xlnx-versal.h | 16 ++
113
include/fpu/softfloat-types.h | 89 +++++++-
80
include/hw/arm/xlnx-zynqmp.h | 4 +
114
include/hw/net/imx_fec.h | 9 +-
81
include/hw/intc/exynos4210_combiner.h | 57 +++++
115
include/hw/net/lan9118_phy.h | 37 ++++
82
include/hw/intc/exynos4210_gic.h | 43 ++++
116
include/hw/net/mii.h | 6 +
83
include/hw/irq.h | 5 -
117
target/mips/fpu_helper.h | 20 ++
84
include/hw/misc/npcm7xx_gcr.h | 30 +++
118
target/sparc/helper.h | 4 +-
85
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++++
119
fpu/softfloat.c | 19 ++
86
include/hw/timer/cadence_ttc.h | 54 +++++
120
hw/net/imx_fec.c | 146 ++------------
87
hw/arm/exynos4210.c | 430 ++++++++++++++++++++++++++++++----
121
hw/net/lan9118.c | 137 ++-----------
88
hw/arm/npcm7xx_boards.c | 24 +-
122
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
89
hw/arm/realview.c | 33 ++-
123
linux-user/arm/nwfpe/fpa11.c | 5 +
90
hw/arm/stellaris.c | 15 +-
124
target/alpha/cpu.c | 2 +
91
hw/arm/virt.c | 7 +
125
target/arm/cpu.c | 10 +
92
hw/arm/xlnx-versal-virt.c | 6 +-
126
target/arm/tcg/vec_helper.c | 20 +-
93
hw/arm/xlnx-versal.c | 99 +++++++-
127
target/hexagon/cpu.c | 2 +
94
hw/arm/xlnx-zynqmp.c | 22 ++
128
target/hppa/fpu_helper.c | 12 ++
95
hw/core/irq.c | 15 --
129
target/i386/tcg/fpu_helper.c | 12 ++
96
hw/intc/exynos4210_combiner.c | 108 +--------
130
target/loongarch/tcg/fpu_helper.c | 14 +-
97
hw/intc/exynos4210_gic.c | 344 +--------------------------
131
target/m68k/cpu.c | 14 +-
98
hw/misc/xlnx-versal-crl.c | 421 +++++++++++++++++++++++++++++++++
132
target/m68k/fpu_helper.c | 6 +-
99
hw/timer/cadence_ttc.c | 32 +--
133
target/m68k/helper.c | 6 +-
100
MAINTAINERS | 2 +-
134
target/microblaze/cpu.c | 2 +
101
hw/misc/meson.build | 1 +
135
target/mips/msa.c | 10 +
102
25 files changed, 1457 insertions(+), 600 deletions(-)
136
target/openrisc/cpu.c | 2 +
103
create mode 100644 include/hw/intc/exynos4210_combiner.h
137
target/ppc/cpu_init.c | 19 ++
104
create mode 100644 include/hw/intc/exynos4210_gic.h
138
target/ppc/fpu_helper.c | 3 +-
105
create mode 100644 include/hw/misc/xlnx-versal-crl.h
139
target/riscv/cpu.c | 2 +
106
create mode 100644 include/hw/timer/cadence_ttc.h
140
target/rx/cpu.c | 2 +
107
create mode 100644 hw/misc/xlnx-versal-crl.c
141
target/s390x/cpu.c | 5 +
142
target/sh4/cpu.c | 2 +
143
target/sparc/cpu.c | 6 +
144
target/sparc/fop_helper.c | 8 +-
145
target/sparc/translate.c | 4 +-
146
target/tricore/helper.c | 2 +
147
target/xtensa/cpu.c | 4 +
148
target/xtensa/fpu_helper.c | 3 +-
149
tests/fp/fp-bench.c | 7 +
150
tests/fp/fp-test-log2.c | 1 +
151
tests/fp/fp-test.c | 7 +
152
fpu/softfloat-parts.c.inc | 152 +++++++++++---
153
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
154
.mailmap | 5 +-
155
hw/net/Kconfig | 5 +
156
hw/net/meson.build | 1 +
157
hw/net/trace-events | 10 +-
158
47 files changed, 778 insertions(+), 730 deletions(-)
159
create mode 100644 include/hw/net/lan9118_phy.h
160
create mode 100644 hw/net/lan9118_phy.c
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Add a model of the Xilinx Versal CRL.
3
A very similar implementation of the same device exists in imx_fec. Prepare for
4
a common implementation by extracting a device model into its own files.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Some migration state has been moved into the new device model which breaks
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
migration compatibility for the following machines:
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
* smdkc210
8
Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com
9
* realview-*
10
* vexpress-*
11
* kzm
12
* mps2-*
13
14
While breaking migration ABI, fix the size of the MII registers to be 16 bit,
15
as defined by IEEE 802.3u.
16
17
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
18
Tested-by: Guenter Roeck <linux@roeck-us.net>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Message-id: 20241102125724.532843-2-shentey@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
22
---
11
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++
23
include/hw/net/lan9118_phy.h | 37 ++++++++
12
hw/misc/xlnx-versal-crl.c | 421 ++++++++++++++++++++++++++++++
24
hw/net/lan9118.c | 137 +++++-----------------------
13
hw/misc/meson.build | 1 +
25
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
14
3 files changed, 657 insertions(+)
26
hw/net/Kconfig | 4 +
15
create mode 100644 include/hw/misc/xlnx-versal-crl.h
27
hw/net/meson.build | 1 +
16
create mode 100644 hw/misc/xlnx-versal-crl.c
28
5 files changed, 233 insertions(+), 115 deletions(-)
29
create mode 100644 include/hw/net/lan9118_phy.h
30
create mode 100644 hw/net/lan9118_phy.c
17
31
18
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
32
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
19
new file mode 100644
33
new file mode 100644
20
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
21
--- /dev/null
35
--- /dev/null
22
+++ b/include/hw/misc/xlnx-versal-crl.h
36
+++ b/include/hw/net/lan9118_phy.h
23
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
24
+/*
38
+/*
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
39
+ * SMSC LAN9118 PHY emulation
26
+ *
40
+ *
27
+ * Copyright (c) 2022 Xilinx Inc.
41
+ * Copyright (c) 2009 CodeSourcery, LLC.
28
+ * SPDX-License-Identifier: GPL-2.0-or-later
42
+ * Written by Paul Brook
29
+ *
43
+ *
30
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
45
+ * See the COPYING file in the top-level directory.
31
+ */
46
+ */
32
+#ifndef HW_MISC_XLNX_VERSAL_CRL_H
47
+
33
+#define HW_MISC_XLNX_VERSAL_CRL_H
48
+#ifndef HW_NET_LAN9118_PHY_H
34
+
49
+#define HW_NET_LAN9118_PHY_H
50
+
51
+#include "qom/object.h"
35
+#include "hw/sysbus.h"
52
+#include "hw/sysbus.h"
36
+#include "hw/register.h"
53
+
37
+#include "target/arm/cpu.h"
54
+#define TYPE_LAN9118_PHY "lan9118-phy"
38
+
55
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
39
+#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl"
56
+
40
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL)
57
+typedef struct Lan9118PhyState {
41
+
42
+REG32(ERR_CTRL, 0x0)
43
+ FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
44
+REG32(IR_STATUS, 0x4)
45
+ FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1)
46
+REG32(IR_MASK, 0x8)
47
+ FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1)
48
+REG32(IR_ENABLE, 0xc)
49
+ FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1)
50
+REG32(IR_DISABLE, 0x10)
51
+ FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1)
52
+REG32(WPROT, 0x1c)
53
+ FIELD(WPROT, ACTIVE, 0, 1)
54
+REG32(PLL_CLK_OTHER_DMN, 0x20)
55
+ FIELD(PLL_CLK_OTHER_DMN, APLL_BYPASS, 0, 1)
56
+REG32(RPLL_CTRL, 0x40)
57
+ FIELD(RPLL_CTRL, POST_SRC, 24, 3)
58
+ FIELD(RPLL_CTRL, PRE_SRC, 20, 3)
59
+ FIELD(RPLL_CTRL, CLKOUTDIV, 16, 2)
60
+ FIELD(RPLL_CTRL, FBDIV, 8, 8)
61
+ FIELD(RPLL_CTRL, BYPASS, 3, 1)
62
+ FIELD(RPLL_CTRL, RESET, 0, 1)
63
+REG32(RPLL_CFG, 0x44)
64
+ FIELD(RPLL_CFG, LOCK_DLY, 25, 7)
65
+ FIELD(RPLL_CFG, LOCK_CNT, 13, 10)
66
+ FIELD(RPLL_CFG, LFHF, 10, 2)
67
+ FIELD(RPLL_CFG, CP, 5, 4)
68
+ FIELD(RPLL_CFG, RES, 0, 4)
69
+REG32(RPLL_FRAC_CFG, 0x48)
70
+ FIELD(RPLL_FRAC_CFG, ENABLED, 31, 1)
71
+ FIELD(RPLL_FRAC_CFG, SEED, 22, 3)
72
+ FIELD(RPLL_FRAC_CFG, ALGRTHM, 19, 1)
73
+ FIELD(RPLL_FRAC_CFG, ORDER, 18, 1)
74
+ FIELD(RPLL_FRAC_CFG, DATA, 0, 16)
75
+REG32(PLL_STATUS, 0x50)
76
+ FIELD(PLL_STATUS, RPLL_STABLE, 2, 1)
77
+ FIELD(PLL_STATUS, RPLL_LOCK, 0, 1)
78
+REG32(RPLL_TO_XPD_CTRL, 0x100)
79
+ FIELD(RPLL_TO_XPD_CTRL, CLKACT, 25, 1)
80
+ FIELD(RPLL_TO_XPD_CTRL, DIVISOR0, 8, 10)
81
+REG32(LPD_TOP_SWITCH_CTRL, 0x104)
82
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT_ADMA, 26, 1)
83
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT, 25, 1)
84
+ FIELD(LPD_TOP_SWITCH_CTRL, DIVISOR0, 8, 10)
85
+ FIELD(LPD_TOP_SWITCH_CTRL, SRCSEL, 0, 3)
86
+REG32(LPD_LSBUS_CTRL, 0x108)
87
+ FIELD(LPD_LSBUS_CTRL, CLKACT, 25, 1)
88
+ FIELD(LPD_LSBUS_CTRL, DIVISOR0, 8, 10)
89
+ FIELD(LPD_LSBUS_CTRL, SRCSEL, 0, 3)
90
+REG32(CPU_R5_CTRL, 0x10c)
91
+ FIELD(CPU_R5_CTRL, CLKACT_OCM2, 28, 1)
92
+ FIELD(CPU_R5_CTRL, CLKACT_OCM, 27, 1)
93
+ FIELD(CPU_R5_CTRL, CLKACT_CORE, 26, 1)
94
+ FIELD(CPU_R5_CTRL, CLKACT, 25, 1)
95
+ FIELD(CPU_R5_CTRL, DIVISOR0, 8, 10)
96
+ FIELD(CPU_R5_CTRL, SRCSEL, 0, 3)
97
+REG32(IOU_SWITCH_CTRL, 0x114)
98
+ FIELD(IOU_SWITCH_CTRL, CLKACT, 25, 1)
99
+ FIELD(IOU_SWITCH_CTRL, DIVISOR0, 8, 10)
100
+ FIELD(IOU_SWITCH_CTRL, SRCSEL, 0, 3)
101
+REG32(GEM0_REF_CTRL, 0x118)
102
+ FIELD(GEM0_REF_CTRL, CLKACT_RX, 27, 1)
103
+ FIELD(GEM0_REF_CTRL, CLKACT_TX, 26, 1)
104
+ FIELD(GEM0_REF_CTRL, CLKACT, 25, 1)
105
+ FIELD(GEM0_REF_CTRL, DIVISOR0, 8, 10)
106
+ FIELD(GEM0_REF_CTRL, SRCSEL, 0, 3)
107
+REG32(GEM1_REF_CTRL, 0x11c)
108
+ FIELD(GEM1_REF_CTRL, CLKACT_RX, 27, 1)
109
+ FIELD(GEM1_REF_CTRL, CLKACT_TX, 26, 1)
110
+ FIELD(GEM1_REF_CTRL, CLKACT, 25, 1)
111
+ FIELD(GEM1_REF_CTRL, DIVISOR0, 8, 10)
112
+ FIELD(GEM1_REF_CTRL, SRCSEL, 0, 3)
113
+REG32(GEM_TSU_REF_CTRL, 0x120)
114
+ FIELD(GEM_TSU_REF_CTRL, CLKACT, 25, 1)
115
+ FIELD(GEM_TSU_REF_CTRL, DIVISOR0, 8, 10)
116
+ FIELD(GEM_TSU_REF_CTRL, SRCSEL, 0, 3)
117
+REG32(USB0_BUS_REF_CTRL, 0x124)
118
+ FIELD(USB0_BUS_REF_CTRL, CLKACT, 25, 1)
119
+ FIELD(USB0_BUS_REF_CTRL, DIVISOR0, 8, 10)
120
+ FIELD(USB0_BUS_REF_CTRL, SRCSEL, 0, 3)
121
+REG32(UART0_REF_CTRL, 0x128)
122
+ FIELD(UART0_REF_CTRL, CLKACT, 25, 1)
123
+ FIELD(UART0_REF_CTRL, DIVISOR0, 8, 10)
124
+ FIELD(UART0_REF_CTRL, SRCSEL, 0, 3)
125
+REG32(UART1_REF_CTRL, 0x12c)
126
+ FIELD(UART1_REF_CTRL, CLKACT, 25, 1)
127
+ FIELD(UART1_REF_CTRL, DIVISOR0, 8, 10)
128
+ FIELD(UART1_REF_CTRL, SRCSEL, 0, 3)
129
+REG32(SPI0_REF_CTRL, 0x130)
130
+ FIELD(SPI0_REF_CTRL, CLKACT, 25, 1)
131
+ FIELD(SPI0_REF_CTRL, DIVISOR0, 8, 10)
132
+ FIELD(SPI0_REF_CTRL, SRCSEL, 0, 3)
133
+REG32(SPI1_REF_CTRL, 0x134)
134
+ FIELD(SPI1_REF_CTRL, CLKACT, 25, 1)
135
+ FIELD(SPI1_REF_CTRL, DIVISOR0, 8, 10)
136
+ FIELD(SPI1_REF_CTRL, SRCSEL, 0, 3)
137
+REG32(CAN0_REF_CTRL, 0x138)
138
+ FIELD(CAN0_REF_CTRL, CLKACT, 25, 1)
139
+ FIELD(CAN0_REF_CTRL, DIVISOR0, 8, 10)
140
+ FIELD(CAN0_REF_CTRL, SRCSEL, 0, 3)
141
+REG32(CAN1_REF_CTRL, 0x13c)
142
+ FIELD(CAN1_REF_CTRL, CLKACT, 25, 1)
143
+ FIELD(CAN1_REF_CTRL, DIVISOR0, 8, 10)
144
+ FIELD(CAN1_REF_CTRL, SRCSEL, 0, 3)
145
+REG32(I2C0_REF_CTRL, 0x140)
146
+ FIELD(I2C0_REF_CTRL, CLKACT, 25, 1)
147
+ FIELD(I2C0_REF_CTRL, DIVISOR0, 8, 10)
148
+ FIELD(I2C0_REF_CTRL, SRCSEL, 0, 3)
149
+REG32(I2C1_REF_CTRL, 0x144)
150
+ FIELD(I2C1_REF_CTRL, CLKACT, 25, 1)
151
+ FIELD(I2C1_REF_CTRL, DIVISOR0, 8, 10)
152
+ FIELD(I2C1_REF_CTRL, SRCSEL, 0, 3)
153
+REG32(DBG_LPD_CTRL, 0x148)
154
+ FIELD(DBG_LPD_CTRL, CLKACT, 25, 1)
155
+ FIELD(DBG_LPD_CTRL, DIVISOR0, 8, 10)
156
+ FIELD(DBG_LPD_CTRL, SRCSEL, 0, 3)
157
+REG32(TIMESTAMP_REF_CTRL, 0x14c)
158
+ FIELD(TIMESTAMP_REF_CTRL, CLKACT, 25, 1)
159
+ FIELD(TIMESTAMP_REF_CTRL, DIVISOR0, 8, 10)
160
+ FIELD(TIMESTAMP_REF_CTRL, SRCSEL, 0, 3)
161
+REG32(CRL_SAFETY_CHK, 0x150)
162
+REG32(PSM_REF_CTRL, 0x154)
163
+ FIELD(PSM_REF_CTRL, DIVISOR0, 8, 10)
164
+ FIELD(PSM_REF_CTRL, SRCSEL, 0, 3)
165
+REG32(DBG_TSTMP_CTRL, 0x158)
166
+ FIELD(DBG_TSTMP_CTRL, CLKACT, 25, 1)
167
+ FIELD(DBG_TSTMP_CTRL, DIVISOR0, 8, 10)
168
+ FIELD(DBG_TSTMP_CTRL, SRCSEL, 0, 3)
169
+REG32(CPM_TOPSW_REF_CTRL, 0x15c)
170
+ FIELD(CPM_TOPSW_REF_CTRL, CLKACT, 25, 1)
171
+ FIELD(CPM_TOPSW_REF_CTRL, DIVISOR0, 8, 10)
172
+ FIELD(CPM_TOPSW_REF_CTRL, SRCSEL, 0, 3)
173
+REG32(USB3_DUAL_REF_CTRL, 0x160)
174
+ FIELD(USB3_DUAL_REF_CTRL, CLKACT, 25, 1)
175
+ FIELD(USB3_DUAL_REF_CTRL, DIVISOR0, 8, 10)
176
+ FIELD(USB3_DUAL_REF_CTRL, SRCSEL, 0, 3)
177
+REG32(RST_CPU_R5, 0x300)
178
+ FIELD(RST_CPU_R5, RESET_PGE, 4, 1)
179
+ FIELD(RST_CPU_R5, RESET_AMBA, 2, 1)
180
+ FIELD(RST_CPU_R5, RESET_CPU1, 1, 1)
181
+ FIELD(RST_CPU_R5, RESET_CPU0, 0, 1)
182
+REG32(RST_ADMA, 0x304)
183
+ FIELD(RST_ADMA, RESET, 0, 1)
184
+REG32(RST_GEM0, 0x308)
185
+ FIELD(RST_GEM0, RESET, 0, 1)
186
+REG32(RST_GEM1, 0x30c)
187
+ FIELD(RST_GEM1, RESET, 0, 1)
188
+REG32(RST_SPARE, 0x310)
189
+ FIELD(RST_SPARE, RESET, 0, 1)
190
+REG32(RST_USB0, 0x314)
191
+ FIELD(RST_USB0, RESET, 0, 1)
192
+REG32(RST_UART0, 0x318)
193
+ FIELD(RST_UART0, RESET, 0, 1)
194
+REG32(RST_UART1, 0x31c)
195
+ FIELD(RST_UART1, RESET, 0, 1)
196
+REG32(RST_SPI0, 0x320)
197
+ FIELD(RST_SPI0, RESET, 0, 1)
198
+REG32(RST_SPI1, 0x324)
199
+ FIELD(RST_SPI1, RESET, 0, 1)
200
+REG32(RST_CAN0, 0x328)
201
+ FIELD(RST_CAN0, RESET, 0, 1)
202
+REG32(RST_CAN1, 0x32c)
203
+ FIELD(RST_CAN1, RESET, 0, 1)
204
+REG32(RST_I2C0, 0x330)
205
+ FIELD(RST_I2C0, RESET, 0, 1)
206
+REG32(RST_I2C1, 0x334)
207
+ FIELD(RST_I2C1, RESET, 0, 1)
208
+REG32(RST_DBG_LPD, 0x338)
209
+ FIELD(RST_DBG_LPD, RPU_DBG1_RESET, 5, 1)
210
+ FIELD(RST_DBG_LPD, RPU_DBG0_RESET, 4, 1)
211
+ FIELD(RST_DBG_LPD, RESET_HSDP, 1, 1)
212
+ FIELD(RST_DBG_LPD, RESET, 0, 1)
213
+REG32(RST_GPIO, 0x33c)
214
+ FIELD(RST_GPIO, RESET, 0, 1)
215
+REG32(RST_TTC, 0x344)
216
+ FIELD(RST_TTC, TTC3_RESET, 3, 1)
217
+ FIELD(RST_TTC, TTC2_RESET, 2, 1)
218
+ FIELD(RST_TTC, TTC1_RESET, 1, 1)
219
+ FIELD(RST_TTC, TTC0_RESET, 0, 1)
220
+REG32(RST_TIMESTAMP, 0x348)
221
+ FIELD(RST_TIMESTAMP, RESET, 0, 1)
222
+REG32(RST_SWDT, 0x34c)
223
+ FIELD(RST_SWDT, RESET, 0, 1)
224
+REG32(RST_OCM, 0x350)
225
+ FIELD(RST_OCM, RESET, 0, 1)
226
+REG32(RST_IPI, 0x354)
227
+ FIELD(RST_IPI, RESET, 0, 1)
228
+REG32(RST_SYSMON, 0x358)
229
+ FIELD(RST_SYSMON, SEQ_RST, 1, 1)
230
+ FIELD(RST_SYSMON, CFG_RST, 0, 1)
231
+REG32(RST_FPD, 0x360)
232
+ FIELD(RST_FPD, SRST, 1, 1)
233
+ FIELD(RST_FPD, POR, 0, 1)
234
+REG32(PSM_RST_MODE, 0x370)
235
+ FIELD(PSM_RST_MODE, WAKEUP, 2, 1)
236
+ FIELD(PSM_RST_MODE, RST_MODE, 0, 2)
237
+
238
+#define CRL_R_MAX (R_PSM_RST_MODE + 1)
239
+
240
+#define RPU_MAX_CPU 2
241
+
242
+struct XlnxVersalCRL {
243
+ SysBusDevice parent_obj;
58
+ SysBusDevice parent_obj;
59
+
60
+ uint16_t status;
61
+ uint16_t control;
62
+ uint16_t advertise;
63
+ uint16_t ints;
64
+ uint16_t int_mask;
244
+ qemu_irq irq;
65
+ qemu_irq irq;
245
+
66
+ bool link_down;
246
+ struct {
67
+} Lan9118PhyState;
247
+ ARMCPU *cpu_r5[RPU_MAX_CPU];
68
+
248
+ DeviceState *adma[8];
69
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down);
249
+ DeviceState *uart[2];
70
+void lan9118_phy_reset(Lan9118PhyState *s);
250
+ DeviceState *gem[2];
71
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg);
251
+ DeviceState *usb;
72
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val);
252
+ } cfg;
73
+
253
+
254
+ RegisterInfoArray *reg_array;
255
+ uint32_t regs[CRL_R_MAX];
256
+ RegisterInfo regs_info[CRL_R_MAX];
257
+};
258
+#endif
74
+#endif
259
diff --git a/hw/misc/xlnx-versal-crl.c b/hw/misc/xlnx-versal-crl.c
75
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/net/lan9118.c
78
+++ b/hw/net/lan9118.c
79
@@ -XXX,XX +XXX,XX @@
80
#include "net/net.h"
81
#include "net/eth.h"
82
#include "hw/irq.h"
83
+#include "hw/net/lan9118_phy.h"
84
#include "hw/net/lan9118.h"
85
#include "hw/ptimer.h"
86
#include "hw/qdev-properties.h"
87
@@ -XXX,XX +XXX,XX @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
88
#define MAC_CR_RXEN 0x00000004
89
#define MAC_CR_RESERVED 0x7f404213
90
91
-#define PHY_INT_ENERGYON 0x80
92
-#define PHY_INT_AUTONEG_COMPLETE 0x40
93
-#define PHY_INT_FAULT 0x20
94
-#define PHY_INT_DOWN 0x10
95
-#define PHY_INT_AUTONEG_LP 0x08
96
-#define PHY_INT_PARFAULT 0x04
97
-#define PHY_INT_AUTONEG_PAGE 0x02
98
-
99
#define GPT_TIMER_EN 0x20000000
100
101
/*
102
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
103
uint32_t mac_mii_data;
104
uint32_t mac_flow;
105
106
- uint32_t phy_status;
107
- uint32_t phy_control;
108
- uint32_t phy_advertise;
109
- uint32_t phy_int;
110
- uint32_t phy_int_mask;
111
+ Lan9118PhyState mii;
112
+ IRQState mii_irq;
113
114
int32_t eeprom_writable;
115
uint8_t eeprom[128];
116
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
117
118
static const VMStateDescription vmstate_lan9118 = {
119
.name = "lan9118",
120
- .version_id = 2,
121
- .minimum_version_id = 1,
122
+ .version_id = 3,
123
+ .minimum_version_id = 3,
124
.fields = (const VMStateField[]) {
125
VMSTATE_PTIMER(timer, lan9118_state),
126
VMSTATE_UINT32(irq_cfg, lan9118_state),
127
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118 = {
128
VMSTATE_UINT32(mac_mii_acc, lan9118_state),
129
VMSTATE_UINT32(mac_mii_data, lan9118_state),
130
VMSTATE_UINT32(mac_flow, lan9118_state),
131
- VMSTATE_UINT32(phy_status, lan9118_state),
132
- VMSTATE_UINT32(phy_control, lan9118_state),
133
- VMSTATE_UINT32(phy_advertise, lan9118_state),
134
- VMSTATE_UINT32(phy_int, lan9118_state),
135
- VMSTATE_UINT32(phy_int_mask, lan9118_state),
136
VMSTATE_INT32(eeprom_writable, lan9118_state),
137
VMSTATE_UINT8_ARRAY(eeprom, lan9118_state, 128),
138
VMSTATE_INT32(tx_fifo_size, lan9118_state),
139
@@ -XXX,XX +XXX,XX @@ static void lan9118_reload_eeprom(lan9118_state *s)
140
lan9118_mac_changed(s);
141
}
142
143
-static void phy_update_irq(lan9118_state *s)
144
+static void lan9118_update_irq(void *opaque, int n, int level)
145
{
146
- if (s->phy_int & s->phy_int_mask) {
147
+ lan9118_state *s = opaque;
148
+
149
+ if (level) {
150
s->int_sts |= PHY_INT;
151
} else {
152
s->int_sts &= ~PHY_INT;
153
@@ -XXX,XX +XXX,XX @@ static void phy_update_irq(lan9118_state *s)
154
lan9118_update(s);
155
}
156
157
-static void phy_update_link(lan9118_state *s)
158
-{
159
- /* Autonegotiation status mirrors link status. */
160
- if (qemu_get_queue(s->nic)->link_down) {
161
- s->phy_status &= ~0x0024;
162
- s->phy_int |= PHY_INT_DOWN;
163
- } else {
164
- s->phy_status |= 0x0024;
165
- s->phy_int |= PHY_INT_ENERGYON;
166
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
167
- }
168
- phy_update_irq(s);
169
-}
170
-
171
static void lan9118_set_link(NetClientState *nc)
172
{
173
- phy_update_link(qemu_get_nic_opaque(nc));
174
-}
175
-
176
-static void phy_reset(lan9118_state *s)
177
-{
178
- s->phy_status = 0x7809;
179
- s->phy_control = 0x3000;
180
- s->phy_advertise = 0x01e1;
181
- s->phy_int_mask = 0;
182
- s->phy_int = 0;
183
- phy_update_link(s);
184
+ lan9118_phy_update_link(&LAN9118(qemu_get_nic_opaque(nc))->mii,
185
+ nc->link_down);
186
}
187
188
static void lan9118_reset(DeviceState *d)
189
@@ -XXX,XX +XXX,XX @@ static void lan9118_reset(DeviceState *d)
190
s->read_word_n = 0;
191
s->write_word_n = 0;
192
193
- phy_reset(s);
194
-
195
s->eeprom_writable = 0;
196
lan9118_reload_eeprom(s);
197
}
198
@@ -XXX,XX +XXX,XX @@ static void do_tx_packet(lan9118_state *s)
199
uint32_t status;
200
201
/* FIXME: Honor TX disable, and allow queueing of packets. */
202
- if (s->phy_control & 0x4000) {
203
+ if (s->mii.control & 0x4000) {
204
/* This assumes the receive routine doesn't touch the VLANClient. */
205
qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
206
} else {
207
@@ -XXX,XX +XXX,XX @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
208
}
209
}
210
211
-static uint32_t do_phy_read(lan9118_state *s, int reg)
212
-{
213
- uint32_t val;
214
-
215
- switch (reg) {
216
- case 0: /* Basic Control */
217
- return s->phy_control;
218
- case 1: /* Basic Status */
219
- return s->phy_status;
220
- case 2: /* ID1 */
221
- return 0x0007;
222
- case 3: /* ID2 */
223
- return 0xc0d1;
224
- case 4: /* Auto-neg advertisement */
225
- return s->phy_advertise;
226
- case 5: /* Auto-neg Link Partner Ability */
227
- return 0x0f71;
228
- case 6: /* Auto-neg Expansion */
229
- return 1;
230
- /* TODO 17, 18, 27, 29, 30, 31 */
231
- case 29: /* Interrupt source. */
232
- val = s->phy_int;
233
- s->phy_int = 0;
234
- phy_update_irq(s);
235
- return val;
236
- case 30: /* Interrupt mask */
237
- return s->phy_int_mask;
238
- default:
239
- qemu_log_mask(LOG_GUEST_ERROR,
240
- "do_phy_read: PHY read reg %d\n", reg);
241
- return 0;
242
- }
243
-}
244
-
245
-static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
246
-{
247
- switch (reg) {
248
- case 0: /* Basic Control */
249
- if (val & 0x8000) {
250
- phy_reset(s);
251
- break;
252
- }
253
- s->phy_control = val & 0x7980;
254
- /* Complete autonegotiation immediately. */
255
- if (val & 0x1000) {
256
- s->phy_status |= 0x0020;
257
- }
258
- break;
259
- case 4: /* Auto-neg advertisement */
260
- s->phy_advertise = (val & 0x2d7f) | 0x80;
261
- break;
262
- /* TODO 17, 18, 27, 31 */
263
- case 30: /* Interrupt mask */
264
- s->phy_int_mask = val & 0xff;
265
- phy_update_irq(s);
266
- break;
267
- default:
268
- qemu_log_mask(LOG_GUEST_ERROR,
269
- "do_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
270
- }
271
-}
272
-
273
static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
274
{
275
switch (reg) {
276
@@ -XXX,XX +XXX,XX @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
277
if (val & 2) {
278
DPRINTF("PHY write %d = 0x%04x\n",
279
(val >> 6) & 0x1f, s->mac_mii_data);
280
- do_phy_write(s, (val >> 6) & 0x1f, s->mac_mii_data);
281
+ lan9118_phy_write(&s->mii, (val >> 6) & 0x1f, s->mac_mii_data);
282
} else {
283
- s->mac_mii_data = do_phy_read(s, (val >> 6) & 0x1f);
284
+ s->mac_mii_data = lan9118_phy_read(&s->mii, (val >> 6) & 0x1f);
285
DPRINTF("PHY read %d = 0x%04x\n",
286
(val >> 6) & 0x1f, s->mac_mii_data);
287
}
288
@@ -XXX,XX +XXX,XX @@ static void lan9118_writel(void *opaque, hwaddr offset,
289
break;
290
case CSR_PMT_CTRL:
291
if (val & 0x400) {
292
- phy_reset(s);
293
+ lan9118_phy_reset(&s->mii);
294
}
295
s->pmt_ctrl &= ~0x34e;
296
s->pmt_ctrl |= (val & 0x34e);
297
@@ -XXX,XX +XXX,XX @@ static void lan9118_realize(DeviceState *dev, Error **errp)
298
const MemoryRegionOps *mem_ops =
299
s->mode_16bit ? &lan9118_16bit_mem_ops : &lan9118_mem_ops;
300
301
+ qemu_init_irq(&s->mii_irq, lan9118_update_irq, s, 0);
302
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
303
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
304
+ return;
305
+ }
306
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
307
+
308
memory_region_init_io(&s->mmio, OBJECT(dev), mem_ops, s,
309
"lan9118-mmio", 0x100);
310
sysbus_init_mmio(sbd, &s->mmio);
311
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
260
new file mode 100644
312
new file mode 100644
261
index XXXXXXX..XXXXXXX
313
index XXXXXXX..XXXXXXX
262
--- /dev/null
314
--- /dev/null
263
+++ b/hw/misc/xlnx-versal-crl.c
315
+++ b/hw/net/lan9118_phy.c
264
@@ -XXX,XX +XXX,XX @@
316
@@ -XXX,XX +XXX,XX @@
265
+/*
317
+/*
266
+ * QEMU model of the Clock-Reset-LPD (CRL).
318
+ * SMSC LAN9118 PHY emulation
267
+ *
319
+ *
268
+ * Copyright (c) 2022 Advanced Micro Devices, Inc.
320
+ * Copyright (c) 2009 CodeSourcery, LLC.
269
+ * SPDX-License-Identifier: GPL-2.0-or-later
321
+ * Written by Paul Brook
270
+ *
322
+ *
271
+ * Written by Edgar E. Iglesias <edgar.iglesias@amd.com>
323
+ * This code is licensed under the GNU GPL v2
324
+ *
325
+ * Contributions after 2012-01-13 are licensed under the terms of the
326
+ * GNU GPL, version 2 or (at your option) any later version.
272
+ */
327
+ */
273
+
328
+
274
+#include "qemu/osdep.h"
329
+#include "qemu/osdep.h"
275
+#include "qapi/error.h"
330
+#include "hw/net/lan9118_phy.h"
331
+#include "hw/irq.h"
332
+#include "hw/resettable.h"
333
+#include "migration/vmstate.h"
276
+#include "qemu/log.h"
334
+#include "qemu/log.h"
277
+#include "qemu/bitops.h"
335
+
278
+#include "migration/vmstate.h"
336
+#define PHY_INT_ENERGYON (1 << 7)
279
+#include "hw/qdev-properties.h"
337
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
280
+#include "hw/sysbus.h"
338
+#define PHY_INT_FAULT (1 << 5)
281
+#include "hw/irq.h"
339
+#define PHY_INT_DOWN (1 << 4)
282
+#include "hw/register.h"
340
+#define PHY_INT_AUTONEG_LP (1 << 3)
283
+#include "hw/resettable.h"
341
+#define PHY_INT_PARFAULT (1 << 2)
284
+
342
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
285
+#include "target/arm/arm-powerctl.h"
343
+
286
+#include "hw/misc/xlnx-versal-crl.h"
344
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
287
+
345
+{
288
+#ifndef XLNX_VERSAL_CRL_ERR_DEBUG
346
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
289
+#define XLNX_VERSAL_CRL_ERR_DEBUG 0
347
+}
290
+#endif
348
+
291
+
349
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
292
+static void crl_update_irq(XlnxVersalCRL *s)
350
+{
293
+{
351
+ uint16_t val;
294
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
352
+
295
+ qemu_set_irq(s->irq, pending);
353
+ switch (reg) {
296
+}
354
+ case 0: /* Basic Control */
297
+
355
+ return s->control;
298
+static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
356
+ case 1: /* Basic Status */
299
+{
357
+ return s->status;
300
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
358
+ case 2: /* ID1 */
301
+ crl_update_irq(s);
359
+ return 0x0007;
302
+}
360
+ case 3: /* ID2 */
303
+
361
+ return 0xc0d1;
304
+static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
362
+ case 4: /* Auto-neg advertisement */
305
+{
363
+ return s->advertise;
306
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
364
+ case 5: /* Auto-neg Link Partner Ability */
307
+ uint32_t val = val64;
365
+ return 0x0f71;
308
+
366
+ case 6: /* Auto-neg Expansion */
309
+ s->regs[R_IR_MASK] &= ~val;
367
+ return 1;
310
+ crl_update_irq(s);
368
+ /* TODO 17, 18, 27, 29, 30, 31 */
311
+ return 0;
369
+ case 29: /* Interrupt source. */
312
+}
370
+ val = s->ints;
313
+
371
+ s->ints = 0;
314
+static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
372
+ lan9118_phy_update_irq(s);
315
+{
373
+ return val;
316
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
374
+ case 30: /* Interrupt mask */
317
+ uint32_t val = val64;
375
+ return s->int_mask;
318
+
376
+ default:
319
+ s->regs[R_IR_MASK] |= val;
377
+ qemu_log_mask(LOG_GUEST_ERROR,
320
+ crl_update_irq(s);
378
+ "lan9118_phy_read: PHY read reg %d\n", reg);
321
+ return 0;
379
+ return 0;
322
+}
380
+ }
323
+
381
+}
324
+static void crl_reset_dev(XlnxVersalCRL *s, DeviceState *dev,
382
+
325
+ bool rst_old, bool rst_new)
383
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
326
+{
384
+{
327
+ device_cold_reset(dev);
385
+ switch (reg) {
328
+}
386
+ case 0: /* Basic Control */
329
+
387
+ if (val & 0x8000) {
330
+static void crl_reset_cpu(XlnxVersalCRL *s, ARMCPU *armcpu,
388
+ lan9118_phy_reset(s);
331
+ bool rst_old, bool rst_new)
389
+ break;
332
+{
390
+ }
333
+ if (rst_new) {
391
+ s->control = val & 0x7980;
334
+ arm_set_cpu_off(armcpu->mp_affinity);
392
+ /* Complete autonegotiation immediately. */
393
+ if (val & 0x1000) {
394
+ s->status |= 0x0020;
395
+ }
396
+ break;
397
+ case 4: /* Auto-neg advertisement */
398
+ s->advertise = (val & 0x2d7f) | 0x80;
399
+ break;
400
+ /* TODO 17, 18, 27, 31 */
401
+ case 30: /* Interrupt mask */
402
+ s->int_mask = val & 0xff;
403
+ lan9118_phy_update_irq(s);
404
+ break;
405
+ default:
406
+ qemu_log_mask(LOG_GUEST_ERROR,
407
+ "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
408
+ }
409
+}
410
+
411
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
412
+{
413
+ s->link_down = link_down;
414
+
415
+ /* Autonegotiation status mirrors link status. */
416
+ if (link_down) {
417
+ s->status &= ~0x0024;
418
+ s->ints |= PHY_INT_DOWN;
335
+ } else {
419
+ } else {
336
+ arm_set_cpu_on_and_reset(armcpu->mp_affinity);
420
+ s->status |= 0x0024;
421
+ s->ints |= PHY_INT_ENERGYON;
422
+ s->ints |= PHY_INT_AUTONEG_COMPLETE;
337
+ }
423
+ }
338
+}
424
+ lan9118_phy_update_irq(s);
339
+
425
+}
340
+#define REGFIELD_RESET(type, s, reg, f, new_val, dev) { \
426
+
341
+ bool old_f = ARRAY_FIELD_EX32((s)->regs, reg, f); \
427
+void lan9118_phy_reset(Lan9118PhyState *s)
342
+ bool new_f = FIELD_EX32(new_val, reg, f); \
428
+{
343
+ \
429
+ s->control = 0x3000;
344
+ /* Detect edges. */ \
430
+ s->status = 0x7809;
345
+ if (dev && old_f != new_f) { \
431
+ s->advertise = 0x01e1;
346
+ crl_reset_ ## type(s, dev, old_f, new_f); \
432
+ s->int_mask = 0;
347
+ } \
433
+ s->ints = 0;
348
+}
434
+ lan9118_phy_update_link(s, s->link_down);
349
+
435
+}
350
+static uint64_t crl_rst_r5_prew(RegisterInfo *reg, uint64_t val64)
436
+
351
+{
437
+static void lan9118_phy_reset_hold(Object *obj, ResetType type)
352
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
438
+{
353
+
439
+ Lan9118PhyState *s = LAN9118_PHY(obj);
354
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU0, val64, s->cfg.cpu_r5[0]);
440
+
355
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU1, val64, s->cfg.cpu_r5[1]);
441
+ lan9118_phy_reset(s);
356
+ return val64;
442
+}
357
+}
443
+
358
+
444
+static void lan9118_phy_init(Object *obj)
359
+static uint64_t crl_rst_adma_prew(RegisterInfo *reg, uint64_t val64)
445
+{
360
+{
446
+ Lan9118PhyState *s = LAN9118_PHY(obj);
361
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
447
+
362
+ int i;
448
+ qdev_init_gpio_out(DEVICE(s), &s->irq, 1);
363
+
449
+}
364
+ /* A single register fans out to all ADMA reset inputs. */
450
+
365
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); i++) {
451
+static const VMStateDescription vmstate_lan9118_phy = {
366
+ REGFIELD_RESET(dev, s, RST_ADMA, RESET, val64, s->cfg.adma[i]);
452
+ .name = "lan9118-phy",
367
+ }
453
+ .version_id = 1,
368
+ return val64;
454
+ .minimum_version_id = 1,
369
+}
455
+ .fields = (const VMStateField[]) {
370
+
456
+ VMSTATE_UINT16(control, Lan9118PhyState),
371
+static uint64_t crl_rst_uart0_prew(RegisterInfo *reg, uint64_t val64)
457
+ VMSTATE_UINT16(status, Lan9118PhyState),
372
+{
458
+ VMSTATE_UINT16(advertise, Lan9118PhyState),
373
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
459
+ VMSTATE_UINT16(ints, Lan9118PhyState),
374
+
460
+ VMSTATE_UINT16(int_mask, Lan9118PhyState),
375
+ REGFIELD_RESET(dev, s, RST_UART0, RESET, val64, s->cfg.uart[0]);
461
+ VMSTATE_BOOL(link_down, Lan9118PhyState),
376
+ return val64;
462
+ VMSTATE_END_OF_LIST()
377
+}
378
+
379
+static uint64_t crl_rst_uart1_prew(RegisterInfo *reg, uint64_t val64)
380
+{
381
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
382
+
383
+ REGFIELD_RESET(dev, s, RST_UART1, RESET, val64, s->cfg.uart[1]);
384
+ return val64;
385
+}
386
+
387
+static uint64_t crl_rst_gem0_prew(RegisterInfo *reg, uint64_t val64)
388
+{
389
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
390
+
391
+ REGFIELD_RESET(dev, s, RST_GEM0, RESET, val64, s->cfg.gem[0]);
392
+ return val64;
393
+}
394
+
395
+static uint64_t crl_rst_gem1_prew(RegisterInfo *reg, uint64_t val64)
396
+{
397
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
398
+
399
+ REGFIELD_RESET(dev, s, RST_GEM1, RESET, val64, s->cfg.gem[1]);
400
+ return val64;
401
+}
402
+
403
+static uint64_t crl_rst_usb_prew(RegisterInfo *reg, uint64_t val64)
404
+{
405
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
406
+
407
+ REGFIELD_RESET(dev, s, RST_USB0, RESET, val64, s->cfg.usb);
408
+ return val64;
409
+}
410
+
411
+static const RegisterAccessInfo crl_regs_info[] = {
412
+ { .name = "ERR_CTRL", .addr = A_ERR_CTRL,
413
+ },{ .name = "IR_STATUS", .addr = A_IR_STATUS,
414
+ .w1c = 0x1,
415
+ .post_write = crl_status_postw,
416
+ },{ .name = "IR_MASK", .addr = A_IR_MASK,
417
+ .reset = 0x1,
418
+ .ro = 0x1,
419
+ },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE,
420
+ .pre_write = crl_enable_prew,
421
+ },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE,
422
+ .pre_write = crl_disable_prew,
423
+ },{ .name = "WPROT", .addr = A_WPROT,
424
+ },{ .name = "PLL_CLK_OTHER_DMN", .addr = A_PLL_CLK_OTHER_DMN,
425
+ .reset = 0x1,
426
+ .rsvd = 0xe,
427
+ },{ .name = "RPLL_CTRL", .addr = A_RPLL_CTRL,
428
+ .reset = 0x24809,
429
+ .rsvd = 0xf88c00f6,
430
+ },{ .name = "RPLL_CFG", .addr = A_RPLL_CFG,
431
+ .reset = 0x2000000,
432
+ .rsvd = 0x1801210,
433
+ },{ .name = "RPLL_FRAC_CFG", .addr = A_RPLL_FRAC_CFG,
434
+ .rsvd = 0x7e330000,
435
+ },{ .name = "PLL_STATUS", .addr = A_PLL_STATUS,
436
+ .reset = R_PLL_STATUS_RPLL_STABLE_MASK |
437
+ R_PLL_STATUS_RPLL_LOCK_MASK,
438
+ .rsvd = 0xfa,
439
+ .ro = 0x5,
440
+ },{ .name = "RPLL_TO_XPD_CTRL", .addr = A_RPLL_TO_XPD_CTRL,
441
+ .reset = 0x2000100,
442
+ .rsvd = 0xfdfc00ff,
443
+ },{ .name = "LPD_TOP_SWITCH_CTRL", .addr = A_LPD_TOP_SWITCH_CTRL,
444
+ .reset = 0x6000300,
445
+ .rsvd = 0xf9fc00f8,
446
+ },{ .name = "LPD_LSBUS_CTRL", .addr = A_LPD_LSBUS_CTRL,
447
+ .reset = 0x2000800,
448
+ .rsvd = 0xfdfc00f8,
449
+ },{ .name = "CPU_R5_CTRL", .addr = A_CPU_R5_CTRL,
450
+ .reset = 0xe000300,
451
+ .rsvd = 0xe1fc00f8,
452
+ },{ .name = "IOU_SWITCH_CTRL", .addr = A_IOU_SWITCH_CTRL,
453
+ .reset = 0x2000500,
454
+ .rsvd = 0xfdfc00f8,
455
+ },{ .name = "GEM0_REF_CTRL", .addr = A_GEM0_REF_CTRL,
456
+ .reset = 0xe000a00,
457
+ .rsvd = 0xf1fc00f8,
458
+ },{ .name = "GEM1_REF_CTRL", .addr = A_GEM1_REF_CTRL,
459
+ .reset = 0xe000a00,
460
+ .rsvd = 0xf1fc00f8,
461
+ },{ .name = "GEM_TSU_REF_CTRL", .addr = A_GEM_TSU_REF_CTRL,
462
+ .reset = 0x300,
463
+ .rsvd = 0xfdfc00f8,
464
+ },{ .name = "USB0_BUS_REF_CTRL", .addr = A_USB0_BUS_REF_CTRL,
465
+ .reset = 0x2001900,
466
+ .rsvd = 0xfdfc00f8,
467
+ },{ .name = "UART0_REF_CTRL", .addr = A_UART0_REF_CTRL,
468
+ .reset = 0xc00,
469
+ .rsvd = 0xfdfc00f8,
470
+ },{ .name = "UART1_REF_CTRL", .addr = A_UART1_REF_CTRL,
471
+ .reset = 0xc00,
472
+ .rsvd = 0xfdfc00f8,
473
+ },{ .name = "SPI0_REF_CTRL", .addr = A_SPI0_REF_CTRL,
474
+ .reset = 0x600,
475
+ .rsvd = 0xfdfc00f8,
476
+ },{ .name = "SPI1_REF_CTRL", .addr = A_SPI1_REF_CTRL,
477
+ .reset = 0x600,
478
+ .rsvd = 0xfdfc00f8,
479
+ },{ .name = "CAN0_REF_CTRL", .addr = A_CAN0_REF_CTRL,
480
+ .reset = 0xc00,
481
+ .rsvd = 0xfdfc00f8,
482
+ },{ .name = "CAN1_REF_CTRL", .addr = A_CAN1_REF_CTRL,
483
+ .reset = 0xc00,
484
+ .rsvd = 0xfdfc00f8,
485
+ },{ .name = "I2C0_REF_CTRL", .addr = A_I2C0_REF_CTRL,
486
+ .reset = 0xc00,
487
+ .rsvd = 0xfdfc00f8,
488
+ },{ .name = "I2C1_REF_CTRL", .addr = A_I2C1_REF_CTRL,
489
+ .reset = 0xc00,
490
+ .rsvd = 0xfdfc00f8,
491
+ },{ .name = "DBG_LPD_CTRL", .addr = A_DBG_LPD_CTRL,
492
+ .reset = 0x300,
493
+ .rsvd = 0xfdfc00f8,
494
+ },{ .name = "TIMESTAMP_REF_CTRL", .addr = A_TIMESTAMP_REF_CTRL,
495
+ .reset = 0x2000c00,
496
+ .rsvd = 0xfdfc00f8,
497
+ },{ .name = "CRL_SAFETY_CHK", .addr = A_CRL_SAFETY_CHK,
498
+ },{ .name = "PSM_REF_CTRL", .addr = A_PSM_REF_CTRL,
499
+ .reset = 0xf04,
500
+ .rsvd = 0xfffc00f8,
501
+ },{ .name = "DBG_TSTMP_CTRL", .addr = A_DBG_TSTMP_CTRL,
502
+ .reset = 0x300,
503
+ .rsvd = 0xfdfc00f8,
504
+ },{ .name = "CPM_TOPSW_REF_CTRL", .addr = A_CPM_TOPSW_REF_CTRL,
505
+ .reset = 0x300,
506
+ .rsvd = 0xfdfc00f8,
507
+ },{ .name = "USB3_DUAL_REF_CTRL", .addr = A_USB3_DUAL_REF_CTRL,
508
+ .reset = 0x3c00,
509
+ .rsvd = 0xfdfc00f8,
510
+ },{ .name = "RST_CPU_R5", .addr = A_RST_CPU_R5,
511
+ .reset = 0x17,
512
+ .rsvd = 0x8,
513
+ .pre_write = crl_rst_r5_prew,
514
+ },{ .name = "RST_ADMA", .addr = A_RST_ADMA,
515
+ .reset = 0x1,
516
+ .pre_write = crl_rst_adma_prew,
517
+ },{ .name = "RST_GEM0", .addr = A_RST_GEM0,
518
+ .reset = 0x1,
519
+ .pre_write = crl_rst_gem0_prew,
520
+ },{ .name = "RST_GEM1", .addr = A_RST_GEM1,
521
+ .reset = 0x1,
522
+ .pre_write = crl_rst_gem1_prew,
523
+ },{ .name = "RST_SPARE", .addr = A_RST_SPARE,
524
+ .reset = 0x1,
525
+ },{ .name = "RST_USB0", .addr = A_RST_USB0,
526
+ .reset = 0x1,
527
+ .pre_write = crl_rst_usb_prew,
528
+ },{ .name = "RST_UART0", .addr = A_RST_UART0,
529
+ .reset = 0x1,
530
+ .pre_write = crl_rst_uart0_prew,
531
+ },{ .name = "RST_UART1", .addr = A_RST_UART1,
532
+ .reset = 0x1,
533
+ .pre_write = crl_rst_uart1_prew,
534
+ },{ .name = "RST_SPI0", .addr = A_RST_SPI0,
535
+ .reset = 0x1,
536
+ },{ .name = "RST_SPI1", .addr = A_RST_SPI1,
537
+ .reset = 0x1,
538
+ },{ .name = "RST_CAN0", .addr = A_RST_CAN0,
539
+ .reset = 0x1,
540
+ },{ .name = "RST_CAN1", .addr = A_RST_CAN1,
541
+ .reset = 0x1,
542
+ },{ .name = "RST_I2C0", .addr = A_RST_I2C0,
543
+ .reset = 0x1,
544
+ },{ .name = "RST_I2C1", .addr = A_RST_I2C1,
545
+ .reset = 0x1,
546
+ },{ .name = "RST_DBG_LPD", .addr = A_RST_DBG_LPD,
547
+ .reset = 0x33,
548
+ .rsvd = 0xcc,
549
+ },{ .name = "RST_GPIO", .addr = A_RST_GPIO,
550
+ .reset = 0x1,
551
+ },{ .name = "RST_TTC", .addr = A_RST_TTC,
552
+ .reset = 0xf,
553
+ },{ .name = "RST_TIMESTAMP", .addr = A_RST_TIMESTAMP,
554
+ .reset = 0x1,
555
+ },{ .name = "RST_SWDT", .addr = A_RST_SWDT,
556
+ .reset = 0x1,
557
+ },{ .name = "RST_OCM", .addr = A_RST_OCM,
558
+ },{ .name = "RST_IPI", .addr = A_RST_IPI,
559
+ },{ .name = "RST_FPD", .addr = A_RST_FPD,
560
+ .reset = 0x3,
561
+ },{ .name = "PSM_RST_MODE", .addr = A_PSM_RST_MODE,
562
+ .reset = 0x1,
563
+ .rsvd = 0xf8,
564
+ }
463
+ }
565
+};
464
+};
566
+
465
+
567
+static void crl_reset_enter(Object *obj, ResetType type)
466
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
568
+{
467
+{
569
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
468
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
570
+ unsigned int i;
469
+ DeviceClass *dc = DEVICE_CLASS(klass);
571
+
470
+
572
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
471
+ rc->phases.hold = lan9118_phy_reset_hold;
573
+ register_reset(&s->regs_info[i]);
472
+ dc->vmsd = &vmstate_lan9118_phy;
574
+ }
473
+}
575
+}
474
+
576
+
475
+static const TypeInfo types[] = {
577
+static void crl_reset_hold(Object *obj)
476
+ {
578
+{
477
+ .name = TYPE_LAN9118_PHY,
579
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
478
+ .parent = TYPE_SYS_BUS_DEVICE,
580
+
479
+ .instance_size = sizeof(Lan9118PhyState),
581
+ crl_update_irq(s);
480
+ .instance_init = lan9118_phy_init,
582
+}
481
+ .class_init = lan9118_phy_class_init,
583
+
584
+static const MemoryRegionOps crl_ops = {
585
+ .read = register_read_memory,
586
+ .write = register_write_memory,
587
+ .endianness = DEVICE_LITTLE_ENDIAN,
588
+ .valid = {
589
+ .min_access_size = 4,
590
+ .max_access_size = 4,
591
+ },
592
+};
593
+
594
+static void crl_init(Object *obj)
595
+{
596
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
597
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
598
+ int i;
599
+
600
+ s->reg_array =
601
+ register_init_block32(DEVICE(obj), crl_regs_info,
602
+ ARRAY_SIZE(crl_regs_info),
603
+ s->regs_info, s->regs,
604
+ &crl_ops,
605
+ XLNX_VERSAL_CRL_ERR_DEBUG,
606
+ CRL_R_MAX * 4);
607
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
608
+ sysbus_init_irq(sbd, &s->irq);
609
+
610
+ for (i = 0; i < ARRAY_SIZE(s->cfg.cpu_r5); ++i) {
611
+ object_property_add_link(obj, "cpu_r5[*]", TYPE_ARM_CPU,
612
+ (Object **)&s->cfg.cpu_r5[i],
613
+ qdev_prop_allow_set_link_before_realize,
614
+ OBJ_PROP_LINK_STRONG);
615
+ }
616
+
617
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); ++i) {
618
+ object_property_add_link(obj, "adma[*]", TYPE_DEVICE,
619
+ (Object **)&s->cfg.adma[i],
620
+ qdev_prop_allow_set_link_before_realize,
621
+ OBJ_PROP_LINK_STRONG);
622
+ }
623
+
624
+ for (i = 0; i < ARRAY_SIZE(s->cfg.uart); ++i) {
625
+ object_property_add_link(obj, "uart[*]", TYPE_DEVICE,
626
+ (Object **)&s->cfg.uart[i],
627
+ qdev_prop_allow_set_link_before_realize,
628
+ OBJ_PROP_LINK_STRONG);
629
+ }
630
+
631
+ for (i = 0; i < ARRAY_SIZE(s->cfg.gem); ++i) {
632
+ object_property_add_link(obj, "gem[*]", TYPE_DEVICE,
633
+ (Object **)&s->cfg.gem[i],
634
+ qdev_prop_allow_set_link_before_realize,
635
+ OBJ_PROP_LINK_STRONG);
636
+ }
637
+
638
+ object_property_add_link(obj, "usb", TYPE_DEVICE,
639
+ (Object **)&s->cfg.gem[i],
640
+ qdev_prop_allow_set_link_before_realize,
641
+ OBJ_PROP_LINK_STRONG);
642
+}
643
+
644
+static void crl_finalize(Object *obj)
645
+{
646
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
647
+ register_finalize_block(s->reg_array);
648
+}
649
+
650
+static const VMStateDescription vmstate_crl = {
651
+ .name = TYPE_XLNX_VERSAL_CRL,
652
+ .version_id = 1,
653
+ .minimum_version_id = 1,
654
+ .fields = (VMStateField[]) {
655
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalCRL, CRL_R_MAX),
656
+ VMSTATE_END_OF_LIST(),
657
+ }
482
+ }
658
+};
483
+};
659
+
484
+
660
+static void crl_class_init(ObjectClass *klass, void *data)
485
+DEFINE_TYPES(types)
661
+{
486
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
662
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
663
+ DeviceClass *dc = DEVICE_CLASS(klass);
664
+
665
+ dc->vmsd = &vmstate_crl;
666
+
667
+ rc->phases.enter = crl_reset_enter;
668
+ rc->phases.hold = crl_reset_hold;
669
+}
670
+
671
+static const TypeInfo crl_info = {
672
+ .name = TYPE_XLNX_VERSAL_CRL,
673
+ .parent = TYPE_SYS_BUS_DEVICE,
674
+ .instance_size = sizeof(XlnxVersalCRL),
675
+ .class_init = crl_class_init,
676
+ .instance_init = crl_init,
677
+ .instance_finalize = crl_finalize,
678
+};
679
+
680
+static void crl_register_types(void)
681
+{
682
+ type_register_static(&crl_info);
683
+}
684
+
685
+type_init(crl_register_types)
686
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
687
index XXXXXXX..XXXXXXX 100644
487
index XXXXXXX..XXXXXXX 100644
688
--- a/hw/misc/meson.build
488
--- a/hw/net/Kconfig
689
+++ b/hw/misc/meson.build
489
+++ b/hw/net/Kconfig
690
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
490
@@ -XXX,XX +XXX,XX @@ config VMXNET3_PCI
691
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
491
config SMC91C111
692
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-crf.c'))
492
bool
693
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-apu-ctrl.c'))
493
694
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
494
+config LAN9118_PHY
695
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
495
+ bool
696
'xlnx-versal-xramc.c',
496
+
697
'xlnx-versal-pmc-iou-slcr.c',
497
config LAN9118
498
bool
499
+ select LAN9118_PHY
500
select PTIMER
501
502
config NE2000_ISA
503
diff --git a/hw/net/meson.build b/hw/net/meson.build
504
index XXXXXXX..XXXXXXX 100644
505
--- a/hw/net/meson.build
506
+++ b/hw/net/meson.build
507
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('vmxnet3.c'))
508
509
system_ss.add(when: 'CONFIG_SMC91C111', if_true: files('smc91c111.c'))
510
system_ss.add(when: 'CONFIG_LAN9118', if_true: files('lan9118.c'))
511
+system_ss.add(when: 'CONFIG_LAN9118_PHY', if_true: files('lan9118_phy.c'))
512
system_ss.add(when: 'CONFIG_NE2000_ISA', if_true: files('ne2000-isa.c'))
513
system_ss.add(when: 'CONFIG_OPENCORES_ETH', if_true: files('opencores_eth.c'))
514
system_ss.add(when: 'CONFIG_XGMAC', if_true: files('xgmac.c'))
698
--
515
--
699
2.25.1
516
2.34.1
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
imx_fec models the same PHY as lan9118_phy. The code is almost the same with
4
imx_fec having more logging and tracing. Merge these improvements into
5
lan9118_phy and reuse in imx_fec to fix the code duplication.
6
7
Some migration state how resides in the new device model which breaks migration
8
compatibility for the following machines:
9
* imx25-pdk
10
* sabrelite
11
* mcimx7d-sabre
12
* mcimx6ul-evk
13
14
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
15
Tested-by: Guenter Roeck <linux@roeck-us.net>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
17
Message-id: 20241102125724.532843-3-shentey@gmail.com
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
19
---
9
include/hw/irq.h | 5 -----
20
include/hw/net/imx_fec.h | 9 ++-
10
hw/core/irq.c | 15 ---------------
21
hw/net/imx_fec.c | 146 ++++-----------------------------------
11
2 files changed, 20 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(-)
12
26
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
27
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
14
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/irq.h
29
--- a/include/hw/net/imx_fec.h
16
+++ b/include/hw/irq.h
30
+++ b/include/hw/net/imx_fec.h
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
18
/* Returns a new IRQ with opposite polarity. */
32
#define TYPE_IMX_ENET "imx.enet"
19
qemu_irq qemu_irq_invert(qemu_irq irq);
33
20
34
#include "hw/sysbus.h"
21
-/* Returns a new IRQ which feeds into both the passed IRQs.
35
+#include "hw/net/lan9118_phy.h"
22
- * It's probably better to use the TYPE_SPLIT_IRQ device instead.
36
+#include "hw/irq.h"
23
- */
37
#include "net/net.h"
24
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
38
25
-
39
#define ENET_EIR 1
26
/* For internal use in qtest. Similar to qemu_irq_split, but operating
40
@@ -XXX,XX +XXX,XX @@ struct IMXFECState {
27
on an existing vector of qemu_irq. */
41
uint32_t tx_descriptor[ENET_TX_RING_NUM];
28
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
42
uint32_t tx_ring_num;
29
diff --git a/hw/core/irq.c b/hw/core/irq.c
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
30
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/core/irq.c
56
--- a/hw/net/imx_fec.c
32
+++ b/hw/core/irq.c
57
+++ b/hw/net/imx_fec.c
33
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_invert(qemu_irq irq)
58
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth_txdescs = {
34
return qemu_allocate_irq(qemu_notirq, irq, 0);
59
35
}
60
static const VMStateDescription vmstate_imx_eth = {
36
61
.name = TYPE_IMX_FEC,
37
-static void qemu_splitirq(void *opaque, int line, int level)
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)
38
-{
104
-{
39
- struct IRQState **irq = opaque;
105
- /* Autonegotiation status mirrors link status. */
40
- irq[0]->handler(irq[0]->opaque, irq[0]->n, level);
106
- if (qemu_get_queue(s->nic)->link_down) {
41
- irq[1]->handler(irq[1]->opaque, irq[1]->n, level);
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)));
42
-}
123
-}
43
-
124
-
44
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
125
-static void imx_phy_reset(IMXFECState *s)
45
-{
126
-{
46
- qemu_irq *s = g_new0(qemu_irq, 2);
127
- trace_imx_phy_reset();
47
- s[0] = irq1;
128
-
48
- s[1] = irq2;
129
- s->phy_status = 0x7809;
49
- return qemu_allocate_irq(qemu_splitirq, s, 0);
130
- s->phy_control = 0x3000;
50
-}
131
- s->phy_advertise = 0x01e1;
51
-
132
- s->phy_int_mask = 0;
52
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
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)
53
{
140
{
54
int i;
141
- uint32_t val;
142
uint32_t phy = reg / 32;
143
144
if (!s->phy_connected) {
145
@@ -XXX,XX +XXX,XX @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
146
147
reg %= 32;
148
149
- switch (reg) {
150
- case 0: /* Basic Control */
151
- val = s->phy_control;
152
- break;
153
- case 1: /* Basic Status */
154
- val = s->phy_status;
155
- break;
156
- case 2: /* ID1 */
157
- val = 0x0007;
158
- break;
159
- case 3: /* ID2 */
160
- val = 0xc0d1;
161
- break;
162
- case 4: /* Auto-neg advertisement */
163
- val = s->phy_advertise;
164
- break;
165
- case 5: /* Auto-neg Link Partner Ability */
166
- val = 0x0f71;
167
- break;
168
- case 6: /* Auto-neg Expansion */
169
- val = 1;
170
- break;
171
- case 29: /* Interrupt source. */
172
- val = s->phy_int;
173
- s->phy_int = 0;
174
- imx_phy_update_irq(s);
175
- break;
176
- case 30: /* Interrupt mask */
177
- val = s->phy_int_mask;
178
- break;
179
- case 17:
180
- case 18:
181
- case 27:
182
- case 31:
183
- qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
184
- TYPE_IMX_FEC, __func__, reg);
185
- val = 0;
186
- break;
187
- default:
188
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
189
- TYPE_IMX_FEC, __func__, reg);
190
- val = 0;
191
- break;
192
- }
193
-
194
- trace_imx_phy_read(val, phy, reg);
195
-
196
- return val;
197
+ return lan9118_phy_read(&s->mii, reg);
198
}
199
200
static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
201
@@ -XXX,XX +XXX,XX @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
202
203
reg %= 32;
204
205
- trace_imx_phy_write(val, phy, reg);
206
-
207
- switch (reg) {
208
- case 0: /* Basic Control */
209
- if (val & 0x8000) {
210
- imx_phy_reset(s);
211
- } else {
212
- s->phy_control = val & 0x7980;
213
- /* Complete autonegotiation immediately. */
214
- if (val & 0x1000) {
215
- s->phy_status |= 0x0020;
216
- }
217
- }
218
- break;
219
- case 4: /* Auto-neg advertisement */
220
- s->phy_advertise = (val & 0x2d7f) | 0x80;
221
- break;
222
- case 30: /* Interrupt mask */
223
- s->phy_int_mask = val & 0xff;
224
- imx_phy_update_irq(s);
225
- break;
226
- case 17:
227
- case 18:
228
- case 27:
229
- case 31:
230
- qemu_log_mask(LOG_UNIMP, "[%s.phy)%s: reg %d not implemented\n",
231
- TYPE_IMX_FEC, __func__, reg);
232
- break;
233
- default:
234
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
235
- TYPE_IMX_FEC, __func__, reg);
236
- break;
237
- }
238
+ lan9118_phy_write(&s->mii, reg, val);
239
}
240
241
static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
242
@@ -XXX,XX +XXX,XX @@ static void imx_eth_reset(DeviceState *d)
243
244
s->rx_descriptor = 0;
245
memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
246
-
247
- /* We also reset the PHY */
248
- imx_phy_reset(s);
249
}
250
251
static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
252
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
253
sysbus_init_irq(sbd, &s->irq[0]);
254
sysbus_init_irq(sbd, &s->irq[1]);
255
256
+ qemu_init_irq(&s->mii_irq, imx_phy_update_irq, s, 0);
257
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
258
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
259
+ return;
260
+ }
261
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
262
+
263
qemu_macaddr_default_if_unset(&s->conf.macaddr);
264
265
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
266
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
267
index XXXXXXX..XXXXXXX 100644
268
--- a/hw/net/lan9118_phy.c
269
+++ b/hw/net/lan9118_phy.c
270
@@ -XXX,XX +XXX,XX @@
271
* Copyright (c) 2009 CodeSourcery, LLC.
272
* Written by Paul Brook
273
*
274
+ * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
275
+ *
276
* This code is licensed under the GNU GPL v2
277
*
278
* Contributions after 2012-01-13 are licensed under the terms of the
279
@@ -XXX,XX +XXX,XX @@
280
#include "hw/resettable.h"
281
#include "migration/vmstate.h"
282
#include "qemu/log.h"
283
+#include "trace.h"
284
285
#define PHY_INT_ENERGYON (1 << 7)
286
#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
287
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
288
289
switch (reg) {
290
case 0: /* Basic Control */
291
- return s->control;
292
+ val = s->control;
293
+ break;
294
case 1: /* Basic Status */
295
- return s->status;
296
+ val = s->status;
297
+ break;
298
case 2: /* ID1 */
299
- return 0x0007;
300
+ val = 0x0007;
301
+ break;
302
case 3: /* ID2 */
303
- return 0xc0d1;
304
+ val = 0xc0d1;
305
+ break;
306
case 4: /* Auto-neg advertisement */
307
- return s->advertise;
308
+ val = s->advertise;
309
+ break;
310
case 5: /* Auto-neg Link Partner Ability */
311
- return 0x0f71;
312
+ val = 0x0f71;
313
+ break;
314
case 6: /* Auto-neg Expansion */
315
- return 1;
316
- /* TODO 17, 18, 27, 29, 30, 31 */
317
+ val = 1;
318
+ break;
319
case 29: /* Interrupt source. */
320
val = s->ints;
321
s->ints = 0;
322
lan9118_phy_update_irq(s);
323
- return val;
324
+ break;
325
case 30: /* Interrupt mask */
326
- return s->int_mask;
327
+ val = s->int_mask;
328
+ break;
329
+ case 17:
330
+ case 18:
331
+ case 27:
332
+ case 31:
333
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
334
+ __func__, reg);
335
+ val = 0;
336
+ break;
337
default:
338
- qemu_log_mask(LOG_GUEST_ERROR,
339
- "lan9118_phy_read: PHY read reg %d\n", reg);
340
- return 0;
341
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
342
+ __func__, reg);
343
+ val = 0;
344
+ break;
345
}
346
+
347
+ trace_lan9118_phy_read(val, reg);
348
+
349
+ return val;
350
}
351
352
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
353
{
354
+ trace_lan9118_phy_write(val, reg);
355
+
356
switch (reg) {
357
case 0: /* Basic Control */
358
if (val & 0x8000) {
359
lan9118_phy_reset(s);
360
- break;
361
- }
362
- s->control = val & 0x7980;
363
- /* Complete autonegotiation immediately. */
364
- if (val & 0x1000) {
365
- s->status |= 0x0020;
366
+ } else {
367
+ s->control = val & 0x7980;
368
+ /* Complete autonegotiation immediately. */
369
+ if (val & 0x1000) {
370
+ s->status |= 0x0020;
371
+ }
372
}
373
break;
374
case 4: /* Auto-neg advertisement */
375
s->advertise = (val & 0x2d7f) | 0x80;
376
break;
377
- /* TODO 17, 18, 27, 31 */
378
case 30: /* Interrupt mask */
379
s->int_mask = val & 0xff;
380
lan9118_phy_update_irq(s);
381
break;
382
+ case 17:
383
+ case 18:
384
+ case 27:
385
+ case 31:
386
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
387
+ __func__, reg);
388
+ break;
389
default:
390
- qemu_log_mask(LOG_GUEST_ERROR,
391
- "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
392
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
393
+ __func__, reg);
394
+ break;
395
}
396
}
397
398
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
399
400
/* Autonegotiation status mirrors link status. */
401
if (link_down) {
402
+ trace_lan9118_phy_update_link("down");
403
s->status &= ~0x0024;
404
s->ints |= PHY_INT_DOWN;
405
} else {
406
+ trace_lan9118_phy_update_link("up");
407
s->status |= 0x0024;
408
s->ints |= PHY_INT_ENERGYON;
409
s->ints |= PHY_INT_AUTONEG_COMPLETE;
410
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
411
412
void lan9118_phy_reset(Lan9118PhyState *s)
413
{
414
+ trace_lan9118_phy_reset();
415
+
416
s->control = 0x3000;
417
s->status = 0x7809;
418
s->advertise = 0x01e1;
419
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_phy = {
420
.version_id = 1,
421
.minimum_version_id = 1,
422
.fields = (const VMStateField[]) {
423
- VMSTATE_UINT16(control, Lan9118PhyState),
424
VMSTATE_UINT16(status, Lan9118PhyState),
425
+ VMSTATE_UINT16(control, Lan9118PhyState),
426
VMSTATE_UINT16(advertise, Lan9118PhyState),
427
VMSTATE_UINT16(ints, Lan9118PhyState),
428
VMSTATE_UINT16(int_mask, Lan9118PhyState),
429
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
430
index XXXXXXX..XXXXXXX 100644
431
--- a/hw/net/Kconfig
432
+++ b/hw/net/Kconfig
433
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_SUN8I_EMAC
434
435
config IMX_FEC
436
bool
437
+ select LAN9118_PHY
438
439
config CADENCE
440
bool
441
diff --git a/hw/net/trace-events b/hw/net/trace-events
442
index XXXXXXX..XXXXXXX 100644
443
--- a/hw/net/trace-events
444
+++ b/hw/net/trace-events
445
@@ -XXX,XX +XXX,XX @@ allwinner_sun8i_emac_set_link(bool active) "Set link: active=%u"
446
allwinner_sun8i_emac_read(uint64_t offset, uint64_t val) "MMIO read: offset=0x%" PRIx64 " value=0x%" PRIx64
447
allwinner_sun8i_emac_write(uint64_t offset, uint64_t val) "MMIO write: offset=0x%" PRIx64 " value=0x%" PRIx64
448
449
+# lan9118_phy.c
450
+lan9118_phy_read(uint16_t val, int reg) "[0x%02x] -> 0x%04" PRIx16
451
+lan9118_phy_write(uint16_t val, int reg) "[0x%02x] <- 0x%04" PRIx16
452
+lan9118_phy_update_link(const char *s) "%s"
453
+lan9118_phy_reset(void) ""
454
+
455
# lance.c
456
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x"
457
lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x"
458
@@ -XXX,XX +XXX,XX @@ i82596_set_multicast(uint16_t count) "Added %d multicast entries"
459
i82596_channel_attention(void *s) "%p: Received CHANNEL ATTENTION"
460
461
# imx_fec.c
462
-imx_phy_read(uint32_t val, int phy, int reg) "0x%04"PRIx32" <= phy[%d].reg[%d]"
463
imx_phy_read_num(int phy, int configured) "read request from unconfigured phy %d (configured %d)"
464
-imx_phy_write(uint32_t val, int phy, int reg) "0x%04"PRIx32" => phy[%d].reg[%d]"
465
imx_phy_write_num(int phy, int configured) "write request to unconfigured phy %d (configured %d)"
466
-imx_phy_update_link(const char *s) "%s"
467
-imx_phy_reset(void) ""
468
imx_fec_read_bd(uint64_t addr, int flags, int len, int data) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x"
469
imx_enet_read_bd(uint64_t addr, int flags, int len, int data, int options, int status) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x option 0x%04x status 0x%04x"
470
imx_eth_tx_bd_busy(void) "tx_bd ran out of descriptors to transmit"
55
--
471
--
56
2.25.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
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
Prefer named constants over magic values for better readability.
4
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
hw/arm/stellaris.c | 15 +++++++++++++--
11
include/hw/net/mii.h | 6 +++++
9
1 file changed, 13 insertions(+), 2 deletions(-)
12
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
13
2 files changed, 46 insertions(+), 23 deletions(-)
10
14
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
15
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/stellaris.c
17
--- a/include/hw/net/mii.h
14
+++ b/hw/arm/stellaris.c
18
+++ b/include/hw/net/mii.h
15
@@ -XXX,XX +XXX,XX @@
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 @@
16
51
17
#include "qemu/osdep.h"
52
#include "qemu/osdep.h"
18
#include "qapi/error.h"
53
#include "hw/net/lan9118_phy.h"
19
+#include "hw/core/split-irq.h"
54
+#include "hw/net/mii.h"
20
#include "hw/sysbus.h"
55
#include "hw/irq.h"
21
#include "hw/sd/sd.h"
56
#include "hw/resettable.h"
22
#include "hw/ssi/ssi.h"
57
#include "migration/vmstate.h"
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
58
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
24
DeviceState *ssddev;
59
uint16_t val;
25
DriveInfo *dinfo;
60
26
DeviceState *carddev;
61
switch (reg) {
27
+ DeviceState *gpio_d_splitter;
62
- case 0: /* Basic Control */
28
BlockBackend *blk;
63
+ case MII_BMCR:
29
64
val = s->control;
30
/*
65
break;
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
66
- case 1: /* Basic Status */
32
&error_fatal);
67
+ case MII_BMSR:
33
68
val = s->status;
34
ssddev = ssi_create_peripheral(bus, "ssd0323");
69
break;
35
- gpio_out[GPIO_D][0] = qemu_irq_split(
70
- case 2: /* ID1 */
36
- qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
71
- val = 0x0007;
37
+
72
+ case MII_PHYID1:
38
+ gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
73
+ val = SMSCLAN9118_PHYID1;
39
+ qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
74
break;
40
+ qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
75
- case 3: /* ID2 */
41
+ qdev_connect_gpio_out(
76
- val = 0xc0d1;
42
+ gpio_d_splitter, 0,
77
+ case MII_PHYID2:
43
+ qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0));
78
+ val = SMSCLAN9118_PHYID2;
44
+ qdev_connect_gpio_out(
79
break;
45
+ gpio_d_splitter, 1,
80
- case 4: /* Auto-neg advertisement */
46
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
81
+ case MII_ANAR:
47
+ gpio_out[GPIO_D][0] = qdev_get_gpio_in(gpio_d_splitter, 0);
82
val = s->advertise;
48
+
83
break;
49
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
84
- case 5: /* Auto-neg Link Partner Ability */
50
85
- val = 0x0fe1;
51
/* Make sure the select pin is high. */
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);
52
--
166
--
53
2.25.1
167
2.34.1
diff view generated by jsdifflib
1
From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Describe that the gic-version influences the maximum number of CPUs.
3
The real device advertises this mode and the device model already advertises
4
100 mbps half duplex and 10 mbps full+half duplex. So advertise this mode to
5
make the model more realistic.
4
6
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
7
[PMM: minor punctuation tweaks]
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
9
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
Message-id: 20241102125724.532843-6-shentey@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
docs/system/arm/virt.rst | 4 ++--
13
hw/net/lan9118_phy.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
13
15
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/virt.rst
18
--- a/hw/net/lan9118_phy.c
17
+++ b/docs/system/arm/virt.rst
19
+++ b/hw/net/lan9118_phy.c
18
@@ -XXX,XX +XXX,XX @@ gic-version
20
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
19
Valid values are:
21
break;
20
22
case MII_ANAR:
21
``2``
23
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
22
- GICv2
24
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
23
+ GICv2. Note that this limits the number of CPUs to 8.
25
- MII_ANAR_SELECT))
24
``3``
26
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
25
- GICv3
27
+ MII_ANAR_10 | MII_ANAR_SELECT))
26
+ GICv3. This allows up to 512 CPUs.
28
| MII_ANAR_TX;
27
``host``
29
break;
28
Use the same GIC version the host provides, when using KVM
30
case 30: /* Interrupt mask */
29
``max``
30
--
31
--
31
2.25.1
32
2.34.1
diff view generated by jsdifflib
1
It's not possible to provide the guest with the Security extensions
1
For IEEE fused multiply-add, the (0 * inf) + NaN case should raise
2
(TrustZone) when using KVM or HVF, because the hardware
2
Invalid for the multiplication of 0 by infinity. Currently we handle
3
virtualization extensions don't permit running EL3 guest code.
3
this in the per-architecture ifdef ladder in pickNaNMulAdd().
4
However, we weren't checking for this combination, with the result
4
However, since this isn't really architecture specific we can hoist
5
that QEMU would assert if you tried it:
5
it up to the generic code.
6
6
7
$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none
7
For the cases where the infzero test in pickNaNMulAdd was
8
Unexpected error in object_property_find_err() at ../../qom/object.c:1304:
8
returning 2, we can delete the check entirely and allow the
9
qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found
9
code to fall into the normal pick-a-NaN handling, because this
10
Aborted
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".
11
13
12
Check for this combination of options and report an error, in the
14
For Arm, this looks like it might be a behaviour change because we
13
same way we already do for attempts to give a KVM or HVF guest the
15
used to set float_flag_invalid | float_flag_invalid_imz only if C is
14
Virtualization or MTE extensions. Now we will report:
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.
15
20
16
qemu-system-aarch64: mach-virt: KVM does not support providing Security extensions (TrustZone) to the guest CPU
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
17
29
18
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/961
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
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20220404155301.566542-1-peter.maydell@linaro.org
36
Message-id: 20241202131347.498124-2-peter.maydell@linaro.org
22
---
37
---
23
hw/arm/virt.c | 7 +++++++
38
fpu/softfloat-parts.c.inc | 13 +++++++------
24
1 file changed, 7 insertions(+)
39
fpu/softfloat-specialize.c.inc | 29 +----------------------------
40
2 files changed, 8 insertions(+), 34 deletions(-)
25
41
26
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
42
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
27
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/virt.c
44
--- a/fpu/softfloat-parts.c.inc
29
+++ b/hw/arm/virt.c
45
+++ b/fpu/softfloat-parts.c.inc
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
46
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
31
exit(1);
47
int ab_mask, int abc_mask)
48
{
49
int which;
50
+ bool infzero = (ab_mask == float_cmask_infzero);
51
52
if (unlikely(abc_mask & float_cmask_snan)) {
53
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
32
}
54
}
33
55
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
56
- which = pickNaNMulAdd(a->cls, b->cls, c->cls,
35
+ error_report("mach-virt: %s does not support providing "
57
- ab_mask == float_cmask_infzero, s);
36
+ "Security extensions (TrustZone) to the guest CPU",
58
+ if (infzero) {
37
+ kvm_enabled() ? "KVM" : "HVF");
59
+ /* This is (0 * inf) + NaN or (inf * 0) + NaN */
38
+ exit(1);
60
+ float_raise(float_flag_invalid | float_flag_invalid_imz, s);
39
+ }
61
+ }
40
+
62
+
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
63
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
42
error_report("mach-virt: %s does not support providing "
64
43
"Virtualization extensions to the guest CPU",
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;
44
--
165
--
45
2.25.1
166
2.34.1
diff view generated by jsdifflib
New patch
1
If the target sets default_nan_mode then we're always going to return
2
the default NaN, and pickNaNMulAdd() no longer has any side effects.
3
For consistency with pickNaN(), check for default_nan_mode before
4
calling pickNaNMulAdd().
1
5
6
When we convert pickNaNMulAdd() to allow runtime selection of the NaN
7
propagation rule, this means we won't have to make the targets which
8
use default_nan_mode also set a propagation rule.
9
10
Since RiscV always uses default_nan_mode, this allows us to remove
11
its ifdef case from pickNaNMulAdd().
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-3-peter.maydell@linaro.org
16
---
17
fpu/softfloat-parts.c.inc | 8 ++++++--
18
fpu/softfloat-specialize.c.inc | 9 +++++++--
19
2 files changed, 13 insertions(+), 4 deletions(-)
20
21
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
index XXXXXXX..XXXXXXX 100644
23
--- a/fpu/softfloat-parts.c.inc
24
+++ b/fpu/softfloat-parts.c.inc
25
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
26
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
27
}
28
29
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
30
+ if (s->default_nan_mode) {
31
+ which = 3;
32
+ } else {
33
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ }
35
36
- if (s->default_nan_mode || which == 3) {
37
+ if (which == 3) {
38
parts_default_nan(a, s);
39
return a;
40
}
41
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
42
index XXXXXXX..XXXXXXX 100644
43
--- a/fpu/softfloat-specialize.c.inc
44
+++ b/fpu/softfloat-specialize.c.inc
45
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
46
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
47
bool infzero, float_status *status)
48
{
49
+ /*
50
+ * We guarantee not to require the target to tell us how to
51
+ * pick a NaN if we're always returning the default NaN.
52
+ * But if we're not in default-NaN mode then the target must
53
+ * specify.
54
+ */
55
+ assert(!status->default_nan_mode);
56
#if defined(TARGET_ARM)
57
/* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
58
* the default NaN
59
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
60
} else {
61
return 1;
62
}
63
-#elif defined(TARGET_RISCV)
64
- return 3; /* default NaN */
65
#elif defined(TARGET_S390X)
66
if (infzero) {
67
return 3;
68
--
69
2.34.1
diff view generated by jsdifflib
1
At this point, the function exynos4210_init_board_irqs() splits input
1
IEEE 758 does not define a fixed rule for what NaN to return in
2
IRQ lines to connect them to the input combiner, output combiner and
2
the case of a fused multiply-add of inf * 0 + NaN. Different
3
external GIC. The function exynos4210_combiner_get_gpioin() splits
3
architectures thus do different things:
4
some of the combiner input lines further to connect them to multiple
4
* some return the default NaN
5
different inputs on the combiner.
5
* some return the input NaN
6
6
* Arm returns the default NaN if the input NaN is quiet,
7
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
7
and the input NaN if it is signalling
8
configurable number of outputs, we can do all this in one place, by
8
9
making exynos4210_init_board_irqs() add extra outputs to the splitter
9
We want to make this logic be runtime selected rather than
10
device when it must be connected to more than one input on each
10
hardcoded into the binary, because:
11
combiner.
11
* this will let us have multiple targets in one QEMU binary
12
12
* the Arm FEAT_AFP architectural feature includes letting
13
We do this with a new data structure, the combinermap, which is an
13
the guest select a NaN propagation rule at runtime
14
array each of whose elements is a list of the interrupt IDs on the
14
15
combiner which must be tied together. As we loop through each
15
In this commit we add an enum for the propagation rule, the field in
16
interrupt ID, if we find that it is the first one in one of these
16
float_status, and the corresponding getters and setters. We change
17
lists, we configure the splitter device with eonugh extra outputs and
17
pickNaNMulAdd to honour this, but because all targets still leave
18
wire them up to the other interrupt IDs in the list.
18
this field at its default 0 value, the fallback logic will pick the
19
19
rule type with the old ifdef ladder.
20
Conveniently, for all the cases where this is necessary, the
20
21
lowest-numbered interrupt ID in each group is in the range of the
21
Note that four architectures both use the muladd softfloat functions
22
external combiner, so we only need to code for this in the first of
22
and did not have a branch of the ifdef ladder to specify their
23
the two loops in exynos4210_init_board_irqs().
23
behaviour (and so were ending up with the "default" case, probably
24
24
wrongly): i386, HPPA, SH4 and Tricore. SH4 and Tricore both set
25
The old code in exynos4210_combiner_get_gpioin() which is being
25
default_nan_mode, and so will never get into pickNaNMulAdd(). For
26
deleted here had several problems which don't exist in the new code
26
HPPA and i386 we retain the same behaviour as the old default-case,
27
in its handling of the multi-core timer interrupts:
27
which is to not ever return the default NaN. This might not be
28
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
28
correct but it is not a behaviour change.
29
exist; these should have been 4 ... 7
30
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
31
multiple times as the input of several different splitters,
32
which isn't allowed
33
(3) in an apparent cut-and-paste error, the cases for all the
34
multi-core timer inputs used "bit + 4" even though the
35
bit range for the case was (intended to be) 4 ... 7, which
36
meant it was looking at non-existent bits 8 ... 11.
37
None of these exist in the new code.
38
29
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
41
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
32
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
42
---
33
---
43
include/hw/arm/exynos4210.h | 6 +-
34
include/fpu/softfloat-helpers.h | 11 ++++
44
hw/arm/exynos4210.c | 178 +++++++++++++++++++++++-------------
35
include/fpu/softfloat-types.h | 23 +++++++++
45
2 files changed, 119 insertions(+), 65 deletions(-)
36
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
46
37
3 files changed, 95 insertions(+), 30 deletions(-)
47
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
38
39
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
48
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/arm/exynos4210.h
41
--- a/include/fpu/softfloat-helpers.h
50
+++ b/include/hw/arm/exynos4210.h
42
+++ b/include/fpu/softfloat-helpers.h
51
@@ -XXX,XX +XXX,XX @@
43
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
52
44
status->float_2nan_prop_rule = rule;
45
}
46
47
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
+ float_status *status)
49
+{
50
+ status->float_infzeronan_rule = rule;
51
+}
52
+
53
static inline void set_flush_to_zero(bool val, float_status *status)
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)
61
+{
62
+ return status->float_infzeronan_rule;
63
+}
64
+
65
static inline bool get_flush_to_zero(float_status *status)
66
{
67
return status->flush_to_zero;
68
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
69
index XXXXXXX..XXXXXXX 100644
70
--- a/include/fpu/softfloat-types.h
71
+++ b/include/fpu/softfloat-types.h
72
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
73
float_2nan_prop_x87,
74
} Float2NaNPropRule;
75
76
+/*
77
+ * Rule for result of fused multiply-add 0 * Inf + NaN.
78
+ * This must be a NaN, but implementations differ on whether this
79
+ * is the input NaN or the default NaN.
80
+ *
81
+ * You don't need to set this if default_nan_mode is enabled.
82
+ * When not in default-NaN mode, it is an error for the target
83
+ * not to set the rule in float_status if it uses muladd, and we
84
+ * will assert if we need to handle an input NaN and no rule was
85
+ * selected.
86
+ */
87
+typedef enum __attribute__((__packed__)) {
88
+ /* No propagation rule specified */
89
+ float_infzeronan_none = 0,
90
+ /* Result is never the default NaN (so always the input NaN) */
91
+ float_infzeronan_dnan_never,
92
+ /* Result is always the default NaN */
93
+ float_infzeronan_dnan_always,
94
+ /* Result is the default NaN if the input NaN is quiet */
95
+ float_infzeronan_dnan_if_qnan,
96
+} FloatInfZeroNaNRule;
97
+
53
/*
98
/*
54
* We need one splitter for every external combiner input, plus
99
* Floating Point Status. Individual architectures may maintain
55
- * one for every non-zero entry in combiner_grp_to_gic_id[].
100
* several versions of float_status for different functions. The
56
+ * one for every non-zero entry in combiner_grp_to_gic_id[],
101
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
57
+ * minus one for every external combiner ID in second or later
102
FloatRoundMode float_rounding_mode;
58
+ * places in a combinermap[] line.
103
FloatX80RoundPrec floatx80_rounding_precision;
59
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
104
Float2NaNPropRule float_2nan_prop_rule;
60
*/
105
+ FloatInfZeroNaNRule float_infzeronan_rule;
61
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
106
bool tininess_before_rounding;
62
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
107
/* should denormalised results go to zero and set the inexact flag? */
63
108
bool flush_to_zero;
64
typedef struct Exynos4210Irq {
109
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
65
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
66
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
67
index XXXXXXX..XXXXXXX 100644
110
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/exynos4210.c
111
--- a/fpu/softfloat-specialize.c.inc
69
+++ b/hw/arm/exynos4210.c
112
+++ b/fpu/softfloat-specialize.c.inc
70
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
113
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
71
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
114
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
72
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
115
bool infzero, float_status *status)
73
116
{
74
+/*
117
+ FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
75
+ * Some interrupt lines go to multiple combiner inputs.
118
+
76
+ * This data structure defines those: each array element is
119
/*
77
+ * a list of combiner inputs which are connected together;
120
* We guarantee not to require the target to tell us how to
78
+ * the one with the smallest interrupt ID value must be first.
121
* pick a NaN if we're always returning the default NaN.
79
+ * As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
122
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
80
+ * wired to anything so we can use 0 as a terminator.
123
* specify.
81
+ */
124
*/
82
+#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
125
assert(!status->default_nan_mode);
83
+#define IRQNONE 0
126
+
84
+
127
+ if (rule == float_infzeronan_none) {
85
+#define COMBINERMAP_SIZE 16
128
+ /*
86
+
129
+ * Temporarily fall back to ifdef ladder
87
+static const int combinermap[COMBINERMAP_SIZE][6] = {
130
+ */
88
+ /* MDNIE_LCD1 */
131
#if defined(TARGET_ARM)
89
+ { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
132
- /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
90
+ { IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
133
- * the default NaN
91
+ { IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
134
- */
92
+ { IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
135
- if (infzero && is_qnan(c_cls)) {
93
+ /* TMU */
136
- return 3;
94
+ { IRQNO(2, 4), IRQNO(3, 4), IRQNONE },
137
+ /*
95
+ { IRQNO(2, 5), IRQNO(3, 5), IRQNONE },
138
+ * For ARM, the (inf,zero,qnan) case returns the default NaN,
96
+ { IRQNO(2, 6), IRQNO(3, 6), IRQNONE },
139
+ * but (inf,zero,snan) returns the input NaN.
97
+ { IRQNO(2, 7), IRQNO(3, 7), IRQNONE },
140
+ */
98
+ /* LCD1 */
141
+ rule = float_infzeronan_dnan_if_qnan;
99
+ { IRQNO(11, 4), IRQNO(12, 0), IRQNONE },
142
+#elif defined(TARGET_MIPS)
100
+ { IRQNO(11, 5), IRQNO(12, 1), IRQNONE },
143
+ if (snan_bit_is_one(status)) {
101
+ { IRQNO(11, 6), IRQNO(12, 2), IRQNONE },
144
+ /*
102
+ { IRQNO(11, 7), IRQNO(12, 3), IRQNONE },
145
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
103
+ /* Multi-core timer */
146
+ * case sets InvalidOp and returns the default NaN
104
+ { IRQNO(1, 4), IRQNO(12, 4), IRQNO(35, 4), IRQNO(51, 4), IRQNO(53, 4), IRQNONE },
147
+ */
105
+ { IRQNO(1, 5), IRQNO(12, 5), IRQNO(35, 5), IRQNO(51, 5), IRQNO(53, 5), IRQNONE },
148
+ rule = float_infzeronan_dnan_always;
106
+ { IRQNO(1, 6), IRQNO(12, 6), IRQNO(35, 6), IRQNO(51, 6), IRQNO(53, 6), IRQNONE },
149
+ } else {
107
+ { IRQNO(1, 7), IRQNO(12, 7), IRQNO(35, 7), IRQNO(51, 7), IRQNO(53, 7), IRQNONE },
150
+ /*
108
+};
151
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
109
+
152
+ * case sets InvalidOp and returns the input value 'c'
110
+#undef IRQNO
153
+ */
111
+
154
+ rule = float_infzeronan_dnan_never;
112
+static const int *combinermap_entry(int irq)
155
+ }
113
+{
156
+#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
114
+ /*
157
+ defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
115
+ * If the interrupt number passed in is the first entry in some
158
+ defined(TARGET_I386) || defined(TARGET_LOONGARCH)
116
+ * line of the combinermap, return a pointer to that line;
159
+ /*
117
+ * otherwise return NULL.
160
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
118
+ */
161
+ * case sets InvalidOp and returns the input value 'c'
119
+ int i;
162
+ */
120
+ for (i = 0; i < COMBINERMAP_SIZE; i++) {
163
+ /*
121
+ if (combinermap[i][0] == irq) {
164
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
122
+ return combinermap[i];
165
+ * to return an input NaN if we have one (ie c) rather than generating
166
+ * a default NaN
167
+ */
168
+ rule = float_infzeronan_dnan_never;
169
+#elif defined(TARGET_S390X)
170
+ rule = float_infzeronan_dnan_always;
171
+#endif
172
}
173
174
+ if (infzero) {
175
+ /*
176
+ * Inf * 0 + NaN -- some implementations return the default NaN here,
177
+ * and some return the input NaN.
178
+ */
179
+ switch (rule) {
180
+ case float_infzeronan_dnan_never:
181
+ return 2;
182
+ case float_infzeronan_dnan_always:
183
+ return 3;
184
+ case float_infzeronan_dnan_if_qnan:
185
+ return is_qnan(c_cls) ? 3 : 2;
186
+ default:
187
+ g_assert_not_reached();
123
+ }
188
+ }
124
+ }
189
+ }
125
+ return NULL;
190
+
126
+}
191
+#if defined(TARGET_ARM)
127
+
192
+
128
+static int mapline_size(const int *mapline)
193
/* This looks different from the ARM ARM pseudocode, because the ARM ARM
129
+{
194
* puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
130
+ /* Return number of entries in this mapline in total */
195
*/
131
+ int i = 0;
196
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
132
+
197
}
133
+ if (!mapline) {
198
#elif defined(TARGET_MIPS)
134
+ /* Not in the map? IRQ goes to exactly one combiner input */
199
if (snan_bit_is_one(status)) {
135
+ return 1;
200
- /*
136
+ }
201
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
137
+ while (*mapline != IRQNONE) {
202
- * case sets InvalidOp and returns the default NaN
138
+ mapline++;
203
- */
139
+ i++;
204
- if (infzero) {
140
+ }
205
- return 3;
141
+ return i;
206
- }
142
+}
207
/* Prefer sNaN over qNaN, in the a, b, c order. */
143
+
208
if (is_snan(a_cls)) {
144
/*
209
return 0;
145
* Initialize board IRQs.
210
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
146
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
211
return 2;
147
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
148
DeviceState *extgicdev = DEVICE(&s->ext_gic);
149
int splitcount = 0;
150
DeviceState *splitter;
151
+ const int *mapline;
152
+ int numlines, splitin, in;
153
154
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
155
irq_id = 0;
156
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
157
irq_id = EXT_GIC_ID_MCT_G1;
158
}
212
}
159
213
} else {
160
+ if (s->irq_table[n]) {
214
- /*
161
+ /*
215
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
162
+ * This must be some non-first entry in a combinermap line,
216
- * case sets InvalidOp and returns the input value 'c'
163
+ * and we've already filled it in.
217
- */
164
+ */
218
/* Prefer sNaN over qNaN, in the c, a, b order. */
165
+ continue;
219
if (is_snan(c_cls)) {
166
+ }
220
return 2;
167
+ mapline = combinermap_entry(n);
221
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
168
+ /*
169
+ * We need to connect the IRQ to multiple inputs on both combiners
170
+ * and possibly also to the external GIC.
171
+ */
172
+ numlines = 2 * mapline_size(mapline);
173
+ if (irq_id) {
174
+ numlines++;
175
+ }
176
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
177
splitter = DEVICE(&s->splitter[splitcount]);
178
- qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
179
+ qdev_prop_set_uint16(splitter, "num-lines", numlines);
180
qdev_realize(splitter, NULL, &error_abort);
181
splitcount++;
182
- s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
183
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
184
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
185
+
186
+ in = n;
187
+ splitin = 0;
188
+ for (;;) {
189
+ s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
190
+ qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
191
+ qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
192
+ splitin += 2;
193
+ if (!mapline) {
194
+ break;
195
+ }
196
+ mapline++;
197
+ in = *mapline;
198
+ if (in == IRQNONE) {
199
+ break;
200
+ }
201
+ }
202
if (irq_id) {
203
- qdev_connect_gpio_out(splitter, 2,
204
+ qdev_connect_gpio_out(splitter, splitin,
205
qdev_get_gpio_in(extgicdev, irq_id - 32));
206
}
222
}
207
}
223
}
208
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
224
#elif defined(TARGET_LOONGARCH64)
209
irq_id = combiner_grp_to_gic_id[grp -
210
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
211
212
+ if (s->irq_table[n]) {
213
+ /*
214
+ * This must be some non-first entry in a combinermap line,
215
+ * and we've already filled it in.
216
+ */
217
+ continue;
218
+ }
219
+
220
if (irq_id) {
221
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
222
splitter = DEVICE(&s->splitter[splitcount]);
223
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
224
DeviceState *dev, int ext)
225
{
226
int n;
227
- int bit;
228
int max;
229
qemu_irq *irq;
230
231
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
232
EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
233
irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
234
235
- /*
225
- /*
236
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
226
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
237
- * so let split them.
227
- * case sets InvalidOp and returns the input value 'c'
238
- */
228
- */
239
for (n = 0; n < max; n++) {
240
-
229
-
241
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
230
/* Prefer sNaN over qNaN, in the c, a, b order. */
231
if (is_snan(c_cls)) {
232
return 2;
233
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
234
return 1;
235
}
236
#elif defined(TARGET_PPC)
237
- /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
238
- * to return an input NaN if we have one (ie c) rather than generating
239
- * a default NaN
240
- */
242
-
241
-
243
- switch (n) {
242
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
244
- /* MDNIE_LCD1 INTG1 */
243
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
245
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
244
*/
246
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
245
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
247
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
246
return 1;
248
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
247
}
249
- continue;
248
#elif defined(TARGET_S390X)
249
- if (infzero) {
250
- return 3;
251
- }
250
-
252
-
251
- /* TMU INTG3 */
253
if (is_snan(a_cls)) {
252
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
254
return 0;
253
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
255
} else if (is_snan(b_cls)) {
254
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
255
- continue;
256
-
257
- /* LCD1 INTG12 */
258
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
259
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
260
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
261
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
262
- continue;
263
-
264
- /* Multi-Core Timer INTG12 */
265
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
266
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
267
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
268
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
269
- continue;
270
-
271
- /* Multi-Core Timer INTG35 */
272
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
273
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
274
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
275
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
276
- continue;
277
-
278
- /* Multi-Core Timer INTG51 */
279
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
280
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
281
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
282
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
283
- continue;
284
-
285
- /* Multi-Core Timer INTG53 */
286
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
287
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
288
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
289
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
290
- continue;
291
- }
292
-
293
irq[n] = qdev_get_gpio_in(dev, n);
294
}
295
}
296
--
256
--
297
2.25.1
257
2.34.1
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for the inf-zero-nan
2
muladd special case. In meson.build we put -DTARGET_ARM in fpcflags,
3
and so we should select here the Arm rule of
4
float_infzeronan_dnan_if_qnan.
1
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241202131347.498124-5-peter.maydell@linaro.org
9
---
10
tests/fp/fp-bench.c | 5 +++++
11
tests/fp/fp-test.c | 5 +++++
12
2 files changed, 10 insertions(+)
13
14
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/fp/fp-bench.c
17
+++ b/tests/fp/fp-bench.c
18
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
19
{
20
bench_func_t f;
21
22
+ /*
23
+ * These implementation-defined choices for various things IEEE
24
+ * doesn't specify match those used by the Arm architecture.
25
+ */
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
28
29
f = bench_funcs[operation][precision];
30
g_assert(f);
31
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/tests/fp/fp-test.c
34
+++ b/tests/fp/fp-test.c
35
@@ -XXX,XX +XXX,XX @@ void run_test(void)
36
{
37
unsigned int i;
38
39
+ /*
40
+ * These implementation-defined choices for various things IEEE
41
+ * doesn't specify match those used by the Arm architecture.
42
+ */
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
44
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
45
46
genCases_setLevel(test_level);
47
verCases_maxErrorCount = n_max_errors;
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the Arm target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-6-peter.maydell@linaro.org
7
---
8
target/arm/cpu.c | 3 +++
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 4 insertions(+), 7 deletions(-)
11
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
17
* * tininess-before-rounding
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
20
+ * * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
21
+ * and the input NaN if it is signalling
22
*/
23
static void arm_set_default_fp_behaviours(float_status *s)
24
{
25
set_float_detect_tininess(float_tininess_before_rounding, s);
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
28
}
29
30
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
/*
37
* Temporarily fall back to ifdef ladder
38
*/
39
-#if defined(TARGET_ARM)
40
- /*
41
- * For ARM, the (inf,zero,qnan) case returns the default NaN,
42
- * but (inf,zero,snan) returns the input NaN.
43
- */
44
- rule = float_infzeronan_dnan_if_qnan;
45
-#elif defined(TARGET_MIPS)
46
+#if defined(TARGET_MIPS)
47
if (snan_bit_is_one(status)) {
48
/*
49
* For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
50
--
51
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for s390, so we
2
can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-7-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_infzeronan_rule(float_infzeronan_dnan_always,
21
+ &env->fpu_status);
22
/* fall through */
23
case RESET_TYPE_S390_CPU_NORMAL:
24
env->psw.mask &= ~PSW_MASK_RI;
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
* a default NaN
31
*/
32
rule = float_infzeronan_dnan_never;
33
-#elif defined(TARGET_S390X)
34
- rule = float_infzeronan_dnan_always;
35
#endif
36
}
37
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the PPC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-8-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 7 +++++++
9
fpu/softfloat-specialize.c.inc | 7 +------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
22
+ * to return an input NaN if we have one (ie c) rather than generating
23
+ * a default NaN
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
27
28
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
29
ppc_spr_t *spr = &env->spr_cb[i];
30
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
31
index XXXXXXX..XXXXXXX 100644
32
--- a/fpu/softfloat-specialize.c.inc
33
+++ b/fpu/softfloat-specialize.c.inc
34
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
*/
36
rule = float_infzeronan_dnan_never;
37
}
38
-#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
39
+#elif defined(TARGET_SPARC) || \
40
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
41
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
42
/*
43
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
44
* case sets InvalidOp and returns the input value 'c'
45
*/
46
- /*
47
- * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
48
- * to return an input NaN if we have one (ie c) rather than generating
49
- * a default NaN
50
- */
51
rule = float_infzeronan_dnan_never;
52
#endif
53
}
54
--
55
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the MIPS target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-9-peter.maydell@linaro.org
7
---
8
target/mips/fpu_helper.h | 9 +++++++++
9
target/mips/msa.c | 4 ++++
10
fpu/softfloat-specialize.c.inc | 16 +---------------
11
3 files changed, 14 insertions(+), 15 deletions(-)
12
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/mips/fpu_helper.h
16
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_flush_mode(CPUMIPSState *env)
18
static inline void restore_snan_bit_mode(CPUMIPSState *env)
19
{
20
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
21
+ FloatInfZeroNaNRule izn_rule;
22
23
/*
24
* With nan2008, SNaNs are silenced in the usual way.
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
26
*/
27
set_snan_bit_is_one(!nan2008, &env->active_fpu.fp_status);
28
set_default_nan_mode(!nan2008, &env->active_fpu.fp_status);
29
+ /*
30
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
31
+ * case sets InvalidOp and returns the default NaN.
32
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
33
+ * case sets InvalidOp and returns the input value 'c'.
34
+ */
35
+ izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
36
+ set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
37
}
38
39
static inline void restore_fp_status(CPUMIPSState *env)
40
diff --git a/target/mips/msa.c b/target/mips/msa.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/mips/msa.c
43
+++ b/target/mips/msa.c
44
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
45
46
/* set proper signanling bit meaning ("1" means "quiet") */
47
set_snan_bit_is_one(0, &env->active_tc.msa_fp_status);
48
+
49
+ /* Inf * 0 + NaN returns the input NaN */
50
+ set_float_infzeronan_rule(float_infzeronan_dnan_never,
51
+ &env->active_tc.msa_fp_status);
52
}
53
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
54
index XXXXXXX..XXXXXXX 100644
55
--- a/fpu/softfloat-specialize.c.inc
56
+++ b/fpu/softfloat-specialize.c.inc
57
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
58
/*
59
* Temporarily fall back to ifdef ladder
60
*/
61
-#if defined(TARGET_MIPS)
62
- if (snan_bit_is_one(status)) {
63
- /*
64
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
65
- * case sets InvalidOp and returns the default NaN
66
- */
67
- rule = float_infzeronan_dnan_always;
68
- } else {
69
- /*
70
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
71
- * case sets InvalidOp and returns the input value 'c'
72
- */
73
- rule = float_infzeronan_dnan_never;
74
- }
75
-#elif defined(TARGET_SPARC) || \
76
+#if defined(TARGET_SPARC) || \
77
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
78
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
79
/*
80
--
81
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the SPARC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-10-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
23
cpu_exec_realizefn(cs, &local_err);
24
if (local_err != NULL) {
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_SPARC) || \
34
- defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
35
+#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
36
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
37
/*
38
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the xtensa target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-11-peter.maydell@linaro.org
7
---
8
target/xtensa/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 +-
10
2 files changed, 3 insertions(+), 1 deletion(-)
11
12
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/xtensa/cpu.c
15
+++ b/target/xtensa/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
17
reset_mmu(env);
18
cs->halted = env->runstall;
19
#endif
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
set_no_signaling_nans(!dfpu, &env->fp_status);
23
xtensa_use_first_nan(env, !dfpu);
24
}
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
34
+#if defined(TARGET_HPPA) || \
35
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
36
/*
37
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the x86 target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-12-peter.maydell@linaro.org
6
---
7
target/i386/tcg/fpu_helper.c | 7 +++++++
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 8 insertions(+), 1 deletion(-)
10
11
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/i386/tcg/fpu_helper.c
14
+++ b/target/i386/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->mmx_status);
18
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->sse_status);
19
+ /*
20
+ * Only SSE has multiply-add instructions. In the SDM Section 14.5.2
21
+ * "Fused-Multiply-ADD (FMA) Numeric Behavior" the NaN handling is
22
+ * specified -- for 0 * inf + NaN the input NaN is selected, and if
23
+ * there are multiple input NaNs they are selected in the order a, b, c.
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
26
}
27
28
static inline uint8_t save_exception_flags(CPUX86State *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
34
* Temporarily fall back to ifdef ladder
35
*/
36
#if defined(TARGET_HPPA) || \
37
- defined(TARGET_I386) || defined(TARGET_LOONGARCH)
38
+ defined(TARGET_LOONGARCH)
39
/*
40
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
41
* case sets InvalidOp and returns the input value 'c'
42
--
43
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the loongarch target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-13-peter.maydell@linaro.org
6
---
7
target/loongarch/tcg/fpu_helper.c | 5 +++++
8
fpu/softfloat-specialize.c.inc | 7 +------
9
2 files changed, 6 insertions(+), 6 deletions(-)
10
11
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/tcg/fpu_helper.c
14
+++ b/target/loongarch/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
16
&env->fp_status);
17
set_flush_to_zero(0, &env->fp_status);
18
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
19
+ /*
20
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
21
+ * case sets InvalidOp and returns the input value 'c'
22
+ */
23
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
}
25
26
int ieee_ex_to_loongarch(int xcpt)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
index XXXXXXX..XXXXXXX 100644
29
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
32
/*
33
* Temporarily fall back to ifdef ladder
34
*/
35
-#if defined(TARGET_HPPA) || \
36
- defined(TARGET_LOONGARCH)
37
- /*
38
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
- * case sets InvalidOp and returns the input value 'c'
40
- */
41
+#if defined(TARGET_HPPA)
42
rule = float_infzeronan_dnan_never;
43
#endif
44
}
45
--
46
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the HPPA target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
As this is the last target to be converted to explicitly setting
5
the rule, we can remove the fallback code in pickNaNMulAdd()
6
entirely.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20241202131347.498124-14-peter.maydell@linaro.org
11
---
12
target/hppa/fpu_helper.c | 2 ++
13
fpu/softfloat-specialize.c.inc | 13 +------------
14
2 files changed, 3 insertions(+), 12 deletions(-)
15
16
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/hppa/fpu_helper.c
19
+++ b/target/hppa/fpu_helper.c
20
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
21
* HPPA does note implement a CPU reset method at all...
22
*/
23
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
24
+ /* For inf * 0 + NaN, return the input NaN */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
}
27
28
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
34
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
bool infzero, float_status *status)
36
{
37
- FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
38
-
39
/*
40
* We guarantee not to require the target to tell us how to
41
* pick a NaN if we're always returning the default NaN.
42
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
43
*/
44
assert(!status->default_nan_mode);
45
46
- if (rule == float_infzeronan_none) {
47
- /*
48
- * Temporarily fall back to ifdef ladder
49
- */
50
-#if defined(TARGET_HPPA)
51
- rule = float_infzeronan_dnan_never;
52
-#endif
53
- }
54
-
55
if (infzero) {
56
/*
57
* Inf * 0 + NaN -- some implementations return the default NaN here,
58
* and some return the input NaN.
59
*/
60
- switch (rule) {
61
+ switch (status->float_infzeronan_rule) {
62
case float_infzeronan_dnan_never:
63
return 2;
64
case float_infzeronan_dnan_always:
65
--
66
2.34.1
diff view generated by jsdifflib
New patch
1
The new implementation of pickNaNMulAdd() will find it convenient
2
to know whether at least one of the three arguments to the muladd
3
was a signaling NaN. We already calculate that in the caller,
4
so pass it in as a new bool have_snan.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-15-peter.maydell@linaro.org
9
---
10
fpu/softfloat-parts.c.inc | 5 +++--
11
fpu/softfloat-specialize.c.inc | 2 +-
12
2 files changed, 4 insertions(+), 3 deletions(-)
13
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat-parts.c.inc
17
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
19
{
20
int which;
21
bool infzero = (ab_mask == float_cmask_infzero);
22
+ bool have_snan = (abc_mask & float_cmask_snan);
23
24
- if (unlikely(abc_mask & float_cmask_snan)) {
25
+ if (unlikely(have_snan)) {
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
27
}
28
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
if (s->default_nan_mode) {
31
which = 3;
32
} else {
33
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
35
}
36
37
if (which == 3) {
38
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
39
index XXXXXXX..XXXXXXX 100644
40
--- a/fpu/softfloat-specialize.c.inc
41
+++ b/fpu/softfloat-specialize.c.inc
42
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
43
| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
44
*----------------------------------------------------------------------------*/
45
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
46
- bool infzero, float_status *status)
47
+ bool infzero, bool have_snan, float_status *status)
48
{
49
/*
50
* We guarantee not to require the target to tell us how to
51
--
52
2.34.1
diff view generated by jsdifflib
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
1
IEEE 758 does not define a fixed rule for which NaN to pick as the
2
instead of qemu_irq_split().
2
result if both operands of a 3-operand fused multiply-add operation
3
are NaNs. As a result different architectures have ended up with
4
different rules for propagating NaNs.
5
6
QEMU currently hardcodes the NaN propagation logic into the binary
7
because pickNaNMulAdd() has an ifdef ladder for different targets.
8
We want to make the propagation rule instead be selectable at
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.
3
23
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
26
Message-id: 20241202131347.498124-16-peter.maydell@linaro.org
7
---
27
---
8
include/hw/arm/exynos4210.h | 9 ++++++++
28
include/fpu/softfloat-helpers.h | 11 +++
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
29
include/fpu/softfloat-types.h | 55 +++++++++++
10
2 files changed, 42 insertions(+), 8 deletions(-)
30
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
11
31
3 files changed, 107 insertions(+), 126 deletions(-)
12
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
32
33
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
13
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/exynos4210.h
35
--- a/include/fpu/softfloat-helpers.h
15
+++ b/include/hw/arm/exynos4210.h
36
+++ b/include/fpu/softfloat-helpers.h
16
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
17
#include "hw/sysbus.h"
38
status->float_2nan_prop_rule = rule;
18
#include "hw/cpu/a9mpcore.h"
39
}
19
#include "hw/intc/exynos4210_gic.h"
40
20
+#include "hw/core/split-irq.h"
41
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
21
#include "target/arm/cpu-qom.h"
42
+ float_status *status)
22
#include "qom/object.h"
43
+{
23
44
+ status->float_3nan_prop_rule = rule;
24
@@ -XXX,XX +XXX,XX @@
45
+}
25
46
+
26
#define EXYNOS4210_NUM_DMA 3
47
static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
float_status *status)
49
{
50
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
51
return status->float_2nan_prop_rule;
52
}
53
54
+static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
55
+{
56
+ return status->float_3nan_prop_rule;
57
+}
58
+
59
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
60
{
61
return status->float_infzeronan_rule;
62
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
63
index XXXXXXX..XXXXXXX 100644
64
--- a/include/fpu/softfloat-types.h
65
+++ b/include/fpu/softfloat-types.h
66
@@ -XXX,XX +XXX,XX @@ this code that are retained.
67
#ifndef SOFTFLOAT_TYPES_H
68
#define SOFTFLOAT_TYPES_H
69
70
+#include "hw/registerfields.h"
71
+
72
/*
73
* Software IEC/IEEE floating-point types.
74
*/
75
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
76
float_2nan_prop_x87,
77
} Float2NaNPropRule;
27
78
28
+/*
79
+/*
29
+ * We need one splitter for every external combiner input, plus
80
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
81
+ * architectures have different rules for which input NaN is
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
82
+ * propagated to the output when there is more than one NaN on the
83
+ * input.
84
+ *
85
+ * If default_nan_mode is enabled then it is valid not to set a NaN
86
+ * propagation rule, because the softfloat code guarantees not to try
87
+ * to pick a NaN to propagate in default NaN mode. When not in
88
+ * default-NaN mode, it is an error for the target not to set the rule
89
+ * in float_status if it uses a muladd, and we will assert if we need
90
+ * to handle an input NaN and no rule was selected.
91
+ *
92
+ * The naming scheme for Float3NaNPropRule values is:
93
+ * float_3nan_prop_s_abc:
94
+ * = "Prefer SNaN over QNaN, then operand A over B over C"
95
+ * float_3nan_prop_abc:
96
+ * = "Prefer A over B over C regardless of SNaN vs QNAN"
97
+ *
98
+ * For QEMU, the multiply-add operation is A * B + C.
32
+ */
99
+ */
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
100
+
34
+
101
+/*
35
typedef struct Exynos4210Irq {
102
+ * We set the Float3NaNPropRule enum values up so we can select the
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
103
+ * right value in pickNaNMulAdd in a data driven way.
37
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
104
+ */
38
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
105
+FIELD(3NAN, 1ST, 0, 2) /* which operand is most preferred ? */
39
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
106
+FIELD(3NAN, 2ND, 2, 2) /* which operand is next most preferred ? */
40
A9MPPrivState a9mpcore;
107
+FIELD(3NAN, 3RD, 4, 2) /* which operand is least preferred ? */
41
Exynos4210GicState ext_gic;
108
+FIELD(3NAN, SNAN, 6, 1) /* do we prefer SNaN over QNaN ? */
42
+ SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
109
+
43
};
110
+#define PROPRULE(X, Y, Z) \
44
111
+ ((X << R_3NAN_1ST_SHIFT) | (Y << R_3NAN_2ND_SHIFT) | (Z << R_3NAN_3RD_SHIFT))
45
#define TYPE_EXYNOS4210_SOC "exynos4210"
112
+
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
113
+typedef enum __attribute__((__packed__)) {
114
+ float_3nan_prop_none = 0, /* No propagation rule specified */
115
+ float_3nan_prop_abc = PROPRULE(0, 1, 2),
116
+ float_3nan_prop_acb = PROPRULE(0, 2, 1),
117
+ float_3nan_prop_bac = PROPRULE(1, 0, 2),
118
+ float_3nan_prop_bca = PROPRULE(1, 2, 0),
119
+ float_3nan_prop_cab = PROPRULE(2, 0, 1),
120
+ float_3nan_prop_cba = PROPRULE(2, 1, 0),
121
+ float_3nan_prop_s_abc = float_3nan_prop_abc | R_3NAN_SNAN_MASK,
122
+ float_3nan_prop_s_acb = float_3nan_prop_acb | R_3NAN_SNAN_MASK,
123
+ float_3nan_prop_s_bac = float_3nan_prop_bac | R_3NAN_SNAN_MASK,
124
+ float_3nan_prop_s_bca = float_3nan_prop_bca | R_3NAN_SNAN_MASK,
125
+ float_3nan_prop_s_cab = float_3nan_prop_cab | R_3NAN_SNAN_MASK,
126
+ float_3nan_prop_s_cba = float_3nan_prop_cba | R_3NAN_SNAN_MASK,
127
+} Float3NaNPropRule;
128
+
129
+#undef PROPRULE
130
+
131
/*
132
* Rule for result of fused multiply-add 0 * Inf + NaN.
133
* This must be a NaN, but implementations differ on whether this
134
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
135
FloatRoundMode float_rounding_mode;
136
FloatX80RoundPrec floatx80_rounding_precision;
137
Float2NaNPropRule float_2nan_prop_rule;
138
+ Float3NaNPropRule float_3nan_prop_rule;
139
FloatInfZeroNaNRule float_infzeronan_rule;
140
bool tininess_before_rounding;
141
/* should denormalised results go to zero and set the inexact flag? */
142
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
47
index XXXXXXX..XXXXXXX 100644
143
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/exynos4210.c
144
--- a/fpu/softfloat-specialize.c.inc
49
+++ b/hw/arm/exynos4210.c
145
+++ b/fpu/softfloat-specialize.c.inc
50
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
146
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
51
uint32_t grp, bit, irq_id, n;
147
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
52
Exynos4210Irq *is = &s->irqs;
148
bool infzero, bool have_snan, float_status *status)
53
DeviceState *extgicdev = DEVICE(&s->ext_gic);
149
{
54
+ int splitcount = 0;
150
+ FloatClass cls[3] = { a_cls, b_cls, c_cls };
55
+ DeviceState *splitter;
151
+ Float3NaNPropRule rule = status->float_3nan_prop_rule;
56
152
+ int which;
57
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
153
+
58
irq_id = 0;
154
/*
59
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
155
* We guarantee not to require the target to tell us how to
60
/* MCT_G1 is passed to External and GIC */
156
* pick a NaN if we're always returning the default NaN.
61
irq_id = EXT_GIC_ID_MCT_G1;
157
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
62
}
63
+
64
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
65
+ splitter = DEVICE(&s->splitter[splitcount]);
66
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
67
+ qdev_realize(splitter, NULL, &error_abort);
68
+ splitcount++;
69
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
70
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
71
if (irq_id) {
72
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
73
- qdev_get_gpio_in(extgicdev,
74
- irq_id - 32));
75
+ qdev_connect_gpio_out(splitter, 1,
76
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
77
} else {
78
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
79
- is->ext_combiner_irq[n]);
80
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
81
}
158
}
82
}
159
}
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
160
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
161
+ if (rule == float_3nan_prop_none) {
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
162
#if defined(TARGET_ARM)
86
163
-
87
if (irq_id) {
164
- /* This looks different from the ARM ARM pseudocode, because the ARM ARM
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
165
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
89
- qdev_get_gpio_in(extgicdev,
166
- */
90
- irq_id - 32));
167
- if (is_snan(c_cls)) {
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
168
- return 2;
92
+ splitter = DEVICE(&s->splitter[splitcount]);
169
- } else if (is_snan(a_cls)) {
93
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
170
- return 0;
94
+ qdev_realize(splitter, NULL, &error_abort);
171
- } else if (is_snan(b_cls)) {
95
+ splitcount++;
172
- return 1;
96
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
173
- } else if (is_qnan(c_cls)) {
97
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
174
- return 2;
98
+ qdev_connect_gpio_out(splitter, 1,
175
- } else if (is_qnan(a_cls)) {
99
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
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;
100
}
203
}
101
}
204
- } else {
102
+ /*
205
- /* Prefer sNaN over qNaN, in the c, a, b order. */
103
+ * We check this here to avoid a more obscure assert later when
206
- if (is_snan(c_cls)) {
104
+ * qdev_assert_realized_properly() checks that we realized every
207
- return 2;
105
+ * child object we initialized.
208
- } else if (is_snan(a_cls)) {
106
+ */
209
- return 0;
107
+ assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
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
321
+ }
322
+
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;
108
}
337
}
109
338
110
/*
339
/*----------------------------------------------------------------------------
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
112
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
113
}
114
115
+ for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
116
+ g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
117
+ object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
118
+ }
119
+
120
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
121
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
122
}
123
--
340
--
124
2.25.1
341
2.34.1
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for propagating NaNs in
2
the muladd case. In meson.build we put -DTARGET_ARM in fpcflags, and
3
so we should select here the Arm rule of float_3nan_prop_s_cab.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-17-peter.maydell@linaro.org
8
---
9
tests/fp/fp-bench.c | 1 +
10
tests/fp/fp-test.c | 1 +
11
2 files changed, 2 insertions(+)
12
13
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/fp/fp-bench.c
16
+++ b/tests/fp/fp-bench.c
17
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
18
* doesn't specify match those used by the Arm architecture.
19
*/
20
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
22
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
23
24
f = bench_funcs[operation][precision];
25
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/fp/fp-test.c
28
+++ b/tests/fp/fp-test.c
29
@@ -XXX,XX +XXX,XX @@ void run_test(void)
30
* doesn't specify match those used by the Arm architecture.
31
*/
32
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
33
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
34
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
35
36
genCases_setLevel(test_level);
37
--
38
2.34.1
diff view generated by jsdifflib
1
The only time we use the ext_gic_irq[] array in the Exynos4210Irq
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
struct is during realize of the SoC -- we initialize it with the
2
ifdef from pickNaNMulAdd().
3
input IRQs of the external GIC device, and then connect those to
4
outputs of other devices further on in realize (including in the
5
exynos4210_init_board_irqs() function). Now that the ext_gic object
6
is easily accessible as s->ext_gic we can make the connections
7
directly from one device to the other without going via this array.
8
3
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-10-peter.maydell@linaro.org
6
Message-id: 20241202131347.498124-18-peter.maydell@linaro.org
12
---
7
---
13
include/hw/arm/exynos4210.h | 1 -
8
target/arm/cpu.c | 5 +++++
14
hw/arm/exynos4210.c | 12 ++++++------
9
fpu/softfloat-specialize.c.inc | 8 +-------
15
2 files changed, 6 insertions(+), 7 deletions(-)
10
2 files changed, 6 insertions(+), 7 deletions(-)
16
11
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
14
--- a/target/arm/cpu.c
20
+++ b/include/hw/arm/exynos4210.h
15
+++ b/target/arm/cpu.c
21
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
22
typedef struct Exynos4210Irq {
17
* * tininess-before-rounding
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
25
- qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
20
+ * * 3-input NaN propagation prefers SNaN over QNaN, and then
26
} Exynos4210Irq;
21
+ * operand C over A over B (see FPProcessNaNs3() pseudocode,
27
22
+ * but note that for QEMU muladd is a * b + c, whereas for
28
struct Exynos4210State {
23
+ * the pseudocode function the arguments are in the order c, a, b.
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
24
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
25
* and the input NaN if it is signalling
26
*/
27
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
28
{
29
set_float_detect_tininess(float_tininess_before_rounding, s);
30
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
31
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
32
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
33
}
34
35
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
37
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/hw/arm/exynos4210.c
38
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
39
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
34
{
40
}
35
uint32_t grp, bit, irq_id, n;
41
36
Exynos4210Irq *is = &s->irqs;
42
if (rule == float_3nan_prop_none) {
37
+ DeviceState *extgicdev = DEVICE(&s->ext_gic);
43
-#if defined(TARGET_ARM)
38
44
- /*
39
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
45
- * This looks different from the ARM ARM pseudocode, because the ARM ARM
40
irq_id = 0;
46
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
47
- */
42
}
48
- rule = float_3nan_prop_s_cab;
43
if (irq_id) {
49
-#elif defined(TARGET_MIPS)
44
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
50
+#if defined(TARGET_MIPS)
45
- is->ext_gic_irq[irq_id - 32]);
51
if (snan_bit_is_one(status)) {
46
+ qdev_get_gpio_in(extgicdev,
52
rule = float_3nan_prop_s_abc;
47
+ irq_id - 32));
48
} else {
53
} else {
49
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
50
is->ext_combiner_irq[n]);
51
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
52
53
if (irq_id) {
54
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
55
- is->ext_gic_irq[irq_id - 32]);
56
+ qdev_get_gpio_in(extgicdev,
57
+ irq_id - 32));
58
}
59
}
60
}
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
62
sysbus_connect_irq(busdev, n,
63
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
64
}
65
- for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
66
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
67
- }
68
69
/* Internal Interrupt Combiner */
70
dev = qdev_new("exynos4210.combiner");
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
72
busdev = SYS_BUS_DEVICE(dev);
73
sysbus_realize_and_unref(busdev, &error_fatal);
74
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
75
- sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
76
+ sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
77
}
78
exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
79
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
80
--
54
--
81
2.25.1
55
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for loongarch, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-19-peter.maydell@linaro.org
7
---
8
target/loongarch/tcg/fpu_helper.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/loongarch/tcg/fpu_helper.c
15
+++ b/target/loongarch/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
17
* case sets InvalidOp and returns the input value 'c'
18
*/
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
21
}
22
23
int ieee_ex_to_loongarch(int xcpt)
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_LOONGARCH64)
33
- rule = float_3nan_prop_s_cab;
34
#elif defined(TARGET_PPC)
35
/*
36
* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for PPC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-20-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 8 ++++++++
9
fpu/softfloat-specialize.c.inc | 6 ------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * NaN propagation for fused multiply-add:
22
+ * if fRA is a NaN return it; otherwise if fRB is a NaN return it;
23
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
24
+ * whereas QEMU labels the operands as (a * b) + c.
25
+ */
26
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->fp_status);
27
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->vec_status);
28
/*
29
* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
30
* to return an input NaN if we have one (ie c) rather than generating
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
} else {
37
rule = float_3nan_prop_s_cab;
38
}
39
-#elif defined(TARGET_PPC)
40
- /*
41
- * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
42
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
43
- */
44
- rule = float_3nan_prop_acb;
45
#elif defined(TARGET_S390X)
46
rule = float_3nan_prop_s_abc;
47
#elif defined(TARGET_SPARC)
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for s390x, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-21-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
21
set_float_infzeronan_rule(float_infzeronan_dnan_always,
22
&env->fpu_status);
23
/* fall through */
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_S390X)
33
- rule = float_3nan_prop_s_abc;
34
#elif defined(TARGET_SPARC)
35
rule = float_3nan_prop_s_cba;
36
#elif defined(TARGET_XTENSA)
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for SPARC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-22-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For fused-multiply add, prefer SNaN over QNaN, then C->B->A */
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
22
/* For inf * 0 + NaN, return the input NaN */
23
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
} else {
31
rule = float_3nan_prop_s_cab;
32
}
33
-#elif defined(TARGET_SPARC)
34
- rule = float_3nan_prop_s_cba;
35
#elif defined(TARGET_XTENSA)
36
if (status->use_first_nan) {
37
rule = float_3nan_prop_abc;
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-23-peter.maydell@linaro.org
7
---
8
target/mips/fpu_helper.h | 4 ++++
9
target/mips/msa.c | 3 +++
10
fpu/softfloat-specialize.c.inc | 8 +-------
11
3 files changed, 8 insertions(+), 7 deletions(-)
12
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/mips/fpu_helper.h
16
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
18
{
19
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
20
FloatInfZeroNaNRule izn_rule;
21
+ Float3NaNPropRule nan3_rule;
22
23
/*
24
* With nan2008, SNaNs are silenced in the usual way.
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
26
*/
27
izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
28
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
29
+ nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
30
+ set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
31
+
32
}
33
34
static inline void restore_fp_status(CPUMIPSState *env)
35
diff --git a/target/mips/msa.c b/target/mips/msa.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/mips/msa.c
38
+++ b/target/mips/msa.c
39
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
40
set_float_2nan_prop_rule(float_2nan_prop_s_ab,
41
&env->active_tc.msa_fp_status);
42
43
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab,
44
+ &env->active_tc.msa_fp_status);
45
+
46
/* clear float_status exception flags */
47
set_float_exception_flags(0, &env->active_tc.msa_fp_status);
48
49
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
50
index XXXXXXX..XXXXXXX 100644
51
--- a/fpu/softfloat-specialize.c.inc
52
+++ b/fpu/softfloat-specialize.c.inc
53
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
54
}
55
56
if (rule == float_3nan_prop_none) {
57
-#if defined(TARGET_MIPS)
58
- if (snan_bit_is_one(status)) {
59
- rule = float_3nan_prop_s_abc;
60
- } else {
61
- rule = float_3nan_prop_s_cab;
62
- }
63
-#elif defined(TARGET_XTENSA)
64
+#if defined(TARGET_XTENSA)
65
if (status->use_first_nan) {
66
rule = float_3nan_prop_abc;
67
} else {
68
--
69
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for xtensa, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-24-peter.maydell@linaro.org
7
---
8
target/xtensa/fpu_helper.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 8 --------
10
2 files changed, 2 insertions(+), 8 deletions(-)
11
12
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/xtensa/fpu_helper.c
15
+++ b/target/xtensa/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
17
set_use_first_nan(use_first, &env->fp_status);
18
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
19
&env->fp_status);
20
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
21
+ &env->fp_status);
22
}
23
24
void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
}
31
32
if (rule == float_3nan_prop_none) {
33
-#if defined(TARGET_XTENSA)
34
- if (status->use_first_nan) {
35
- rule = float_3nan_prop_abc;
36
- } else {
37
- rule = float_3nan_prop_cba;
38
- }
39
-#else
40
rule = float_3nan_prop_abc;
41
-#endif
42
}
43
44
assert(rule != float_3nan_prop_none);
45
--
46
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for i386. We had no
2
i386-specific behaviour in the old ifdef ladder, so we were using the
3
default "prefer a then b then c" fallback; this is actually the
4
correct per-the-spec handling for i386.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-25-peter.maydell@linaro.org
9
---
10
target/i386/tcg/fpu_helper.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/i386/tcg/fpu_helper.c
16
+++ b/target/i386/tcg/fpu_helper.c
17
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
18
* there are multiple input NaNs they are selected in the order a, b, c.
19
*/
20
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
22
}
23
24
static inline uint8_t save_exception_flags(CPUX86State *env)
25
--
26
2.34.1
diff view generated by jsdifflib
1
Currently for the interrupts MCT_G0 and MCT_G1 which are
1
Set the Float3NaNPropRule explicitly for HPPA, and remove the
2
the only ones in the input range of the external combiner
2
ifdef from pickNaNMulAdd().
3
and which are also wired to the external GIC, we connect
4
them only to the internal combiner and the external GIC.
5
This seems likely to be a bug, as all other interrupts
6
which are in the input range of both combiners are
7
connected to both combiners. (The fact that the code in
8
exynos4210_combiner_get_gpioin() is also trying to wire
9
up these inputs on both combiners also suggests this.)
10
3
11
Wire these interrupts up to both combiners, like the rest.
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
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-15-peter.maydell@linaro.org
15
Message-id: 20241202131347.498124-26-peter.maydell@linaro.org
16
---
16
---
17
hw/arm/exynos4210.c | 7 +++----
17
target/hppa/fpu_helper.c | 8 ++++++++
18
1 file changed, 3 insertions(+), 4 deletions(-)
18
fpu/softfloat-specialize.c.inc | 4 ----
19
2 files changed, 8 insertions(+), 4 deletions(-)
19
20
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
21
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/exynos4210.c
23
--- a/target/hppa/fpu_helper.c
23
+++ b/hw/arm/exynos4210.c
24
+++ b/target/hppa/fpu_helper.c
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
25
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
25
26
* HPPA does note implement a CPU reset method at all...
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
27
*/
27
splitter = DEVICE(&s->splitter[splitcount]);
28
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
29
+ /*
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
30
+ * TODO: The HPPA architecture reference only documents its NaN
30
qdev_realize(splitter, NULL, &error_abort);
31
+ * propagation rule for 2-operand operations. Testing on real hardware
31
splitcount++;
32
+ * might be necessary to confirm whether this order for muladd is correct.
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
33
+ * Not preferring the SNaN is almost certainly incorrect as it diverges
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
34
+ * from the documented rules for 2-operand operations.
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
35
+ */
35
if (irq_id) {
36
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
36
- qdev_connect_gpio_out(splitter, 1,
37
/* For inf * 0 + NaN, return the input NaN */
37
+ qdev_connect_gpio_out(splitter, 2,
38
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
39
}
39
- } else {
40
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
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,
41
}
45
}
42
}
46
}
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
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 */
44
--
55
--
45
2.25.1
56
2.34.1
diff view generated by jsdifflib
1
The only time we use the int_combiner_irq[] and ext_combiner_irq[]
1
The use_first_nan field in float_status was an xtensa-specific way to
2
arrays in the Exynos4210Irq struct is during realize of the SoC -- we
2
select at runtime from two different NaN propagation rules. Now that
3
initialize them with the input IRQs of the combiner devices, and then
3
xtensa is using the target-agnostic NaN propagation rule selection
4
connect those to outputs of other devices in
4
that we've just added, we can remove use_first_nan, because there is
5
exynos4210_init_board_irqs(). Now that the combiner objects are
5
no longer any code that reads it.
6
easily accessible as s->int_combiner and s->ext_combiner we can make
7
the connections directly from one device to the other without going
8
via these arrays.
9
10
Since these are the only two remaining elements of Exynos4210Irq,
11
we can remove that struct entirely.
12
6
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
9
Message-id: 20241202131347.498124-27-peter.maydell@linaro.org
16
---
10
---
17
include/hw/arm/exynos4210.h | 6 ------
11
include/fpu/softfloat-helpers.h | 5 -----
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
12
include/fpu/softfloat-types.h | 1 -
19
2 files changed, 8 insertions(+), 32 deletions(-)
13
target/xtensa/fpu_helper.c | 1 -
14
3 files changed, 7 deletions(-)
20
15
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
16
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/exynos4210.h
18
--- a/include/fpu/softfloat-helpers.h
24
+++ b/include/hw/arm/exynos4210.h
19
+++ b/include/fpu/softfloat-helpers.h
25
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static inline void set_snan_bit_is_one(bool val, float_status *status)
26
*/
21
status->snan_bit_is_one = val;
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
28
29
-typedef struct Exynos4210Irq {
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
32
-} Exynos4210Irq;
33
-
34
struct Exynos4210State {
35
/*< private >*/
36
SysBusDevice parent_obj;
37
/*< public >*/
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
39
- Exynos4210Irq irqs;
40
qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
41
42
MemoryRegion chipid_mem;
43
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/arm/exynos4210.c
46
+++ b/hw/arm/exynos4210.c
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
48
static void exynos4210_init_board_irqs(Exynos4210State *s)
49
{
50
uint32_t grp, bit, irq_id, n;
51
- Exynos4210Irq *is = &s->irqs;
52
DeviceState *extgicdev = DEVICE(&s->ext_gic);
53
+ DeviceState *intcdev = DEVICE(&s->int_combiner);
54
+ DeviceState *extcdev = DEVICE(&s->ext_combiner);
55
int splitcount = 0;
56
DeviceState *splitter;
57
const int *mapline;
58
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
59
splitin = 0;
60
for (;;) {
61
s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
62
- qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
63
- qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
64
+ qdev_connect_gpio_out(splitter, splitin,
65
+ qdev_get_gpio_in(intcdev, in));
66
+ qdev_connect_gpio_out(splitter, splitin + 1,
67
+ qdev_get_gpio_in(extcdev, in));
68
splitin += 2;
69
if (!mapline) {
70
break;
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
72
qdev_realize(splitter, NULL, &error_abort);
73
splitcount++;
74
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
75
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
76
+ qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
77
qdev_connect_gpio_out(splitter, 1,
78
qdev_get_gpio_in(extgicdev, irq_id - 32));
79
} else {
80
- s->irq_table[n] = is->int_combiner_irq[n];
81
+ s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
82
}
83
}
84
/*
85
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
86
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
87
}
22
}
88
23
89
-/*
24
-static inline void set_use_first_nan(bool val, float_status *status)
90
- * Get Combiner input GPIO into irqs structure
91
- */
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
93
- DeviceState *dev, int ext)
94
-{
25
-{
95
- int n;
26
- status->use_first_nan = val;
96
- int max;
97
- qemu_irq *irq;
98
-
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
102
-
103
- for (n = 0; n < max; n++) {
104
- irq[n] = qdev_get_gpio_in(dev, n);
105
- }
106
-}
27
-}
107
-
28
-
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
29
static inline void set_no_signaling_nans(bool val, float_status *status)
109
0x09, 0x00, 0x00, 0x00 };
30
{
110
31
status->no_signaling_nans = val;
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
32
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
112
sysbus_connect_irq(busdev, n,
33
index XXXXXXX..XXXXXXX 100644
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
34
--- a/include/fpu/softfloat-types.h
114
}
35
+++ b/include/fpu/softfloat-types.h
115
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
36
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
116
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
37
* softfloat-specialize.inc.c)
117
38
*/
118
/* External Interrupt Combiner */
39
bool snan_bit_is_one;
119
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
40
- bool use_first_nan;
120
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
41
bool no_signaling_nans;
121
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
42
/* should overflowed results subtract re_bias to its exponent? */
122
}
43
bool rebias_overflow;
123
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
44
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
124
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
45
index XXXXXXX..XXXXXXX 100644
125
46
--- a/target/xtensa/fpu_helper.c
126
/* Initialize board IRQs. */
47
+++ b/target/xtensa/fpu_helper.c
48
@@ -XXX,XX +XXX,XX @@ static const struct {
49
50
void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
51
{
52
- set_use_first_nan(use_first, &env->fp_status);
53
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
54
&env->fp_status);
55
set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
127
--
56
--
128
2.25.1
57
2.34.1
diff view generated by jsdifflib
New patch
1
Currently m68k_cpu_reset_hold() calls floatx80_default_nan(NULL)
2
to get the NaN bit pattern to reset the FPU registers. This
3
works because it happens that our implementation of
4
floatx80_default_nan() doesn't actually look at the float_status
5
pointer except for TARGET_MIPS. However, this isn't guaranteed,
6
and to be able to remove the ifdef in floatx80_default_nan()
7
we're going to need a real float_status here.
1
8
9
Rearrange m68k_cpu_reset_hold() so that we initialize env->fp_status
10
earlier, and thus can pass it to floatx80_default_nan().
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20241202131347.498124-28-peter.maydell@linaro.org
15
---
16
target/m68k/cpu.c | 12 +++++++-----
17
1 file changed, 7 insertions(+), 5 deletions(-)
18
19
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/m68k/cpu.c
22
+++ b/target/m68k/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
24
CPUState *cs = CPU(obj);
25
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(obj);
26
CPUM68KState *env = cpu_env(cs);
27
- floatx80 nan = floatx80_default_nan(NULL);
28
+ floatx80 nan;
29
int i;
30
31
if (mcc->parent_phases.hold) {
32
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
33
#else
34
cpu_m68k_set_sr(env, SR_S | SR_I);
35
#endif
36
- for (i = 0; i < 8; i++) {
37
- env->fregs[i].d = nan;
38
- }
39
- cpu_m68k_set_fpcr(env, 0);
40
/*
41
* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
42
* 3.4 FLOATING-POINT INSTRUCTION DETAILS
43
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
44
* preceding paragraph for nonsignaling NaNs.
45
*/
46
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
47
+
48
+ nan = floatx80_default_nan(&env->fp_status);
49
+ for (i = 0; i < 8; i++) {
50
+ env->fregs[i].d = nan;
51
+ }
52
+ cpu_m68k_set_fpcr(env, 0);
53
env->fpsr = 0;
54
55
/* TODO: We should set PC from the interrupt vector. */
56
--
57
2.34.1
diff view generated by jsdifflib
New patch
1
We create our 128-bit default NaN by calling parts64_default_nan()
2
and then adjusting the result. We can do the same trick for creating
3
the floatx80 default NaN, which lets us drop a target ifdef.
1
4
5
floatx80 is used only by:
6
i386
7
m68k
8
arm nwfpe old floating-point emulation emulation support
9
(which is essentially dead, especially the parts involving floatx80)
10
PPC (only in the xsrqpxp instruction, which just rounds an input
11
value by converting to floatx80 and back, so will never generate
12
the default NaN)
13
14
The floatx80 default NaN as currently implemented is:
15
m68k: sign = 0, exp = 1...1, int = 1, frac = 1....1
16
i386: sign = 1, exp = 1...1, int = 1, frac = 10...0
17
18
These are the same as the parts64_default_nan for these architectures.
19
20
This is technically a possible behaviour change for arm linux-user
21
nwfpe emulation emulation, because the default NaN will now have the
22
sign bit clear. But we were already generating a different floatx80
23
default NaN from the real kernel emulation we are supposedly
24
following, which appears to use an all-bits-1 value:
25
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L267
26
27
This won't affect the only "real" use of the nwfpe emulation, which
28
is ancient binaries that used it as part of the old floating point
29
calling convention; that only uses loads and stores of 32 and 64 bit
30
floats, not any of the floatx80 behaviour the original hardware had.
31
We also get the nwfpe float64 default NaN value wrong:
32
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L166
33
so if we ever cared about this obscure corner the right fix would be
34
to correct that so nwfpe used its own default-NaN setting rather
35
than the Arm VFP one.
36
37
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
38
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
39
Message-id: 20241202131347.498124-29-peter.maydell@linaro.org
40
---
41
fpu/softfloat-specialize.c.inc | 20 ++++++++++----------
42
1 file changed, 10 insertions(+), 10 deletions(-)
43
44
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
45
index XXXXXXX..XXXXXXX 100644
46
--- a/fpu/softfloat-specialize.c.inc
47
+++ b/fpu/softfloat-specialize.c.inc
48
@@ -XXX,XX +XXX,XX @@ static void parts128_silence_nan(FloatParts128 *p, float_status *status)
49
floatx80 floatx80_default_nan(float_status *status)
50
{
51
floatx80 r;
52
+ /*
53
+ * Extrapolate from the choices made by parts64_default_nan to fill
54
+ * in the floatx80 format. We assume that floatx80's explicit
55
+ * integer bit is always set (this is true for i386 and m68k,
56
+ * which are the only real users of this format).
57
+ */
58
+ FloatParts64 p64;
59
+ parts64_default_nan(&p64, status);
60
61
- /* None of the targets that have snan_bit_is_one use floatx80. */
62
- assert(!snan_bit_is_one(status));
63
-#if defined(TARGET_M68K)
64
- r.low = UINT64_C(0xFFFFFFFFFFFFFFFF);
65
- r.high = 0x7FFF;
66
-#else
67
- /* X86 */
68
- r.low = UINT64_C(0xC000000000000000);
69
- r.high = 0xFFFF;
70
-#endif
71
+ r.high = 0x7FFF | (p64.sign << 15);
72
+ r.low = (1ULL << DECOMPOSED_BINARY_POINT) | p64.frac;
73
return r;
74
}
75
76
--
77
2.34.1
diff view generated by jsdifflib
New patch
1
In target/loongarch's helper_fclass_s() and helper_fclass_d() we pass
2
a zero-initialized float_status struct to float32_is_quiet_nan() and
3
float64_is_quiet_nan(), with the cryptic comment "for
4
snan_bit_is_one".
1
5
6
This pattern appears to have been copied from target/riscv, where it
7
is used because the functions there do not have ready access to the
8
CPU state struct. The comment presumably refers to the fact that the
9
main reason the is_quiet_nan() functions want the float_state is
10
because they want to know about the snan_bit_is_one config.
11
12
In the loongarch helpers, though, we have the CPU state struct
13
to hand. Use the usual env->fp_status here. This avoids our needing
14
to track that we need to update the initializer of the local
15
float_status structs when the core softfloat code adds new
16
options for targets to configure their behaviour.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20241202131347.498124-30-peter.maydell@linaro.org
21
---
22
target/loongarch/tcg/fpu_helper.c | 6 ++----
23
1 file changed, 2 insertions(+), 4 deletions(-)
24
25
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/loongarch/tcg/fpu_helper.c
28
+++ b/target/loongarch/tcg/fpu_helper.c
29
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
30
} else if (float32_is_zero_or_denormal(f)) {
31
return sign ? 1 << 4 : 1 << 8;
32
} else if (float32_is_any_nan(f)) {
33
- float_status s = { }; /* for snan_bit_is_one */
34
- return float32_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
35
+ return float32_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
36
} else {
37
return sign ? 1 << 3 : 1 << 7;
38
}
39
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
40
} else if (float64_is_zero_or_denormal(f)) {
41
return sign ? 1 << 4 : 1 << 8;
42
} else if (float64_is_any_nan(f)) {
43
- float_status s = { }; /* for snan_bit_is_one */
44
- return float64_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
45
+ return float64_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
46
} else {
47
return sign ? 1 << 3 : 1 << 7;
48
}
49
--
50
2.34.1
diff view generated by jsdifflib
New patch
1
In the frem helper, we have a local float_status because we want to
2
execute the floatx80_div() with a custom rounding mode. Instead of
3
zero-initializing the local float_status and then having to set it up
4
with the m68k standard behaviour (including the NaN propagation rule
5
and copying the rounding precision from env->fp_status), initialize
6
it as a complete copy of env->fp_status. This will avoid our having
7
to add new code in this function for every new config knob we add
8
to fp_status.
1
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-31-peter.maydell@linaro.org
13
---
14
target/m68k/fpu_helper.c | 6 ++----
15
1 file changed, 2 insertions(+), 4 deletions(-)
16
17
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/m68k/fpu_helper.c
20
+++ b/target/m68k/fpu_helper.c
21
@@ -XXX,XX +XXX,XX @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
22
23
fp_rem = floatx80_rem(val1->d, val0->d, &env->fp_status);
24
if (!floatx80_is_any_nan(fp_rem)) {
25
- float_status fp_status = { };
26
+ /* Use local temporary fp_status to set different rounding mode */
27
+ float_status fp_status = env->fp_status;
28
uint32_t quotient;
29
int sign;
30
31
/* Calculate quotient directly using round to nearest mode */
32
- set_float_2nan_prop_rule(float_2nan_prop_ab, &fp_status);
33
set_float_rounding_mode(float_round_nearest_even, &fp_status);
34
- set_floatx80_rounding_precision(
35
- get_floatx80_rounding_precision(&env->fp_status), &fp_status);
36
fp_quot.d = floatx80_div(val1->d, val0->d, &fp_status);
37
38
sign = extractFloatx80Sign(fp_quot.d);
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
In cf_fpu_gdb_get_reg() and cf_fpu_gdb_set_reg() we do the conversion
2
from float64 to floatx80 using a scratch float_status, because we
3
don't want the conversion to affect the CPU's floating point exception
4
status. Currently we use a zero-initialized float_status. This will
5
get steadily more awkward as we add config knobs to float_status
6
that the target must initialize. Avoid having to add any of that
7
configuration here by instead initializing our local float_status
8
from the env->fp_status.
1
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-32-peter.maydell@linaro.org
13
---
14
target/m68k/helper.c | 6 ++++--
15
1 file changed, 4 insertions(+), 2 deletions(-)
16
17
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/m68k/helper.c
20
+++ b/target/m68k/helper.c
21
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
22
CPUM68KState *env = &cpu->env;
23
24
if (n < 8) {
25
- float_status s = {};
26
+ /* Use scratch float_status so any exceptions don't change CPU state */
27
+ float_status s = env->fp_status;
28
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
29
}
30
switch (n) {
31
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
32
CPUM68KState *env = &cpu->env;
33
34
if (n < 8) {
35
- float_status s = {};
36
+ /* Use scratch float_status so any exceptions don't change CPU state */
37
+ float_status s = env->fp_status;
38
env->fregs[n].d = float64_to_floatx80(ldq_be_p(mem_buf), &s);
39
return 8;
40
}
41
--
42
2.34.1
diff view generated by jsdifflib
New patch
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.
1
7
8
To do this we need to pass the CPU env pointer in to the helper.
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-33-peter.maydell@linaro.org
13
---
14
target/sparc/helper.h | 4 ++--
15
target/sparc/fop_helper.c | 8 ++++----
16
target/sparc/translate.c | 4 ++--
17
3 files changed, 8 insertions(+), 8 deletions(-)
18
19
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/sparc/helper.h
22
+++ b/target/sparc/helper.h
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
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());
40
}
41
42
-uint32_t helper_flcmps(float32 src1, float32 src2)
43
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
44
{
45
/*
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();
56
}
57
58
-uint32_t helper_flcmpd(float64 src1, float64 src2)
59
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
60
{
61
- float_status discard = { };
62
+ float_status discard = env->fp_status;
63
FloatRelation r;
64
65
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
66
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/sparc/translate.c
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);
77
}
78
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
88
--
89
2.34.1
diff view generated by jsdifflib
New patch
1
In the helper_compute_fprf functions, we pass a dummy float_status
2
in to the is_signaling_nan() function. This is unnecessary, because
3
we have convenient access to the CPU env pointer here and that
4
is already set up with the correct values for the snan_bit_is_one
5
and no_signaling_nans config settings. is_signaling_nan() doesn't
6
ever update the fp_status with any exception flags, so there is
7
no reason not to use env->fp_status here.
1
8
9
Use env->fp_status instead of the dummy fp_status.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20241202131347.498124-34-peter.maydell@linaro.org
14
---
15
target/ppc/fpu_helper.c | 3 +--
16
1 file changed, 1 insertion(+), 2 deletions(-)
17
18
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/ppc/fpu_helper.c
21
+++ b/target/ppc/fpu_helper.c
22
@@ -XXX,XX +XXX,XX @@ void helper_compute_fprf_##tp(CPUPPCState *env, tp arg) \
23
} else if (tp##_is_infinity(arg)) { \
24
fprf = neg ? 0x09 << FPSCR_FPRF : 0x05 << FPSCR_FPRF; \
25
} else { \
26
- float_status dummy = { }; /* snan_bit_is_one = 0 */ \
27
- if (tp##_is_signaling_nan(arg, &dummy)) { \
28
+ if (tp##_is_signaling_nan(arg, &env->fp_status)) { \
29
fprf = 0x00 << FPSCR_FPRF; \
30
} else { \
31
fprf = 0x11 << FPSCR_FPRF; \
32
--
33
2.34.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This patch uses the defined fields to describe PWRON STRAPs for
3
Now that float_status has a bunch of fp parameters,
4
better readability.
4
it is easier to copy an existing structure than create
5
one from scratch. Begin by copying the structure that
6
corresponds to the FPSR and make only the adjustments
7
required for BFloat16 semantics.
5
8
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Patrick Venture <venture@google.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20220411165842.3912945-3-wuhaotsh@google.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20241203203949.483774-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
hw/arm/npcm7xx_boards.c | 24 +++++++++++++++++++-----
15
target/arm/tcg/vec_helper.c | 20 +++++++-------------
13
1 file changed, 19 insertions(+), 5 deletions(-)
16
1 file changed, 7 insertions(+), 13 deletions(-)
14
17
15
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
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/npcm7xx_boards.c
20
--- a/target/arm/tcg/vec_helper.c
18
+++ b/hw/arm/npcm7xx_boards.c
21
+++ b/target/arm/tcg/vec_helper.c
19
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
20
#include "sysemu/sysemu.h"
23
* no effect on AArch32 instructions.
21
#include "sysemu/block-backend.h"
24
*/
22
25
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
26
- *statusp = (float_status){
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
27
- .tininess_before_rounding = float_tininess_before_rounding,
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
28
- .float_rounding_mode = float_round_to_odd_inf,
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
29
- .flush_to_zero = true,
27
-#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
30
- .flush_inputs_to_zero = true,
28
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT ( \
31
- .default_nan_mode = true,
29
+ NPCM7XX_PWRON_STRAP_SPI0F18 | \
32
- };
30
+ NPCM7XX_PWRON_STRAP_SFAB | \
31
+ NPCM7XX_PWRON_STRAP_BSPA | \
32
+ NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) | \
33
+ NPCM7XX_PWRON_STRAP_SECEN | \
34
+ NPCM7XX_PWRON_STRAP_HIZ | \
35
+ NPCM7XX_PWRON_STRAP_ECC | \
36
+ NPCM7XX_PWRON_STRAP_RESERVE1 | \
37
+ NPCM7XX_PWRON_STRAP_J2EN | \
38
+ NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))
39
+
33
+
40
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
34
+ *statusp = env->vfp.fp_status;
41
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_J2EN)
35
+ set_default_nan_mode(true, statusp);
42
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
36
43
+#define QUANTA_GBS_POWER_ON_STRAPS ( \
37
if (ebf) {
44
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_SFAB)
38
- float_status *fpst = &env->vfp.fp_status;
45
+#define KUDO_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
39
- set_flush_to_zero(get_flush_to_zero(fpst), statusp);
46
+#define MORI_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
40
- set_flush_inputs_to_zero(get_flush_inputs_to_zero(fpst), statusp);
47
41
- set_float_rounding_mode(get_float_rounding_mode(fpst), statusp);
48
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
42
-
43
/* EBF=1 needs to do a step with round-to-odd semantics */
44
*oddstatusp = *statusp;
45
set_float_rounding_mode(float_round_to_odd, oddstatusp);
46
+ } else {
47
+ set_flush_to_zero(true, statusp);
48
+ set_flush_inputs_to_zero(true, statusp);
49
+ set_float_rounding_mode(float_round_to_odd_inf, statusp);
50
}
51
-
52
return ebf;
53
}
49
54
50
--
55
--
51
2.25.1
56
2.34.1
57
58
diff view generated by jsdifflib
1
The function exynos4210_combiner_get_gpioin() currently lives in
1
Currently we hardcode the default NaN value in parts64_default_nan()
2
exynos4210_combiner.c, but it isn't really part of the combiner
2
using a compile-time ifdef ladder. This is awkward for two cases:
3
device itself -- it is a function that implements the wiring up of
3
* for single-QEMU-binary we can't hard-code target-specifics like this
4
some interrupt sources to multiple combiner inputs. Move it to live
4
* for Arm FEAT_AFP the default NaN value depends on FPCR.AH
5
with the other SoC-level code in exynos4210.c, along with a few
5
(specifically the sign bit is different)
6
macros previously defined in exynos4210.h which are now used only
6
7
in exynos4210.c.
7
Add a field to float_status to specify the default NaN value; fall
8
back to the old ifdef behaviour if these are not set.
9
10
The default NaN value is specified by setting a uint8_t to a
11
pattern corresponding to the sign and upper fraction parts of
12
the NaN; the lower bits of the fraction are set from bit 0 of
13
the pattern.
8
14
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-11-peter.maydell@linaro.org
17
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
12
---
18
---
13
include/hw/arm/exynos4210.h | 11 -----
19
include/fpu/softfloat-helpers.h | 11 +++++++
14
hw/arm/exynos4210.c | 82 +++++++++++++++++++++++++++++++++++
20
include/fpu/softfloat-types.h | 10 ++++++
15
hw/intc/exynos4210_combiner.c | 77 --------------------------------
21
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
16
3 files changed, 82 insertions(+), 88 deletions(-)
22
3 files changed, 54 insertions(+), 22 deletions(-)
17
23
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
24
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
19
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
26
--- a/include/fpu/softfloat-helpers.h
21
+++ b/include/hw/arm/exynos4210.h
27
+++ b/include/fpu/softfloat-helpers.h
22
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
23
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
29
status->float_infzeronan_rule = rule;
24
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
25
26
-#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
27
-#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
28
-#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
29
- ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
30
-
31
/* IRQs number for external and internal GIC */
32
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
33
#define EXYNOS4210_INT_GIC_NIRQ 64
34
@@ -XXX,XX +XXX,XX @@ void exynos4210_write_secondary(ARMCPU *cpu,
35
* bit - bit number inside group */
36
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
37
38
-/*
39
- * Get Combiner input GPIO into irqs structure
40
- */
41
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
42
- int ext);
43
-
44
/*
45
* exynos4210 UART
46
*/
47
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/exynos4210.c
50
+++ b/hw/arm/exynos4210.c
51
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
52
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
53
};
54
55
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
56
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
57
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
58
+ ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
59
+
60
/*
61
* Initialize board IRQs.
62
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
63
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
64
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
65
}
30
}
66
31
67
+/*
32
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
68
+ * Get Combiner input GPIO into irqs structure
33
+ float_status *status)
69
+ */
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
71
+ DeviceState *dev, int ext)
72
+{
34
+{
73
+ int n;
35
+ status->default_nan_pattern = dnan_pattern;
74
+ int bit;
75
+ int max;
76
+ qemu_irq *irq;
77
+
78
+ max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
79
+ EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
80
+ irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
81
+
82
+ /*
83
+ * Some IRQs of Int/External Combiner are going to two Combiners groups,
84
+ * so let split them.
85
+ */
86
+ for (n = 0; n < max; n++) {
87
+
88
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
89
+
90
+ switch (n) {
91
+ /* MDNIE_LCD1 INTG1 */
92
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
93
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
94
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
95
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
96
+ continue;
97
+
98
+ /* TMU INTG3 */
99
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
100
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
101
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
102
+ continue;
103
+
104
+ /* LCD1 INTG12 */
105
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
106
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
107
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
108
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
109
+ continue;
110
+
111
+ /* Multi-Core Timer INTG12 */
112
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
113
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
114
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
115
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
116
+ continue;
117
+
118
+ /* Multi-Core Timer INTG35 */
119
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
120
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
121
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
122
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
123
+ continue;
124
+
125
+ /* Multi-Core Timer INTG51 */
126
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
127
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
128
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
129
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
130
+ continue;
131
+
132
+ /* Multi-Core Timer INTG53 */
133
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
134
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
135
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
136
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
137
+ continue;
138
+ }
139
+
140
+ irq[n] = qdev_get_gpio_in(dev, n);
141
+ }
142
+}
36
+}
143
+
37
+
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
38
static inline void set_flush_to_zero(bool val, float_status *status)
145
0x09, 0x00, 0x00, 0x00 };
39
{
146
40
status->flush_to_zero = val;
147
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
41
@@ -XXX,XX +XXX,XX @@ static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status
42
return status->float_infzeronan_rule;
43
}
44
45
+static inline uint8_t get_float_default_nan_pattern(float_status *status)
46
+{
47
+ return status->default_nan_pattern;
48
+}
49
+
50
static inline bool get_flush_to_zero(float_status *status)
51
{
52
return status->flush_to_zero;
53
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
148
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
149
--- a/hw/intc/exynos4210_combiner.c
55
--- a/include/fpu/softfloat-types.h
150
+++ b/hw/intc/exynos4210_combiner.c
56
+++ b/include/fpu/softfloat-types.h
151
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_exynos4210_combiner = {
57
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
152
}
58
/* should denormalised inputs go to zero and set the input_denormal flag? */
153
};
59
bool flush_inputs_to_zero;
154
60
bool default_nan_mode;
155
-/*
61
+ /*
156
- * Get Combiner input GPIO into irqs structure
62
+ * The pattern to use for the default NaN. Here the high bit specifies
157
- */
63
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
158
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
64
+ * fractional part. The low bits of the fractional part are copies of bit 0.
159
- int ext)
65
+ * The exponent of the default NaN is (as for any NaN) always all 1s.
160
-{
66
+ * Note that a value of 0 here is not a valid NaN. The target must set
161
- int n;
67
+ * this to the correct non-zero value, or we will assert when trying to
162
- int bit;
68
+ * create a default NaN.
163
- int max;
69
+ */
164
- qemu_irq *irq;
70
+ uint8_t default_nan_pattern;
165
-
71
/*
166
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
72
* The flags below are not used on all specializations and may
167
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
73
* constant fold away (see snan_bit_is_one()/no_signalling_nans() in
168
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
74
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
169
-
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
170
- /*
109
- /*
171
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
110
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
172
- * so let split them.
111
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
112
- * do not have floating-point.
173
- */
113
- */
174
- for (n = 0; n < max; n++) {
114
- if (snan_bit_is_one(status)) {
175
-
115
- /* set all bits other than msb */
176
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
116
- frac = (1ULL << (DECOMPOSED_BINARY_POINT - 1)) - 1;
177
-
117
- } else {
178
- switch (n) {
118
- /* set msb */
179
- /* MDNIE_LCD1 INTG1 */
119
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
180
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
181
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
182
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
183
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
184
- continue;
185
-
186
- /* TMU INTG3 */
187
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
188
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
189
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
190
- continue;
191
-
192
- /* LCD1 INTG12 */
193
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
194
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
195
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
196
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
197
- continue;
198
-
199
- /* Multi-Core Timer INTG12 */
200
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
201
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
202
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
203
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
204
- continue;
205
-
206
- /* Multi-Core Timer INTG35 */
207
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
208
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
209
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
210
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
211
- continue;
212
-
213
- /* Multi-Core Timer INTG51 */
214
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
215
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
216
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
217
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
218
- continue;
219
-
220
- /* Multi-Core Timer INTG53 */
221
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
222
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
223
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
224
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
225
- continue;
226
- }
227
-
228
- irq[n] = qdev_get_gpio_in(dev, n);
229
- }
120
- }
230
-}
121
+ /*
231
-
122
+ * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
232
static uint64_t
123
+ * S390, SH4, TriCore, and Xtensa. Our other supported targets
233
exynos4210_combiner_read(void *opaque, hwaddr offset, unsigned size)
124
+ * do not have floating-point.
234
{
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);
136
+
137
+ sign = dnan_pattern >> 7;
138
+ /*
139
+ * Place default_nan_pattern [6:0] into bits [62:56],
140
+ * and replecate bit [0] down into [55:0]
141
+ */
142
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
143
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
144
145
*p = (FloatParts64) {
146
.cls = float_class_qnan,
235
--
147
--
236
2.25.1
148
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the tests/fp code.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-36-peter.maydell@linaro.org
6
---
7
tests/fp/fp-bench.c | 1 +
8
tests/fp/fp-test-log2.c | 1 +
9
tests/fp/fp-test.c | 1 +
10
3 files changed, 3 insertions(+)
11
12
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/fp/fp-bench.c
15
+++ b/tests/fp/fp-bench.c
16
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
17
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
18
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
19
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
20
+ set_float_default_nan_pattern(0b01000000, &soft_status);
21
22
f = bench_funcs[operation][precision];
23
g_assert(f);
24
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/tests/fp/fp-test-log2.c
27
+++ b/tests/fp/fp-test-log2.c
28
@@ -XXX,XX +XXX,XX @@ int main(int ac, char **av)
29
int i;
30
31
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
32
+ set_float_default_nan_pattern(0b01000000, &qsf);
33
set_float_rounding_mode(float_round_nearest_even, &qsf);
34
35
test.d = 0.0;
36
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/fp/fp-test.c
39
+++ b/tests/fp/fp-test.c
40
@@ -XXX,XX +XXX,XX @@ void run_test(void)
41
*/
42
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
43
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
44
+ set_float_default_nan_pattern(0b01000000, &qsf);
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
46
47
genCases_setLevel(test_level);
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-37-peter.maydell@linaro.org
7
---
8
target/microblaze/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/microblaze/cpu.c
15
+++ b/target/microblaze/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_reset_hold(Object *obj, ResetType type)
17
* this architecture.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
23
#if defined(CONFIG_USER_ONLY)
24
/* start in user mode with interrupts enabled. */
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
34
- || defined(TARGET_MICROBLAZE)
35
+#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
/* Sign bit set, most significant frac bit set */
37
dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-38-peter.maydell@linaro.org
7
---
8
target/i386/tcg/fpu_helper.c | 4 ++++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 4 insertions(+), 3 deletions(-)
11
12
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/i386/tcg/fpu_helper.c
15
+++ b/target/i386/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
17
*/
18
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
19
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
+ set_float_default_nan_pattern(0b11000000, &env->mmx_status);
23
+ set_float_default_nan_pattern(0b11000000, &env->sse_status);
24
}
25
26
static inline uint8_t save_exception_flags(CPUX86State *env)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
index XXXXXXX..XXXXXXX 100644
29
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
32
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
/* Sign bit clear, all frac bits set */
34
dnan_pattern = 0b01111111;
35
-#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
- /* Sign bit set, most significant frac bit set */
37
- dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
/* Sign bit clear, msb-1 frac bit set */
40
dnan_pattern = 0b00100000;
41
--
42
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-39-peter.maydell@linaro.org
7
---
8
target/hppa/fpu_helper.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 2 insertions(+), 3 deletions(-)
11
12
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/hppa/fpu_helper.c
15
+++ b/target/hppa/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
17
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
18
/* For inf * 0 + NaN, return the input NaN */
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ /* Default NaN: sign bit clear, msb-1 frac bit set */
21
+ set_float_default_nan_pattern(0b00100000, &env->fp_status);
22
}
23
24
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_HPPA)
34
- /* Sign bit clear, msb-1 frac bit set */
35
- dnan_pattern = 0b00100000;
36
#elif defined(TARGET_HEXAGON)
37
/* Sign bit set, all frac bits set. */
38
dnan_pattern = 0b11111111;
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the alpha target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-40-peter.maydell@linaro.org
6
---
7
target/alpha/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/alpha/cpu.c
13
+++ b/target/alpha/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_initfn(Object *obj)
15
* operand in Fa. That is float_2nan_prop_ba.
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
18
+ /* Default NaN: sign bit clear, msb frac bit set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
#if defined(CONFIG_USER_ONLY)
21
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
22
cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the arm target.
2
This includes setting it for the old linux-user nwfpe emulation.
3
For nwfpe, our default doesn't match the real kernel, but we
4
avoid making a behaviour change in this commit.
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-41-peter.maydell@linaro.org
9
---
10
linux-user/arm/nwfpe/fpa11.c | 5 +++++
11
target/arm/cpu.c | 2 ++
12
2 files changed, 7 insertions(+)
13
14
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/arm/nwfpe/fpa11.c
17
+++ b/linux-user/arm/nwfpe/fpa11.c
18
@@ -XXX,XX +XXX,XX @@ void resetFPA11(void)
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
}
28
29
void SetRoundingMode(const unsigned int opcode)
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)
41
{
42
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
44
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
46
+ set_float_default_nan_pattern(0b01000000, s);
47
}
48
49
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
50
--
51
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for loongarch.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-42-peter.maydell@linaro.org
6
---
7
target/loongarch/tcg/fpu_helper.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/loongarch/tcg/fpu_helper.c
13
+++ b/target/loongarch/tcg/fpu_helper.c
14
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
15
*/
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
17
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
18
+ /* Default NaN: sign bit clear, msb frac bit set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
}
21
22
int ieee_ex_to_loongarch(int xcpt)
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for m68k.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-43-peter.maydell@linaro.org
6
---
7
target/m68k/cpu.c | 2 ++
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 3 insertions(+), 1 deletion(-)
10
11
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/m68k/cpu.c
14
+++ b/target/m68k/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
16
* preceding paragraph for nonsignaling NaNs.
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
+ /* Default NaN: sign bit clear, all frac bits set */
20
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
21
22
nan = floatx80_default_nan(&env->fp_status);
23
for (i = 0; i < 8; i++) {
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
29
uint8_t dnan_pattern = status->default_nan_pattern;
30
31
if (dnan_pattern == 0) {
32
-#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
+#if defined(TARGET_SPARC)
34
/* Sign bit clear, all frac bits set */
35
dnan_pattern = 0b01111111;
36
#elif defined(TARGET_HEXAGON)
37
--
38
2.34.1
diff view generated by jsdifflib
1
The exynos4210 code currently has two very similar arrays of IRQs:
1
Set the default NaN pattern explicitly for MIPS. Note that this
2
2
is our only target which currently changes the default NaN
3
* board_irqs is a field of the Exynos4210Irq struct which is filled
3
at runtime (which it was previously doing indirectly when it
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
4
changed the snan_bit_is_one setting).
5
for each IRQ the board/SoC can assert
6
* irq_table is a set of qemu_irqs pointed to from the
7
Exynos4210State struct. It's allocated in exynos4210_init_irq,
8
and the only behaviour these irqs have is that they pass on the
9
level to the equivalent board_irqs[] irq
10
11
The extra indirection through irq_table is unnecessary, so coalesce
12
these into a single irq_table[] array as a direct field in
13
Exynos4210State which exynos4210_init_board_irqs() fills in.
14
5
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20220404154658.565020-6-peter.maydell@linaro.org
8
Message-id: 20241202131347.498124-44-peter.maydell@linaro.org
18
---
9
---
19
include/hw/arm/exynos4210.h | 8 ++------
10
target/mips/fpu_helper.h | 7 +++++++
20
hw/arm/exynos4210.c | 6 +-----
11
target/mips/msa.c | 3 +++
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
12
2 files changed, 10 insertions(+)
22
3 files changed, 11 insertions(+), 35 deletions(-)
23
13
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
14
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/arm/exynos4210.h
16
--- a/target/mips/fpu_helper.h
27
+++ b/include/hw/arm/exynos4210.h
17
+++ b/target/mips/fpu_helper.h
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
18
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
19
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
20
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
21
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
22
+ /*
33
} Exynos4210Irq;
23
+ * With nan2008, the default NaN value has the sign bit clear and the
34
24
+ * frac msb set; with the older mode, the sign bit is clear, and all
35
struct Exynos4210State {
25
+ * frac bits except the msb are set.
36
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
26
+ */
37
/*< public >*/
27
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
28
+ &env->active_fpu.fp_status);
39
Exynos4210Irq irqs;
29
40
- qemu_irq *irq_table;
30
}
41
+ qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
31
42
32
diff --git a/target/mips/msa.c b/target/mips/msa.c
43
MemoryRegion chipid_mem;
44
MemoryRegion iram_mem;
45
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
46
void exynos4210_write_secondary(ARMCPU *cpu,
47
const struct arm_boot_info *info);
48
49
-/* Initialize exynos4210 IRQ subsystem stub */
50
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
51
-
52
/* Initialize board IRQs.
53
* These IRQs contain splitted Int/External Combiner and External Gic IRQs */
54
-void exynos4210_init_board_irqs(Exynos4210Irq *s);
55
+void exynos4210_init_board_irqs(Exynos4210State *s);
56
57
/* Get IRQ number from exynos4210 IRQ subsystem stub.
58
* To identify IRQ source use internal combiner group and bit number
59
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
60
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/exynos4210.c
34
--- a/target/mips/msa.c
62
+++ b/hw/arm/exynos4210.c
35
+++ b/target/mips/msa.c
63
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
36
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
64
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
37
/* Inf * 0 + NaN returns the input NaN */
65
}
38
set_float_infzeronan_rule(float_infzeronan_dnan_never,
66
39
&env->active_tc.msa_fp_status);
67
- /*** IRQs ***/
40
+ /* Default NaN: sign bit clear, frac msb set */
68
-
41
+ set_float_default_nan_pattern(0b01000000,
69
- s->irq_table = exynos4210_init_irq(&s->irqs);
42
+ &env->active_tc.msa_fp_status);
70
-
71
/* IRQ Gate */
72
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
73
DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
74
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
75
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
76
77
/* Initialize board IRQs. */
78
- exynos4210_init_board_irqs(&s->irqs);
79
+ exynos4210_init_board_irqs(s);
80
81
/*** Memory ***/
82
83
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/intc/exynos4210_gic.c
86
+++ b/hw/intc/exynos4210_gic.c
87
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
88
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
89
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
90
91
-static void exynos4210_irq_handler(void *opaque, int irq, int level)
92
-{
93
- Exynos4210Irq *s = (Exynos4210Irq *)opaque;
94
-
95
- /* Bypass */
96
- qemu_set_irq(s->board_irqs[irq], level);
97
-}
98
-
99
-/*
100
- * Initialize exynos4210 IRQ subsystem stub.
101
- */
102
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *s)
103
-{
104
- return qemu_allocate_irqs(exynos4210_irq_handler, s,
105
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ);
106
-}
107
-
108
/*
109
* Initialize board IRQs.
110
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
111
*/
112
-void exynos4210_init_board_irqs(Exynos4210Irq *s)
113
+void exynos4210_init_board_irqs(Exynos4210State *s)
114
{
115
uint32_t grp, bit, irq_id, n;
116
+ Exynos4210Irq *is = &s->irqs;
117
118
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
119
irq_id = 0;
120
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
121
irq_id = EXT_GIC_ID_MCT_G1;
122
}
123
if (irq_id) {
124
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
125
- s->ext_gic_irq[irq_id-32]);
126
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
127
+ is->ext_gic_irq[irq_id - 32]);
128
} else {
129
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
130
- s->ext_combiner_irq[n]);
131
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
132
+ is->ext_combiner_irq[n]);
133
}
134
}
135
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
136
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
137
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
138
139
if (irq_id) {
140
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
141
- s->ext_gic_irq[irq_id-32]);
142
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
143
+ is->ext_gic_irq[irq_id - 32]);
144
}
145
}
146
}
43
}
147
--
44
--
148
2.25.1
45
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for openrisc.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-45-peter.maydell@linaro.org
6
---
7
target/openrisc/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/openrisc/cpu.c
13
+++ b/target/openrisc/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
15
*/
16
set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
17
18
+ /* Default NaN: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
20
21
#ifndef CONFIG_USER_ONLY
22
cpu->env.picmr = 0x00000000;
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for ppc.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-46-peter.maydell@linaro.org
6
---
7
target/ppc/cpu_init.c | 4 ++++
8
1 file changed, 4 insertions(+)
9
10
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/ppc/cpu_init.c
13
+++ b/target/ppc/cpu_init.c
14
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
15
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
17
18
+ /* Default NaN: sign bit clear, set frac msb */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
+ set_float_default_nan_pattern(0b01000000, &env->vec_status);
21
+
22
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
23
ppc_spr_t *spr = &env->spr_cb[i];
24
25
--
26
2.34.1
diff view generated by jsdifflib
1
Switch the creation of the combiner devices to the new-style
1
Set the default NaN pattern explicitly for sh4. Note that sh4
2
"embedded in state struct" approach, so we can easily refer
2
is one of the only three targets (the others being HPPA and
3
to the object elsewhere during realize.
3
sometimes MIPS) that has snan_bit_is_one set.
4
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-18-peter.maydell@linaro.org
7
Message-id: 20241202131347.498124-47-peter.maydell@linaro.org
8
---
8
---
9
include/hw/arm/exynos4210.h | 3 ++
9
target/sh4/cpu.c | 2 ++
10
include/hw/intc/exynos4210_combiner.h | 57 +++++++++++++++++++++++++++
10
1 file changed, 2 insertions(+)
11
hw/arm/exynos4210.c | 20 +++++-----
12
hw/intc/exynos4210_combiner.c | 31 +--------------
13
4 files changed, 72 insertions(+), 39 deletions(-)
14
create mode 100644 include/hw/intc/exynos4210_combiner.h
15
11
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/exynos4210.h
14
--- a/target/sh4/cpu.c
19
+++ b/include/hw/arm/exynos4210.h
15
+++ b/target/sh4/cpu.c
20
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_reset_hold(Object *obj, ResetType type)
21
#include "hw/sysbus.h"
17
set_flush_to_zero(1, &env->fp_status);
22
#include "hw/cpu/a9mpcore.h"
18
#endif
23
#include "hw/intc/exynos4210_gic.h"
19
set_default_nan_mode(1, &env->fp_status);
24
+#include "hw/intc/exynos4210_combiner.h"
20
+ /* sign bit clear, set all frac bits other than msb */
25
#include "hw/core/split-irq.h"
21
+ set_float_default_nan_pattern(0b00111111, &env->fp_status);
26
#include "target/arm/cpu-qom.h"
27
#include "qom/object.h"
28
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
29
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
30
A9MPPrivState a9mpcore;
31
Exynos4210GicState ext_gic;
32
+ Exynos4210CombinerState int_combiner;
33
+ Exynos4210CombinerState ext_combiner;
34
SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
35
};
36
37
diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_combiner.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Samsung exynos4210 Interrupt Combiner
45
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
59
+ * See the GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+
65
+#ifndef HW_INTC_EXYNOS4210_COMBINER
66
+#define HW_INTC_EXYNOS4210_COMBINER
67
+
68
+#include "hw/sysbus.h"
69
+
70
+/*
71
+ * State for each output signal of internal combiner
72
+ */
73
+typedef struct CombinerGroupState {
74
+ uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
75
+ uint8_t src_pending; /* Pending source interrupts before masking */
76
+} CombinerGroupState;
77
+
78
+#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
79
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
80
+
81
+/* Number of groups and total number of interrupts for the internal combiner */
82
+#define IIC_NGRP 64
83
+#define IIC_NIRQ (IIC_NGRP * 8)
84
+#define IIC_REGSET_SIZE 0x41
85
+
86
+struct Exynos4210CombinerState {
87
+ SysBusDevice parent_obj;
88
+
89
+ MemoryRegion iomem;
90
+
91
+ struct CombinerGroupState group[IIC_NGRP];
92
+ uint32_t reg_set[IIC_REGSET_SIZE];
93
+ uint32_t icipsr[2];
94
+ uint32_t external; /* 1 means that this combiner is external */
95
+
96
+ qemu_irq output_irq[IIC_NGRP];
97
+};
98
+
99
+#endif
100
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/arm/exynos4210.c
103
+++ b/hw/arm/exynos4210.c
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
}
106
107
/* Internal Interrupt Combiner */
108
- dev = qdev_new("exynos4210.combiner");
109
- busdev = SYS_BUS_DEVICE(dev);
110
- sysbus_realize_and_unref(busdev, &error_fatal);
111
+ busdev = SYS_BUS_DEVICE(&s->int_combiner);
112
+ sysbus_realize(busdev, &error_fatal);
113
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
114
sysbus_connect_irq(busdev, n,
115
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
116
}
117
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
118
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
119
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
120
121
/* External Interrupt Combiner */
122
- dev = qdev_new("exynos4210.combiner");
123
- qdev_prop_set_uint32(dev, "external", 1);
124
- busdev = SYS_BUS_DEVICE(dev);
125
- sysbus_realize_and_unref(busdev, &error_fatal);
126
+ qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
127
+ busdev = SYS_BUS_DEVICE(&s->ext_combiner);
128
+ sysbus_realize(busdev, &error_fatal);
129
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
130
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
131
}
132
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
133
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
134
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
135
136
/* Initialize board IRQs. */
137
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
138
139
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
140
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
141
+ object_initialize_child(obj, "int-combiner", &s->int_combiner,
142
+ TYPE_EXYNOS4210_COMBINER);
143
+ object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
144
+ TYPE_EXYNOS4210_COMBINER);
145
}
22
}
146
23
147
static void exynos4210_class_init(ObjectClass *klass, void *data)
24
static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
148
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/hw/intc/exynos4210_combiner.c
151
+++ b/hw/intc/exynos4210_combiner.c
152
@@ -XXX,XX +XXX,XX @@
153
#include "hw/sysbus.h"
154
#include "migration/vmstate.h"
155
#include "qemu/module.h"
156
-
157
+#include "hw/intc/exynos4210_combiner.h"
158
#include "hw/arm/exynos4210.h"
159
#include "hw/hw.h"
160
#include "hw/irq.h"
161
@@ -XXX,XX +XXX,XX @@
162
#define DPRINTF(fmt, ...) do {} while (0)
163
#endif
164
165
-#define IIC_NGRP 64 /* Internal Interrupt Combiner
166
- Groups number */
167
-#define IIC_NIRQ (IIC_NGRP * 8)/* Internal Interrupt Combiner
168
- Interrupts number */
169
#define IIC_REGION_SIZE 0x108 /* Size of memory mapped region */
170
-#define IIC_REGSET_SIZE 0x41
171
-
172
-/*
173
- * State for each output signal of internal combiner
174
- */
175
-typedef struct CombinerGroupState {
176
- uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
177
- uint8_t src_pending; /* Pending source interrupts before masking */
178
-} CombinerGroupState;
179
-
180
-#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
181
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
182
-
183
-struct Exynos4210CombinerState {
184
- SysBusDevice parent_obj;
185
-
186
- MemoryRegion iomem;
187
-
188
- struct CombinerGroupState group[IIC_NGRP];
189
- uint32_t reg_set[IIC_REGSET_SIZE];
190
- uint32_t icipsr[2];
191
- uint32_t external; /* 1 means that this combiner is external */
192
-
193
- qemu_irq output_irq[IIC_NGRP];
194
-};
195
196
static const VMStateDescription vmstate_exynos4210_combiner_group_state = {
197
.name = "exynos4210.combiner.groupstate",
198
--
25
--
199
2.25.1
26
2.34.1
diff view generated by jsdifflib
1
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
1
Set the default NaN pattern explicitly for rx.
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
3
connect multiple IRQs up to the same external GIC input, which
4
is not permitted. We do the same thing in the code in
5
exynos4210_init_board_irqs() because the conditionals selecting
6
an irq_id in the first loop match multiple interrupt IDs.
7
8
Overall we do this for interrupt IDs
9
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
10
and
11
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
12
13
These correspond to the cases for the multi-core timer that we are
14
wiring up to multiple inputs on the combiner in
15
exynos4210_combiner_get_gpioin(). That code already deals with all
16
these interrupt IDs being the same input source, so we don't need to
17
connect the external GIC interrupt for any of them except the first
18
(1, 4) and (1, 5). Remove the array entries and conditionals which
19
were incorrectly causing us to wire up extra lines.
20
21
This bug didn't cause any visible effects, because we only connect
22
up a device to the "primary" ID values (1, 4) and (1, 5), so the
23
extra lines would never be set to a level.
24
2
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-48-peter.maydell@linaro.org
28
---
6
---
29
include/hw/arm/exynos4210.h | 2 +-
7
target/rx/cpu.c | 2 ++
30
hw/arm/exynos4210.c | 12 +++++-------
8
1 file changed, 2 insertions(+)
31
2 files changed, 6 insertions(+), 8 deletions(-)
32
9
33
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
10
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
34
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
35
--- a/include/hw/arm/exynos4210.h
12
--- a/target/rx/cpu.c
36
+++ b/include/hw/arm/exynos4210.h
13
+++ b/target/rx/cpu.c
37
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_reset_hold(Object *obj, ResetType type)
38
* one for every non-zero entry in combiner_grp_to_gic_id[].
15
* then prefer dest over source", which is float_2nan_prop_s_ab.
39
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
16
*/
40
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
41
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
18
+ /* Default NaN value: sign bit clear, set frac msb */
42
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
43
20
}
44
typedef struct Exynos4210Irq {
21
45
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
22
static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/exynos4210.c
49
+++ b/hw/arm/exynos4210.c
50
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
51
/* int combiner group 34 */
52
{ EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
53
/* int combiner group 35 */
54
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
55
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
56
/* int combiner group 36 */
57
{ EXT_GIC_ID_MIXER },
58
/* int combiner group 37 */
59
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
60
/* groups 38-50 */
61
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
62
/* int combiner group 51 */
63
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
64
+ { EXT_GIC_ID_MCT_L0 },
65
/* group 52 */
66
{ },
67
/* int combiner group 53 */
68
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
69
+ { EXT_GIC_ID_WDT },
70
/* groups 54-63 */
71
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
72
};
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
74
75
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
76
irq_id = 0;
77
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
78
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
79
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
80
/* MCT_G0 is passed to External GIC */
81
irq_id = EXT_GIC_ID_MCT_G0;
82
}
83
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
84
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
85
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
86
/* MCT_G1 is passed to External and GIC */
87
irq_id = EXT_GIC_ID_MCT_G1;
88
}
89
--
23
--
90
2.25.1
24
2.34.1
diff view generated by jsdifflib
1
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
1
Set the default NaN pattern explicitly for s390x.
2
are in a range that applies to the internal combiner only creates a
3
splitter for those interrupts which go to both the internal combiner
4
and to the external GIC, but it does nothing at all for the
5
interrupts which don't go to the external GIC, leaving the
6
irq_table[] array element empty for those. (This will result in
7
those interrupts simply being lost, not in a QEMU crash.)
8
9
I don't have a reliable datasheet for this SoC, but since we do wire
10
up one interrupt line in this category (the HDMI I2C device on
11
interrupt 16,1), this seems like it must be a bug in the existing
12
QEMU code. Fill in the irq_table[] entries where we're not splitting
13
the IRQ to both the internal combiner and the external GIC with the
14
IRQ line of the internal combiner. (That is, these IRQ lines go to
15
just one device, not multiple.)
16
17
This bug didn't have any visible guest effects because the only
18
implemented device that was affected was the HDMI I2C controller,
19
and we never connect any I2C devices to that bus.
20
2
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-49-peter.maydell@linaro.org
24
---
6
---
25
hw/arm/exynos4210.c | 2 ++
7
target/s390x/cpu.c | 2 ++
26
1 file changed, 2 insertions(+)
8
1 file changed, 2 insertions(+)
27
9
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
10
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
29
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/exynos4210.c
12
--- a/target/s390x/cpu.c
31
+++ b/hw/arm/exynos4210.c
13
+++ b/target/s390x/cpu.c
32
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
14
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
15
set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
34
qdev_connect_gpio_out(splitter, 1,
16
set_float_infzeronan_rule(float_infzeronan_dnan_always,
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
17
&env->fpu_status);
36
+ } else {
18
+ /* Default NaN value: sign bit clear, frac msb set */
37
+ s->irq_table[n] = is->int_combiner_irq[n];
19
+ set_float_default_nan_pattern(0b01000000, &env->fpu_status);
38
}
20
/* fall through */
39
}
21
case RESET_TYPE_S390_CPU_NORMAL:
40
/*
22
env->psw.mask &= ~PSW_MASK_RI;
41
--
23
--
42
2.25.1
24
2.34.1
diff view generated by jsdifflib
1
Delete a couple of #defines which are never used.
1
Set the default NaN pattern explicitly for SPARC, and remove
2
the ifdef from parts64_default_nan.
2
3
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220404154658.565020-12-peter.maydell@linaro.org
6
Message-id: 20241202131347.498124-50-peter.maydell@linaro.org
6
---
7
---
7
include/hw/arm/exynos4210.h | 4 ----
8
target/sparc/cpu.c | 2 ++
8
1 file changed, 4 deletions(-)
9
fpu/softfloat-specialize.c.inc | 5 +----
10
2 files changed, 3 insertions(+), 4 deletions(-)
9
11
10
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
11
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
12
--- a/include/hw/arm/exynos4210.h
14
--- a/target/sparc/cpu.c
13
+++ b/include/hw/arm/exynos4210.h
15
+++ b/target/sparc/cpu.c
14
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
15
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
17
set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
16
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
18
/* For inf * 0 + NaN, return the input NaN */
17
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
18
-/* IRQs number for external and internal GIC */
20
+ /* Default NaN value: sign bit clear, all frac bits set */
19
-#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
21
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
20
-#define EXYNOS4210_INT_GIC_NIRQ 64
22
21
-
23
cpu_exec_realizefn(cs, &local_err);
22
#define EXYNOS4210_I2C_NUMBER 9
24
if (local_err != NULL) {
23
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
24
#define EXYNOS4210_NUM_DMA 3
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
25
--
41
--
26
2.25.1
42
2.34.1
diff view generated by jsdifflib
1
The exynos4210 SoC mostly creates its child devices as if it were
1
Set the default NaN pattern explicitly for xtensa.
2
board code. This includes the a9mpcore object. Switch that to a
3
new-style "embedded in the state struct" creation, because in the
4
next commit we're going to want to refer to the object again further
5
down in the exynos4210_realize() function.
6
2
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220404154658.565020-4-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-51-peter.maydell@linaro.org
10
---
6
---
11
include/hw/arm/exynos4210.h | 2 ++
7
target/xtensa/cpu.c | 2 ++
12
hw/arm/exynos4210.c | 11 ++++++-----
8
1 file changed, 2 insertions(+)
13
2 files changed, 8 insertions(+), 5 deletions(-)
14
9
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
10
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/exynos4210.h
12
--- a/target/xtensa/cpu.c
18
+++ b/include/hw/arm/exynos4210.h
13
+++ b/target/xtensa/cpu.c
19
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
20
15
/* For inf * 0 + NaN, return the input NaN */
21
#include "hw/or-irq.h"
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
#include "hw/sysbus.h"
17
set_no_signaling_nans(!dfpu, &env->fp_status);
23
+#include "hw/cpu/a9mpcore.h"
18
+ /* Default NaN value: sign bit clear, set frac msb */
24
#include "target/arm/cpu-qom.h"
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
25
#include "qom/object.h"
20
xtensa_use_first_nan(env, !dfpu);
26
27
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
28
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
29
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
30
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
31
+ A9MPPrivState a9mpcore;
32
};
33
34
#define TYPE_EXYNOS4210_SOC "exynos4210"
35
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/arm/exynos4210.c
38
+++ b/hw/arm/exynos4210.c
39
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
40
}
41
42
/* Private memory region and Internal GIC */
43
- dev = qdev_new(TYPE_A9MPCORE_PRIV);
44
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
45
- busdev = SYS_BUS_DEVICE(dev);
46
- sysbus_realize_and_unref(busdev, &error_fatal);
47
+ qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
48
+ busdev = SYS_BUS_DEVICE(&s->a9mpcore);
49
+ sysbus_realize(busdev, &error_fatal);
50
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
51
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
52
sysbus_connect_irq(busdev, n,
53
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
54
}
55
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
56
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
57
+ s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
58
}
59
60
/* Cache controller */
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
62
g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
63
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
64
}
65
+
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
67
}
21
}
68
22
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
70
--
23
--
71
2.25.1
24
2.34.1
diff view generated by jsdifflib
1
The only time we use the int_gic_irq[] array in the Exynos4210Irq
1
Set the default NaN pattern explicitly for hexagon.
2
struct is in the exynos4210_realize() function: we initialize it with
2
Remove the ifdef from parts64_default_nan(); the only
3
the GPIO inputs of the a9mpcore device, and then a bit later on we
3
remaining unconverted targets all use the default case.
4
connect those to the outputs of the internal combiner. Now that the
5
a9mpcore object is easily accessible as s->a9mpcore we can make the
6
connection directly from one device to the other without going via
7
this array.
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: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-5-peter.maydell@linaro.org
7
Message-id: 20241202131347.498124-52-peter.maydell@linaro.org
12
---
8
---
13
include/hw/arm/exynos4210.h | 1 -
9
target/hexagon/cpu.c | 2 ++
14
hw/arm/exynos4210.c | 6 ++----
10
fpu/softfloat-specialize.c.inc | 5 -----
15
2 files changed, 2 insertions(+), 5 deletions(-)
11
2 files changed, 2 insertions(+), 5 deletions(-)
16
12
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
13
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
15
--- a/target/hexagon/cpu.c
20
+++ b/include/hw/arm/exynos4210.h
16
+++ b/target/hexagon/cpu.c
21
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
22
typedef struct Exynos4210Irq {
18
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
19
set_default_nan_mode(1, &env->fp_status);
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
20
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
25
- qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
21
+ /* Default NaN value: sign bit set, all frac bits set */
26
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
22
+ set_float_default_nan_pattern(0b11111111, &env->fp_status);
27
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
23
}
28
} Exynos4210Irq;
24
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
25
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
26
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
28
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/hw/arm/exynos4210.c
29
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
30
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
34
sysbus_connect_irq(busdev, n,
31
uint8_t dnan_pattern = status->default_nan_pattern;
35
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
32
33
if (dnan_pattern == 0) {
34
-#if defined(TARGET_HEXAGON)
35
- /* Sign bit set, all frac bits set. */
36
- dnan_pattern = 0b11111111;
37
-#else
38
/*
39
* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
40
* S390, SH4, TriCore, and Xtensa. Our other supported targets
41
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
42
/* sign bit clear, set frac msb */
43
dnan_pattern = 0b01000000;
44
}
45
-#endif
36
}
46
}
37
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
47
assert(dnan_pattern != 0);
38
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
48
39
- }
40
41
/* Cache controller */
42
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
43
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
44
busdev = SYS_BUS_DEVICE(dev);
45
sysbus_realize_and_unref(busdev, &error_fatal);
46
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
47
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
48
+ sysbus_connect_irq(busdev, n,
49
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
50
}
51
exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
52
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
53
--
49
--
54
2.25.1
50
2.34.1
diff view generated by jsdifflib
1
Fix a missing set of spaces around '-' in the definition of
1
Set the default NaN pattern explicitly for riscv.
2
combiner_grp_to_gic_id[]. We're about to move this code, so
3
fix the style issue first to keep checkpatch happy with the
4
code-motion patch.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220404154658.565020-7-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-53-peter.maydell@linaro.org
9
---
6
---
10
hw/intc/exynos4210_gic.c | 2 +-
7
target/riscv/cpu.c | 2 ++
11
1 file changed, 1 insertion(+), 1 deletion(-)
8
1 file changed, 2 insertions(+)
12
9
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
10
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/exynos4210_gic.c
12
--- a/target/riscv/cpu.c
16
+++ b/hw/intc/exynos4210_gic.c
13
+++ b/target/riscv/cpu.c
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
14
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
18
*/
15
cs->exception_index = RISCV_EXCP_NONE;
19
16
env->load_res = -1;
20
static const uint32_t
17
set_default_nan_mode(1, &env->fp_status);
21
-combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
18
+ /* Default NaN value: sign bit clear, frac msb set */
22
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
23
/* int combiner groups 16-19 */
20
env->vill = true;
24
{ }, { }, { }, { },
21
25
/* int combiner group 20 */
22
#ifndef CONFIG_USER_ONLY
26
--
23
--
27
2.25.1
24
2.34.1
diff view generated by jsdifflib
1
The Exynos4210 SoC device currently uses a custom device
1
Set the default NaN pattern explicitly for tricore.
2
"exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ
3
line. We have a standard TYPE_OR_IRQ device for this now, so use
4
that instead.
5
6
(This is a migration compatibility break, but that is OK for this
7
machine type.)
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: 20220404154658.565020-2-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-54-peter.maydell@linaro.org
12
---
6
---
13
include/hw/arm/exynos4210.h | 1 +
7
target/tricore/helper.c | 2 ++
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
8
1 file changed, 2 insertions(+)
15
2 files changed, 17 insertions(+), 15 deletions(-)
16
9
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
10
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
12
--- a/target/tricore/helper.c
20
+++ b/include/hw/arm/exynos4210.h
13
+++ b/target/tricore/helper.c
21
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
14
@@ -XXX,XX +XXX,XX @@ void fpu_set_state(CPUTriCoreState *env)
22
MemoryRegion bootreg_mem;
15
set_flush_to_zero(1, &env->fp_status);
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
16
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
17
set_default_nan_mode(1, &env->fp_status);
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
18
+ /* Default NaN pattern: sign bit clear, frac msb set */
26
};
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
27
28
#define TYPE_EXYNOS4210_SOC "exynos4210"
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
{
35
Exynos4210State *s = EXYNOS4210_SOC(socdev);
36
MemoryRegion *system_mem = get_system_memory();
37
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
38
SysBusDevice *busdev;
39
DeviceState *dev, *uart[4], *pl330[3];
40
int i, n;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
42
43
/* IRQ Gate */
44
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
45
- dev = qdev_new("exynos4210.irq_gate");
46
- qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
47
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
48
- /* Get IRQ Gate input in gate_irq */
49
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
50
- gate_irq[i][n] = qdev_get_gpio_in(dev, n);
51
- }
52
- busdev = SYS_BUS_DEVICE(dev);
53
-
54
- /* Connect IRQ Gate output to CPU's IRQ line */
55
- sysbus_connect_irq(busdev, 0,
56
- qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
57
+ DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
58
+ object_property_set_int(OBJECT(orgate), "num-lines",
59
+ EXYNOS4210_IRQ_GATE_NINPUTS,
60
+ &error_abort);
61
+ qdev_realize(orgate, NULL, &error_abort);
62
+ qdev_connect_gpio_out(orgate, 0,
63
+ qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
64
}
65
66
/* Private memory region and Internal GIC */
67
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
68
sysbus_realize_and_unref(busdev, &error_fatal);
69
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
70
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
71
- sysbus_connect_irq(busdev, n, gate_irq[n][0]);
72
+ sysbus_connect_irq(busdev, n,
73
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
74
}
75
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
76
s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
77
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
78
/* Map Distributer interface */
79
sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
80
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
81
- sysbus_connect_irq(busdev, n, gate_irq[n][1]);
82
+ sysbus_connect_irq(busdev, n,
83
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
84
}
85
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
86
s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
87
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
88
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
89
g_free(name);
90
}
91
+
92
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
93
+ g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
94
+ object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
95
+ }
96
}
20
}
97
21
98
static void exynos4210_class_init(ObjectClass *klass, void *data)
22
uint32_t psw_read(CPUTriCoreState *env)
99
--
23
--
100
2.25.1
24
2.34.1
diff view generated by jsdifflib
1
The function exynos4210_init_board_irqs() currently lives in
1
Now that all our targets have bene converted to explicitly specify
2
exynos4210_gic.c, but it isn't really part of the exynos4210.gic
2
their pattern for the default NaN value we can remove the remaining
3
device -- it is a function that implements (some of) the wiring up of
3
fallback code in parts64_default_nan().
4
interrupts between the SoC's GIC and combiner components. This means
5
it fits better in exynos4210.c, which is the SoC-level code. Move it
6
there. Similarly, exynos4210_git_irq() is used almost only in the
7
SoC-level code, so move it too.
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: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
7
Message-id: 20241202131347.498124-55-peter.maydell@linaro.org
12
---
8
---
13
include/hw/arm/exynos4210.h | 4 -
9
fpu/softfloat-specialize.c.inc | 14 --------------
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
10
1 file changed, 14 deletions(-)
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
16
3 files changed, 202 insertions(+), 208 deletions(-)
17
11
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/exynos4210.h
14
--- a/fpu/softfloat-specialize.c.inc
21
+++ b/include/hw/arm/exynos4210.h
15
+++ b/fpu/softfloat-specialize.c.inc
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
16
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
23
void exynos4210_write_secondary(ARMCPU *cpu,
17
uint64_t frac;
24
const struct arm_boot_info *info);
18
uint8_t dnan_pattern = status->default_nan_pattern;
25
19
26
-/* Initialize board IRQs.
20
- if (dnan_pattern == 0) {
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
21
- /*
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
22
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
29
-
23
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
24
- * do not have floating-point.
31
* To identify IRQ source use internal combiner group and bit number
25
- */
32
* grp - group number
26
- if (snan_bit_is_one(status)) {
33
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
27
- /* sign bit clear, set all frac bits other than msb */
34
index XXXXXXX..XXXXXXX 100644
28
- dnan_pattern = 0b00111111;
35
--- a/hw/arm/exynos4210.c
36
+++ b/hw/arm/exynos4210.c
37
@@ -XXX,XX +XXX,XX @@
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
40
41
+enum ExtGicId {
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
43
+ EXT_GIC_ID_PDMA0,
44
+ EXT_GIC_ID_PDMA1,
45
+ EXT_GIC_ID_TIMER0,
46
+ EXT_GIC_ID_TIMER1,
47
+ EXT_GIC_ID_TIMER2,
48
+ EXT_GIC_ID_TIMER3,
49
+ EXT_GIC_ID_TIMER4,
50
+ EXT_GIC_ID_MCT_L0,
51
+ EXT_GIC_ID_WDT,
52
+ EXT_GIC_ID_RTC_ALARM,
53
+ EXT_GIC_ID_RTC_TIC,
54
+ EXT_GIC_ID_GPIO_XB,
55
+ EXT_GIC_ID_GPIO_XA,
56
+ EXT_GIC_ID_MCT_L1,
57
+ EXT_GIC_ID_IEM_APC,
58
+ EXT_GIC_ID_IEM_IEC,
59
+ EXT_GIC_ID_NFC,
60
+ EXT_GIC_ID_UART0,
61
+ EXT_GIC_ID_UART1,
62
+ EXT_GIC_ID_UART2,
63
+ EXT_GIC_ID_UART3,
64
+ EXT_GIC_ID_UART4,
65
+ EXT_GIC_ID_MCT_G0,
66
+ EXT_GIC_ID_I2C0,
67
+ EXT_GIC_ID_I2C1,
68
+ EXT_GIC_ID_I2C2,
69
+ EXT_GIC_ID_I2C3,
70
+ EXT_GIC_ID_I2C4,
71
+ EXT_GIC_ID_I2C5,
72
+ EXT_GIC_ID_I2C6,
73
+ EXT_GIC_ID_I2C7,
74
+ EXT_GIC_ID_SPI0,
75
+ EXT_GIC_ID_SPI1,
76
+ EXT_GIC_ID_SPI2,
77
+ EXT_GIC_ID_MCT_G1,
78
+ EXT_GIC_ID_USB_HOST,
79
+ EXT_GIC_ID_USB_DEVICE,
80
+ EXT_GIC_ID_MODEMIF,
81
+ EXT_GIC_ID_HSMMC0,
82
+ EXT_GIC_ID_HSMMC1,
83
+ EXT_GIC_ID_HSMMC2,
84
+ EXT_GIC_ID_HSMMC3,
85
+ EXT_GIC_ID_SDMMC,
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
90
+ EXT_GIC_ID_ONENAND_AUDI,
91
+ EXT_GIC_ID_ROTATOR,
92
+ EXT_GIC_ID_FIMC0,
93
+ EXT_GIC_ID_FIMC1,
94
+ EXT_GIC_ID_FIMC2,
95
+ EXT_GIC_ID_FIMC3,
96
+ EXT_GIC_ID_JPEG,
97
+ EXT_GIC_ID_2D,
98
+ EXT_GIC_ID_PCIe,
99
+ EXT_GIC_ID_MIXER,
100
+ EXT_GIC_ID_HDMI,
101
+ EXT_GIC_ID_HDMI_I2C,
102
+ EXT_GIC_ID_MFC,
103
+ EXT_GIC_ID_TVENC,
104
+};
105
+
106
+enum ExtInt {
107
+ EXT_GIC_ID_EXTINT0 = 48,
108
+ EXT_GIC_ID_EXTINT1,
109
+ EXT_GIC_ID_EXTINT2,
110
+ EXT_GIC_ID_EXTINT3,
111
+ EXT_GIC_ID_EXTINT4,
112
+ EXT_GIC_ID_EXTINT5,
113
+ EXT_GIC_ID_EXTINT6,
114
+ EXT_GIC_ID_EXTINT7,
115
+ EXT_GIC_ID_EXTINT8,
116
+ EXT_GIC_ID_EXTINT9,
117
+ EXT_GIC_ID_EXTINT10,
118
+ EXT_GIC_ID_EXTINT11,
119
+ EXT_GIC_ID_EXTINT12,
120
+ EXT_GIC_ID_EXTINT13,
121
+ EXT_GIC_ID_EXTINT14,
122
+ EXT_GIC_ID_EXTINT15
123
+};
124
+
125
+/*
126
+ * External GIC sources which are not from External Interrupt Combiner or
127
+ * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
128
+ * which is INTG16 in Internal Interrupt Combiner.
129
+ */
130
+
131
+static const uint32_t
132
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
133
+ /* int combiner groups 16-19 */
134
+ { }, { }, { }, { },
135
+ /* int combiner group 20 */
136
+ { 0, EXT_GIC_ID_MDMA_LCD0 },
137
+ /* int combiner group 21 */
138
+ { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
139
+ /* int combiner group 22 */
140
+ { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
141
+ EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
142
+ /* int combiner group 23 */
143
+ { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
144
+ /* int combiner group 24 */
145
+ { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
146
+ /* int combiner group 25 */
147
+ { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
148
+ /* int combiner group 26 */
149
+ { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
150
+ EXT_GIC_ID_UART4 },
151
+ /* int combiner group 27 */
152
+ { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
153
+ EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
154
+ EXT_GIC_ID_I2C7 },
155
+ /* int combiner group 28 */
156
+ { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
157
+ /* int combiner group 29 */
158
+ { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
159
+ EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
160
+ /* int combiner group 30 */
161
+ { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
162
+ /* int combiner group 31 */
163
+ { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
164
+ /* int combiner group 32 */
165
+ { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
166
+ /* int combiner group 33 */
167
+ { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
168
+ /* int combiner group 34 */
169
+ { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
170
+ /* int combiner group 35 */
171
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
172
+ /* int combiner group 36 */
173
+ { EXT_GIC_ID_MIXER },
174
+ /* int combiner group 37 */
175
+ { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
176
+ EXT_GIC_ID_EXTINT7 },
177
+ /* groups 38-50 */
178
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
179
+ /* int combiner group 51 */
180
+ { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
181
+ /* group 52 */
182
+ { },
183
+ /* int combiner group 53 */
184
+ { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
185
+ /* groups 54-63 */
186
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
187
+};
188
+
189
+/*
190
+ * Initialize board IRQs.
191
+ * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
192
+ */
193
+static void exynos4210_init_board_irqs(Exynos4210State *s)
194
+{
195
+ uint32_t grp, bit, irq_id, n;
196
+ Exynos4210Irq *is = &s->irqs;
197
+
198
+ for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
199
+ irq_id = 0;
200
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
201
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
202
+ /* MCT_G0 is passed to External GIC */
203
+ irq_id = EXT_GIC_ID_MCT_G0;
204
+ }
205
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
206
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
207
+ /* MCT_G1 is passed to External and GIC */
208
+ irq_id = EXT_GIC_ID_MCT_G1;
209
+ }
210
+ if (irq_id) {
211
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
212
+ is->ext_gic_irq[irq_id - 32]);
213
+ } else {
214
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
215
+ is->ext_combiner_irq[n]);
216
+ }
217
+ }
218
+ for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
219
+ /* these IDs are passed to Internal Combiner and External GIC */
220
+ grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
221
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
222
+ irq_id = combiner_grp_to_gic_id[grp -
223
+ EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
224
+
225
+ if (irq_id) {
226
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
227
+ is->ext_gic_irq[irq_id - 32]);
228
+ }
229
+ }
230
+}
231
+
232
+/*
233
+ * Get IRQ number from exynos4210 IRQ subsystem stub.
234
+ * To identify IRQ source use internal combiner group and bit number
235
+ * grp - group number
236
+ * bit - bit number inside group
237
+ */
238
+uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
239
+{
240
+ return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
241
+}
242
+
243
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
244
0x09, 0x00, 0x00, 0x00 };
245
246
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/hw/intc/exynos4210_gic.c
249
+++ b/hw/intc/exynos4210_gic.c
250
@@ -XXX,XX +XXX,XX @@
251
#include "hw/arm/exynos4210.h"
252
#include "qom/object.h"
253
254
-enum ExtGicId {
255
- EXT_GIC_ID_MDMA_LCD0 = 66,
256
- EXT_GIC_ID_PDMA0,
257
- EXT_GIC_ID_PDMA1,
258
- EXT_GIC_ID_TIMER0,
259
- EXT_GIC_ID_TIMER1,
260
- EXT_GIC_ID_TIMER2,
261
- EXT_GIC_ID_TIMER3,
262
- EXT_GIC_ID_TIMER4,
263
- EXT_GIC_ID_MCT_L0,
264
- EXT_GIC_ID_WDT,
265
- EXT_GIC_ID_RTC_ALARM,
266
- EXT_GIC_ID_RTC_TIC,
267
- EXT_GIC_ID_GPIO_XB,
268
- EXT_GIC_ID_GPIO_XA,
269
- EXT_GIC_ID_MCT_L1,
270
- EXT_GIC_ID_IEM_APC,
271
- EXT_GIC_ID_IEM_IEC,
272
- EXT_GIC_ID_NFC,
273
- EXT_GIC_ID_UART0,
274
- EXT_GIC_ID_UART1,
275
- EXT_GIC_ID_UART2,
276
- EXT_GIC_ID_UART3,
277
- EXT_GIC_ID_UART4,
278
- EXT_GIC_ID_MCT_G0,
279
- EXT_GIC_ID_I2C0,
280
- EXT_GIC_ID_I2C1,
281
- EXT_GIC_ID_I2C2,
282
- EXT_GIC_ID_I2C3,
283
- EXT_GIC_ID_I2C4,
284
- EXT_GIC_ID_I2C5,
285
- EXT_GIC_ID_I2C6,
286
- EXT_GIC_ID_I2C7,
287
- EXT_GIC_ID_SPI0,
288
- EXT_GIC_ID_SPI1,
289
- EXT_GIC_ID_SPI2,
290
- EXT_GIC_ID_MCT_G1,
291
- EXT_GIC_ID_USB_HOST,
292
- EXT_GIC_ID_USB_DEVICE,
293
- EXT_GIC_ID_MODEMIF,
294
- EXT_GIC_ID_HSMMC0,
295
- EXT_GIC_ID_HSMMC1,
296
- EXT_GIC_ID_HSMMC2,
297
- EXT_GIC_ID_HSMMC3,
298
- EXT_GIC_ID_SDMMC,
299
- EXT_GIC_ID_MIPI_CSI_4LANE,
300
- EXT_GIC_ID_MIPI_DSI_4LANE,
301
- EXT_GIC_ID_MIPI_CSI_2LANE,
302
- EXT_GIC_ID_MIPI_DSI_2LANE,
303
- EXT_GIC_ID_ONENAND_AUDI,
304
- EXT_GIC_ID_ROTATOR,
305
- EXT_GIC_ID_FIMC0,
306
- EXT_GIC_ID_FIMC1,
307
- EXT_GIC_ID_FIMC2,
308
- EXT_GIC_ID_FIMC3,
309
- EXT_GIC_ID_JPEG,
310
- EXT_GIC_ID_2D,
311
- EXT_GIC_ID_PCIe,
312
- EXT_GIC_ID_MIXER,
313
- EXT_GIC_ID_HDMI,
314
- EXT_GIC_ID_HDMI_I2C,
315
- EXT_GIC_ID_MFC,
316
- EXT_GIC_ID_TVENC,
317
-};
318
-
319
-enum ExtInt {
320
- EXT_GIC_ID_EXTINT0 = 48,
321
- EXT_GIC_ID_EXTINT1,
322
- EXT_GIC_ID_EXTINT2,
323
- EXT_GIC_ID_EXTINT3,
324
- EXT_GIC_ID_EXTINT4,
325
- EXT_GIC_ID_EXTINT5,
326
- EXT_GIC_ID_EXTINT6,
327
- EXT_GIC_ID_EXTINT7,
328
- EXT_GIC_ID_EXTINT8,
329
- EXT_GIC_ID_EXTINT9,
330
- EXT_GIC_ID_EXTINT10,
331
- EXT_GIC_ID_EXTINT11,
332
- EXT_GIC_ID_EXTINT12,
333
- EXT_GIC_ID_EXTINT13,
334
- EXT_GIC_ID_EXTINT14,
335
- EXT_GIC_ID_EXTINT15
336
-};
337
-
338
-/*
339
- * External GIC sources which are not from External Interrupt Combiner or
340
- * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
341
- * which is INTG16 in Internal Interrupt Combiner.
342
- */
343
-
344
-static const uint32_t
345
-combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
346
- /* int combiner groups 16-19 */
347
- { }, { }, { }, { },
348
- /* int combiner group 20 */
349
- { 0, EXT_GIC_ID_MDMA_LCD0 },
350
- /* int combiner group 21 */
351
- { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
352
- /* int combiner group 22 */
353
- { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
354
- EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
355
- /* int combiner group 23 */
356
- { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
357
- /* int combiner group 24 */
358
- { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
359
- /* int combiner group 25 */
360
- { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
361
- /* int combiner group 26 */
362
- { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
363
- EXT_GIC_ID_UART4 },
364
- /* int combiner group 27 */
365
- { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
366
- EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
367
- EXT_GIC_ID_I2C7 },
368
- /* int combiner group 28 */
369
- { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
370
- /* int combiner group 29 */
371
- { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
372
- EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
373
- /* int combiner group 30 */
374
- { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
375
- /* int combiner group 31 */
376
- { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
377
- /* int combiner group 32 */
378
- { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
379
- /* int combiner group 33 */
380
- { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
381
- /* int combiner group 34 */
382
- { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
383
- /* int combiner group 35 */
384
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
385
- /* int combiner group 36 */
386
- { EXT_GIC_ID_MIXER },
387
- /* int combiner group 37 */
388
- { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
389
- EXT_GIC_ID_EXTINT7 },
390
- /* groups 38-50 */
391
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
392
- /* int combiner group 51 */
393
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
394
- /* group 52 */
395
- { },
396
- /* int combiner group 53 */
397
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
398
- /* groups 54-63 */
399
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
400
-};
401
-
402
#define EXYNOS4210_GIC_NIRQ 160
403
404
#define EXYNOS4210_EXT_GIC_CPU_REGION_SIZE 0x10000
405
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
406
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
407
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
408
409
-/*
410
- * Initialize board IRQs.
411
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
412
- */
413
-void exynos4210_init_board_irqs(Exynos4210State *s)
414
-{
415
- uint32_t grp, bit, irq_id, n;
416
- Exynos4210Irq *is = &s->irqs;
417
-
418
- for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
419
- irq_id = 0;
420
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
421
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
422
- /* MCT_G0 is passed to External GIC */
423
- irq_id = EXT_GIC_ID_MCT_G0;
424
- }
425
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
426
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
427
- /* MCT_G1 is passed to External and GIC */
428
- irq_id = EXT_GIC_ID_MCT_G1;
429
- }
430
- if (irq_id) {
431
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
432
- is->ext_gic_irq[irq_id - 32]);
433
- } else {
29
- } else {
434
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
30
- /* sign bit clear, set frac msb */
435
- is->ext_combiner_irq[n]);
31
- dnan_pattern = 0b01000000;
436
- }
32
- }
437
- }
33
- }
438
- for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
34
assert(dnan_pattern != 0);
439
- /* these IDs are passed to Internal Combiner and External GIC */
35
440
- grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
36
sign = dnan_pattern >> 7;
441
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
442
- irq_id = combiner_grp_to_gic_id[grp -
443
- EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
444
-
445
- if (irq_id) {
446
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
447
- is->ext_gic_irq[irq_id - 32]);
448
- }
449
- }
450
-}
451
-
452
-/*
453
- * Get IRQ number from exynos4210 IRQ subsystem stub.
454
- * To identify IRQ source use internal combiner group and bit number
455
- * grp - group number
456
- * bit - bit number inside group
457
- */
458
-uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
459
-{
460
- return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
461
-}
462
-
463
-/********* GIC part *********/
464
-
465
#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
466
OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
467
468
--
37
--
469
2.25.1
38
2.34.1
diff view generated by jsdifflib
1
Now we have removed the only use of TYPE_EXYNOS4210_IRQ_GATE we can
1
From: Richard Henderson <richard.henderson@linaro.org>
2
delete the device entirely.
3
2
3
Inline pickNaNMulAdd into its only caller. This makes
4
one assert redundant with the immediately preceding IF.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-3-richard.henderson@linaro.org
9
[PMM: keep comment from old code in new location]
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
6
Message-id: 20220404154658.565020-3-peter.maydell@linaro.org
7
---
11
---
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
12
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
9
1 file changed, 107 deletions(-)
13
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
14
2 files changed, 40 insertions(+), 55 deletions(-)
10
15
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/intc/exynos4210_gic.c
18
--- a/fpu/softfloat-parts.c.inc
14
+++ b/hw/intc/exynos4210_gic.c
19
+++ b/fpu/softfloat-parts.c.inc
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
21
}
22
23
if (s->default_nan_mode) {
24
+ /*
25
+ * We guarantee not to require the target to tell us how to
26
+ * pick a NaN if we're always returning the default NaN.
27
+ * But if we're not in default-NaN mode then the target must
28
+ * specify.
29
+ */
30
which = 3;
31
+ } else if (infzero) {
32
+ /*
33
+ * Inf * 0 + NaN -- some implementations return the
34
+ * default NaN here, and some return the input NaN.
35
+ */
36
+ switch (s->float_infzeronan_rule) {
37
+ case float_infzeronan_dnan_never:
38
+ which = 2;
39
+ break;
40
+ case float_infzeronan_dnan_always:
41
+ which = 3;
42
+ break;
43
+ case float_infzeronan_dnan_if_qnan:
44
+ which = is_qnan(c->cls) ? 3 : 2;
45
+ break;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
} else {
50
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
51
+ FloatClass cls[3] = { a->cls, b->cls, c->cls };
52
+ Float3NaNPropRule rule = s->float_3nan_prop_rule;
53
+
54
+ assert(rule != float_3nan_prop_none);
55
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
56
+ /* We have at least one SNaN input and should prefer it */
57
+ do {
58
+ which = rule & R_3NAN_1ST_MASK;
59
+ rule >>= R_3NAN_1ST_LENGTH;
60
+ } while (!is_snan(cls[which]));
61
+ } else {
62
+ do {
63
+ which = rule & R_3NAN_1ST_MASK;
64
+ rule >>= R_3NAN_1ST_LENGTH;
65
+ } while (!is_nan(cls[which]));
66
+ }
67
}
68
69
if (which == 3) {
70
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
71
index XXXXXXX..XXXXXXX 100644
72
--- a/fpu/softfloat-specialize.c.inc
73
+++ b/fpu/softfloat-specialize.c.inc
74
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
75
}
16
}
76
}
17
77
18
type_init(exynos4210_gic_register_types)
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;
19
-
90
-
20
-/* IRQ OR Gate struct.
91
- /*
21
- *
92
- * We guarantee not to require the target to tell us how to
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
93
- * pick a NaN if we're always returning the default NaN.
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
94
- * But if we're not in default-NaN mode then the target must
24
- * gpio inputs.
95
- * specify.
25
- */
96
- */
97
- assert(!status->default_nan_mode);
26
-
98
-
27
-#define TYPE_EXYNOS4210_IRQ_GATE "exynos4210.irq_gate"
99
- if (infzero) {
28
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210IRQGateState, EXYNOS4210_IRQ_GATE)
100
- /*
29
-
101
- * Inf * 0 + NaN -- some implementations return the default NaN here,
30
-struct Exynos4210IRQGateState {
102
- * and some return the input NaN.
31
- SysBusDevice parent_obj;
103
- */
32
-
104
- switch (status->float_infzeronan_rule) {
33
- uint32_t n_in; /* inputs amount */
105
- case float_infzeronan_dnan_never:
34
- uint32_t *level; /* input levels */
106
- return 2;
35
- qemu_irq out; /* output IRQ */
107
- case float_infzeronan_dnan_always:
36
-};
108
- return 3;
37
-
109
- case float_infzeronan_dnan_if_qnan:
38
-static Property exynos4210_irq_gate_properties[] = {
110
- return is_qnan(c_cls) ? 3 : 2;
39
- DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
111
- default:
40
- DEFINE_PROP_END_OF_LIST(),
112
- g_assert_not_reached();
41
-};
42
-
43
-static const VMStateDescription vmstate_exynos4210_irq_gate = {
44
- .name = "exynos4210.irq_gate",
45
- .version_id = 2,
46
- .minimum_version_id = 2,
47
- .fields = (VMStateField[]) {
48
- VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, n_in),
49
- VMSTATE_END_OF_LIST()
50
- }
51
-};
52
-
53
-/* Process a change in IRQ input. */
54
-static void exynos4210_irq_gate_handler(void *opaque, int irq, int level)
55
-{
56
- Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)opaque;
57
- uint32_t i;
58
-
59
- assert(irq < s->n_in);
60
-
61
- s->level[irq] = level;
62
-
63
- for (i = 0; i < s->n_in; i++) {
64
- if (s->level[i] >= 1) {
65
- qemu_irq_raise(s->out);
66
- return;
67
- }
113
- }
68
- }
114
- }
69
-
115
-
70
- qemu_irq_lower(s->out);
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;
71
-}
130
-}
72
-
131
-
73
-static void exynos4210_irq_gate_reset(DeviceState *d)
132
/*----------------------------------------------------------------------------
74
-{
133
| Returns 1 if the double-precision floating-point value `a' is a quiet
75
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(d);
134
| NaN; otherwise returns 0.
76
-
77
- memset(s->level, 0, s->n_in * sizeof(*s->level));
78
-}
79
-
80
-/*
81
- * IRQ Gate initialization.
82
- */
83
-static void exynos4210_irq_gate_init(Object *obj)
84
-{
85
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(obj);
86
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
87
-
88
- sysbus_init_irq(sbd, &s->out);
89
-}
90
-
91
-static void exynos4210_irq_gate_realize(DeviceState *dev, Error **errp)
92
-{
93
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(dev);
94
-
95
- /* Allocate general purpose input signals and connect a handler to each of
96
- * them */
97
- qdev_init_gpio_in(dev, exynos4210_irq_gate_handler, s->n_in);
98
-
99
- s->level = g_malloc0(s->n_in * sizeof(*s->level));
100
-}
101
-
102
-static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
103
-{
104
- DeviceClass *dc = DEVICE_CLASS(klass);
105
-
106
- dc->reset = exynos4210_irq_gate_reset;
107
- dc->vmsd = &vmstate_exynos4210_irq_gate;
108
- device_class_set_props(dc, exynos4210_irq_gate_properties);
109
- dc->realize = exynos4210_irq_gate_realize;
110
-}
111
-
112
-static const TypeInfo exynos4210_irq_gate_info = {
113
- .name = TYPE_EXYNOS4210_IRQ_GATE,
114
- .parent = TYPE_SYS_BUS_DEVICE,
115
- .instance_size = sizeof(Exynos4210IRQGateState),
116
- .instance_init = exynos4210_irq_gate_init,
117
- .class_init = exynos4210_irq_gate_class_init,
118
-};
119
-
120
-static void exynos4210_irq_gate_register_types(void)
121
-{
122
- type_register_static(&exynos4210_irq_gate_info);
123
-}
124
-
125
-type_init(exynos4210_irq_gate_register_types)
126
--
135
--
127
2.25.1
136
2.34.1
137
138
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Create an APU CPU Cluster. This is in preparation to add the RPU.
3
Remove "3" as a special case for which and simply
4
branch to return the desired value.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
8
Message-id: 20241203203949.483774-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
include/hw/arm/xlnx-versal.h | 2 ++
11
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
11
hw/arm/xlnx-versal.c | 9 ++++++++-
12
1 file changed, 10 insertions(+), 10 deletions(-)
12
2 files changed, 10 insertions(+), 1 deletion(-)
13
13
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/xlnx-versal.h
16
--- a/fpu/softfloat-parts.c.inc
17
+++ b/include/hw/arm/xlnx-versal.h
17
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
19
19
* But if we're not in default-NaN mode then the target must
20
#include "hw/sysbus.h"
20
* specify.
21
#include "hw/arm/boot.h"
21
*/
22
+#include "hw/cpu/cluster.h"
22
- which = 3;
23
#include "hw/or-irq.h"
23
+ goto default_nan;
24
#include "hw/sd/sdhci.h"
24
} else if (infzero) {
25
#include "hw/intc/arm_gicv3.h"
25
/*
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
26
* Inf * 0 + NaN -- some implementations return the
27
struct {
27
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
28
struct {
28
*/
29
MemoryRegion mr;
29
switch (s->float_infzeronan_rule) {
30
+ CPUClusterState cluster;
30
case float_infzeronan_dnan_never:
31
ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
31
- which = 2;
32
GICv3State gic;
32
break;
33
} apu;
33
case float_infzeronan_dnan_always:
34
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
34
- which = 3;
35
index XXXXXXX..XXXXXXX 100644
35
- break;
36
--- a/hw/arm/xlnx-versal.c
36
+ goto default_nan;
37
+++ b/hw/arm/xlnx-versal.c
37
case float_infzeronan_dnan_if_qnan:
38
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
38
- which = is_qnan(c->cls) ? 3 : 2;
39
{
39
+ if (is_qnan(c->cls)) {
40
int i;
40
+ goto default_nan;
41
41
+ }
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
42
break;
43
+ TYPE_CPU_CLUSTER);
43
default:
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
44
g_assert_not_reached();
45
}
46
+ which = 2;
47
} else {
48
FloatClass cls[3] = { a->cls, b->cls, c->cls };
49
Float3NaNPropRule rule = s->float_3nan_prop_rule;
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
51
}
52
}
53
54
- if (which == 3) {
55
- parts_default_nan(a, s);
56
- return a;
57
- }
58
-
59
switch (which) {
60
case 0:
61
break;
62
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
63
parts_silence_nan(a, s);
64
}
65
return a;
45
+
66
+
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
67
+ default_nan:
47
Object *obj;
68
+ parts_default_nan(a, s);
48
69
+ return a;
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
52
XLNX_VERSAL_ACPU_TYPE);
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
54
if (i) {
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
56
&error_abort);
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
58
}
59
+
60
+ qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
61
}
70
}
62
71
63
static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
72
/*
64
--
73
--
65
2.25.1
74
2.34.1
75
76
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Assign the pointer return value to 'a' directly,
4
rather than going through an intermediary index.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
12
1 file changed, 10 insertions(+), 22 deletions(-)
13
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat-parts.c.inc
17
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
19
FloatPartsN *c, float_status *s,
20
int ab_mask, int abc_mask)
21
{
22
- int which;
23
bool infzero = (ab_mask == float_cmask_infzero);
24
bool have_snan = (abc_mask & float_cmask_snan);
25
+ FloatPartsN *ret;
26
27
if (unlikely(have_snan)) {
28
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
default:
31
g_assert_not_reached();
32
}
33
- which = 2;
34
+ ret = c;
35
} else {
36
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
37
+ FloatPartsN *val[3] = { a, b, c };
38
Float3NaNPropRule rule = s->float_3nan_prop_rule;
39
40
assert(rule != float_3nan_prop_none);
41
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
42
/* We have at least one SNaN input and should prefer it */
43
do {
44
- which = rule & R_3NAN_1ST_MASK;
45
+ ret = val[rule & R_3NAN_1ST_MASK];
46
rule >>= R_3NAN_1ST_LENGTH;
47
- } while (!is_snan(cls[which]));
48
+ } while (!is_snan(ret->cls));
49
} else {
50
do {
51
- which = rule & R_3NAN_1ST_MASK;
52
+ ret = val[rule & R_3NAN_1ST_MASK];
53
rule >>= R_3NAN_1ST_LENGTH;
54
- } while (!is_nan(cls[which]));
55
+ } while (!is_nan(ret->cls));
56
}
57
}
58
59
- switch (which) {
60
- case 0:
61
- break;
62
- case 1:
63
- a = b;
64
- break;
65
- case 2:
66
- a = c;
67
- break;
68
- default:
69
- g_assert_not_reached();
70
+ if (is_snan(ret->cls)) {
71
+ parts_silence_nan(ret, s);
72
}
73
- if (is_snan(a->cls)) {
74
- parts_silence_nan(a, s);
75
- }
76
- return a;
77
+ return ret;
78
79
default_nan:
80
parts_default_nan(a, s);
81
--
82
2.34.1
83
84
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
While all indices into val[] should be in [0-2], the mask
4
applied is two bits. To help static analysis see there is
5
no possibility of read beyond the end of the array, pad the
6
array to 4 entries, with the final being (implicitly) NULL.
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20241203203949.483774-6-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
fpu/softfloat-parts.c.inc | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
17
index XXXXXXX..XXXXXXX 100644
18
--- a/fpu/softfloat-parts.c.inc
19
+++ b/fpu/softfloat-parts.c.inc
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
21
}
22
ret = c;
23
} else {
24
- FloatPartsN *val[3] = { a, b, c };
25
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
26
Float3NaNPropRule rule = s->float_3nan_prop_rule;
27
28
assert(rule != float_3nan_prop_none);
29
--
30
2.34.1
31
32
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Connect the CRL (Clock Reset LPD) to the Versal SoC.
3
This function is part of the public interface and
4
is not "specialized" to any target in any way.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
8
Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
include/hw/arm/xlnx-versal.h | 4 +++
11
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
12
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
13
2 files changed, 56 insertions(+), 2 deletions(-)
13
2 files changed, 52 insertions(+), 52 deletions(-)
14
14
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.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/xlnx-versal.h
17
--- a/fpu/softfloat.c
18
+++ b/include/hw/arm/xlnx-versal.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/nvram/xlnx-versal-efuse.h"
20
*zExpPtr = 1 - shiftCount;
21
#include "hw/ssi/xlnx-versal-ospi.h"
21
}
22
#include "hw/dma/xlnx_csu_dma.h"
22
23
+#include "hw/misc/xlnx-versal-crl.h"
23
+/*----------------------------------------------------------------------------
24
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
24
+| Takes two extended double-precision floating-point values `a' and `b', one
25
25
+| of which is a NaN, and returns the appropriate NaN result. If either `a' or
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
26
+| `b' is a signaling NaN, the invalid exception is raised.
27
@@ -XXX,XX +XXX,XX @@ struct Versal {
27
+*----------------------------------------------------------------------------*/
28
qemu_or_irq irq_orgate;
29
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
30
} xram;
31
+
28
+
32
+ XlnxVersalCRL crl;
29
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
33
} lpd;
34
35
/* The Platform Management Controller subsystem. */
36
@@ -XXX,XX +XXX,XX @@ struct Versal {
37
#define VERSAL_TIMER_NS_EL1_IRQ 14
38
#define VERSAL_TIMER_NS_EL2_IRQ 10
39
40
+#define VERSAL_CRL_IRQ 10
41
#define VERSAL_UART0_IRQ_0 18
42
#define VERSAL_UART1_IRQ_0 19
43
#define VERSAL_USB0_IRQ_0 22
44
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal.c
47
+++ b/hw/arm/xlnx-versal.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
49
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
50
}
51
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
53
+{
30
+{
54
+ SysBusDevice *sbd;
31
+ bool aIsLargerSignificand;
55
+ int i;
32
+ FloatClass a_cls, b_cls;
56
+
33
+
57
+ object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
34
+ /* This is not complete, but is good enough for pickNaN. */
58
+ TYPE_XLNX_VERSAL_CRL);
35
+ a_cls = (!floatx80_is_any_nan(a)
59
+ sbd = SYS_BUS_DEVICE(&s->lpd.crl);
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);
60
+
45
+
61
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
46
+ if (is_snan(a_cls) || is_snan(b_cls)) {
62
+ g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
47
+ float_raise(float_flag_invalid, status);
63
+
64
+ object_property_set_link(OBJECT(&s->lpd.crl),
65
+ name, OBJECT(&s->lpd.rpu.cpu[i]),
66
+ &error_abort);
67
+ }
48
+ }
68
+
49
+
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
50
+ if (status->default_nan_mode) {
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
51
+ return floatx80_default_nan(status);
71
+
72
+ object_property_set_link(OBJECT(&s->lpd.crl),
73
+ name, OBJECT(&s->lpd.iou.gem[i]),
74
+ &error_abort);
75
+ }
52
+ }
76
+
53
+
77
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
54
+ if (a.low < b.low) {
78
+ g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
55
+ aIsLargerSignificand = 0;
79
+
56
+ } else if (b.low < a.low) {
80
+ object_property_set_link(OBJECT(&s->lpd.crl),
57
+ aIsLargerSignificand = 1;
81
+ name, OBJECT(&s->lpd.iou.adma[i]),
58
+ } else {
82
+ &error_abort);
59
+ aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
83
+ }
60
+ }
84
+
61
+
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
62
+ if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
86
+ g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
63
+ if (is_snan(b_cls)) {
87
+
64
+ return floatx80_silence_nan(b, status);
88
+ object_property_set_link(OBJECT(&s->lpd.crl),
65
+ }
89
+ name, OBJECT(&s->lpd.iou.uart[i]),
66
+ return b;
90
+ &error_abort);
67
+ } else {
68
+ if (is_snan(a_cls)) {
69
+ return floatx80_silence_nan(a, status);
70
+ }
71
+ return a;
91
+ }
72
+ }
92
+
93
+ object_property_set_link(OBJECT(&s->lpd.crl),
94
+ "usb", OBJECT(&s->lpd.iou.usb),
95
+ &error_abort);
96
+
97
+ sysbus_realize(sbd, &error_fatal);
98
+ memory_region_add_subregion(&s->mr_ps, MM_CRL,
99
+ sysbus_mmio_get_region(sbd, 0));
100
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
101
+}
73
+}
102
+
74
+
103
/* This takes the board allocated linear DDR memory and creates aliases
75
/*----------------------------------------------------------------------------
104
* for each split DDR range/aperture on the Versal address map.
76
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
105
*/
77
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
106
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
78
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
107
79
index XXXXXXX..XXXXXXX 100644
108
versal_unimp_area(s, "psm", &s->mr_ps,
80
--- a/fpu/softfloat-specialize.c.inc
109
MM_PSM_START, MM_PSM_END - MM_PSM_START);
81
+++ b/fpu/softfloat-specialize.c.inc
110
- versal_unimp_area(s, "crl", &s->mr_ps,
82
@@ -XXX,XX +XXX,XX @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
111
- MM_CRL, MM_CRL_SIZE);
83
return a;
112
versal_unimp_area(s, "crf", &s->mr_ps,
84
}
113
MM_FPD_CRF, MM_FPD_CRF_SIZE);
85
114
versal_unimp_area(s, "apu", &s->mr_ps,
86
-/*----------------------------------------------------------------------------
115
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
87
-| Takes two extended double-precision floating-point values `a' and `b', one
116
versal_create_efuse(s, pic);
88
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
117
versal_create_pmc_iou_slcr(s, pic);
89
-| `b' is a signaling NaN, the invalid exception is raised.
118
versal_create_ospi(s, pic);
90
-*----------------------------------------------------------------------------*/
119
+ versal_create_crl(s, pic);
91
-
120
versal_map_ddr(s);
92
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
121
versal_unimp(s);
93
-{
122
94
- bool aIsLargerSignificand;
95
- FloatClass a_cls, b_cls;
96
-
97
- /* This is not complete, but is good enough for pickNaN. */
98
- a_cls = (!floatx80_is_any_nan(a)
99
- ? float_class_normal
100
- : floatx80_is_signaling_nan(a, status)
101
- ? float_class_snan
102
- : float_class_qnan);
103
- b_cls = (!floatx80_is_any_nan(b)
104
- ? float_class_normal
105
- : floatx80_is_signaling_nan(b, status)
106
- ? float_class_snan
107
- : float_class_qnan);
108
-
109
- if (is_snan(a_cls) || is_snan(b_cls)) {
110
- float_raise(float_flag_invalid, status);
111
- }
112
-
113
- if (status->default_nan_mode) {
114
- return floatx80_default_nan(status);
115
- }
116
-
117
- if (a.low < b.low) {
118
- aIsLargerSignificand = 0;
119
- } else if (b.low < a.low) {
120
- aIsLargerSignificand = 1;
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.
123
--
141
--
124
2.25.1
142
2.34.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Unpacking and repacking the parts may be slightly more work
4
than we did before, but we get to reuse more code. For a
5
code path handling exceptional values, this is an improvement.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241203203949.483774-8-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
fpu/softfloat.c | 43 +++++--------------------------------------
13
1 file changed, 5 insertions(+), 38 deletions(-)
14
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/fpu/softfloat.c
18
+++ b/fpu/softfloat.c
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
20
21
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
22
{
23
- bool aIsLargerSignificand;
24
- FloatClass a_cls, b_cls;
25
+ FloatParts128 pa, pb, *pr;
26
27
- /* This is not complete, but is good enough for pickNaN. */
28
- a_cls = (!floatx80_is_any_nan(a)
29
- ? float_class_normal
30
- : floatx80_is_signaling_nan(a, status)
31
- ? float_class_snan
32
- : float_class_qnan);
33
- b_cls = (!floatx80_is_any_nan(b)
34
- ? float_class_normal
35
- : floatx80_is_signaling_nan(b, status)
36
- ? float_class_snan
37
- : float_class_qnan);
38
-
39
- if (is_snan(a_cls) || is_snan(b_cls)) {
40
- float_raise(float_flag_invalid, status);
41
- }
42
-
43
- if (status->default_nan_mode) {
44
+ if (!floatx80_unpack_canonical(&pa, a, status) ||
45
+ !floatx80_unpack_canonical(&pb, b, status)) {
46
return floatx80_default_nan(status);
47
}
48
49
- if (a.low < b.low) {
50
- aIsLargerSignificand = 0;
51
- } else if (b.low < a.low) {
52
- aIsLargerSignificand = 1;
53
- } else {
54
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
55
- }
56
-
57
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
58
- if (is_snan(b_cls)) {
59
- return floatx80_silence_nan(b, status);
60
- }
61
- return b;
62
- } else {
63
- if (is_snan(a_cls)) {
64
- return floatx80_silence_nan(a, status);
65
- }
66
- return a;
67
- }
68
+ pr = parts_pick_nan(&pa, &pb, status);
69
+ return floatx80_round_pack_canonical(pr, status);
70
}
71
72
/*----------------------------------------------------------------------------
73
--
74
2.34.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit)
3
Inline pickNaN into its only caller. This makes one assert
4
subsystem.
4
redundant with the immediately preceding IF.
5
5
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com
8
Message-id: 20241203203949.483774-9-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
include/hw/arm/xlnx-versal.h | 10 ++++++++++
11
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
12
hw/arm/xlnx-versal-virt.c | 6 +++---
12
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
13
2 files changed, 73 insertions(+), 105 deletions(-)
14
3 files changed, 49 insertions(+), 3 deletions(-)
14
15
15
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
17
--- a/fpu/softfloat-parts.c.inc
19
+++ b/include/hw/arm/xlnx-versal.h
18
+++ b/fpu/softfloat-parts.c.inc
20
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
21
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
20
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
22
21
float_status *s)
23
#define XLNX_VERSAL_NR_ACPUS 2
22
{
24
+#define XLNX_VERSAL_NR_RCPUS 2
23
+ int cmp, which;
25
#define XLNX_VERSAL_NR_UARTS 2
26
#define XLNX_VERSAL_NR_GEMS 2
27
#define XLNX_VERSAL_NR_ADMAS 8
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
29
VersalUsb2 usb;
30
} iou;
31
32
+ /* Real-time Processing Unit. */
33
+ struct {
34
+ MemoryRegion mr;
35
+ MemoryRegion mr_ps_alias;
36
+
24
+
37
+ CPUClusterState cluster;
25
if (is_snan(a->cls) || is_snan(b->cls)) {
38
+ ARMCPU cpu[XLNX_VERSAL_NR_RCPUS];
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
39
+ } rpu;
27
}
28
29
if (s->default_nan_mode) {
30
parts_default_nan(a, s);
31
- } else {
32
- int cmp = frac_cmp(a, b);
33
- if (cmp == 0) {
34
- cmp = a->sign < b->sign;
35
- }
36
+ return a;
37
+ }
38
39
- if (pickNaN(a->cls, b->cls, cmp > 0, s)) {
40
- a = b;
41
- }
42
+ cmp = frac_cmp(a, b);
43
+ if (cmp == 0) {
44
+ cmp = a->sign < b->sign;
45
+ }
40
+
46
+
41
struct {
47
+ switch (s->float_2nan_prop_rule) {
42
qemu_or_irq irq_orgate;
48
+ case float_2nan_prop_s_ab:
43
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
49
if (is_snan(a->cls)) {
44
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
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
45
index XXXXXXX..XXXXXXX 100644
118
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal-virt.c
119
--- a/fpu/softfloat-specialize.c.inc
47
+++ b/hw/arm/xlnx-versal-virt.c
120
+++ b/fpu/softfloat-specialize.c.inc
48
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
121
@@ -XXX,XX +XXX,XX @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
49
50
mc->desc = "Xilinx Versal Virtual development board";
51
mc->init = versal_virt_init;
52
- mc->min_cpus = XLNX_VERSAL_NR_ACPUS;
53
- mc->max_cpus = XLNX_VERSAL_NR_ACPUS;
54
- mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
55
+ mc->min_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
56
+ mc->max_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
57
+ mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
58
mc->no_cdrom = true;
59
mc->default_ram_id = "ddr";
60
}
61
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/xlnx-versal.c
64
+++ b/hw/arm/xlnx-versal.c
65
@@ -XXX,XX +XXX,XX @@
66
#include "hw/sysbus.h"
67
68
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
69
+#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
70
#define GEM_REVISION 0x40070106
71
72
#define VERSAL_NUM_PMC_APB_IRQS 3
73
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
74
}
122
}
75
}
123
}
76
124
77
+static void versal_create_rpu_cpus(Versal *s)
125
-/*----------------------------------------------------------------------------
78
+{
126
-| Select which NaN to propagate for a two-input operation.
79
+ int i;
127
-| IEEE754 doesn't specify all the details of this, so the
80
+
128
-| algorithm is target-specific.
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
129
-| The routine is passed various bits of information about the
82
+ TYPE_CPU_CLUSTER);
130
-| two NaNs and should return 0 to select NaN a and 1 for NaN b.
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
131
-| Note that signalling NaNs are always squashed to quiet NaNs
84
+
132
-| by the caller, by calling floatXX_silence_nan() before
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
133
-| returning them.
86
+ Object *obj;
134
-|
87
+
135
-| aIsLargerSignificand is only valid if both a and b are NaNs
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
136
-| of some kind, and is true if a has the larger significand,
89
+ "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
137
-| or if both a and b have the same significand but a is
90
+ XLNX_VERSAL_RCPU_TYPE);
138
-| positive but b is negative. It is only needed for the x87
91
+ obj = OBJECT(&s->lpd.rpu.cpu[i]);
139
-| tie-break rule.
92
+ object_property_set_bool(obj, "start-powered-off", true,
140
-*----------------------------------------------------------------------------*/
93
+ &error_abort);
141
-
94
+
142
-static int pickNaN(FloatClass a_cls, FloatClass b_cls,
95
+ object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
143
- bool aIsLargerSignificand, float_status *status)
96
+ object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
144
-{
97
+ &error_abort);
145
- /*
98
+ object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
146
- * We guarantee not to require the target to tell us how to
99
+ &error_abort);
147
- * pick a NaN if we're always returning the default NaN.
100
+ qdev_realize(DEVICE(obj), NULL, &error_fatal);
148
- * But if we're not in default-NaN mode then the target must
101
+ }
149
- * specify via set_float_2nan_prop_rule().
102
+
150
- */
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
151
- assert(!status->default_nan_mode);
104
+}
152
-
105
+
153
- switch (status->float_2nan_prop_rule) {
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
154
- case float_2nan_prop_s_ab:
107
{
155
- if (is_snan(a_cls)) {
108
int i;
156
- return 0;
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
157
- } else if (is_snan(b_cls)) {
110
158
- return 1;
111
versal_create_apu_cpus(s);
159
- } else if (is_qnan(a_cls)) {
112
versal_create_apu_gic(s, pic);
160
- return 0;
113
+ versal_create_rpu_cpus(s);
161
- } else {
114
versal_create_uarts(s, pic);
162
- return 1;
115
versal_create_usbs(s, pic);
163
- }
116
versal_create_gems(s, pic);
164
- break;
117
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
165
- case float_2nan_prop_s_ba:
118
166
- if (is_snan(b_cls)) {
119
memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0);
167
- return 1;
120
memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0);
168
- } else if (is_snan(a_cls)) {
121
+ memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0,
169
- return 0;
122
+ &s->lpd.rpu.mr_ps_alias, 0);
170
- } else if (is_qnan(b_cls)) {
123
}
171
- return 1;
124
172
- } else {
125
static void versal_init(Object *obj)
173
- return 0;
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
174
- }
127
Versal *s = XLNX_VERSAL(obj);
175
- break;
128
176
- case float_2nan_prop_ab:
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
177
- if (is_nan(a_cls)) {
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
178
- return 0;
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
179
- } else {
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
180
- return 1;
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
181
- }
134
}
182
- break;
135
183
- case float_2nan_prop_ba:
136
static Property versal_properties[] = {
184
- if (is_nan(b_cls)) {
185
- return 1;
186
- } else {
187
- return 0;
188
- }
189
- break;
190
- case float_2nan_prop_x87:
191
- /*
192
- * This implements x87 NaN propagation rules:
193
- * SNaN + QNaN => return the QNaN
194
- * two SNaNs => return the one with the larger significand, silenced
195
- * two QNaNs => return the one with the larger significand
196
- * SNaN and a non-NaN => return the SNaN, silenced
197
- * QNaN and a non-NaN => return the QNaN
198
- *
199
- * If we get down to comparing significands and they are the same,
200
- * return the NaN with the positive sign bit (if any).
201
- */
202
- if (is_snan(a_cls)) {
203
- if (is_snan(b_cls)) {
204
- return aIsLargerSignificand ? 0 : 1;
205
- }
206
- return is_qnan(b_cls) ? 1 : 0;
207
- } else if (is_qnan(a_cls)) {
208
- if (is_snan(b_cls) || !is_qnan(b_cls)) {
209
- return 0;
210
- } else {
211
- return aIsLargerSignificand ? 0 : 1;
212
- }
213
- } else {
214
- return 1;
215
- }
216
- default:
217
- g_assert_not_reached();
218
- }
219
-}
220
-
221
/*----------------------------------------------------------------------------
222
| Returns 1 if the double-precision floating-point value `a' is a quiet
223
| NaN; otherwise returns 0.
137
--
224
--
138
2.25.1
225
2.34.1
226
227
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
3
Remember if there was an SNaN, and use that to simplify
4
the PWRON STRAP fields in their corresponding module for NPCM7XX.
4
float_2nan_prop_s_{ab,ba} to only the snan component.
5
Then, fall through to the corresponding
6
float_2nan_prop_{ab,ba} case to handle any remaining
7
nans, which must be quiet.
5
8
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Message-id: 20220411165842.3912945-2-wuhaotsh@google.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20241203203949.483774-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
14
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
13
1 file changed, 30 insertions(+)
15
1 file changed, 12 insertions(+), 20 deletions(-)
14
16
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/npcm7xx_gcr.h
19
--- a/fpu/softfloat-parts.c.inc
18
+++ b/include/hw/misc/npcm7xx_gcr.h
20
+++ b/fpu/softfloat-parts.c.inc
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
20
#include "exec/memory.h"
22
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
21
#include "hw/sysbus.h"
23
float_status *s)
22
24
{
23
+/*
25
+ bool have_snan = false;
24
+ * NPCM7XX PWRON STRAP bit fields
26
int cmp, which;
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
27
26
+ * 11: System flash attached to BMC
28
if (is_snan(a->cls) || is_snan(b->cls)) {
27
+ * 10: BSP alternative pins.
29
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
28
+ * 9:8: Flash UART command route enabled.
30
+ have_snan = true;
29
+ * 7: Security enabled.
31
}
30
+ * 6: HI-Z state control.
32
31
+ * 5: ECC disabled.
33
if (s->default_nan_mode) {
32
+ * 4: Reserved
34
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
33
+ * 3: JTAG2 enabled.
35
34
+ * 2:0: CPU and DRAM clock frequency.
36
switch (s->float_2nan_prop_rule) {
35
+ */
37
case float_2nan_prop_s_ab:
36
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
38
- if (is_snan(a->cls)) {
37
+#define NPCM7XX_PWRON_STRAP_SFAB BIT(11)
39
- which = 0;
38
+#define NPCM7XX_PWRON_STRAP_BSPA BIT(10)
40
- } else if (is_snan(b->cls)) {
39
+#define NPCM7XX_PWRON_STRAP_FUP(x) ((x) << 8)
41
- which = 1;
40
+#define FUP_NORM_UART2 3
42
- } else if (is_qnan(a->cls)) {
41
+#define FUP_PROG_UART3 2
43
- which = 0;
42
+#define FUP_PROG_UART2 1
44
- } else {
43
+#define FUP_NORM_UART3 0
45
- which = 1;
44
+#define NPCM7XX_PWRON_STRAP_SECEN BIT(7)
46
+ if (have_snan) {
45
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
47
+ which = is_snan(a->cls) ? 0 : 1;
46
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
48
+ break;
47
+#define NPCM7XX_PWRON_STRAP_RESERVE1 BIT(4)
49
}
48
+#define NPCM7XX_PWRON_STRAP_J2EN BIT(3)
50
- break;
49
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x) (x)
51
- case float_2nan_prop_s_ba:
50
+#define CKFRQ_SKIPINIT 0x000
52
- if (is_snan(b->cls)) {
51
+#define CKFRQ_DEFAULT 0x111
53
- which = 1;
52
+
54
- } else if (is_snan(a->cls)) {
53
/*
55
- which = 0;
54
* Number of registers in our device state structure. Don't change this without
56
- } else if (is_qnan(b->cls)) {
55
* incrementing the version_id in the vmstate.
57
- which = 1;
58
- } else {
59
- which = 0;
60
- }
61
- break;
62
+ /* fall through */
63
case float_2nan_prop_ab:
64
which = is_nan(a->cls) ? 0 : 1;
65
break;
66
+ case float_2nan_prop_s_ba:
67
+ if (have_snan) {
68
+ which = is_snan(b->cls) ? 1 : 0;
69
+ break;
70
+ }
71
+ /* fall through */
72
case float_2nan_prop_ba:
73
which = is_nan(b->cls) ? 1 : 0;
74
break;
56
--
75
--
57
2.25.1
76
2.34.1
diff view generated by jsdifflib
1
From: Zongyuan Li <zongyuan.li@smartx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
3
Move the fractional comparison to the end of the
4
float_2nan_prop_x87 case. This is not required for
5
any other 2nan propagation rule. Reorganize the
6
x87 case itself to break out of the switch when the
7
fractional comparison is not required.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
11
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
13
---
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
14
fpu/softfloat-parts.c.inc | 19 +++++++++----------
9
1 file changed, 24 insertions(+), 9 deletions(-)
15
1 file changed, 9 insertions(+), 10 deletions(-)
10
16
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/realview.c
19
--- a/fpu/softfloat-parts.c.inc
14
+++ b/hw/arm/realview.c
20
+++ b/fpu/softfloat-parts.c.inc
15
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
16
#include "hw/sysbus.h"
22
return a;
17
#include "hw/arm/boot.h"
23
}
18
#include "hw/arm/primecell.h"
24
19
+#include "hw/core/split-irq.h"
25
- cmp = frac_cmp(a, b);
20
#include "hw/net/lan9118.h"
26
- if (cmp == 0) {
21
#include "hw/net/smc91c111.h"
27
- cmp = a->sign < b->sign;
22
#include "hw/pci/pci.h"
28
- }
23
+#include "hw/qdev-core.h"
29
-
24
#include "net/net.h"
30
switch (s->float_2nan_prop_rule) {
25
#include "sysemu/sysemu.h"
31
case float_2nan_prop_s_ab:
26
#include "hw/boards.h"
32
if (have_snan) {
27
@@ -XXX,XX +XXX,XX @@ static const int realview_board_id[] = {
33
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
28
0x76d
34
* return the NaN with the positive sign bit (if any).
29
};
35
*/
30
36
if (is_snan(a->cls)) {
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
37
- if (is_snan(b->cls)) {
32
+ qemu_irq out1, qemu_irq out2) {
38
- which = cmp > 0 ? 0 : 1;
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
39
- } else {
34
+
40
+ if (!is_snan(b->cls)) {
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
41
which = is_qnan(b->cls) ? 1 : 0;
36
+
42
+ break;
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
43
}
38
+
44
} else if (is_qnan(a->cls)) {
39
+ qdev_connect_gpio_out(splitter, 0, out1);
45
if (is_snan(b->cls) || !is_qnan(b->cls)) {
40
+ qdev_connect_gpio_out(splitter, 1, out2);
46
which = 0;
41
+ qdev_connect_gpio_out_named(src, outname, 0,
47
- } else {
42
+ qdev_get_gpio_in(splitter, 0));
48
- which = cmp > 0 ? 0 : 1;
43
+}
49
+ break;
44
+
50
}
45
static void realview_init(MachineState *machine,
51
} else {
46
enum realview_board_type board_type)
52
which = 1;
47
{
53
+ break;
48
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
54
}
49
DeviceState *dev, *sysctl, *gpio2, *pl041;
55
+ cmp = frac_cmp(a, b);
50
SysBusDevice *busdev;
56
+ if (cmp == 0) {
51
qemu_irq pic[64];
57
+ cmp = a->sign < b->sign;
52
- qemu_irq mmc_irq[2];
58
+ }
53
PCIBus *pci_bus = NULL;
59
+ which = cmp > 0 ? 0 : 1;
54
NICInfo *nd;
60
break;
55
DriveInfo *dinfo;
61
default:
56
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
62
g_assert_not_reached();
57
* and the PL061 has them the other way about. Also the card
58
* detect line is inverted.
59
*/
60
- mmc_irq[0] = qemu_irq_split(
61
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
62
- qdev_get_gpio_in(gpio2, 1));
63
- mmc_irq[1] = qemu_irq_split(
64
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
65
- qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
66
- qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
67
- qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_irq[1]);
68
+ split_irq_from_named(dev, "card-read-only",
69
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
70
+ qdev_get_gpio_in(gpio2, 1));
71
+
72
+ split_irq_from_named(dev, "card-inserted",
73
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
74
+ qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
75
+
76
dinfo = drive_get(IF_SD, 0, 0);
77
if (dinfo) {
78
DeviceState *card;
79
--
63
--
80
2.25.1
64
2.34.1
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Connect the 4 TTC timers on the ZynqMP.
3
Replace the "index" selecting between A and B with a result variable
4
of the proper type. This improves clarity within the function.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Message-id: 20241203203949.483774-12-richard.henderson@linaro.org
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Message-id: 20220331222017.2914409-3-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
include/hw/arm/xlnx-zynqmp.h | 4 ++++
11
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
12
1 file changed, 13 insertions(+), 15 deletions(-)
14
2 files changed, 26 insertions(+)
15
13
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-zynqmp.h
16
--- a/fpu/softfloat-parts.c.inc
19
+++ b/include/hw/arm/xlnx-zynqmp.h
17
+++ b/fpu/softfloat-parts.c.inc
20
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
21
#include "hw/or-irq.h"
19
float_status *s)
22
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
20
{
23
#include "hw/misc/xlnx-zynqmp-crf.h"
21
bool have_snan = false;
24
+#include "hw/timer/cadence_ttc.h"
22
- int cmp, which;
25
23
+ FloatPartsN *ret;
26
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
24
+ int cmp;
27
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
25
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
26
if (is_snan(a->cls) || is_snan(b->cls)) {
29
#define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
27
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
30
XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
28
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
31
29
switch (s->float_2nan_prop_rule) {
32
+#define XLNX_ZYNQMP_NUM_TTC 4
30
case float_2nan_prop_s_ab:
33
+
31
if (have_snan) {
34
/*
32
- which = is_snan(a->cls) ? 0 : 1;
35
* Unimplemented mmio regions needed to boot some images.
33
+ ret = is_snan(a->cls) ? a : b;
36
*/
34
break;
37
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
35
}
38
qemu_or_irq qspi_irq_orgate;
36
/* fall through */
39
XlnxZynqMPAPUCtrl apu_ctrl;
37
case float_2nan_prop_ab:
40
XlnxZynqMPCRF crf;
38
- which = is_nan(a->cls) ? 0 : 1;
41
+ CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
39
+ ret = is_nan(a->cls) ? a : b;
42
40
break;
43
char *boot_cpu;
41
case float_2nan_prop_s_ba:
44
ARMCPU *boot_cpu_ptr;
42
if (have_snan) {
45
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
43
- which = is_snan(b->cls) ? 1 : 0;
46
index XXXXXXX..XXXXXXX 100644
44
+ ret = is_snan(b->cls) ? b : a;
47
--- a/hw/arm/xlnx-zynqmp.c
45
break;
48
+++ b/hw/arm/xlnx-zynqmp.c
46
}
49
@@ -XXX,XX +XXX,XX @@
47
/* fall through */
50
#define APU_ADDR 0xfd5c0000
48
case float_2nan_prop_ba:
51
#define APU_IRQ 153
49
- which = is_nan(b->cls) ? 1 : 0;
52
50
+ ret = is_nan(b->cls) ? b : a;
53
+#define TTC0_ADDR 0xFF110000
51
break;
54
+#define TTC0_IRQ 36
52
case float_2nan_prop_x87:
55
+
53
/*
56
#define IPI_ADDR 0xFF300000
54
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
57
#define IPI_IRQ 64
55
*/
58
56
if (is_snan(a->cls)) {
59
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, qemu_irq *gic)
57
if (!is_snan(b->cls)) {
60
sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
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;
61
}
94
}
62
95
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
96
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
64
+{
65
+ SysBusDevice *sbd;
66
+ int i, irq;
67
+
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
70
+ TYPE_CADENCE_TTC);
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
72
+
73
+ sysbus_realize(sbd, &error_fatal);
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
75
+ for (irq = 0; irq < 3; irq++) {
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
77
+ }
78
+ }
79
+}
80
+
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
82
{
83
static const struct UnimpInfo {
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
85
xlnx_zynqmp_create_efuse(s, gic_spi);
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
87
xlnx_zynqmp_create_crf(s, gic_spi);
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
89
xlnx_zynqmp_create_unimp_mmio(s);
90
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
92
--
97
--
93
2.25.1
98
2.34.1
99
100
diff view generated by jsdifflib
1
Switch the creation of the external GIC to the new-style "embedded in
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
state struct" approach, so we can easily refer to the object
3
elsewhere during realize.
4
2
3
I'm migrating to Qualcomm's new open source email infrastructure, so
4
update my email address, and update the mailmap to match.
5
6
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
8
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-9-peter.maydell@linaro.org
8
---
13
---
9
include/hw/arm/exynos4210.h | 2 ++
14
MAINTAINERS | 2 +-
10
include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++
15
.mailmap | 5 +++--
11
hw/arm/exynos4210.c | 10 ++++----
16
2 files changed, 4 insertions(+), 3 deletions(-)
12
hw/intc/exynos4210_gic.c | 17 ++-----------
13
MAINTAINERS | 2 +-
14
5 files changed, 53 insertions(+), 21 deletions(-)
15
create mode 100644 include/hw/intc/exynos4210_gic.h
16
17
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/exynos4210.h
20
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/or-irq.h"
23
#include "hw/sysbus.h"
24
#include "hw/cpu/a9mpcore.h"
25
+#include "hw/intc/exynos4210_gic.h"
26
#include "target/arm/cpu-qom.h"
27
#include "qom/object.h"
28
29
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
30
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
31
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
32
A9MPPrivState a9mpcore;
33
+ Exynos4210GicState ext_gic;
34
};
35
36
#define TYPE_EXYNOS4210_SOC "exynos4210"
37
diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_gic.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Samsung exynos4210 GIC implementation. Based on hw/arm_gic.c
45
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
59
+ * See the GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+#ifndef HW_INTC_EXYNOS4210_GIC_H
65
+#define HW_INTC_EXYNOS4210_GIC_H
66
+
67
+#include "hw/sysbus.h"
68
+
69
+#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
70
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
71
+
72
+#define EXYNOS4210_GIC_NCPUS 2
73
+
74
+struct Exynos4210GicState {
75
+ SysBusDevice parent_obj;
76
+
77
+ MemoryRegion cpu_container;
78
+ MemoryRegion dist_container;
79
+ MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS];
80
+ MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS];
81
+ uint32_t num_cpu;
82
+ DeviceState *gic;
83
+};
84
+
85
+#endif
86
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/arm/exynos4210.c
89
+++ b/hw/arm/exynos4210.c
90
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
91
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
92
93
/* External GIC */
94
- dev = qdev_new("exynos4210.gic");
95
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
96
- busdev = SYS_BUS_DEVICE(dev);
97
- sysbus_realize_and_unref(busdev, &error_fatal);
98
+ qdev_prop_set_uint32(DEVICE(&s->ext_gic), "num-cpu", EXYNOS4210_NCPUS);
99
+ busdev = SYS_BUS_DEVICE(&s->ext_gic);
100
+ sysbus_realize(busdev, &error_fatal);
101
/* Map CPU interface */
102
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
103
/* Map Distributer interface */
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
106
}
107
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
108
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
109
+ s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
110
}
111
112
/* Internal Interrupt Combiner */
113
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
114
}
115
116
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
117
+ object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
118
}
119
120
static void exynos4210_class_init(ObjectClass *klass, void *data)
121
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/hw/intc/exynos4210_gic.c
124
+++ b/hw/intc/exynos4210_gic.c
125
@@ -XXX,XX +XXX,XX @@
126
#include "qemu/module.h"
127
#include "hw/irq.h"
128
#include "hw/qdev-properties.h"
129
+#include "hw/intc/exynos4210_gic.h"
130
#include "hw/arm/exynos4210.h"
131
#include "qom/object.h"
132
133
@@ -XXX,XX +XXX,XX @@
134
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
135
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
136
137
-#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
138
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
139
-
140
-struct Exynos4210GicState {
141
- SysBusDevice parent_obj;
142
-
143
- MemoryRegion cpu_container;
144
- MemoryRegion dist_container;
145
- MemoryRegion cpu_alias[EXYNOS4210_NCPUS];
146
- MemoryRegion dist_alias[EXYNOS4210_NCPUS];
147
- uint32_t num_cpu;
148
- DeviceState *gic;
149
-};
150
-
151
static void exynos4210_gic_set_irq(void *opaque, int irq, int level)
152
{
153
Exynos4210GicState *s = (Exynos4210GicState *)opaque;
154
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
155
* enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
156
* doesn't figure this out, otherwise and gives spurious warnings.
157
*/
158
- assert(n <= EXYNOS4210_NCPUS);
159
+ assert(n <= EXYNOS4210_GIC_NCPUS);
160
for (i = 0; i < n; i++) {
161
/* Map CPU interface per SMP Core */
162
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
163
diff --git a/MAINTAINERS b/MAINTAINERS
18
diff --git a/MAINTAINERS b/MAINTAINERS
164
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
165
--- a/MAINTAINERS
20
--- a/MAINTAINERS
166
+++ b/MAINTAINERS
21
+++ b/MAINTAINERS
167
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
22
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
23
SBSA-REF
24
M: Radoslaw Biernacki <rad@semihalf.com>
25
M: Peter Maydell <peter.maydell@linaro.org>
26
-R: Leif Lindholm <quic_llindhol@quicinc.com>
27
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
28
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
168
L: qemu-arm@nongnu.org
29
L: qemu-arm@nongnu.org
169
S: Odd Fixes
30
S: Maintained
170
F: hw/*/exynos*
31
diff --git a/.mailmap b/.mailmap
171
-F: include/hw/arm/exynos4210.h
32
index XXXXXXX..XXXXXXX 100644
172
+F: include/hw/*/exynos*
33
--- a/.mailmap
173
34
+++ b/.mailmap
174
Calxeda Highbank
35
@@ -XXX,XX +XXX,XX @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
175
M: Rob Herring <robh@kernel.org>
36
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
37
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
38
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
39
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
40
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
41
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
42
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
43
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
44
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
45
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
46
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
176
--
47
--
177
2.25.1
48
2.34.1
49
50
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
1
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
2
2
3
Break out header file to allow embedding of the the TTC.
3
Previously, maintainer role was paused due to inactive email id. Commit id:
4
c009d715721861984c4987bcc78b7ee183e86d75.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Message-id: 20220331222017.2914409-2-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
include/hw/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++
11
MAINTAINERS | 2 ++
13
hw/timer/cadence_ttc.c | 32 ++------------------
12
1 file changed, 2 insertions(+)
14
2 files changed, 56 insertions(+), 30 deletions(-)
15
create mode 100644 include/hw/timer/cadence_ttc.h
16
13
17
diff --git a/include/hw/timer/cadence_ttc.h b/include/hw/timer/cadence_ttc.h
14
diff --git a/MAINTAINERS b/MAINTAINERS
18
new file mode 100644
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/include/hw/timer/cadence_ttc.h
22
@@ -XXX,XX +XXX,XX @@
23
+/*
24
+ * Xilinx Zynq cadence TTC model
25
+ *
26
+ * Copyright (c) 2011 Xilinx Inc.
27
+ * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@petalogix.com)
28
+ * Copyright (c) 2012 PetaLogix Pty Ltd.
29
+ * Written By Haibing Ma
30
+ * M. Habib
31
+ *
32
+ * This program is free software; you can redistribute it and/or
33
+ * modify it under the terms of the GNU General Public License
34
+ * as published by the Free Software Foundation; either version
35
+ * 2 of the License, or (at your option) any later version.
36
+ *
37
+ * You should have received a copy of the GNU General Public License along
38
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
39
+ */
40
+#ifndef HW_TIMER_CADENCE_TTC_H
41
+#define HW_TIMER_CADENCE_TTC_H
42
+
43
+#include "hw/sysbus.h"
44
+#include "qemu/timer.h"
45
+
46
+typedef struct {
47
+ QEMUTimer *timer;
48
+ int freq;
49
+
50
+ uint32_t reg_clock;
51
+ uint32_t reg_count;
52
+ uint32_t reg_value;
53
+ uint16_t reg_interval;
54
+ uint16_t reg_match[3];
55
+ uint32_t reg_intr;
56
+ uint32_t reg_intr_en;
57
+ uint32_t reg_event_ctrl;
58
+ uint32_t reg_event;
59
+
60
+ uint64_t cpu_time;
61
+ unsigned int cpu_time_valid;
62
+
63
+ qemu_irq irq;
64
+} CadenceTimerState;
65
+
66
+#define TYPE_CADENCE_TTC "cadence_ttc"
67
+OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
68
+
69
+struct CadenceTTCState {
70
+ SysBusDevice parent_obj;
71
+
72
+ MemoryRegion iomem;
73
+ CadenceTimerState timer[3];
74
+};
75
+
76
+#endif
77
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
78
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/timer/cadence_ttc.c
16
--- a/MAINTAINERS
80
+++ b/hw/timer/cadence_ttc.c
17
+++ b/MAINTAINERS
81
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-sb16-test.c
82
#include "qemu/timer.h"
19
83
#include "qom/object.h"
20
Xilinx CAN
84
21
M: Francisco Iglesias <francisco.iglesias@amd.com>
85
+#include "hw/timer/cadence_ttc.h"
22
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
86
+
23
S: Maintained
87
#ifdef CADENCE_TTC_ERR_DEBUG
24
F: hw/net/can/xlnx-*
88
#define DB_PRINT(...) do { \
25
F: include/hw/net/xlnx-*
89
fprintf(stderr, ": %s: ", __func__); \
26
@@ -XXX,XX +XXX,XX @@ F: include/hw/rx/
90
@@ -XXX,XX +XXX,XX @@
27
CAN bus subsystem and hardware
91
#define CLOCK_CTRL_PS_EN 0x00000001
28
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
92
#define CLOCK_CTRL_PS_V 0x0000001e
29
M: Francisco Iglesias <francisco.iglesias@amd.com>
93
30
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
94
-typedef struct {
31
S: Maintained
95
- QEMUTimer *timer;
32
W: https://canbus.pages.fel.cvut.cz/
96
- int freq;
33
F: net/can/*
97
-
98
- uint32_t reg_clock;
99
- uint32_t reg_count;
100
- uint32_t reg_value;
101
- uint16_t reg_interval;
102
- uint16_t reg_match[3];
103
- uint32_t reg_intr;
104
- uint32_t reg_intr_en;
105
- uint32_t reg_event_ctrl;
106
- uint32_t reg_event;
107
-
108
- uint64_t cpu_time;
109
- unsigned int cpu_time_valid;
110
-
111
- qemu_irq irq;
112
-} CadenceTimerState;
113
-
114
-#define TYPE_CADENCE_TTC "cadence_ttc"
115
-OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
116
-
117
-struct CadenceTTCState {
118
- SysBusDevice parent_obj;
119
-
120
- MemoryRegion iomem;
121
- CadenceTimerState timer[3];
122
-};
123
-
124
static void cadence_timer_update(CadenceTimerState *s)
125
{
126
qemu_set_irq(s->irq, !!(s->reg_intr & s->reg_intr_en));
127
--
34
--
128
2.25.1
35
2.34.1
diff view generated by jsdifflib