1
Last pullreq before 6.0 softfreeze: a few minor feature patches,
1
First arm pullreq of the cycle; this is mostly my softfloat NaN
2
some bugfixes, some cleanups.
2
handling series. (Lots more in my to-review queue, but I don't
3
like pullreqs growing too close to a hundred patches at a time :-))
3
4
5
thanks
4
-- PMM
6
-- PMM
5
7
6
The following changes since commit 6f34661b6c97a37a5efc27d31c037ddeda4547e2:
8
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
7
9
8
Merge remote-tracking branch 'remotes/vivier2/tags/trivial-branch-for-6.0-pull-request' into staging (2021-03-11 18:55:27 +0000)
10
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
9
11
10
are available in the Git repository at:
12
are available in the Git repository at:
11
13
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210312-1
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
13
15
14
for you to fetch changes up to 41f09f2e9f09e4dd386d84174a6dcb5136af17ca:
16
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
15
17
16
hw/display/pxa2xx: Inline template header (2021-03-12 13:26:08 +0000)
18
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
17
19
18
----------------------------------------------------------------
20
----------------------------------------------------------------
19
target-arm queue:
21
target-arm queue:
20
* versal: Support XRAMs and XRAM controller
22
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
21
* smmu: Various minor bug fixes
23
* fpu: Make muladd NaN handling runtime-selected, not compile-time
22
* SVE emulation: fix bugs handling odd vector lengths
24
* fpu: Make default NaN pattern runtime-selected, not compile-time
23
* allwinner-sun8i-emac: traverse transmit queue using TX_CUR_DESC register value
25
* fpu: Minor NaN-related cleanups
24
* tests/acceptance: fix orangepi-pc acceptance tests
26
* MAINTAINERS: email address updates
25
* hw/timer/sse-timer: Propagate eventual error in sse_timer_realize()
26
* hw/arm/virt: KVM: The IPA lower bound is 32
27
* npcm7xx: support MFT module
28
* pl110, pxa2xx_lcd: tidy up template headers
29
27
30
----------------------------------------------------------------
28
----------------------------------------------------------------
31
Andrew Jones (2):
29
Bernhard Beschow (5):
32
accel: kvm: Fix kvm_type invocation
30
hw/net/lan9118: Extract lan9118_phy
33
hw/arm/virt: KVM: The IPA lower bound is 32
31
hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations
32
hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register
33
hw/net/lan9118_phy: Reuse MII constants
34
hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement
34
35
35
Edgar E. Iglesias (2):
36
Leif Lindholm (1):
36
hw/misc: versal: Add a model of the XRAM controller
37
MAINTAINERS: update email address for Leif Lindholm
37
hw/arm: versal: Add support for the XRAMs
38
38
39
Eric Auger (7):
39
Peter Maydell (54):
40
intel_iommu: Fix mask may be uninitialized in vtd_context_device_invalidate
40
fpu: handle raising Invalid for infzero in pick_nan_muladd
41
dma: Introduce dma_aligned_pow2_mask()
41
fpu: Check for default_nan_mode before calling pickNaNMulAdd
42
virtio-iommu: Handle non power of 2 range invalidations
42
softfloat: Allow runtime choice of inf * 0 + NaN result
43
hw/arm/smmu-common: Fix smmu_iotlb_inv_iova when asid is not set
43
tests/fp: Explicitly set inf-zero-nan rule
44
hw/arm/smmuv3: Enforce invalidation on a power of two range
44
target/arm: Set FloatInfZeroNaNRule explicitly
45
hw/arm/smmuv3: Fix SMMU_CMD_CFGI_STE_RANGE handling
45
target/s390: Set FloatInfZeroNaNRule explicitly
46
hw/arm/smmuv3: Uniformize sid traces
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
47
94
48
Hao Wu (5):
95
Richard Henderson (11):
49
hw/misc: Add GPIOs for duty in NPCM7xx PWM
96
target/arm: Copy entire float_status in is_ebf
50
hw/misc: Add NPCM7XX MFT Module
97
softfloat: Inline pickNaNMulAdd
51
hw/arm: Add MFT device to NPCM7xx Soc
98
softfloat: Use goto for default nan case in pick_nan_muladd
52
hw/arm: Connect PWM fans in NPCM7XX boards
99
softfloat: Remove which from parts_pick_nan_muladd
53
tests/qtest: Test PWM fan RPM using MFT in PWM test
100
softfloat: Pad array size in pick_nan_muladd
101
softfloat: Move propagateFloatx80NaN to softfloat.c
102
softfloat: Use parts_pick_nan in propagateFloatx80NaN
103
softfloat: Inline pickNaN
104
softfloat: Share code between parts_pick_nan cases
105
softfloat: Sink frac_cmp in parts_pick_nan until needed
106
softfloat: Replace WHICH with RET in parts_pick_nan
54
107
55
Niek Linnenbank (5):
108
Vikram Garhwal (1):
56
hw/net/allwinner-sun8i-emac: traverse transmit queue using TX_CUR_DESC register value
109
MAINTAINERS: Add correct email address for Vikram Garhwal
57
tests/acceptance/boot_linux_console: remove Armbian 19.11.3 bionic test for orangepi-pc machine
58
tests/acceptance/boot_linux_console: change URL for test_arm_orangepi_bionic_20_08
59
tests/acceptance: update sunxi kernel from armbian to 5.10.16
60
tests/acceptance: drop ARMBIAN_ARTIFACTS_CACHED condition for orangepi-pc, cubieboard tests
61
110
62
Peter Maydell (9):
111
MAINTAINERS | 4 +-
63
hw/display/pl110: Remove dead code for non-32-bpp surfaces
112
include/fpu/softfloat-helpers.h | 38 +++-
64
hw/display/pl110: Pull included-once parts of template header into pl110.c
113
include/fpu/softfloat-types.h | 89 +++++++-
65
hw/display/pl110: Remove use of BITS from pl110_template.h
114
include/hw/net/imx_fec.h | 9 +-
66
hw/display/pxa2xx_lcd: Remove dead code for non-32-bpp surfaces
115
include/hw/net/lan9118_phy.h | 37 ++++
67
hw/display/pxa2xx_lcd: Remove dest_width state field
116
include/hw/net/mii.h | 6 +
68
hw/display/pxa2xx: Remove use of BITS in pxa2xx_template.h
117
target/mips/fpu_helper.h | 20 ++
69
hw/display/pxa2xx: Apply brace-related coding style fixes to template header
118
target/sparc/helper.h | 4 +-
70
hw/display/pxa2xx: Apply whitespace-only coding style fixes to template header
119
fpu/softfloat.c | 19 ++
71
hw/display/pxa2xx: Inline template header
120
hw/net/imx_fec.c | 146 ++------------
72
121
hw/net/lan9118.c | 137 ++-----------
73
Philippe Mathieu-Daudé (1):
122
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
74
hw/timer/sse-timer: Propagate eventual error in sse_timer_realize()
123
linux-user/arm/nwfpe/fpa11.c | 5 +
75
124
target/alpha/cpu.c | 2 +
76
Richard Henderson (8):
125
target/arm/cpu.c | 10 +
77
target/arm: Fix sve_uzp_p vs odd vector lengths
126
target/arm/tcg/vec_helper.c | 20 +-
78
target/arm: Fix sve_zip_p vs odd vector lengths
127
target/hexagon/cpu.c | 2 +
79
target/arm: Fix sve_punpk_p vs odd vector lengths
128
target/hppa/fpu_helper.c | 12 ++
80
target/arm: Update find_last_active for PREDDESC
129
target/i386/tcg/fpu_helper.c | 12 ++
81
target/arm: Update BRKA, BRKB, BRKN for PREDDESC
130
target/loongarch/tcg/fpu_helper.c | 14 +-
82
target/arm: Update CNTP for PREDDESC
131
target/m68k/cpu.c | 14 +-
83
target/arm: Update WHILE for PREDDESC
132
target/m68k/fpu_helper.c | 6 +-
84
target/arm: Update sve reduction vs simd_desc
133
target/m68k/helper.c | 6 +-
85
134
target/microblaze/cpu.c | 2 +
86
docs/system/arm/nuvoton.rst | 2 +-
135
target/mips/msa.c | 10 +
87
docs/system/arm/xlnx-versal-virt.rst | 1 +
136
target/openrisc/cpu.c | 2 +
88
hw/arm/smmu-internal.h | 5 +
137
target/ppc/cpu_init.c | 19 ++
89
hw/display/pl110_template.h | 120 +-------
138
target/ppc/fpu_helper.c | 3 +-
90
hw/display/pxa2xx_template.h | 447 ---------------------------
139
target/riscv/cpu.c | 2 +
91
include/hw/arm/npcm7xx.h | 13 +-
140
target/rx/cpu.c | 2 +
92
include/hw/arm/xlnx-versal.h | 13 +
141
target/s390x/cpu.c | 5 +
93
include/hw/boards.h | 1 +
142
target/sh4/cpu.c | 2 +
94
include/hw/misc/npcm7xx_mft.h | 70 +++++
143
target/sparc/cpu.c | 6 +
95
include/hw/misc/npcm7xx_pwm.h | 4 +-
144
target/sparc/fop_helper.c | 8 +-
96
include/hw/misc/xlnx-versal-xramc.h | 97 ++++++
145
target/sparc/translate.c | 4 +-
97
include/sysemu/dma.h | 12 +
146
target/tricore/helper.c | 2 +
98
target/arm/kvm_arm.h | 6 +-
147
target/xtensa/cpu.c | 4 +
99
accel/kvm/kvm-all.c | 2 +
148
target/xtensa/fpu_helper.c | 3 +-
100
hw/arm/npcm7xx.c | 45 ++-
149
tests/fp/fp-bench.c | 7 +
101
hw/arm/npcm7xx_boards.c | 99 ++++++
150
tests/fp/fp-test-log2.c | 1 +
102
hw/arm/smmu-common.c | 32 +-
151
tests/fp/fp-test.c | 7 +
103
hw/arm/smmuv3.c | 58 ++--
152
fpu/softfloat-parts.c.inc | 152 +++++++++++---
104
hw/arm/virt.c | 23 +-
153
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
105
hw/arm/xlnx-versal.c | 36 +++
154
.mailmap | 5 +-
106
hw/display/pl110.c | 123 +++++---
155
hw/net/Kconfig | 5 +
107
hw/display/pxa2xx_lcd.c | 520 ++++++++++++++++++++++++++-----
156
hw/net/meson.build | 1 +
108
hw/i386/intel_iommu.c | 32 +-
157
hw/net/trace-events | 10 +-
109
hw/misc/npcm7xx_mft.c | 540 +++++++++++++++++++++++++++++++++
158
47 files changed, 778 insertions(+), 730 deletions(-)
110
hw/misc/npcm7xx_pwm.c | 4 +
159
create mode 100644 include/hw/net/lan9118_phy.h
111
hw/misc/xlnx-versal-xramc.c | 253 +++++++++++++++
160
create mode 100644 hw/net/lan9118_phy.c
112
hw/net/allwinner-sun8i-emac.c | 62 ++--
113
hw/timer/sse-timer.c | 1 +
114
hw/virtio/virtio-iommu.c | 19 +-
115
softmmu/dma-helpers.c | 26 ++
116
target/arm/kvm.c | 4 +-
117
target/arm/sve_helper.c | 107 ++++---
118
target/arm/translate-sve.c | 26 +-
119
tests/qtest/npcm7xx_pwm-test.c | 205 ++++++++++++-
120
hw/arm/trace-events | 24 +-
121
hw/misc/meson.build | 2 +
122
hw/misc/trace-events | 8 +
123
tests/acceptance/boot_linux_console.py | 120 +++-----
124
tests/acceptance/replay_kernel.py | 10 +-
125
39 files changed, 2235 insertions(+), 937 deletions(-)
126
delete mode 100644 hw/display/pxa2xx_template.h
127
create mode 100644 include/hw/misc/npcm7xx_mft.h
128
create mode 100644 include/hw/misc/xlnx-versal-xramc.h
129
create mode 100644 hw/misc/npcm7xx_mft.c
130
create mode 100644 hw/misc/xlnx-versal-xramc.c
131
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Add a model of the Xilinx Versal Accelerator RAM (XRAM).
3
A very similar implementation of the same device exists in imx_fec. Prepare for
4
This is mainly a stub to make firmware happy. The size of
4
a common implementation by extracting a device model into its own files.
5
the RAMs can be probed. The interrupt mask logic is
6
modelled but none of the interrups will ever be raised
7
unless injected.
8
5
9
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Some migration state has been moved into the new device model which breaks
10
Message-id: 20210308224637.2949533-2-edgar.iglesias@gmail.com
7
migration compatibility for the following machines:
8
* smdkc210
9
* realview-*
10
* vexpress-*
11
* kzm
12
* mps2-*
13
14
While breaking migration ABI, fix the size of the MII registers to be 16 bit,
15
as defined by IEEE 802.3u.
16
17
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
18
Tested-by: Guenter Roeck <linux@roeck-us.net>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Message-id: 20241102125724.532843-2-shentey@gmail.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
22
---
14
include/hw/misc/xlnx-versal-xramc.h | 97 +++++++++++
23
include/hw/net/lan9118_phy.h | 37 ++++++++
15
hw/misc/xlnx-versal-xramc.c | 253 ++++++++++++++++++++++++++++
24
hw/net/lan9118.c | 137 +++++-----------------------
16
hw/misc/meson.build | 1 +
25
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
17
3 files changed, 351 insertions(+)
26
hw/net/Kconfig | 4 +
18
create mode 100644 include/hw/misc/xlnx-versal-xramc.h
27
hw/net/meson.build | 1 +
19
create mode 100644 hw/misc/xlnx-versal-xramc.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
20
31
21
diff --git a/include/hw/misc/xlnx-versal-xramc.h b/include/hw/misc/xlnx-versal-xramc.h
32
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
22
new file mode 100644
33
new file mode 100644
23
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
24
--- /dev/null
35
--- /dev/null
25
+++ b/include/hw/misc/xlnx-versal-xramc.h
36
+++ b/include/hw/net/lan9118_phy.h
26
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
27
+/*
38
+/*
28
+ * QEMU model of the Xilinx XRAM Controller.
39
+ * SMSC LAN9118 PHY emulation
29
+ *
40
+ *
30
+ * Copyright (c) 2021 Xilinx Inc.
41
+ * Copyright (c) 2009 CodeSourcery, LLC.
31
+ * SPDX-License-Identifier: GPL-2.0-or-later
42
+ * Written by Paul Brook
32
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
43
+ *
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.
33
+ */
46
+ */
34
+
47
+
35
+#ifndef XLNX_VERSAL_XRAMC_H
48
+#ifndef HW_NET_LAN9118_PHY_H
36
+#define XLNX_VERSAL_XRAMC_H
49
+#define HW_NET_LAN9118_PHY_H
37
+
50
+
51
+#include "qom/object.h"
38
+#include "hw/sysbus.h"
52
+#include "hw/sysbus.h"
39
+#include "hw/register.h"
53
+
40
+
54
+#define TYPE_LAN9118_PHY "lan9118-phy"
41
+#define TYPE_XLNX_XRAM_CTRL "xlnx.versal-xramc"
55
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
42
+
56
+
43
+#define XLNX_XRAM_CTRL(obj) \
57
+typedef struct Lan9118PhyState {
44
+ OBJECT_CHECK(XlnxXramCtrl, (obj), TYPE_XLNX_XRAM_CTRL)
45
+
46
+REG32(XRAM_ERR_CTRL, 0x0)
47
+ FIELD(XRAM_ERR_CTRL, UE_RES, 3, 1)
48
+ FIELD(XRAM_ERR_CTRL, PWR_ERR_RES, 2, 1)
49
+ FIELD(XRAM_ERR_CTRL, PZ_ERR_RES, 1, 1)
50
+ FIELD(XRAM_ERR_CTRL, APB_ERR_RES, 0, 1)
51
+REG32(XRAM_ISR, 0x4)
52
+ FIELD(XRAM_ISR, INV_APB, 0, 1)
53
+REG32(XRAM_IMR, 0x8)
54
+ FIELD(XRAM_IMR, INV_APB, 0, 1)
55
+REG32(XRAM_IEN, 0xc)
56
+ FIELD(XRAM_IEN, INV_APB, 0, 1)
57
+REG32(XRAM_IDS, 0x10)
58
+ FIELD(XRAM_IDS, INV_APB, 0, 1)
59
+REG32(XRAM_ECC_CNTL, 0x14)
60
+ FIELD(XRAM_ECC_CNTL, FI_MODE, 2, 1)
61
+ FIELD(XRAM_ECC_CNTL, DET_ONLY, 1, 1)
62
+ FIELD(XRAM_ECC_CNTL, ECC_ON_OFF, 0, 1)
63
+REG32(XRAM_CLR_EXE, 0x18)
64
+ FIELD(XRAM_CLR_EXE, MON_7, 7, 1)
65
+ FIELD(XRAM_CLR_EXE, MON_6, 6, 1)
66
+ FIELD(XRAM_CLR_EXE, MON_5, 5, 1)
67
+ FIELD(XRAM_CLR_EXE, MON_4, 4, 1)
68
+ FIELD(XRAM_CLR_EXE, MON_3, 3, 1)
69
+ FIELD(XRAM_CLR_EXE, MON_2, 2, 1)
70
+ FIELD(XRAM_CLR_EXE, MON_1, 1, 1)
71
+ FIELD(XRAM_CLR_EXE, MON_0, 0, 1)
72
+REG32(XRAM_CE_FFA, 0x1c)
73
+ FIELD(XRAM_CE_FFA, ADDR, 0, 20)
74
+REG32(XRAM_CE_FFD0, 0x20)
75
+REG32(XRAM_CE_FFD1, 0x24)
76
+REG32(XRAM_CE_FFD2, 0x28)
77
+REG32(XRAM_CE_FFD3, 0x2c)
78
+REG32(XRAM_CE_FFE, 0x30)
79
+ FIELD(XRAM_CE_FFE, SYNDROME, 0, 16)
80
+REG32(XRAM_UE_FFA, 0x34)
81
+ FIELD(XRAM_UE_FFA, ADDR, 0, 20)
82
+REG32(XRAM_UE_FFD0, 0x38)
83
+REG32(XRAM_UE_FFD1, 0x3c)
84
+REG32(XRAM_UE_FFD2, 0x40)
85
+REG32(XRAM_UE_FFD3, 0x44)
86
+REG32(XRAM_UE_FFE, 0x48)
87
+ FIELD(XRAM_UE_FFE, SYNDROME, 0, 16)
88
+REG32(XRAM_FI_D0, 0x4c)
89
+REG32(XRAM_FI_D1, 0x50)
90
+REG32(XRAM_FI_D2, 0x54)
91
+REG32(XRAM_FI_D3, 0x58)
92
+REG32(XRAM_FI_SY, 0x5c)
93
+ FIELD(XRAM_FI_SY, DATA, 0, 16)
94
+REG32(XRAM_RMW_UE_FFA, 0x70)
95
+ FIELD(XRAM_RMW_UE_FFA, ADDR, 0, 20)
96
+REG32(XRAM_FI_CNTR, 0x74)
97
+ FIELD(XRAM_FI_CNTR, COUNT, 0, 24)
98
+REG32(XRAM_IMP, 0x80)
99
+ FIELD(XRAM_IMP, SIZE, 0, 4)
100
+REG32(XRAM_PRDY_DBG, 0x84)
101
+ FIELD(XRAM_PRDY_DBG, ISLAND3, 12, 4)
102
+ FIELD(XRAM_PRDY_DBG, ISLAND2, 8, 4)
103
+ FIELD(XRAM_PRDY_DBG, ISLAND1, 4, 4)
104
+ FIELD(XRAM_PRDY_DBG, ISLAND0, 0, 4)
105
+REG32(XRAM_SAFETY_CHK, 0xff8)
106
+
107
+#define XRAM_CTRL_R_MAX (R_XRAM_SAFETY_CHK + 1)
108
+
109
+typedef struct XlnxXramCtrl {
110
+ SysBusDevice parent_obj;
58
+ SysBusDevice parent_obj;
111
+ MemoryRegion ram;
59
+
60
+ uint16_t status;
61
+ uint16_t control;
62
+ uint16_t advertise;
63
+ uint16_t ints;
64
+ uint16_t int_mask;
112
+ qemu_irq irq;
65
+ qemu_irq irq;
113
+
66
+ bool link_down;
114
+ struct {
67
+} Lan9118PhyState;
115
+ uint64_t size;
68
+
116
+ unsigned int encoded_size;
69
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down);
117
+ } cfg;
70
+void lan9118_phy_reset(Lan9118PhyState *s);
118
+
71
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg);
119
+ RegisterInfoArray *reg_array;
72
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val);
120
+ uint32_t regs[XRAM_CTRL_R_MAX];
73
+
121
+ RegisterInfo regs_info[XRAM_CTRL_R_MAX];
122
+} XlnxXramCtrl;
123
+#endif
74
+#endif
124
diff --git a/hw/misc/xlnx-versal-xramc.c b/hw/misc/xlnx-versal-xramc.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
125
new file mode 100644
312
new file mode 100644
126
index XXXXXXX..XXXXXXX
313
index XXXXXXX..XXXXXXX
127
--- /dev/null
314
--- /dev/null
128
+++ b/hw/misc/xlnx-versal-xramc.c
315
+++ b/hw/net/lan9118_phy.c
129
@@ -XXX,XX +XXX,XX @@
316
@@ -XXX,XX +XXX,XX @@
130
+/*
317
+/*
131
+ * QEMU model of the Xilinx XRAM Controller.
318
+ * SMSC LAN9118 PHY emulation
132
+ *
319
+ *
133
+ * Copyright (c) 2021 Xilinx Inc.
320
+ * Copyright (c) 2009 CodeSourcery, LLC.
134
+ * SPDX-License-Identifier: GPL-2.0-or-later
321
+ * Written by Paul Brook
135
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
322
+ *
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.
136
+ */
327
+ */
137
+
328
+
138
+#include "qemu/osdep.h"
329
+#include "qemu/osdep.h"
139
+#include "qemu/units.h"
330
+#include "hw/net/lan9118_phy.h"
140
+#include "qapi/error.h"
331
+#include "hw/irq.h"
332
+#include "hw/resettable.h"
141
+#include "migration/vmstate.h"
333
+#include "migration/vmstate.h"
142
+#include "hw/sysbus.h"
334
+#include "qemu/log.h"
143
+#include "hw/register.h"
335
+
144
+#include "hw/qdev-properties.h"
336
+#define PHY_INT_ENERGYON (1 << 7)
145
+#include "hw/irq.h"
337
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
146
+#include "hw/misc/xlnx-versal-xramc.h"
338
+#define PHY_INT_FAULT (1 << 5)
147
+
339
+#define PHY_INT_DOWN (1 << 4)
148
+#ifndef XLNX_XRAM_CTRL_ERR_DEBUG
340
+#define PHY_INT_AUTONEG_LP (1 << 3)
149
+#define XLNX_XRAM_CTRL_ERR_DEBUG 0
341
+#define PHY_INT_PARFAULT (1 << 2)
150
+#endif
342
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
151
+
343
+
152
+static void xram_update_irq(XlnxXramCtrl *s)
344
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
153
+{
345
+{
154
+ bool pending = s->regs[R_XRAM_ISR] & ~s->regs[R_XRAM_IMR];
346
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
155
+ qemu_set_irq(s->irq, pending);
347
+}
156
+}
348
+
157
+
349
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
158
+static void xram_isr_postw(RegisterInfo *reg, uint64_t val64)
350
+{
159
+{
351
+ uint16_t val;
160
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
352
+
161
+ xram_update_irq(s);
353
+ switch (reg) {
162
+}
354
+ case 0: /* Basic Control */
163
+
355
+ return s->control;
164
+static uint64_t xram_ien_prew(RegisterInfo *reg, uint64_t val64)
356
+ case 1: /* Basic Status */
165
+{
357
+ return s->status;
166
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
358
+ case 2: /* ID1 */
167
+ uint32_t val = val64;
359
+ return 0x0007;
168
+
360
+ case 3: /* ID2 */
169
+ s->regs[R_XRAM_IMR] &= ~val;
361
+ return 0xc0d1;
170
+ xram_update_irq(s);
362
+ case 4: /* Auto-neg advertisement */
171
+ return 0;
363
+ return s->advertise;
172
+}
364
+ case 5: /* Auto-neg Link Partner Ability */
173
+
365
+ return 0x0f71;
174
+static uint64_t xram_ids_prew(RegisterInfo *reg, uint64_t val64)
366
+ case 6: /* Auto-neg Expansion */
175
+{
367
+ return 1;
176
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
368
+ /* TODO 17, 18, 27, 29, 30, 31 */
177
+ uint32_t val = val64;
369
+ case 29: /* Interrupt source. */
178
+
370
+ val = s->ints;
179
+ s->regs[R_XRAM_IMR] |= val;
371
+ s->ints = 0;
180
+ xram_update_irq(s);
372
+ lan9118_phy_update_irq(s);
181
+ return 0;
373
+ return val;
182
+}
374
+ case 30: /* Interrupt mask */
183
+
375
+ return s->int_mask;
184
+static const RegisterAccessInfo xram_ctrl_regs_info[] = {
376
+ default:
185
+ { .name = "XRAM_ERR_CTRL", .addr = A_XRAM_ERR_CTRL,
377
+ qemu_log_mask(LOG_GUEST_ERROR,
186
+ .reset = 0xf,
378
+ "lan9118_phy_read: PHY read reg %d\n", reg);
187
+ .rsvd = 0xfffffff0,
379
+ return 0;
188
+ },{ .name = "XRAM_ISR", .addr = A_XRAM_ISR,
380
+ }
189
+ .rsvd = 0xfffff800,
381
+}
190
+ .w1c = 0x7ff,
382
+
191
+ .post_write = xram_isr_postw,
383
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
192
+ },{ .name = "XRAM_IMR", .addr = A_XRAM_IMR,
384
+{
193
+ .reset = 0x7ff,
385
+ switch (reg) {
194
+ .rsvd = 0xfffff800,
386
+ case 0: /* Basic Control */
195
+ .ro = 0x7ff,
387
+ if (val & 0x8000) {
196
+ },{ .name = "XRAM_IEN", .addr = A_XRAM_IEN,
388
+ lan9118_phy_reset(s);
197
+ .rsvd = 0xfffff800,
389
+ break;
198
+ .pre_write = xram_ien_prew,
390
+ }
199
+ },{ .name = "XRAM_IDS", .addr = A_XRAM_IDS,
391
+ s->control = val & 0x7980;
200
+ .rsvd = 0xfffff800,
392
+ /* Complete autonegotiation immediately. */
201
+ .pre_write = xram_ids_prew,
393
+ if (val & 0x1000) {
202
+ },{ .name = "XRAM_ECC_CNTL", .addr = A_XRAM_ECC_CNTL,
394
+ s->status |= 0x0020;
203
+ .rsvd = 0xfffffff8,
395
+ }
204
+ },{ .name = "XRAM_CLR_EXE", .addr = A_XRAM_CLR_EXE,
396
+ break;
205
+ .rsvd = 0xffffff00,
397
+ case 4: /* Auto-neg advertisement */
206
+ },{ .name = "XRAM_CE_FFA", .addr = A_XRAM_CE_FFA,
398
+ s->advertise = (val & 0x2d7f) | 0x80;
207
+ .rsvd = 0xfff00000,
399
+ break;
208
+ .ro = 0xfffff,
400
+ /* TODO 17, 18, 27, 31 */
209
+ },{ .name = "XRAM_CE_FFD0", .addr = A_XRAM_CE_FFD0,
401
+ case 30: /* Interrupt mask */
210
+ .ro = 0xffffffff,
402
+ s->int_mask = val & 0xff;
211
+ },{ .name = "XRAM_CE_FFD1", .addr = A_XRAM_CE_FFD1,
403
+ lan9118_phy_update_irq(s);
212
+ .ro = 0xffffffff,
404
+ break;
213
+ },{ .name = "XRAM_CE_FFD2", .addr = A_XRAM_CE_FFD2,
405
+ default:
214
+ .ro = 0xffffffff,
406
+ qemu_log_mask(LOG_GUEST_ERROR,
215
+ },{ .name = "XRAM_CE_FFD3", .addr = A_XRAM_CE_FFD3,
407
+ "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
216
+ .ro = 0xffffffff,
408
+ }
217
+ },{ .name = "XRAM_CE_FFE", .addr = A_XRAM_CE_FFE,
409
+}
218
+ .rsvd = 0xffff0000,
410
+
219
+ .ro = 0xffff,
411
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
220
+ },{ .name = "XRAM_UE_FFA", .addr = A_XRAM_UE_FFA,
412
+{
221
+ .rsvd = 0xfff00000,
413
+ s->link_down = link_down;
222
+ .ro = 0xfffff,
414
+
223
+ },{ .name = "XRAM_UE_FFD0", .addr = A_XRAM_UE_FFD0,
415
+ /* Autonegotiation status mirrors link status. */
224
+ .ro = 0xffffffff,
416
+ if (link_down) {
225
+ },{ .name = "XRAM_UE_FFD1", .addr = A_XRAM_UE_FFD1,
417
+ s->status &= ~0x0024;
226
+ .ro = 0xffffffff,
418
+ s->ints |= PHY_INT_DOWN;
227
+ },{ .name = "XRAM_UE_FFD2", .addr = A_XRAM_UE_FFD2,
419
+ } else {
228
+ .ro = 0xffffffff,
420
+ s->status |= 0x0024;
229
+ },{ .name = "XRAM_UE_FFD3", .addr = A_XRAM_UE_FFD3,
421
+ s->ints |= PHY_INT_ENERGYON;
230
+ .ro = 0xffffffff,
422
+ s->ints |= PHY_INT_AUTONEG_COMPLETE;
231
+ },{ .name = "XRAM_UE_FFE", .addr = A_XRAM_UE_FFE,
423
+ }
232
+ .rsvd = 0xffff0000,
424
+ lan9118_phy_update_irq(s);
233
+ .ro = 0xffff,
425
+}
234
+ },{ .name = "XRAM_FI_D0", .addr = A_XRAM_FI_D0,
426
+
235
+ },{ .name = "XRAM_FI_D1", .addr = A_XRAM_FI_D1,
427
+void lan9118_phy_reset(Lan9118PhyState *s)
236
+ },{ .name = "XRAM_FI_D2", .addr = A_XRAM_FI_D2,
428
+{
237
+ },{ .name = "XRAM_FI_D3", .addr = A_XRAM_FI_D3,
429
+ s->control = 0x3000;
238
+ },{ .name = "XRAM_FI_SY", .addr = A_XRAM_FI_SY,
430
+ s->status = 0x7809;
239
+ .rsvd = 0xffff0000,
431
+ s->advertise = 0x01e1;
240
+ },{ .name = "XRAM_RMW_UE_FFA", .addr = A_XRAM_RMW_UE_FFA,
432
+ s->int_mask = 0;
241
+ .rsvd = 0xfff00000,
433
+ s->ints = 0;
242
+ .ro = 0xfffff,
434
+ lan9118_phy_update_link(s, s->link_down);
243
+ },{ .name = "XRAM_FI_CNTR", .addr = A_XRAM_FI_CNTR,
435
+}
244
+ .rsvd = 0xff000000,
436
+
245
+ },{ .name = "XRAM_IMP", .addr = A_XRAM_IMP,
437
+static void lan9118_phy_reset_hold(Object *obj, ResetType type)
246
+ .reset = 0x4,
438
+{
247
+ .rsvd = 0xfffffff0,
439
+ Lan9118PhyState *s = LAN9118_PHY(obj);
248
+ .ro = 0xf,
440
+
249
+ },{ .name = "XRAM_PRDY_DBG", .addr = A_XRAM_PRDY_DBG,
441
+ lan9118_phy_reset(s);
250
+ .reset = 0xffff,
442
+}
251
+ .rsvd = 0xffff0000,
443
+
252
+ .ro = 0xffff,
444
+static void lan9118_phy_init(Object *obj)
253
+ },{ .name = "XRAM_SAFETY_CHK", .addr = A_XRAM_SAFETY_CHK,
445
+{
446
+ Lan9118PhyState *s = LAN9118_PHY(obj);
447
+
448
+ qdev_init_gpio_out(DEVICE(s), &s->irq, 1);
449
+}
450
+
451
+static const VMStateDescription vmstate_lan9118_phy = {
452
+ .name = "lan9118-phy",
453
+ .version_id = 1,
454
+ .minimum_version_id = 1,
455
+ .fields = (const VMStateField[]) {
456
+ VMSTATE_UINT16(control, Lan9118PhyState),
457
+ VMSTATE_UINT16(status, Lan9118PhyState),
458
+ VMSTATE_UINT16(advertise, Lan9118PhyState),
459
+ VMSTATE_UINT16(ints, Lan9118PhyState),
460
+ VMSTATE_UINT16(int_mask, Lan9118PhyState),
461
+ VMSTATE_BOOL(link_down, Lan9118PhyState),
462
+ VMSTATE_END_OF_LIST()
254
+ }
463
+ }
255
+};
464
+};
256
+
465
+
257
+static void xram_ctrl_reset_enter(Object *obj, ResetType type)
466
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
258
+{
467
+{
259
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
468
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
260
+ unsigned int i;
469
+ DeviceClass *dc = DEVICE_CLASS(klass);
261
+
470
+
262
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
471
+ rc->phases.hold = lan9118_phy_reset_hold;
263
+ register_reset(&s->regs_info[i]);
472
+ dc->vmsd = &vmstate_lan9118_phy;
264
+ }
473
+}
265
+
474
+
266
+ ARRAY_FIELD_DP32(s->regs, XRAM_IMP, SIZE, s->cfg.encoded_size);
475
+static const TypeInfo types[] = {
267
+}
476
+ {
268
+
477
+ .name = TYPE_LAN9118_PHY,
269
+static void xram_ctrl_reset_hold(Object *obj)
478
+ .parent = TYPE_SYS_BUS_DEVICE,
270
+{
479
+ .instance_size = sizeof(Lan9118PhyState),
271
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
480
+ .instance_init = lan9118_phy_init,
272
+
481
+ .class_init = lan9118_phy_class_init,
273
+ xram_update_irq(s);
274
+}
275
+
276
+static const MemoryRegionOps xram_ctrl_ops = {
277
+ .read = register_read_memory,
278
+ .write = register_write_memory,
279
+ .endianness = DEVICE_LITTLE_ENDIAN,
280
+ .valid = {
281
+ .min_access_size = 4,
282
+ .max_access_size = 4,
283
+ },
284
+};
285
+
286
+static void xram_ctrl_realize(DeviceState *dev, Error **errp)
287
+{
288
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
289
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(dev);
290
+
291
+ switch (s->cfg.size) {
292
+ case 64 * KiB:
293
+ s->cfg.encoded_size = 0;
294
+ break;
295
+ case 128 * KiB:
296
+ s->cfg.encoded_size = 1;
297
+ break;
298
+ case 256 * KiB:
299
+ s->cfg.encoded_size = 2;
300
+ break;
301
+ case 512 * KiB:
302
+ s->cfg.encoded_size = 3;
303
+ break;
304
+ case 1 * MiB:
305
+ s->cfg.encoded_size = 4;
306
+ break;
307
+ default:
308
+ error_setg(errp, "Unsupported XRAM size %" PRId64, s->cfg.size);
309
+ return;
310
+ }
311
+
312
+ memory_region_init_ram(&s->ram, OBJECT(s),
313
+ object_get_canonical_path_component(OBJECT(s)),
314
+ s->cfg.size, &error_fatal);
315
+ sysbus_init_mmio(sbd, &s->ram);
316
+}
317
+
318
+static void xram_ctrl_init(Object *obj)
319
+{
320
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
321
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
322
+
323
+ s->reg_array =
324
+ register_init_block32(DEVICE(obj), xram_ctrl_regs_info,
325
+ ARRAY_SIZE(xram_ctrl_regs_info),
326
+ s->regs_info, s->regs,
327
+ &xram_ctrl_ops,
328
+ XLNX_XRAM_CTRL_ERR_DEBUG,
329
+ XRAM_CTRL_R_MAX * 4);
330
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
331
+ sysbus_init_irq(sbd, &s->irq);
332
+}
333
+
334
+static void xram_ctrl_finalize(Object *obj)
335
+{
336
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
337
+ register_finalize_block(s->reg_array);
338
+}
339
+
340
+static const VMStateDescription vmstate_xram_ctrl = {
341
+ .name = TYPE_XLNX_XRAM_CTRL,
342
+ .version_id = 1,
343
+ .minimum_version_id = 1,
344
+ .fields = (VMStateField[]) {
345
+ VMSTATE_UINT32_ARRAY(regs, XlnxXramCtrl, XRAM_CTRL_R_MAX),
346
+ VMSTATE_END_OF_LIST(),
347
+ }
482
+ }
348
+};
483
+};
349
+
484
+
350
+static Property xram_ctrl_properties[] = {
485
+DEFINE_TYPES(types)
351
+ DEFINE_PROP_UINT64("size", XlnxXramCtrl, cfg.size, 1 * MiB),
486
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
352
+ DEFINE_PROP_END_OF_LIST(),
353
+};
354
+
355
+static void xram_ctrl_class_init(ObjectClass *klass, void *data)
356
+{
357
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
358
+ DeviceClass *dc = DEVICE_CLASS(klass);
359
+
360
+ dc->realize = xram_ctrl_realize;
361
+ dc->vmsd = &vmstate_xram_ctrl;
362
+ device_class_set_props(dc, xram_ctrl_properties);
363
+
364
+ rc->phases.enter = xram_ctrl_reset_enter;
365
+ rc->phases.hold = xram_ctrl_reset_hold;
366
+}
367
+
368
+static const TypeInfo xram_ctrl_info = {
369
+ .name = TYPE_XLNX_XRAM_CTRL,
370
+ .parent = TYPE_SYS_BUS_DEVICE,
371
+ .instance_size = sizeof(XlnxXramCtrl),
372
+ .class_init = xram_ctrl_class_init,
373
+ .instance_init = xram_ctrl_init,
374
+ .instance_finalize = xram_ctrl_finalize,
375
+};
376
+
377
+static void xram_ctrl_register_types(void)
378
+{
379
+ type_register_static(&xram_ctrl_info);
380
+}
381
+
382
+type_init(xram_ctrl_register_types)
383
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
384
index XXXXXXX..XXXXXXX 100644
487
index XXXXXXX..XXXXXXX 100644
385
--- a/hw/misc/meson.build
488
--- a/hw/net/Kconfig
386
+++ b/hw/misc/meson.build
489
+++ b/hw/net/Kconfig
387
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
490
@@ -XXX,XX +XXX,XX @@ config VMXNET3_PCI
388
))
491
config SMC91C111
389
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
492
bool
390
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
493
391
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-xramc.c'))
494
+config LAN9118_PHY
392
softmmu_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: files('stm32f2xx_syscfg.c'))
495
+ bool
393
softmmu_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: files('stm32f4xx_syscfg.c'))
496
+
394
softmmu_ss.add(when: 'CONFIG_STM32F4XX_EXTI', if_true: files('stm32f4xx_exti.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'))
395
--
515
--
396
2.20.1
516
2.34.1
397
398
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
As of today, the driver can invalidate a number of pages that is
3
imx_fec models the same PHY as lan9118_phy. The code is almost the same with
4
not a power of 2. However IOTLB unmap notifications and internal
4
imx_fec having more logging and tracing. Merge these improvements into
5
IOTLB invalidations work with masks leading to erroneous
5
lan9118_phy and reuse in imx_fec to fix the code duplication.
6
invalidations.
7
6
8
In case the range is not a power of 2, split invalidations into
7
Some migration state how resides in the new device model which breaks migration
9
power of 2 invalidations.
8
compatibility for the following machines:
9
* imx25-pdk
10
* sabrelite
11
* mcimx7d-sabre
12
* mcimx6ul-evk
10
13
11
When looking for a single page entry in the vSMMU internal IOTLB,
14
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
12
let's make sure that if the entry is not found using a
15
Tested-by: Guenter Roeck <linux@roeck-us.net>
13
g_hash_table_remove() we iterate over all the entries to find a
14
potential range that overlaps it.
15
16
Signed-off-by: Eric Auger <eric.auger@redhat.com>
17
Message-id: 20210309102742.30442-6-eric.auger@redhat.com
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20241102125724.532843-3-shentey@gmail.com
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
19
---
21
hw/arm/smmu-common.c | 30 ++++++++++++++++++------------
20
include/hw/net/imx_fec.h | 9 ++-
22
hw/arm/smmuv3.c | 24 ++++++++++++++++++++----
21
hw/net/imx_fec.c | 146 ++++-----------------------------------
23
2 files changed, 38 insertions(+), 16 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(-)
24
26
25
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
27
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
26
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/smmu-common.c
29
--- a/include/hw/net/imx_fec.h
28
+++ b/hw/arm/smmu-common.c
30
+++ b/include/hw/net/imx_fec.h
29
@@ -XXX,XX +XXX,XX @@ inline void
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
30
smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
32
#define TYPE_IMX_ENET "imx.enet"
31
uint8_t tg, uint64_t num_pages, uint8_t ttl)
33
34
#include "hw/sysbus.h"
35
+#include "hw/net/lan9118_phy.h"
36
+#include "hw/irq.h"
37
#include "net/net.h"
38
39
#define ENET_EIR 1
40
@@ -XXX,XX +XXX,XX @@ struct IMXFECState {
41
uint32_t tx_descriptor[ENET_TX_RING_NUM];
42
uint32_t tx_ring_num;
43
44
- uint32_t phy_status;
45
- uint32_t phy_control;
46
- uint32_t phy_advertise;
47
- uint32_t phy_int;
48
- uint32_t phy_int_mask;
49
+ Lan9118PhyState mii;
50
+ IRQState mii_irq;
51
uint32_t phy_num;
52
bool phy_connected;
53
struct IMXFECState *phy_consumer;
54
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/net/imx_fec.c
57
+++ b/hw/net/imx_fec.c
58
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth_txdescs = {
59
60
static const VMStateDescription vmstate_imx_eth = {
61
.name = TYPE_IMX_FEC,
62
- .version_id = 2,
63
- .minimum_version_id = 2,
64
+ .version_id = 3,
65
+ .minimum_version_id = 3,
66
.fields = (const VMStateField[]) {
67
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
68
VMSTATE_UINT32(rx_descriptor, IMXFECState),
69
VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
70
- VMSTATE_UINT32(phy_status, IMXFECState),
71
- VMSTATE_UINT32(phy_control, IMXFECState),
72
- VMSTATE_UINT32(phy_advertise, IMXFECState),
73
- VMSTATE_UINT32(phy_int, IMXFECState),
74
- VMSTATE_UINT32(phy_int_mask, IMXFECState),
75
VMSTATE_END_OF_LIST()
76
},
77
.subsections = (const VMStateDescription * const []) {
78
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth = {
79
},
80
};
81
82
-#define PHY_INT_ENERGYON (1 << 7)
83
-#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
84
-#define PHY_INT_FAULT (1 << 5)
85
-#define PHY_INT_DOWN (1 << 4)
86
-#define PHY_INT_AUTONEG_LP (1 << 3)
87
-#define PHY_INT_PARFAULT (1 << 2)
88
-#define PHY_INT_AUTONEG_PAGE (1 << 1)
89
-
90
static void imx_eth_update(IMXFECState *s);
91
92
/*
93
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s);
94
* For now we don't handle any GPIO/interrupt line, so the OS will
95
* have to poll for the PHY status.
96
*/
97
-static void imx_phy_update_irq(IMXFECState *s)
98
+static void imx_phy_update_irq(void *opaque, int n, int level)
32
{
99
{
33
+ /* if tg is not set we use 4KB range invalidation */
100
- imx_eth_update(s);
34
+ uint8_t granule = tg ? tg * 2 + 10 : 12;
101
-}
35
+
102
-
36
if (ttl && (num_pages == 1) && (asid >= 0)) {
103
-static void imx_phy_update_link(IMXFECState *s)
37
SMMUIOTLBKey key = smmu_get_iotlb_key(asid, iova, tg, ttl);
104
-{
38
105
- /* Autonegotiation status mirrors link status. */
39
- g_hash_table_remove(s->iotlb, &key);
106
- if (qemu_get_queue(s->nic)->link_down) {
107
- trace_imx_phy_update_link("down");
108
- s->phy_status &= ~0x0024;
109
- s->phy_int |= PHY_INT_DOWN;
40
- } else {
110
- } else {
41
- /* if tg is not set we use 4KB range invalidation */
111
- trace_imx_phy_update_link("up");
42
- uint8_t granule = tg ? tg * 2 + 10 : 12;
112
- s->phy_status |= 0x0024;
43
-
113
- s->phy_int |= PHY_INT_ENERGYON;
44
- SMMUIOTLBPageInvInfo info = {
114
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
45
- .asid = asid, .iova = iova,
115
- }
46
- .mask = (num_pages * 1 << granule) - 1};
116
- imx_phy_update_irq(s);
47
-
117
+ imx_eth_update(opaque);
48
- g_hash_table_foreach_remove(s->iotlb,
118
}
49
- smmu_hash_remove_by_asid_iova,
119
50
- &info);
120
static void imx_eth_set_link(NetClientState *nc)
51
+ if (g_hash_table_remove(s->iotlb, &key)) {
121
{
52
+ return;
122
- imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
53
+ }
123
-}
54
+ /*
124
-
55
+ * if the entry is not found, let's see if it does not
125
-static void imx_phy_reset(IMXFECState *s)
56
+ * belong to a larger IOTLB entry
126
-{
57
+ */
127
- trace_imx_phy_reset();
128
-
129
- s->phy_status = 0x7809;
130
- s->phy_control = 0x3000;
131
- s->phy_advertise = 0x01e1;
132
- s->phy_int_mask = 0;
133
- s->phy_int = 0;
134
- imx_phy_update_link(s);
135
+ lan9118_phy_update_link(&IMX_FEC(qemu_get_nic_opaque(nc))->mii,
136
+ nc->link_down);
137
}
138
139
static uint32_t imx_phy_read(IMXFECState *s, int reg)
140
{
141
- uint32_t val;
142
uint32_t phy = reg / 32;
143
144
if (!s->phy_connected) {
145
@@ -XXX,XX +XXX,XX @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
146
147
reg %= 32;
148
149
- switch (reg) {
150
- case 0: /* Basic Control */
151
- val = s->phy_control;
152
- break;
153
- case 1: /* Basic Status */
154
- val = s->phy_status;
155
- break;
156
- case 2: /* ID1 */
157
- val = 0x0007;
158
- break;
159
- case 3: /* ID2 */
160
- val = 0xc0d1;
161
- break;
162
- case 4: /* Auto-neg advertisement */
163
- val = s->phy_advertise;
164
- break;
165
- case 5: /* Auto-neg Link Partner Ability */
166
- val = 0x0f71;
167
- break;
168
- case 6: /* Auto-neg Expansion */
169
- val = 1;
170
- break;
171
- case 29: /* Interrupt source. */
172
- val = s->phy_int;
173
- s->phy_int = 0;
174
- imx_phy_update_irq(s);
175
- break;
176
- case 30: /* Interrupt mask */
177
- val = s->phy_int_mask;
178
- break;
179
- case 17:
180
- case 18:
181
- case 27:
182
- case 31:
183
- qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
184
- TYPE_IMX_FEC, __func__, reg);
185
- val = 0;
186
- break;
187
- default:
188
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
189
- TYPE_IMX_FEC, __func__, reg);
190
- val = 0;
191
- break;
192
- }
193
-
194
- trace_imx_phy_read(val, phy, reg);
195
-
196
- return val;
197
+ return lan9118_phy_read(&s->mii, reg);
198
}
199
200
static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
201
@@ -XXX,XX +XXX,XX @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
202
203
reg %= 32;
204
205
- trace_imx_phy_write(val, phy, reg);
206
-
207
- switch (reg) {
208
- case 0: /* Basic Control */
209
- if (val & 0x8000) {
210
- imx_phy_reset(s);
211
- } else {
212
- s->phy_control = val & 0x7980;
213
- /* Complete autonegotiation immediately. */
214
- if (val & 0x1000) {
215
- s->phy_status |= 0x0020;
216
- }
217
- }
218
- break;
219
- case 4: /* Auto-neg advertisement */
220
- s->phy_advertise = (val & 0x2d7f) | 0x80;
221
- break;
222
- case 30: /* Interrupt mask */
223
- s->phy_int_mask = val & 0xff;
224
- imx_phy_update_irq(s);
225
- break;
226
- case 17:
227
- case 18:
228
- case 27:
229
- case 31:
230
- qemu_log_mask(LOG_UNIMP, "[%s.phy)%s: reg %d not implemented\n",
231
- TYPE_IMX_FEC, __func__, reg);
232
- break;
233
- default:
234
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
235
- TYPE_IMX_FEC, __func__, reg);
236
- break;
237
- }
238
+ lan9118_phy_write(&s->mii, reg, val);
239
}
240
241
static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
242
@@ -XXX,XX +XXX,XX @@ static void imx_eth_reset(DeviceState *d)
243
244
s->rx_descriptor = 0;
245
memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
246
-
247
- /* We also reset the PHY */
248
- imx_phy_reset(s);
249
}
250
251
static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
252
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
253
sysbus_init_irq(sbd, &s->irq[0]);
254
sysbus_init_irq(sbd, &s->irq[1]);
255
256
+ qemu_init_irq(&s->mii_irq, imx_phy_update_irq, s, 0);
257
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
258
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
259
+ return;
260
+ }
261
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
262
+
263
qemu_macaddr_default_if_unset(&s->conf.macaddr);
264
265
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
266
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
267
index XXXXXXX..XXXXXXX 100644
268
--- a/hw/net/lan9118_phy.c
269
+++ b/hw/net/lan9118_phy.c
270
@@ -XXX,XX +XXX,XX @@
271
* Copyright (c) 2009 CodeSourcery, LLC.
272
* Written by Paul Brook
273
*
274
+ * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
275
+ *
276
* This code is licensed under the GNU GPL v2
277
*
278
* Contributions after 2012-01-13 are licensed under the terms of the
279
@@ -XXX,XX +XXX,XX @@
280
#include "hw/resettable.h"
281
#include "migration/vmstate.h"
282
#include "qemu/log.h"
283
+#include "trace.h"
284
285
#define PHY_INT_ENERGYON (1 << 7)
286
#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
287
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
288
289
switch (reg) {
290
case 0: /* Basic Control */
291
- return s->control;
292
+ val = s->control;
293
+ break;
294
case 1: /* Basic Status */
295
- return s->status;
296
+ val = s->status;
297
+ break;
298
case 2: /* ID1 */
299
- return 0x0007;
300
+ val = 0x0007;
301
+ break;
302
case 3: /* ID2 */
303
- return 0xc0d1;
304
+ val = 0xc0d1;
305
+ break;
306
case 4: /* Auto-neg advertisement */
307
- return s->advertise;
308
+ val = s->advertise;
309
+ break;
310
case 5: /* Auto-neg Link Partner Ability */
311
- return 0x0f71;
312
+ val = 0x0f71;
313
+ break;
314
case 6: /* Auto-neg Expansion */
315
- return 1;
316
- /* TODO 17, 18, 27, 29, 30, 31 */
317
+ val = 1;
318
+ break;
319
case 29: /* Interrupt source. */
320
val = s->ints;
321
s->ints = 0;
322
lan9118_phy_update_irq(s);
323
- return val;
324
+ break;
325
case 30: /* Interrupt mask */
326
- return s->int_mask;
327
+ val = s->int_mask;
328
+ break;
329
+ case 17:
330
+ case 18:
331
+ case 27:
332
+ case 31:
333
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
334
+ __func__, reg);
335
+ val = 0;
336
+ break;
337
default:
338
- qemu_log_mask(LOG_GUEST_ERROR,
339
- "lan9118_phy_read: PHY read reg %d\n", reg);
340
- return 0;
341
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
342
+ __func__, reg);
343
+ val = 0;
344
+ break;
58
}
345
}
59
+
346
+
60
+ SMMUIOTLBPageInvInfo info = {
347
+ trace_lan9118_phy_read(val, reg);
61
+ .asid = asid, .iova = iova,
348
+
62
+ .mask = (num_pages * 1 << granule) - 1};
349
+ return val;
63
+
350
}
64
+ g_hash_table_foreach_remove(s->iotlb,
351
65
+ smmu_hash_remove_by_asid_iova,
352
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
66
+ &info);
353
{
67
}
354
+ trace_lan9118_phy_write(val, reg);
68
355
+
69
inline void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
356
switch (reg) {
70
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
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
71
index XXXXXXX..XXXXXXX 100644
430
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/arm/smmuv3.c
431
--- a/hw/net/Kconfig
73
+++ b/hw/arm/smmuv3.c
432
+++ b/hw/net/Kconfig
74
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
433
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_SUN8I_EMAC
75
uint16_t vmid = CMD_VMID(cmd);
434
76
bool leaf = CMD_LEAF(cmd);
435
config IMX_FEC
77
uint8_t tg = CMD_TG(cmd);
436
bool
78
- hwaddr num_pages = 1;
437
+ select LAN9118_PHY
79
+ uint64_t first_page = 0, last_page;
438
80
+ uint64_t num_pages = 1;
439
config CADENCE
81
int asid = -1;
440
bool
82
441
diff --git a/hw/net/trace-events b/hw/net/trace-events
83
if (tg) {
442
index XXXXXXX..XXXXXXX 100644
84
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
443
--- a/hw/net/trace-events
85
if (type == SMMU_CMD_TLBI_NH_VA) {
444
+++ b/hw/net/trace-events
86
asid = CMD_ASID(cmd);
445
@@ -XXX,XX +XXX,XX @@ allwinner_sun8i_emac_set_link(bool active) "Set link: active=%u"
87
}
446
allwinner_sun8i_emac_read(uint64_t offset, uint64_t val) "MMIO read: offset=0x%" PRIx64 " value=0x%" PRIx64
88
- trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf);
447
allwinner_sun8i_emac_write(uint64_t offset, uint64_t val) "MMIO write: offset=0x%" PRIx64 " value=0x%" PRIx64
89
- smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages);
448
90
- smmu_iotlb_inv_iova(s, asid, addr, tg, num_pages, ttl);
449
+# lan9118_phy.c
91
+
450
+lan9118_phy_read(uint16_t val, int reg) "[0x%02x] -> 0x%04" PRIx16
92
+ /* Split invalidations into ^2 range invalidations */
451
+lan9118_phy_write(uint16_t val, int reg) "[0x%02x] <- 0x%04" PRIx16
93
+ last_page = num_pages - 1;
452
+lan9118_phy_update_link(const char *s) "%s"
94
+ while (num_pages) {
453
+lan9118_phy_reset(void) ""
95
+ uint8_t granule = tg * 2 + 10;
454
+
96
+ uint64_t mask, count;
455
# lance.c
97
+
456
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x"
98
+ mask = dma_aligned_pow2_mask(first_page, last_page, 64 - granule);
457
lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x"
99
+ count = mask + 1;
458
@@ -XXX,XX +XXX,XX @@ i82596_set_multicast(uint16_t count) "Added %d multicast entries"
100
+
459
i82596_channel_attention(void *s) "%p: Received CHANNEL ATTENTION"
101
+ trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, count, ttl, leaf);
460
102
+ smmuv3_inv_notifiers_iova(s, asid, addr, tg, count);
461
# imx_fec.c
103
+ smmu_iotlb_inv_iova(s, asid, addr, tg, count, ttl);
462
-imx_phy_read(uint32_t val, int phy, int reg) "0x%04"PRIx32" <= phy[%d].reg[%d]"
104
+
463
imx_phy_read_num(int phy, int configured) "read request from unconfigured phy %d (configured %d)"
105
+ num_pages -= count;
464
-imx_phy_write(uint32_t val, int phy, int reg) "0x%04"PRIx32" => phy[%d].reg[%d]"
106
+ first_page += count;
465
imx_phy_write_num(int phy, int configured) "write request to unconfigured phy %d (configured %d)"
107
+ addr += count * BIT_ULL(granule);
466
-imx_phy_update_link(const char *s) "%s"
108
+ }
467
-imx_phy_reset(void) ""
109
}
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"
110
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"
111
static int smmuv3_cmdq_consume(SMMUv3State *s)
470
imx_eth_tx_bd_busy(void) "tx_bd ran out of descriptors to transmit"
112
--
471
--
113
2.20.1
472
2.34.1
114
115
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Update the download URL of the Armbian 20.08 Bionic image for
3
Turns 0x70 into 0xe0 (== 0x70 << 1) which adds the missing MII_ANLPAR_TX and
4
test_arm_orangepi_bionic_20_08 of the orangepi-pc machine.
4
fixes the MSB of selector field to be zero, as specified in the datasheet.
5
5
6
The archive.armbian.com URL contains more images and should keep stable
6
Fixes: 2a424990170b "LAN9118 emulation"
7
for a longer period of time than dl.armbian.com.
7
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
8
8
Tested-by: Guenter Roeck <linux@roeck-us.net>
9
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20241102125724.532843-4-shentey@gmail.com
11
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
13
Message-id: 20210310195820.21950-4-nieklinnenbank@gmail.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
12
---
16
tests/acceptance/boot_linux_console.py | 2 +-
13
hw/net/lan9118_phy.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
18
15
19
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/tests/acceptance/boot_linux_console.py
18
--- a/hw/net/lan9118_phy.c
22
+++ b/tests/acceptance/boot_linux_console.py
19
+++ b/hw/net/lan9118_phy.c
23
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_bionic_20_08(self):
20
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
24
# to 1036 MiB, but the underlying filesystem is 1552 MiB...
21
val = s->advertise;
25
# As we expand it to 2 GiB we are safe.
22
break;
26
23
case 5: /* Auto-neg Link Partner Ability */
27
- image_url = ('https://dl.armbian.com/orangepipc/archive/'
24
- val = 0x0f71;
28
+ image_url = ('https://archive.armbian.com/orangepipc/archive/'
25
+ val = 0x0fe1;
29
'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
26
break;
30
image_hash = ('b4d6775f5673486329e45a0586bf06b6'
27
case 6: /* Auto-neg Expansion */
31
'dbe792199fd182ac6b9c7bb6c7d3e6dd')
28
val = 1;
32
--
29
--
33
2.20.1
30
2.34.1
34
35
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Connect the support for the Versal Accelerator RAMs (XRAMs).
3
Prefer named constants over magic values for better readability.
4
4
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
7
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Tested-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20210308224637.2949533-3-edgar.iglesias@gmail.com
8
Message-id: 20241102125724.532843-5-shentey@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
docs/system/arm/xlnx-versal-virt.rst | 1 +
11
include/hw/net/mii.h | 6 +++++
12
include/hw/arm/xlnx-versal.h | 13 ++++++++++
12
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++
13
2 files changed, 46 insertions(+), 23 deletions(-)
14
3 files changed, 50 insertions(+)
15
14
16
diff --git a/docs/system/arm/xlnx-versal-virt.rst b/docs/system/arm/xlnx-versal-virt.rst
15
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/xlnx-versal-virt.rst
17
--- a/include/hw/net/mii.h
19
+++ b/docs/system/arm/xlnx-versal-virt.rst
18
+++ b/include/hw/net/mii.h
20
@@ -XXX,XX +XXX,XX @@ Implemented devices:
19
@@ -XXX,XX +XXX,XX @@
21
- 8 ADMA (Xilinx zDMA) channels
20
#define MII_BMSR_JABBER (1 << 1) /* Jabber detected */
22
- 2 SD Controllers
21
#define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */
23
- OCM (256KB of On Chip Memory)
22
24
+- XRAM (4MB of on chip Accelerator RAM)
23
+#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */
25
- DDR memory
24
#define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */
26
25
#define MII_ANAR_PAUSE (1 << 10) /* Try for pause */
27
QEMU does not yet model any other devices, including the PL and the AI Engine.
26
#define MII_ANAR_TXFD (1 << 8)
28
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
27
@@ -XXX,XX +XXX,XX @@
28
#define MII_ANAR_10FD (1 << 6)
29
#define MII_ANAR_10 (1 << 5)
30
#define MII_ANAR_CSMACD (1 << 0)
31
+#define MII_ANAR_SELECT (0x001f) /* Selector bits */
32
33
#define MII_ANLPAR_ACK (1 << 14)
34
#define MII_ANLPAR_PAUSEASY (1 << 11) /* can pause asymmetrically */
35
@@ -XXX,XX +XXX,XX @@
36
#define RTL8201CP_PHYID1 0x0000
37
#define RTL8201CP_PHYID2 0x8201
38
39
+/* SMSC LAN9118 */
40
+#define SMSCLAN9118_PHYID1 0x0007
41
+#define SMSCLAN9118_PHYID2 0xc0d1
42
+
43
/* RealTek 8211E */
44
#define RTL8211E_PHYID1 0x001c
45
#define RTL8211E_PHYID2 0xc915
46
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
29
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/xlnx-versal.h
48
--- a/hw/net/lan9118_phy.c
31
+++ b/include/hw/arm/xlnx-versal.h
49
+++ b/hw/net/lan9118_phy.c
32
@@ -XXX,XX +XXX,XX @@
50
@@ -XXX,XX +XXX,XX @@
33
51
34
#include "hw/sysbus.h"
35
#include "hw/arm/boot.h"
36
+#include "hw/or-irq.h"
37
#include "hw/sd/sdhci.h"
38
#include "hw/intc/arm_gicv3.h"
39
#include "hw/char/pl011.h"
40
@@ -XXX,XX +XXX,XX @@
41
#include "hw/rtc/xlnx-zynqmp-rtc.h"
42
#include "qom/object.h"
43
#include "hw/usb/xlnx-usb-subsystem.h"
44
+#include "hw/misc/xlnx-versal-xramc.h"
45
46
#define TYPE_XLNX_VERSAL "xlnx-versal"
47
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
48
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
49
#define XLNX_VERSAL_NR_GEMS 2
50
#define XLNX_VERSAL_NR_ADMAS 8
51
#define XLNX_VERSAL_NR_SDS 2
52
+#define XLNX_VERSAL_NR_XRAM 4
53
#define XLNX_VERSAL_NR_IRQS 192
54
55
struct Versal {
56
@@ -XXX,XX +XXX,XX @@ struct Versal {
57
XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
58
VersalUsb2 usb;
59
} iou;
60
+
61
+ struct {
62
+ qemu_or_irq irq_orgate;
63
+ XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
64
+ } xram;
65
} lpd;
66
67
/* The Platform Management Controller subsystem. */
68
@@ -XXX,XX +XXX,XX @@ struct Versal {
69
#define VERSAL_GEM1_IRQ_0 58
70
#define VERSAL_GEM1_WAKE_IRQ_0 59
71
#define VERSAL_ADMA_IRQ_0 60
72
+#define VERSAL_XRAM_IRQ_0 79
73
#define VERSAL_RTC_APB_ERR_IRQ 121
74
#define VERSAL_SD0_IRQ_0 126
75
#define VERSAL_RTC_ALARM_IRQ 142
76
@@ -XXX,XX +XXX,XX @@ struct Versal {
77
#define MM_OCM 0xfffc0000U
78
#define MM_OCM_SIZE 0x40000
79
80
+#define MM_XRAM 0xfe800000
81
+#define MM_XRAMC 0xff8e0000
82
+#define MM_XRAMC_SIZE 0x10000
83
+
84
#define MM_USB2_CTRL_REGS 0xFF9D0000
85
#define MM_USB2_CTRL_REGS_SIZE 0x10000
86
87
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/arm/xlnx-versal.c
90
+++ b/hw/arm/xlnx-versal.c
91
@@ -XXX,XX +XXX,XX @@
92
*/
93
94
#include "qemu/osdep.h"
52
#include "qemu/osdep.h"
95
+#include "qemu/units.h"
53
#include "hw/net/lan9118_phy.h"
96
#include "qapi/error.h"
54
+#include "hw/net/mii.h"
97
#include "qemu/log.h"
55
#include "hw/irq.h"
98
#include "qemu/module.h"
56
#include "hw/resettable.h"
99
@@ -XXX,XX +XXX,XX @@ static void versal_create_rtc(Versal *s, qemu_irq *pic)
57
#include "migration/vmstate.h"
100
sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
58
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
101
}
59
uint16_t val;
102
60
103
+static void versal_create_xrams(Versal *s, qemu_irq *pic)
61
switch (reg) {
104
+{
62
- case 0: /* Basic Control */
105
+ int nr_xrams = ARRAY_SIZE(s->lpd.xram.ctrl);
63
+ case MII_BMCR:
106
+ DeviceState *orgate;
64
val = s->control;
107
+ int i;
65
break;
108
+
66
- case 1: /* Basic Status */
109
+ /* XRAM IRQs get ORed into a single line. */
67
+ case MII_BMSR:
110
+ object_initialize_child(OBJECT(s), "xram-irq-orgate",
68
val = s->status;
111
+ &s->lpd.xram.irq_orgate, TYPE_OR_IRQ);
69
break;
112
+ orgate = DEVICE(&s->lpd.xram.irq_orgate);
70
- case 2: /* ID1 */
113
+ object_property_set_int(OBJECT(orgate),
71
- val = 0x0007;
114
+ "num-lines", nr_xrams, &error_fatal);
72
+ case MII_PHYID1:
115
+ qdev_realize(orgate, NULL, &error_fatal);
73
+ val = SMSCLAN9118_PHYID1;
116
+ qdev_connect_gpio_out(orgate, 0, pic[VERSAL_XRAM_IRQ_0]);
74
break;
117
+
75
- case 3: /* ID2 */
118
+ for (i = 0; i < ARRAY_SIZE(s->lpd.xram.ctrl); i++) {
76
- val = 0xc0d1;
119
+ SysBusDevice *sbd;
77
+ case MII_PHYID2:
120
+ MemoryRegion *mr;
78
+ val = SMSCLAN9118_PHYID2;
121
+
79
break;
122
+ object_initialize_child(OBJECT(s), "xram[*]", &s->lpd.xram.ctrl[i],
80
- case 4: /* Auto-neg advertisement */
123
+ TYPE_XLNX_XRAM_CTRL);
81
+ case MII_ANAR:
124
+ sbd = SYS_BUS_DEVICE(&s->lpd.xram.ctrl[i]);
82
val = s->advertise;
125
+ sysbus_realize(sbd, &error_fatal);
83
break;
126
+
84
- case 5: /* Auto-neg Link Partner Ability */
127
+ mr = sysbus_mmio_get_region(sbd, 0);
85
- val = 0x0fe1;
128
+ memory_region_add_subregion(&s->mr_ps,
86
+ case MII_ANLPAR:
129
+ MM_XRAMC + i * MM_XRAMC_SIZE, mr);
87
+ val = MII_ANLPAR_PAUSEASY | MII_ANLPAR_PAUSE | MII_ANLPAR_T4 |
130
+ mr = sysbus_mmio_get_region(sbd, 1);
88
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
131
+ memory_region_add_subregion(&s->mr_ps, MM_XRAM + i * MiB, mr);
89
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
132
+
90
break;
133
+ sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(orgate, i));
91
- case 6: /* Auto-neg Expansion */
134
+ }
92
- val = 1;
135
+}
93
+ case MII_ANER:
136
+
94
+ val = MII_ANER_NWAY;
137
/* This takes the board allocated linear DDR memory and creates aliases
95
break;
138
* for each split DDR range/aperture on the Versal address map.
96
case 29: /* Interrupt source. */
139
*/
97
val = s->ints;
140
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
98
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
141
versal_create_admas(s, pic);
99
trace_lan9118_phy_write(val, reg);
142
versal_create_sds(s, pic);
100
143
versal_create_rtc(s, pic);
101
switch (reg) {
144
+ versal_create_xrams(s, pic);
102
- case 0: /* Basic Control */
145
versal_map_ddr(s);
103
- if (val & 0x8000) {
146
versal_unimp(s);
104
+ case MII_BMCR:
147
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);
148
--
166
--
149
2.20.1
167
2.34.1
150
151
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Wrote too much with punpk1 with vl % 512 != 0.
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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20210309155305.11301-4-richard.henderson@linaro.org
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
target/arm/sve_helper.c | 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/target/arm/sve_helper.c b/target/arm/sve_helper.c
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/sve_helper.c
18
--- a/hw/net/lan9118_phy.c
17
+++ b/target/arm/sve_helper.c
19
+++ b/hw/net/lan9118_phy.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_punpk_p)(void *vd, void *vn, uint32_t pred_desc)
20
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
19
high = oprsz >> 1;
21
break;
20
}
22
case MII_ANAR:
21
23
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
22
- if ((high & 3) == 0) {
24
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
23
+ if ((oprsz & 7) == 0) {
25
- MII_ANAR_SELECT))
24
uint32_t *n = vn;
26
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
25
high >>= 2;
27
+ MII_ANAR_10 | MII_ANAR_SELECT))
26
28
| MII_ANAR_TX;
27
- for (i = 0; i < DIV_ROUND_UP(oprsz, 8); i++) {
29
break;
28
+ for (i = 0; i < oprsz / 8; i++) {
30
case 30: /* Interrupt mask */
29
uint64_t nn = n[H4(high + i)];
30
d[i] = expand_bits(nn, 0);
31
}
32
--
31
--
33
2.20.1
32
2.34.1
34
35
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
For IEEE fused multiply-add, the (0 * inf) + NaN case should raise
2
Invalid for the multiplication of 0 by infinity. Currently we handle
3
this in the per-architecture ifdef ladder in pickNaNMulAdd().
4
However, since this isn't really architecture specific we can hoist
5
it up to the generic code.
2
6
3
This patch adds the recently implemented MFT device to the NPCM7XX
7
For the cases where the infzero test in pickNaNMulAdd was
4
SoC file.
8
returning 2, we can delete the check entirely and allow the
9
code to fall into the normal pick-a-NaN handling, because this
10
will return 2 anyway (input 'c' being the only NaN in this case).
11
For the cases where infzero was returning 3 to indicate "return
12
the default NaN", we must retain that "return 3".
5
13
6
Reviewed-by: Doug Evans <dje@google.com>
14
For Arm, this looks like it might be a behaviour change because we
7
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
15
used to set float_flag_invalid | float_flag_invalid_imz only if C is
8
Signed-off-by: Hao Wu <wuhaotsh@google.com>
16
a quiet NaN. However, it is not, because Arm target code never looks
9
Message-id: 20210311180855.149764-4-wuhaotsh@google.com
17
at float_flag_invalid_imz, and for the (0 * inf) + SNaN case we
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
already raised float_flag_invalid via the "abc_mask &
19
float_cmask_snan" check in pick_nan_muladd.
20
21
For any target architecture using the "default implementation" at the
22
bottom of the ifdef, this is a behaviour change but will be fixing a
23
bug (where we failed to raise the Invalid exception for (0 * inf +
24
QNaN). The architectures using the default case are:
25
* hppa
26
* i386
27
* sh4
28
* tricore
29
30
The x86, Tricore and SH4 CPU architecture manuals are clear that this
31
should have raised Invalid; HPPA is a bit vaguer but still seems
32
clear enough.
33
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
36
Message-id: 20241202131347.498124-2-peter.maydell@linaro.org
12
---
37
---
13
docs/system/arm/nuvoton.rst | 2 +-
38
fpu/softfloat-parts.c.inc | 13 +++++++------
14
include/hw/arm/npcm7xx.h | 2 ++
39
fpu/softfloat-specialize.c.inc | 29 +----------------------------
15
hw/arm/npcm7xx.c | 45 ++++++++++++++++++++++++++++++-------
40
2 files changed, 8 insertions(+), 34 deletions(-)
16
3 files changed, 40 insertions(+), 9 deletions(-)
17
41
18
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
42
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
19
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
20
--- a/docs/system/arm/nuvoton.rst
44
--- a/fpu/softfloat-parts.c.inc
21
+++ b/docs/system/arm/nuvoton.rst
45
+++ b/fpu/softfloat-parts.c.inc
22
@@ -XXX,XX +XXX,XX @@ Supported devices
46
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
23
* Pulse Width Modulation (PWM)
47
int ab_mask, int abc_mask)
24
* SMBus controller (SMBF)
48
{
25
* Ethernet controller (EMC)
49
int which;
26
+ * Tachometer
50
+ bool infzero = (ab_mask == float_cmask_infzero);
27
51
28
Missing devices
52
if (unlikely(abc_mask & float_cmask_snan)) {
29
---------------
53
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
30
@@ -XXX,XX +XXX,XX @@ Missing devices
31
* Peripheral SPI controller (PSPI)
32
* SD/MMC host
33
* PECI interface
34
- * Tachometer
35
* PCI and PCIe root complex and bridges
36
* VDM and MCTP support
37
* Serial I/O expansion
38
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/include/hw/arm/npcm7xx.h
41
+++ b/include/hw/arm/npcm7xx.h
42
@@ -XXX,XX +XXX,XX @@
43
#include "hw/mem/npcm7xx_mc.h"
44
#include "hw/misc/npcm7xx_clk.h"
45
#include "hw/misc/npcm7xx_gcr.h"
46
+#include "hw/misc/npcm7xx_mft.h"
47
#include "hw/misc/npcm7xx_pwm.h"
48
#include "hw/misc/npcm7xx_rng.h"
49
#include "hw/net/npcm7xx_emc.h"
50
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
51
NPCM7xxTimerCtrlState tim[3];
52
NPCM7xxADCState adc;
53
NPCM7xxPWMState pwm[2];
54
+ NPCM7xxMFTState mft[8];
55
NPCM7xxOTPState key_storage;
56
NPCM7xxOTPState fuse_array;
57
NPCM7xxMCState mc;
58
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/arm/npcm7xx.c
61
+++ b/hw/arm/npcm7xx.c
62
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
63
NPCM7XX_SMBUS15_IRQ,
64
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
65
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
66
+ NPCM7XX_MFT0_IRQ = 96, /* MFT module 0 */
67
+ NPCM7XX_MFT1_IRQ, /* MFT module 1 */
68
+ NPCM7XX_MFT2_IRQ, /* MFT module 2 */
69
+ NPCM7XX_MFT3_IRQ, /* MFT module 3 */
70
+ NPCM7XX_MFT4_IRQ, /* MFT module 4 */
71
+ NPCM7XX_MFT5_IRQ, /* MFT module 5 */
72
+ NPCM7XX_MFT6_IRQ, /* MFT module 6 */
73
+ NPCM7XX_MFT7_IRQ, /* MFT module 7 */
74
NPCM7XX_EMC2RX_IRQ = 114,
75
NPCM7XX_EMC2TX_IRQ,
76
NPCM7XX_GPIO0_IRQ = 116,
77
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_pwm_addr[] = {
78
0xf0104000,
79
};
80
81
+/* Register base address for each MFT Module */
82
+static const hwaddr npcm7xx_mft_addr[] = {
83
+ 0xf0180000,
84
+ 0xf0181000,
85
+ 0xf0182000,
86
+ 0xf0183000,
87
+ 0xf0184000,
88
+ 0xf0185000,
89
+ 0xf0186000,
90
+ 0xf0187000,
91
+};
92
+
93
/* Direct memory-mapped access to each SMBus Module. */
94
static const hwaddr npcm7xx_smbus_addr[] = {
95
0xf0080000,
96
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
97
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
98
}
54
}
99
55
100
+ for (i = 0; i < ARRAY_SIZE(s->mft); i++) {
56
- which = pickNaNMulAdd(a->cls, b->cls, c->cls,
101
+ object_initialize_child(obj, "mft[*]", &s->mft[i], TYPE_NPCM7XX_MFT);
57
- ab_mask == float_cmask_infzero, s);
58
+ if (infzero) {
59
+ /* This is (0 * inf) + NaN or (inf * 0) + NaN */
60
+ float_raise(float_flag_invalid | float_flag_invalid_imz, s);
102
+ }
61
+ }
103
+
62
+
104
for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
63
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
105
object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
64
65
if (s->default_nan_mode || which == 3) {
66
- /*
67
- * Note that this check is after pickNaNMulAdd so that function
68
- * has an opportunity to set the Invalid flag for infzero.
69
- */
70
parts_default_nan(a, s);
71
return a;
106
}
72
}
107
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
73
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
108
sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
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;
109
}
83
}
110
84
111
+ /* MFT Modules. Cannot fail. */
85
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
112
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_mft_addr) != ARRAY_SIZE(s->mft));
86
* case sets InvalidOp and returns the default NaN
113
+ for (i = 0; i < ARRAY_SIZE(s->mft); i++) {
87
*/
114
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->mft[i]);
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
- }
115
+
112
+
116
+ qdev_connect_clock_in(DEVICE(&s->mft[i]), "clock-in",
113
/* Prefer sNaN over qNaN, in the c, a, b order. */
117
+ qdev_get_clock_out(DEVICE(&s->clk),
114
if (is_snan(c_cls)) {
118
+ "apb4-clock"));
115
return 2;
119
+ sysbus_realize(sbd, &error_abort);
116
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
120
+ sysbus_mmio_map(sbd, 0, npcm7xx_mft_addr[i]);
117
* to return an input NaN if we have one (ie c) rather than generating
121
+ sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, NPCM7XX_MFT0_IRQ + i));
118
* a default NaN
122
+ }
119
*/
123
+
120
- if (infzero) {
124
/*
121
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
125
* EMC Modules. Cannot fail.
122
- return 2;
126
* The mapping of the device to its netdev backend works as follows:
123
- }
127
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
124
128
create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB);
125
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
129
create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB);
126
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
130
create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB);
127
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
131
- create_unimplemented_device("npcm7xx.mft[0]", 0xf0180000, 4 * KiB);
128
return 1;
132
- create_unimplemented_device("npcm7xx.mft[1]", 0xf0181000, 4 * KiB);
129
}
133
- create_unimplemented_device("npcm7xx.mft[2]", 0xf0182000, 4 * KiB);
130
#elif defined(TARGET_RISCV)
134
- create_unimplemented_device("npcm7xx.mft[3]", 0xf0183000, 4 * KiB);
131
- /* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */
135
- create_unimplemented_device("npcm7xx.mft[4]", 0xf0184000, 4 * KiB);
132
- if (infzero) {
136
- create_unimplemented_device("npcm7xx.mft[5]", 0xf0185000, 4 * KiB);
133
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
137
- create_unimplemented_device("npcm7xx.mft[6]", 0xf0186000, 4 * KiB);
134
- }
138
- create_unimplemented_device("npcm7xx.mft[7]", 0xf0187000, 4 * KiB);
135
return 3; /* default NaN */
139
create_unimplemented_device("npcm7xx.pspi1", 0xf0200000, 4 * KiB);
136
#elif defined(TARGET_S390X)
140
create_unimplemented_device("npcm7xx.pspi2", 0xf0201000, 4 * KiB);
137
if (infzero) {
141
create_unimplemented_device("npcm7xx.ahbpci", 0xf0400000, 1 * MiB);
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;
142
--
165
--
143
2.20.1
166
2.34.1
144
145
diff view generated by jsdifflib
New patch
1
If the target sets default_nan_mode then we're always going to return
2
the default NaN, and pickNaNMulAdd() no longer has any side effects.
3
For consistency with pickNaN(), check for default_nan_mode before
4
calling pickNaNMulAdd().
1
5
6
When we convert pickNaNMulAdd() to allow runtime selection of the NaN
7
propagation rule, this means we won't have to make the targets which
8
use default_nan_mode also set a propagation rule.
9
10
Since RiscV always uses default_nan_mode, this allows us to remove
11
its ifdef case from pickNaNMulAdd().
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-3-peter.maydell@linaro.org
16
---
17
fpu/softfloat-parts.c.inc | 8 ++++++--
18
fpu/softfloat-specialize.c.inc | 9 +++++++--
19
2 files changed, 13 insertions(+), 4 deletions(-)
20
21
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
index XXXXXXX..XXXXXXX 100644
23
--- a/fpu/softfloat-parts.c.inc
24
+++ b/fpu/softfloat-parts.c.inc
25
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
26
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
27
}
28
29
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
30
+ if (s->default_nan_mode) {
31
+ which = 3;
32
+ } else {
33
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ }
35
36
- if (s->default_nan_mode || which == 3) {
37
+ if (which == 3) {
38
parts_default_nan(a, s);
39
return a;
40
}
41
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
42
index XXXXXXX..XXXXXXX 100644
43
--- a/fpu/softfloat-specialize.c.inc
44
+++ b/fpu/softfloat-specialize.c.inc
45
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
46
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
47
bool infzero, float_status *status)
48
{
49
+ /*
50
+ * We guarantee not to require the target to tell us how to
51
+ * pick a NaN if we're always returning the default NaN.
52
+ * But if we're not in default-NaN mode then the target must
53
+ * specify.
54
+ */
55
+ assert(!status->default_nan_mode);
56
#if defined(TARGET_ARM)
57
/* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
58
* the default NaN
59
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
60
} else {
61
return 1;
62
}
63
-#elif defined(TARGET_RISCV)
64
- return 3; /* default NaN */
65
#elif defined(TARGET_S390X)
66
if (infzero) {
67
return 3;
68
--
69
2.34.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
IEEE 758 does not define a fixed rule for what NaN to return in
2
2
the case of a fused multiply-add of inf * 0 + NaN. Different
3
This patch implements Multi Function Timer (MFT) module for NPCM7XX.
3
architectures thus do different things:
4
This module is mainly used to configure PWM fans. It has just enough
4
* some return the default NaN
5
functionality to make the PWM fan kernel module work.
5
* some return the input NaN
6
6
* Arm returns the default NaN if the input NaN is quiet,
7
The module takes two input, the max_rpm of a fan (modifiable via QMP)
7
and the input NaN if it is signalling
8
and duty cycle (a GPIO from the PWM module.) The actual measured RPM
8
9
is equal to max_rpm * duty_cycle / NPCM7XX_PWM_MAX_DUTY. The RPM is
9
We want to make this logic be runtime selected rather than
10
measured as a counter compared to a prescaled input clock. The kernel
10
hardcoded into the binary, because:
11
driver reads this counter and report to user space.
11
* this will let us have multiple targets in one QEMU binary
12
12
* the Arm FEAT_AFP architectural feature includes letting
13
Refs:
13
the guest select a NaN propagation rule at runtime
14
https://github.com/torvalds/linux/blob/master/drivers/hwmon/npcm750-pwm-fan.c
14
15
15
In this commit we add an enum for the propagation rule, the field in
16
Reviewed-by: Doug Evans <dje@google.com>
16
float_status, and the corresponding getters and setters. We change
17
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
17
pickNaNMulAdd to honour this, but because all targets still leave
18
Signed-off-by: Hao Wu <wuhaotsh@google.com>
18
this field at its default 0 value, the fallback logic will pick the
19
Message-id: 20210311180855.149764-3-wuhaotsh@google.com
19
rule type with the old ifdef ladder.
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
21
Note that four architectures both use the muladd softfloat functions
22
and did not have a branch of the ifdef ladder to specify their
23
behaviour (and so were ending up with the "default" case, probably
24
wrongly): i386, HPPA, SH4 and Tricore. SH4 and Tricore both set
25
default_nan_mode, and so will never get into pickNaNMulAdd(). For
26
HPPA and i386 we retain the same behaviour as the old default-case,
27
which is to not ever return the default NaN. This might not be
28
correct but it is not a behaviour change.
29
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
22
---
33
---
23
include/hw/misc/npcm7xx_mft.h | 70 +++++
34
include/fpu/softfloat-helpers.h | 11 ++++
24
hw/misc/npcm7xx_mft.c | 540 ++++++++++++++++++++++++++++++++++
35
include/fpu/softfloat-types.h | 23 +++++++++
25
hw/misc/meson.build | 1 +
36
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
26
hw/misc/trace-events | 8 +
37
3 files changed, 95 insertions(+), 30 deletions(-)
27
4 files changed, 619 insertions(+)
38
28
create mode 100644 include/hw/misc/npcm7xx_mft.h
39
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
29
create mode 100644 hw/misc/npcm7xx_mft.c
40
index XXXXXXX..XXXXXXX 100644
30
41
--- a/include/fpu/softfloat-helpers.h
31
diff --git a/include/hw/misc/npcm7xx_mft.h b/include/hw/misc/npcm7xx_mft.h
42
+++ b/include/fpu/softfloat-helpers.h
32
new file mode 100644
43
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
33
index XXXXXXX..XXXXXXX
44
status->float_2nan_prop_rule = rule;
34
--- /dev/null
45
}
35
+++ b/include/hw/misc/npcm7xx_mft.h
46
36
@@ -XXX,XX +XXX,XX @@
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
37
+/*
76
+/*
38
+ * Nuvoton NPCM7xx MFT Module
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.
39
+ *
80
+ *
40
+ * Copyright 2021 Google LLC
81
+ * You don't need to set this if default_nan_mode is enabled.
41
+ *
82
+ * When not in default-NaN mode, it is an error for the target
42
+ * This program is free software; you can redistribute it and/or modify it
83
+ * not to set the rule in float_status if it uses muladd, and we
43
+ * under the terms of the GNU General Public License as published by the
84
+ * will assert if we need to handle an input NaN and no rule was
44
+ * Free Software Foundation; either version 2 of the License, or
85
+ * selected.
45
+ * (at your option) any later version.
46
+ *
47
+ * This program is distributed in the hope that it will be useful, but WITHOUT
48
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
49
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
50
+ * for more details.
51
+ */
86
+ */
52
+#ifndef NPCM7XX_MFT_H
87
+typedef enum __attribute__((__packed__)) {
53
+#define NPCM7XX_MFT_H
88
+ /* No propagation rule specified */
54
+
89
+ float_infzeronan_none = 0,
55
+#include "exec/memory.h"
90
+ /* Result is never the default NaN (so always the input NaN) */
56
+#include "hw/clock.h"
91
+ float_infzeronan_dnan_never,
57
+#include "hw/irq.h"
92
+ /* Result is always the default NaN */
58
+#include "hw/sysbus.h"
93
+ float_infzeronan_dnan_always,
59
+#include "qom/object.h"
94
+ /* Result is the default NaN if the input NaN is quiet */
60
+
95
+ float_infzeronan_dnan_if_qnan,
61
+/* Max Fan input number. */
96
+} FloatInfZeroNaNRule;
62
+#define NPCM7XX_MFT_MAX_FAN_INPUT 19
97
+
63
+
98
/*
64
+/*
99
* Floating Point Status. Individual architectures may maintain
65
+ * Number of registers in one MFT module. Don't change this without increasing
100
* several versions of float_status for different functions. The
66
+ * the version_id in vmstate.
101
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
67
+ */
102
FloatRoundMode float_rounding_mode;
68
+#define NPCM7XX_MFT_NR_REGS (0x20 / sizeof(uint16_t))
103
FloatX80RoundPrec floatx80_rounding_precision;
69
+
104
Float2NaNPropRule float_2nan_prop_rule;
70
+/*
105
+ FloatInfZeroNaNRule float_infzeronan_rule;
71
+ * The MFT can take up to 4 inputs: A0, B0, A1, B1. It can measure one A and one
106
bool tininess_before_rounding;
72
+ * B simultaneously. NPCM7XX_MFT_INASEL and NPCM7XX_MFT_INBSEL are used to
107
/* should denormalised results go to zero and set the inexact flag? */
73
+ * select which A or B input are used.
108
bool flush_to_zero;
74
+ */
109
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
75
+#define NPCM7XX_MFT_FANIN_COUNT 4
110
index XXXXXXX..XXXXXXX 100644
76
+
111
--- a/fpu/softfloat-specialize.c.inc
77
+/**
112
+++ b/fpu/softfloat-specialize.c.inc
78
+ * struct NPCM7xxMFTState - Multi Functional Tachometer device state.
113
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
79
+ * @parent: System bus device.
114
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
80
+ * @iomem: Memory region through which registers are accessed.
115
bool infzero, float_status *status)
81
+ * @clock_in: The input clock for MFT from CLK module.
116
{
82
+ * @clock_{1,2}: The counter clocks for NPCM7XX_MFT_CNT{1,2}
117
+ FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
83
+ * @irq: The IRQ for this MFT state.
118
+
84
+ * @regs: The MMIO registers.
119
/*
85
+ * @max_rpm: The maximum rpm for fans. Order: A0, B0, A1, B1.
120
* We guarantee not to require the target to tell us how to
86
+ * @duty: The duty cycles for fans, relative to NPCM7XX_PWM_MAX_DUTY.
121
* pick a NaN if we're always returning the default NaN.
87
+ */
122
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
88
+typedef struct NPCM7xxMFTState {
123
* specify.
89
+ SysBusDevice parent;
124
*/
90
+
125
assert(!status->default_nan_mode);
91
+ MemoryRegion iomem;
126
+
92
+
127
+ if (rule == float_infzeronan_none) {
93
+ Clock *clock_in;
128
+ /*
94
+ Clock *clock_1, *clock_2;
129
+ * Temporarily fall back to ifdef ladder
95
+ qemu_irq irq;
130
+ */
96
+ uint16_t regs[NPCM7XX_MFT_NR_REGS];
131
#if defined(TARGET_ARM)
97
+
132
- /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
98
+ uint32_t max_rpm[NPCM7XX_MFT_FANIN_COUNT];
133
- * the default NaN
99
+ uint32_t duty[NPCM7XX_MFT_FANIN_COUNT];
134
- */
100
+} NPCM7xxMFTState;
135
- if (infzero && is_qnan(c_cls)) {
101
+
136
- return 3;
102
+#define TYPE_NPCM7XX_MFT "npcm7xx-mft"
137
+ /*
103
+#define NPCM7XX_MFT(obj) \
138
+ * For ARM, the (inf,zero,qnan) case returns the default NaN,
104
+ OBJECT_CHECK(NPCM7xxMFTState, (obj), TYPE_NPCM7XX_MFT)
139
+ * but (inf,zero,snan) returns the input NaN.
105
+
140
+ */
106
+#endif /* NPCM7XX_MFT_H */
141
+ rule = float_infzeronan_dnan_if_qnan;
107
diff --git a/hw/misc/npcm7xx_mft.c b/hw/misc/npcm7xx_mft.c
142
+#elif defined(TARGET_MIPS)
108
new file mode 100644
143
+ if (snan_bit_is_one(status)) {
109
index XXXXXXX..XXXXXXX
144
+ /*
110
--- /dev/null
145
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
111
+++ b/hw/misc/npcm7xx_mft.c
146
+ * case sets InvalidOp and returns the default NaN
112
@@ -XXX,XX +XXX,XX @@
147
+ */
113
+/*
148
+ rule = float_infzeronan_dnan_always;
114
+ * Nuvoton NPCM7xx MFT Module
115
+ *
116
+ * Copyright 2021 Google LLC
117
+ *
118
+ * This program is free software; you can redistribute it and/or modify it
119
+ * under the terms of the GNU General Public License as published by the
120
+ * Free Software Foundation; either version 2 of the License, or
121
+ * (at your option) any later version.
122
+ *
123
+ * This program is distributed in the hope that it will be useful, but WITHOUT
124
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
125
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
126
+ * for more details.
127
+ */
128
+
129
+#include "qemu/osdep.h"
130
+#include "hw/irq.h"
131
+#include "hw/qdev-clock.h"
132
+#include "hw/qdev-properties.h"
133
+#include "hw/misc/npcm7xx_mft.h"
134
+#include "hw/misc/npcm7xx_pwm.h"
135
+#include "hw/registerfields.h"
136
+#include "migration/vmstate.h"
137
+#include "qapi/error.h"
138
+#include "qapi/visitor.h"
139
+#include "qemu/bitops.h"
140
+#include "qemu/error-report.h"
141
+#include "qemu/log.h"
142
+#include "qemu/module.h"
143
+#include "qemu/timer.h"
144
+#include "qemu/units.h"
145
+#include "trace.h"
146
+
147
+/*
148
+ * Some of the registers can only accessed via 16-bit ops and some can only
149
+ * be accessed via 8-bit ops. However we mark all of them using REG16 to
150
+ * simplify implementation. npcm7xx_mft_check_mem_op checks the access length
151
+ * of memory operations.
152
+ */
153
+REG16(NPCM7XX_MFT_CNT1, 0x00);
154
+REG16(NPCM7XX_MFT_CRA, 0x02);
155
+REG16(NPCM7XX_MFT_CRB, 0x04);
156
+REG16(NPCM7XX_MFT_CNT2, 0x06);
157
+REG16(NPCM7XX_MFT_PRSC, 0x08);
158
+REG16(NPCM7XX_MFT_CKC, 0x0a);
159
+REG16(NPCM7XX_MFT_MCTRL, 0x0c);
160
+REG16(NPCM7XX_MFT_ICTRL, 0x0e);
161
+REG16(NPCM7XX_MFT_ICLR, 0x10);
162
+REG16(NPCM7XX_MFT_IEN, 0x12);
163
+REG16(NPCM7XX_MFT_CPA, 0x14);
164
+REG16(NPCM7XX_MFT_CPB, 0x16);
165
+REG16(NPCM7XX_MFT_CPCFG, 0x18);
166
+REG16(NPCM7XX_MFT_INASEL, 0x1a);
167
+REG16(NPCM7XX_MFT_INBSEL, 0x1c);
168
+
169
+/* Register Fields */
170
+#define NPCM7XX_MFT_CKC_C2CSEL BIT(3)
171
+#define NPCM7XX_MFT_CKC_C1CSEL BIT(0)
172
+
173
+#define NPCM7XX_MFT_MCTRL_TBEN BIT(6)
174
+#define NPCM7XX_MFT_MCTRL_TAEN BIT(5)
175
+#define NPCM7XX_MFT_MCTRL_TBEDG BIT(4)
176
+#define NPCM7XX_MFT_MCTRL_TAEDG BIT(3)
177
+#define NPCM7XX_MFT_MCTRL_MODE5 BIT(2)
178
+
179
+#define NPCM7XX_MFT_ICTRL_TFPND BIT(5)
180
+#define NPCM7XX_MFT_ICTRL_TEPND BIT(4)
181
+#define NPCM7XX_MFT_ICTRL_TDPND BIT(3)
182
+#define NPCM7XX_MFT_ICTRL_TCPND BIT(2)
183
+#define NPCM7XX_MFT_ICTRL_TBPND BIT(1)
184
+#define NPCM7XX_MFT_ICTRL_TAPND BIT(0)
185
+
186
+#define NPCM7XX_MFT_ICLR_TFCLR BIT(5)
187
+#define NPCM7XX_MFT_ICLR_TECLR BIT(4)
188
+#define NPCM7XX_MFT_ICLR_TDCLR BIT(3)
189
+#define NPCM7XX_MFT_ICLR_TCCLR BIT(2)
190
+#define NPCM7XX_MFT_ICLR_TBCLR BIT(1)
191
+#define NPCM7XX_MFT_ICLR_TACLR BIT(0)
192
+
193
+#define NPCM7XX_MFT_IEN_TFIEN BIT(5)
194
+#define NPCM7XX_MFT_IEN_TEIEN BIT(4)
195
+#define NPCM7XX_MFT_IEN_TDIEN BIT(3)
196
+#define NPCM7XX_MFT_IEN_TCIEN BIT(2)
197
+#define NPCM7XX_MFT_IEN_TBIEN BIT(1)
198
+#define NPCM7XX_MFT_IEN_TAIEN BIT(0)
199
+
200
+#define NPCM7XX_MFT_CPCFG_GET_B(rv) extract8((rv), 4, 4)
201
+#define NPCM7XX_MFT_CPCFG_GET_A(rv) extract8((rv), 0, 4)
202
+#define NPCM7XX_MFT_CPCFG_HIEN BIT(3)
203
+#define NPCM7XX_MFT_CPCFG_EQEN BIT(2)
204
+#define NPCM7XX_MFT_CPCFG_LOEN BIT(1)
205
+#define NPCM7XX_MFT_CPCFG_CPSEL BIT(0)
206
+
207
+#define NPCM7XX_MFT_INASEL_SELA BIT(0)
208
+#define NPCM7XX_MFT_INBSEL_SELB BIT(0)
209
+
210
+/* Max CNT values of the module. The CNT value is a countdown from it. */
211
+#define NPCM7XX_MFT_MAX_CNT 0xFFFF
212
+
213
+/* Each fan revolution should generated 2 pulses */
214
+#define NPCM7XX_MFT_PULSE_PER_REVOLUTION 2
215
+
216
+typedef enum NPCM7xxMFTCaptureState {
217
+ /* capture succeeded with a valid CNT value. */
218
+ NPCM7XX_CAPTURE_SUCCEED,
219
+ /* capture stopped prematurely due to reaching CPCFG condition. */
220
+ NPCM7XX_CAPTURE_COMPARE_HIT,
221
+ /* capture fails since it reaches underflow condition for CNT. */
222
+ NPCM7XX_CAPTURE_UNDERFLOW,
223
+} NPCM7xxMFTCaptureState;
224
+
225
+static void npcm7xx_mft_reset(NPCM7xxMFTState *s)
226
+{
227
+ int i;
228
+
229
+ /* Only registers PRSC ~ INBSEL need to be reset. */
230
+ for (i = R_NPCM7XX_MFT_PRSC; i <= R_NPCM7XX_MFT_INBSEL; ++i) {
231
+ s->regs[i] = 0;
232
+ }
233
+}
234
+
235
+static void npcm7xx_mft_clear_interrupt(NPCM7xxMFTState *s, uint8_t iclr)
236
+{
237
+ /*
238
+ * Clear bits in ICTRL where corresponding bits in iclr is 1.
239
+ * Both iclr and ictrl are 8-bit regs. (See npcm7xx_mft_check_mem_op)
240
+ */
241
+ s->regs[R_NPCM7XX_MFT_ICTRL] &= ~iclr;
242
+}
243
+
244
+/*
245
+ * If the CPCFG's condition should be triggered during count down from
246
+ * NPCM7XX_MFT_MAX_CNT to src if compared to tgt, return the count when
247
+ * the condition is triggered.
248
+ * Otherwise return -1.
249
+ * Since tgt is uint16_t it must always <= NPCM7XX_MFT_MAX_CNT.
250
+ */
251
+static int npcm7xx_mft_compare(int32_t src, uint16_t tgt, uint8_t cpcfg)
252
+{
253
+ if (cpcfg & NPCM7XX_MFT_CPCFG_HIEN) {
254
+ return NPCM7XX_MFT_MAX_CNT;
255
+ }
256
+ if ((cpcfg & NPCM7XX_MFT_CPCFG_EQEN) && (src <= tgt)) {
257
+ return tgt;
258
+ }
259
+ if ((cpcfg & NPCM7XX_MFT_CPCFG_LOEN) && (tgt > 0) && (src < tgt)) {
260
+ return tgt - 1;
261
+ }
262
+
263
+ return -1;
264
+}
265
+
266
+/* Compute CNT according to corresponding fan's RPM. */
267
+static NPCM7xxMFTCaptureState npcm7xx_mft_compute_cnt(
268
+ Clock *clock, uint32_t max_rpm, uint32_t duty, uint16_t tgt,
269
+ uint8_t cpcfg, uint16_t *cnt)
270
+{
271
+ uint32_t rpm = (uint64_t)max_rpm * (uint64_t)duty / NPCM7XX_PWM_MAX_DUTY;
272
+ int32_t count;
273
+ int stopped;
274
+ NPCM7xxMFTCaptureState state;
275
+
276
+ if (rpm == 0) {
277
+ /*
278
+ * If RPM = 0, capture won't happen. CNT will continue count down.
279
+ * So it's effective equivalent to have a cnt > NPCM7XX_MFT_MAX_CNT
280
+ */
281
+ count = NPCM7XX_MFT_MAX_CNT + 1;
282
+ } else {
283
+ /*
284
+ * RPM = revolution/min. The time for one revlution (in ns) is
285
+ * MINUTE_TO_NANOSECOND / RPM.
286
+ */
287
+ count = clock_ns_to_ticks(clock, (60 * NANOSECONDS_PER_SECOND) /
288
+ (rpm * NPCM7XX_MFT_PULSE_PER_REVOLUTION));
289
+ }
290
+
291
+ if (count > NPCM7XX_MFT_MAX_CNT) {
292
+ count = -1;
293
+ } else {
294
+ /* The CNT is a countdown value from NPCM7XX_MFT_MAX_CNT. */
295
+ count = NPCM7XX_MFT_MAX_CNT - count;
296
+ }
297
+ stopped = npcm7xx_mft_compare(count, tgt, cpcfg);
298
+ if (stopped == -1) {
299
+ if (count == -1) {
300
+ /* Underflow */
301
+ state = NPCM7XX_CAPTURE_UNDERFLOW;
302
+ } else {
149
+ } else {
303
+ state = NPCM7XX_CAPTURE_SUCCEED;
150
+ /*
151
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
152
+ * case sets InvalidOp and returns the input value 'c'
153
+ */
154
+ rule = float_infzeronan_dnan_never;
304
+ }
155
+ }
305
+ } else {
156
+#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
306
+ count = stopped;
157
+ defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
307
+ state = NPCM7XX_CAPTURE_COMPARE_HIT;
158
+ defined(TARGET_I386) || defined(TARGET_LOONGARCH)
308
+ }
159
+ /*
309
+
160
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
310
+ if (count != -1) {
161
+ * case sets InvalidOp and returns the input value 'c'
311
+ *cnt = count;
162
+ */
312
+ }
163
+ /*
313
+ trace_npcm7xx_mft_rpm(clock->canonical_path, clock_get_hz(clock),
164
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
314
+ state, count, rpm, duty);
165
+ * to return an input NaN if we have one (ie c) rather than generating
315
+ return state;
166
+ * a default NaN
316
+}
167
+ */
317
+
168
+ rule = float_infzeronan_dnan_never;
318
+/*
169
+#elif defined(TARGET_S390X)
319
+ * Capture Fan RPM and update CNT and CR registers accordingly.
170
+ rule = float_infzeronan_dnan_always;
320
+ * Raise IRQ if certain contidions are met in IEN.
171
+#endif
321
+ */
172
}
322
+static void npcm7xx_mft_capture(NPCM7xxMFTState *s)
173
323
+{
174
+ if (infzero) {
324
+ int irq_level = 0;
175
+ /*
325
+ NPCM7xxMFTCaptureState state;
176
+ * Inf * 0 + NaN -- some implementations return the default NaN here,
326
+ int sel;
177
+ * and some return the input NaN.
327
+ uint8_t cpcfg;
178
+ */
328
+
179
+ switch (rule) {
329
+ /*
180
+ case float_infzeronan_dnan_never:
330
+ * If not mode 5, the behavior is undefined. We just do nothing in this
181
+ return 2;
331
+ * case.
182
+ case float_infzeronan_dnan_always:
332
+ */
183
+ return 3;
333
+ if (!(s->regs[R_NPCM7XX_MFT_MCTRL] & NPCM7XX_MFT_MCTRL_MODE5)) {
184
+ case float_infzeronan_dnan_if_qnan:
334
+ return;
185
+ return is_qnan(c_cls) ? 3 : 2;
335
+ }
336
+
337
+ /* Capture input A. */
338
+ if (s->regs[R_NPCM7XX_MFT_MCTRL] & NPCM7XX_MFT_MCTRL_TAEN &&
339
+ s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C1CSEL) {
340
+ sel = s->regs[R_NPCM7XX_MFT_INASEL] & NPCM7XX_MFT_INASEL_SELA;
341
+ cpcfg = NPCM7XX_MFT_CPCFG_GET_A(s->regs[R_NPCM7XX_MFT_CPCFG]);
342
+ state = npcm7xx_mft_compute_cnt(s->clock_1,
343
+ sel ? s->max_rpm[2] : s->max_rpm[0],
344
+ sel ? s->duty[2] : s->duty[0],
345
+ s->regs[R_NPCM7XX_MFT_CPA],
346
+ cpcfg,
347
+ &s->regs[R_NPCM7XX_MFT_CNT1]);
348
+ switch (state) {
349
+ case NPCM7XX_CAPTURE_SUCCEED:
350
+ /* Interrupt on input capture on TAn transition - TAPND */
351
+ s->regs[R_NPCM7XX_MFT_CRA] = s->regs[R_NPCM7XX_MFT_CNT1];
352
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TAPND;
353
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TAIEN) {
354
+ irq_level = 1;
355
+ }
356
+ break;
357
+
358
+ case NPCM7XX_CAPTURE_COMPARE_HIT:
359
+ /* Compare Hit - TEPND */
360
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TEPND;
361
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TEIEN) {
362
+ irq_level = 1;
363
+ }
364
+ break;
365
+
366
+ case NPCM7XX_CAPTURE_UNDERFLOW:
367
+ /* Underflow - TCPND */
368
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TCPND;
369
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TCIEN) {
370
+ irq_level = 1;
371
+ }
372
+ break;
373
+
374
+ default:
186
+ default:
375
+ g_assert_not_reached();
187
+ g_assert_not_reached();
376
+ }
188
+ }
377
+ }
189
+ }
378
+
190
+
379
+ /* Capture input B. */
191
+#if defined(TARGET_ARM)
380
+ if (s->regs[R_NPCM7XX_MFT_MCTRL] & NPCM7XX_MFT_MCTRL_TBEN &&
192
+
381
+ s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C2CSEL) {
193
/* This looks different from the ARM ARM pseudocode, because the ARM ARM
382
+ sel = s->regs[R_NPCM7XX_MFT_INBSEL] & NPCM7XX_MFT_INBSEL_SELB;
194
* puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
383
+ cpcfg = NPCM7XX_MFT_CPCFG_GET_B(s->regs[R_NPCM7XX_MFT_CPCFG]);
195
*/
384
+ state = npcm7xx_mft_compute_cnt(s->clock_2,
196
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
385
+ sel ? s->max_rpm[3] : s->max_rpm[1],
197
}
386
+ sel ? s->duty[3] : s->duty[1],
198
#elif defined(TARGET_MIPS)
387
+ s->regs[R_NPCM7XX_MFT_CPB],
199
if (snan_bit_is_one(status)) {
388
+ cpcfg,
200
- /*
389
+ &s->regs[R_NPCM7XX_MFT_CNT2]);
201
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
390
+ switch (state) {
202
- * case sets InvalidOp and returns the default NaN
391
+ case NPCM7XX_CAPTURE_SUCCEED:
203
- */
392
+ /* Interrupt on input capture on TBn transition - TBPND */
204
- if (infzero) {
393
+ s->regs[R_NPCM7XX_MFT_CRB] = s->regs[R_NPCM7XX_MFT_CNT2];
205
- return 3;
394
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TBPND;
206
- }
395
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TBIEN) {
207
/* Prefer sNaN over qNaN, in the a, b, c order. */
396
+ irq_level = 1;
208
if (is_snan(a_cls)) {
397
+ }
209
return 0;
398
+ break;
210
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
399
+
211
return 2;
400
+ case NPCM7XX_CAPTURE_COMPARE_HIT:
212
}
401
+ /* Compare Hit - TFPND */
213
} else {
402
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TFPND;
214
- /*
403
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TFIEN) {
215
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
404
+ irq_level = 1;
216
- * case sets InvalidOp and returns the input value 'c'
405
+ }
217
- */
406
+ break;
218
/* Prefer sNaN over qNaN, in the c, a, b order. */
407
+
219
if (is_snan(c_cls)) {
408
+ case NPCM7XX_CAPTURE_UNDERFLOW:
220
return 2;
409
+ /* Underflow - TDPND */
221
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
410
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TDPND;
222
}
411
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TDIEN) {
223
}
412
+ irq_level = 1;
224
#elif defined(TARGET_LOONGARCH64)
413
+ }
225
- /*
414
+ break;
226
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
415
+
227
- * case sets InvalidOp and returns the input value 'c'
416
+ default:
228
- */
417
+ g_assert_not_reached();
229
-
418
+ }
230
/* Prefer sNaN over qNaN, in the c, a, b order. */
419
+ }
231
if (is_snan(c_cls)) {
420
+
232
return 2;
421
+ trace_npcm7xx_mft_capture(DEVICE(s)->canonical_path, irq_level);
233
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
422
+ qemu_set_irq(s->irq, irq_level);
234
return 1;
423
+}
235
}
424
+
236
#elif defined(TARGET_PPC)
425
+/* Update clock for counters. */
237
- /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
426
+static void npcm7xx_mft_update_clock(void *opaque, ClockEvent event)
238
- * to return an input NaN if we have one (ie c) rather than generating
427
+{
239
- * a default NaN
428
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
240
- */
429
+ uint64_t prescaled_clock_period;
241
-
430
+
242
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
431
+ prescaled_clock_period = clock_get(s->clock_in) *
243
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
432
+ (s->regs[R_NPCM7XX_MFT_PRSC] + 1ULL);
244
*/
433
+ trace_npcm7xx_mft_update_clock(s->clock_in->canonical_path,
245
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
434
+ s->regs[R_NPCM7XX_MFT_CKC],
246
return 1;
435
+ clock_get(s->clock_in),
247
}
436
+ prescaled_clock_period);
248
#elif defined(TARGET_S390X)
437
+ /* Update clock 1 */
249
- if (infzero) {
438
+ if (s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C1CSEL) {
250
- return 3;
439
+ /* Clock is prescaled. */
251
- }
440
+ clock_update(s->clock_1, prescaled_clock_period);
252
-
441
+ } else {
253
if (is_snan(a_cls)) {
442
+ /* Clock stopped. */
254
return 0;
443
+ clock_update(s->clock_1, 0);
255
} else if (is_snan(b_cls)) {
444
+ }
445
+ /* Update clock 2 */
446
+ if (s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C2CSEL) {
447
+ /* Clock is prescaled. */
448
+ clock_update(s->clock_2, prescaled_clock_period);
449
+ } else {
450
+ /* Clock stopped. */
451
+ clock_update(s->clock_2, 0);
452
+ }
453
+
454
+ npcm7xx_mft_capture(s);
455
+}
456
+
457
+static uint64_t npcm7xx_mft_read(void *opaque, hwaddr offset, unsigned size)
458
+{
459
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
460
+ uint16_t value = 0;
461
+
462
+ switch (offset) {
463
+ case A_NPCM7XX_MFT_ICLR:
464
+ qemu_log_mask(LOG_GUEST_ERROR,
465
+ "%s: register @ 0x%04" HWADDR_PRIx " is write-only\n",
466
+ __func__, offset);
467
+ break;
468
+
469
+ default:
470
+ value = s->regs[offset / 2];
471
+ }
472
+
473
+ trace_npcm7xx_mft_read(DEVICE(s)->canonical_path, offset, value);
474
+ return value;
475
+}
476
+
477
+static void npcm7xx_mft_write(void *opaque, hwaddr offset,
478
+ uint64_t v, unsigned size)
479
+{
480
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
481
+
482
+ trace_npcm7xx_mft_write(DEVICE(s)->canonical_path, offset, v);
483
+ switch (offset) {
484
+ case A_NPCM7XX_MFT_ICLR:
485
+ npcm7xx_mft_clear_interrupt(s, v);
486
+ break;
487
+
488
+ case A_NPCM7XX_MFT_CKC:
489
+ case A_NPCM7XX_MFT_PRSC:
490
+ s->regs[offset / 2] = v;
491
+ npcm7xx_mft_update_clock(s, ClockUpdate);
492
+ break;
493
+
494
+ default:
495
+ s->regs[offset / 2] = v;
496
+ npcm7xx_mft_capture(s);
497
+ break;
498
+ }
499
+}
500
+
501
+static bool npcm7xx_mft_check_mem_op(void *opaque, hwaddr offset,
502
+ unsigned size, bool is_write,
503
+ MemTxAttrs attrs)
504
+{
505
+ switch (offset) {
506
+ /* 16-bit registers. Must be accessed with 16-bit read/write.*/
507
+ case A_NPCM7XX_MFT_CNT1:
508
+ case A_NPCM7XX_MFT_CRA:
509
+ case A_NPCM7XX_MFT_CRB:
510
+ case A_NPCM7XX_MFT_CNT2:
511
+ case A_NPCM7XX_MFT_CPA:
512
+ case A_NPCM7XX_MFT_CPB:
513
+ return size == 2;
514
+
515
+ /* 8-bit registers. Must be accessed with 8-bit read/write.*/
516
+ case A_NPCM7XX_MFT_PRSC:
517
+ case A_NPCM7XX_MFT_CKC:
518
+ case A_NPCM7XX_MFT_MCTRL:
519
+ case A_NPCM7XX_MFT_ICTRL:
520
+ case A_NPCM7XX_MFT_ICLR:
521
+ case A_NPCM7XX_MFT_IEN:
522
+ case A_NPCM7XX_MFT_CPCFG:
523
+ case A_NPCM7XX_MFT_INASEL:
524
+ case A_NPCM7XX_MFT_INBSEL:
525
+ return size == 1;
526
+
527
+ default:
528
+ /* Invalid registers. */
529
+ return false;
530
+ }
531
+}
532
+
533
+static void npcm7xx_mft_get_max_rpm(Object *obj, Visitor *v, const char *name,
534
+ void *opaque, Error **errp)
535
+{
536
+ visit_type_uint32(v, name, (uint32_t *)opaque, errp);
537
+}
538
+
539
+static void npcm7xx_mft_set_max_rpm(Object *obj, Visitor *v, const char *name,
540
+ void *opaque, Error **errp)
541
+{
542
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
543
+ uint32_t *max_rpm = opaque;
544
+ uint32_t value;
545
+
546
+ if (!visit_type_uint32(v, name, &value, errp)) {
547
+ return;
548
+ }
549
+
550
+ *max_rpm = value;
551
+ npcm7xx_mft_capture(s);
552
+}
553
+
554
+static void npcm7xx_mft_duty_handler(void *opaque, int n, int value)
555
+{
556
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
557
+
558
+ trace_npcm7xx_mft_set_duty(DEVICE(s)->canonical_path, n, value);
559
+ s->duty[n] = value;
560
+ npcm7xx_mft_capture(s);
561
+}
562
+
563
+static const struct MemoryRegionOps npcm7xx_mft_ops = {
564
+ .read = npcm7xx_mft_read,
565
+ .write = npcm7xx_mft_write,
566
+ .endianness = DEVICE_LITTLE_ENDIAN,
567
+ .valid = {
568
+ .min_access_size = 1,
569
+ .max_access_size = 2,
570
+ .unaligned = false,
571
+ .accepts = npcm7xx_mft_check_mem_op,
572
+ },
573
+};
574
+
575
+static void npcm7xx_mft_enter_reset(Object *obj, ResetType type)
576
+{
577
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
578
+
579
+ npcm7xx_mft_reset(s);
580
+}
581
+
582
+static void npcm7xx_mft_hold_reset(Object *obj)
583
+{
584
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
585
+
586
+ qemu_irq_lower(s->irq);
587
+}
588
+
589
+static void npcm7xx_mft_init(Object *obj)
590
+{
591
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
592
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
593
+ DeviceState *dev = DEVICE(obj);
594
+
595
+ memory_region_init_io(&s->iomem, obj, &npcm7xx_mft_ops, s,
596
+ TYPE_NPCM7XX_MFT, 4 * KiB);
597
+ sysbus_init_mmio(sbd, &s->iomem);
598
+ sysbus_init_irq(sbd, &s->irq);
599
+ s->clock_in = qdev_init_clock_in(dev, "clock-in", npcm7xx_mft_update_clock,
600
+ s, ClockUpdate);
601
+ s->clock_1 = qdev_init_clock_out(dev, "clock1");
602
+ s->clock_2 = qdev_init_clock_out(dev, "clock2");
603
+
604
+ for (int i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) {
605
+ object_property_add(obj, "max_rpm[*]", "uint32",
606
+ npcm7xx_mft_get_max_rpm,
607
+ npcm7xx_mft_set_max_rpm,
608
+ NULL, &s->max_rpm[i]);
609
+ }
610
+ qdev_init_gpio_in_named(dev, npcm7xx_mft_duty_handler, "duty",
611
+ NPCM7XX_MFT_FANIN_COUNT);
612
+}
613
+
614
+static const VMStateDescription vmstate_npcm7xx_mft = {
615
+ .name = "npcm7xx-mft-module",
616
+ .version_id = 0,
617
+ .minimum_version_id = 0,
618
+ .fields = (VMStateField[]) {
619
+ VMSTATE_CLOCK(clock_in, NPCM7xxMFTState),
620
+ VMSTATE_CLOCK(clock_1, NPCM7xxMFTState),
621
+ VMSTATE_CLOCK(clock_2, NPCM7xxMFTState),
622
+ VMSTATE_UINT16_ARRAY(regs, NPCM7xxMFTState, NPCM7XX_MFT_NR_REGS),
623
+ VMSTATE_UINT32_ARRAY(max_rpm, NPCM7xxMFTState, NPCM7XX_MFT_FANIN_COUNT),
624
+ VMSTATE_UINT32_ARRAY(duty, NPCM7xxMFTState, NPCM7XX_MFT_FANIN_COUNT),
625
+ VMSTATE_END_OF_LIST(),
626
+ },
627
+};
628
+
629
+static void npcm7xx_mft_class_init(ObjectClass *klass, void *data)
630
+{
631
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
632
+ DeviceClass *dc = DEVICE_CLASS(klass);
633
+
634
+ dc->desc = "NPCM7xx MFT Controller";
635
+ dc->vmsd = &vmstate_npcm7xx_mft;
636
+ rc->phases.enter = npcm7xx_mft_enter_reset;
637
+ rc->phases.hold = npcm7xx_mft_hold_reset;
638
+}
639
+
640
+static const TypeInfo npcm7xx_mft_info = {
641
+ .name = TYPE_NPCM7XX_MFT,
642
+ .parent = TYPE_SYS_BUS_DEVICE,
643
+ .instance_size = sizeof(NPCM7xxMFTState),
644
+ .class_init = npcm7xx_mft_class_init,
645
+ .instance_init = npcm7xx_mft_init,
646
+};
647
+
648
+static void npcm7xx_mft_register_type(void)
649
+{
650
+ type_register_static(&npcm7xx_mft_info);
651
+}
652
+type_init(npcm7xx_mft_register_type);
653
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
654
index XXXXXXX..XXXXXXX 100644
655
--- a/hw/misc/meson.build
656
+++ b/hw/misc/meson.build
657
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mst_fpga.c'))
658
softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
659
'npcm7xx_clk.c',
660
'npcm7xx_gcr.c',
661
+ 'npcm7xx_mft.c',
662
'npcm7xx_pwm.c',
663
'npcm7xx_rng.c',
664
))
665
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
666
index XXXXXXX..XXXXXXX 100644
667
--- a/hw/misc/trace-events
668
+++ b/hw/misc/trace-events
669
@@ -XXX,XX +XXX,XX @@ npcm7xx_clk_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " valu
670
npcm7xx_gcr_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
671
npcm7xx_gcr_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
672
673
+# npcm7xx_mft.c
674
+npcm7xx_mft_read(const char *name, uint64_t offset, uint16_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
675
+npcm7xx_mft_write(const char *name, uint64_t offset, uint16_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
676
+npcm7xx_mft_rpm(const char *clock, uint32_t clock_hz, int state, int32_t cnt, uint32_t rpm, uint32_t duty) " fan clk: %s clock_hz: %" PRIu32 ", state: %d, cnt: %" PRIi32 ", rpm: %" PRIu32 ", duty: %" PRIu32
677
+npcm7xx_mft_capture(const char *name, int irq_level) "%s: level: %d"
678
+npcm7xx_mft_update_clock(const char *name, uint16_t sel, uint64_t clock_period, uint64_t prescaled_clock_period) "%s: sel: 0x%02" PRIx16 ", period: %" PRIu64 ", prescaled: %" PRIu64
679
+npcm7xx_mft_set_duty(const char *name, int n, int value) "%s[%d]: %d"
680
+
681
# npcm7xx_rng.c
682
npcm7xx_rng_read(uint64_t offset, uint64_t value, unsigned size) "offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u"
683
npcm7xx_rng_write(uint64_t offset, uint64_t value, unsigned size) "offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u"
684
--
256
--
685
2.20.1
257
2.34.1
686
687
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for the inf-zero-nan
2
muladd special case. In meson.build we put -DTARGET_ARM in fpcflags,
3
and so we should select here the Arm rule of
4
float_infzeronan_dnan_if_qnan.
1
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241202131347.498124-5-peter.maydell@linaro.org
9
---
10
tests/fp/fp-bench.c | 5 +++++
11
tests/fp/fp-test.c | 5 +++++
12
2 files changed, 10 insertions(+)
13
14
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/fp/fp-bench.c
17
+++ b/tests/fp/fp-bench.c
18
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
19
{
20
bench_func_t f;
21
22
+ /*
23
+ * These implementation-defined choices for various things IEEE
24
+ * doesn't specify match those used by the Arm architecture.
25
+ */
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
28
29
f = bench_funcs[operation][precision];
30
g_assert(f);
31
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/tests/fp/fp-test.c
34
+++ b/tests/fp/fp-test.c
35
@@ -XXX,XX +XXX,XX @@ void run_test(void)
36
{
37
unsigned int i;
38
39
+ /*
40
+ * These implementation-defined choices for various things IEEE
41
+ * doesn't specify match those used by the Arm architecture.
42
+ */
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
44
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
45
46
genCases_setLevel(test_level);
47
verCases_maxErrorCount = n_max_errors;
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the Arm target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-6-peter.maydell@linaro.org
7
---
8
target/arm/cpu.c | 3 +++
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 4 insertions(+), 7 deletions(-)
11
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
17
* * tininess-before-rounding
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
20
+ * * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
21
+ * and the input NaN if it is signalling
22
*/
23
static void arm_set_default_fp_behaviours(float_status *s)
24
{
25
set_float_detect_tininess(float_tininess_before_rounding, s);
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
28
}
29
30
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
/*
37
* Temporarily fall back to ifdef ladder
38
*/
39
-#if defined(TARGET_ARM)
40
- /*
41
- * For ARM, the (inf,zero,qnan) case returns the default NaN,
42
- * but (inf,zero,snan) returns the input NaN.
43
- */
44
- rule = float_infzeronan_dnan_if_qnan;
45
-#elif defined(TARGET_MIPS)
46
+#if defined(TARGET_MIPS)
47
if (snan_bit_is_one(status)) {
48
/*
49
* For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
50
--
51
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for s390, so we
2
can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-7-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_infzeronan_rule(float_infzeronan_dnan_always,
21
+ &env->fpu_status);
22
/* fall through */
23
case RESET_TYPE_S390_CPU_NORMAL:
24
env->psw.mask &= ~PSW_MASK_RI;
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
* a default NaN
31
*/
32
rule = float_infzeronan_dnan_never;
33
-#elif defined(TARGET_S390X)
34
- rule = float_infzeronan_dnan_always;
35
#endif
36
}
37
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the PPC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-8-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 7 +++++++
9
fpu/softfloat-specialize.c.inc | 7 +------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
22
+ * to return an input NaN if we have one (ie c) rather than generating
23
+ * a default NaN
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
27
28
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
29
ppc_spr_t *spr = &env->spr_cb[i];
30
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
31
index XXXXXXX..XXXXXXX 100644
32
--- a/fpu/softfloat-specialize.c.inc
33
+++ b/fpu/softfloat-specialize.c.inc
34
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
*/
36
rule = float_infzeronan_dnan_never;
37
}
38
-#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
39
+#elif defined(TARGET_SPARC) || \
40
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
41
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
42
/*
43
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
44
* case sets InvalidOp and returns the input value 'c'
45
*/
46
- /*
47
- * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
48
- * to return an input NaN if we have one (ie c) rather than generating
49
- * a default NaN
50
- */
51
rule = float_infzeronan_dnan_never;
52
#endif
53
}
54
--
55
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the MIPS target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-9-peter.maydell@linaro.org
7
---
8
target/mips/fpu_helper.h | 9 +++++++++
9
target/mips/msa.c | 4 ++++
10
fpu/softfloat-specialize.c.inc | 16 +---------------
11
3 files changed, 14 insertions(+), 15 deletions(-)
12
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/mips/fpu_helper.h
16
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_flush_mode(CPUMIPSState *env)
18
static inline void restore_snan_bit_mode(CPUMIPSState *env)
19
{
20
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
21
+ FloatInfZeroNaNRule izn_rule;
22
23
/*
24
* With nan2008, SNaNs are silenced in the usual way.
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
26
*/
27
set_snan_bit_is_one(!nan2008, &env->active_fpu.fp_status);
28
set_default_nan_mode(!nan2008, &env->active_fpu.fp_status);
29
+ /*
30
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
31
+ * case sets InvalidOp and returns the default NaN.
32
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
33
+ * case sets InvalidOp and returns the input value 'c'.
34
+ */
35
+ izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
36
+ set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
37
}
38
39
static inline void restore_fp_status(CPUMIPSState *env)
40
diff --git a/target/mips/msa.c b/target/mips/msa.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/mips/msa.c
43
+++ b/target/mips/msa.c
44
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
45
46
/* set proper signanling bit meaning ("1" means "quiet") */
47
set_snan_bit_is_one(0, &env->active_tc.msa_fp_status);
48
+
49
+ /* Inf * 0 + NaN returns the input NaN */
50
+ set_float_infzeronan_rule(float_infzeronan_dnan_never,
51
+ &env->active_tc.msa_fp_status);
52
}
53
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
54
index XXXXXXX..XXXXXXX 100644
55
--- a/fpu/softfloat-specialize.c.inc
56
+++ b/fpu/softfloat-specialize.c.inc
57
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
58
/*
59
* Temporarily fall back to ifdef ladder
60
*/
61
-#if defined(TARGET_MIPS)
62
- if (snan_bit_is_one(status)) {
63
- /*
64
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
65
- * case sets InvalidOp and returns the default NaN
66
- */
67
- rule = float_infzeronan_dnan_always;
68
- } else {
69
- /*
70
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
71
- * case sets InvalidOp and returns the input value 'c'
72
- */
73
- rule = float_infzeronan_dnan_never;
74
- }
75
-#elif defined(TARGET_SPARC) || \
76
+#if defined(TARGET_SPARC) || \
77
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
78
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
79
/*
80
--
81
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the SPARC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-10-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
23
cpu_exec_realizefn(cs, &local_err);
24
if (local_err != NULL) {
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_SPARC) || \
34
- defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
35
+#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
36
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
37
/*
38
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the xtensa target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-11-peter.maydell@linaro.org
7
---
8
target/xtensa/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 +-
10
2 files changed, 3 insertions(+), 1 deletion(-)
11
12
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/xtensa/cpu.c
15
+++ b/target/xtensa/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
17
reset_mmu(env);
18
cs->halted = env->runstall;
19
#endif
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
set_no_signaling_nans(!dfpu, &env->fp_status);
23
xtensa_use_first_nan(env, !dfpu);
24
}
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
34
+#if defined(TARGET_HPPA) || \
35
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
36
/*
37
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the x86 target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-12-peter.maydell@linaro.org
6
---
7
target/i386/tcg/fpu_helper.c | 7 +++++++
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 8 insertions(+), 1 deletion(-)
10
11
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/i386/tcg/fpu_helper.c
14
+++ b/target/i386/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->mmx_status);
18
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->sse_status);
19
+ /*
20
+ * Only SSE has multiply-add instructions. In the SDM Section 14.5.2
21
+ * "Fused-Multiply-ADD (FMA) Numeric Behavior" the NaN handling is
22
+ * specified -- for 0 * inf + NaN the input NaN is selected, and if
23
+ * there are multiple input NaNs they are selected in the order a, b, c.
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
26
}
27
28
static inline uint8_t save_exception_flags(CPUX86State *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
34
* Temporarily fall back to ifdef ladder
35
*/
36
#if defined(TARGET_HPPA) || \
37
- defined(TARGET_I386) || defined(TARGET_LOONGARCH)
38
+ defined(TARGET_LOONGARCH)
39
/*
40
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
41
* case sets InvalidOp and returns the input value 'c'
42
--
43
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the loongarch target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-13-peter.maydell@linaro.org
6
---
7
target/loongarch/tcg/fpu_helper.c | 5 +++++
8
fpu/softfloat-specialize.c.inc | 7 +------
9
2 files changed, 6 insertions(+), 6 deletions(-)
10
11
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/tcg/fpu_helper.c
14
+++ b/target/loongarch/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
16
&env->fp_status);
17
set_flush_to_zero(0, &env->fp_status);
18
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
19
+ /*
20
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
21
+ * case sets InvalidOp and returns the input value 'c'
22
+ */
23
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
}
25
26
int ieee_ex_to_loongarch(int xcpt)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
index XXXXXXX..XXXXXXX 100644
29
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
32
/*
33
* Temporarily fall back to ifdef ladder
34
*/
35
-#if defined(TARGET_HPPA) || \
36
- defined(TARGET_LOONGARCH)
37
- /*
38
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
- * case sets InvalidOp and returns the input value 'c'
40
- */
41
+#if defined(TARGET_HPPA)
42
rule = float_infzeronan_dnan_never;
43
#endif
44
}
45
--
46
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the HPPA target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
As this is the last target to be converted to explicitly setting
5
the rule, we can remove the fallback code in pickNaNMulAdd()
6
entirely.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20241202131347.498124-14-peter.maydell@linaro.org
11
---
12
target/hppa/fpu_helper.c | 2 ++
13
fpu/softfloat-specialize.c.inc | 13 +------------
14
2 files changed, 3 insertions(+), 12 deletions(-)
15
16
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/hppa/fpu_helper.c
19
+++ b/target/hppa/fpu_helper.c
20
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
21
* HPPA does note implement a CPU reset method at all...
22
*/
23
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
24
+ /* For inf * 0 + NaN, return the input NaN */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
}
27
28
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
34
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
bool infzero, float_status *status)
36
{
37
- FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
38
-
39
/*
40
* We guarantee not to require the target to tell us how to
41
* pick a NaN if we're always returning the default NaN.
42
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
43
*/
44
assert(!status->default_nan_mode);
45
46
- if (rule == float_infzeronan_none) {
47
- /*
48
- * Temporarily fall back to ifdef ladder
49
- */
50
-#if defined(TARGET_HPPA)
51
- rule = float_infzeronan_dnan_never;
52
-#endif
53
- }
54
-
55
if (infzero) {
56
/*
57
* Inf * 0 + NaN -- some implementations return the default NaN here,
58
* and some return the input NaN.
59
*/
60
- switch (rule) {
61
+ switch (status->float_infzeronan_rule) {
62
case float_infzeronan_dnan_never:
63
return 2;
64
case float_infzeronan_dnan_always:
65
--
66
2.34.1
diff view generated by jsdifflib
New patch
1
The new implementation of pickNaNMulAdd() will find it convenient
2
to know whether at least one of the three arguments to the muladd
3
was a signaling NaN. We already calculate that in the caller,
4
so pass it in as a new bool have_snan.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-15-peter.maydell@linaro.org
9
---
10
fpu/softfloat-parts.c.inc | 5 +++--
11
fpu/softfloat-specialize.c.inc | 2 +-
12
2 files changed, 4 insertions(+), 3 deletions(-)
13
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat-parts.c.inc
17
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
19
{
20
int which;
21
bool infzero = (ab_mask == float_cmask_infzero);
22
+ bool have_snan = (abc_mask & float_cmask_snan);
23
24
- if (unlikely(abc_mask & float_cmask_snan)) {
25
+ if (unlikely(have_snan)) {
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
27
}
28
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
if (s->default_nan_mode) {
31
which = 3;
32
} else {
33
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
35
}
36
37
if (which == 3) {
38
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
39
index XXXXXXX..XXXXXXX 100644
40
--- a/fpu/softfloat-specialize.c.inc
41
+++ b/fpu/softfloat-specialize.c.inc
42
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
43
| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
44
*----------------------------------------------------------------------------*/
45
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
46
- bool infzero, float_status *status)
47
+ bool infzero, bool have_snan, float_status *status)
48
{
49
/*
50
* We guarantee not to require the target to tell us how to
51
--
52
2.34.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
IEEE 758 does not define a fixed rule for which NaN to pick as the
2
2
result if both operands of a 3-operand fused multiply-add operation
3
This patch adds testing of PWM fan RPMs in the existing npcm7xx pwm
3
are NaNs. As a result different architectures have ended up with
4
test. It tests whether the MFT module can measure correct fan values
4
different rules for propagating NaNs.
5
for a PWM fan in NPCM7XX boards.
5
6
6
QEMU currently hardcodes the NaN propagation logic into the binary
7
Reviewed-by: Doug Evans <dje@google.com>
7
because pickNaNMulAdd() has an ifdef ladder for different targets.
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
8
We want to make the propagation rule instead be selectable at
9
Signed-off-by: Hao Wu <wuhaotsh@google.com>
9
runtime, because:
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
* this will let us have multiple targets in one QEMU binary
11
Message-id: 20210311180855.149764-6-wuhaotsh@google.com
11
* the Arm FEAT_AFP architectural feature includes letting
12
the guest select a NaN propagation rule at runtime
13
14
In this commit we add an enum for the propagation rule, the field in
15
float_status, and the corresponding getters and setters. We change
16
pickNaNMulAdd to honour this, but because all targets still leave
17
this field at its default 0 value, the fallback logic will pick the
18
rule type with the old ifdef ladder.
19
20
It's valid not to set a propagation rule if default_nan_mode is
21
enabled, because in that case there's no need to pick a NaN; all the
22
callers of pickNaNMulAdd() catch this case and skip calling it.
23
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20241202131347.498124-16-peter.maydell@linaro.org
13
---
27
---
14
tests/qtest/npcm7xx_pwm-test.c | 205 ++++++++++++++++++++++++++++++++-
28
include/fpu/softfloat-helpers.h | 11 +++
15
1 file changed, 199 insertions(+), 6 deletions(-)
29
include/fpu/softfloat-types.h | 55 +++++++++++
16
30
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
17
diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c
31
3 files changed, 107 insertions(+), 126 deletions(-)
32
33
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
18
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qtest/npcm7xx_pwm-test.c
35
--- a/include/fpu/softfloat-helpers.h
20
+++ b/tests/qtest/npcm7xx_pwm-test.c
36
+++ b/include/fpu/softfloat-helpers.h
21
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
22
#define PLL_FBDV(rv) extract32((rv), 16, 12)
38
status->float_2nan_prop_rule = rule;
23
#define PLL_OTDV1(rv) extract32((rv), 8, 3)
24
#define PLL_OTDV2(rv) extract32((rv), 13, 3)
25
+#define APB4CKDIV(rv) extract32((rv), 30, 2)
26
#define APB3CKDIV(rv) extract32((rv), 28, 2)
27
#define CLK2CKDIV(rv) extract32((rv), 0, 1)
28
#define CLK4CKDIV(rv) extract32((rv), 26, 2)
29
@@ -XXX,XX +XXX,XX @@
30
31
#define MAX_DUTY 1000000
32
33
+/* MFT (PWM fan) related */
34
+#define MFT_BA(n) (0xf0180000 + ((n) * 0x1000))
35
+#define MFT_IRQ(n) (96 + (n))
36
+#define MFT_CNT1 0x00
37
+#define MFT_CRA 0x02
38
+#define MFT_CRB 0x04
39
+#define MFT_CNT2 0x06
40
+#define MFT_PRSC 0x08
41
+#define MFT_CKC 0x0a
42
+#define MFT_MCTRL 0x0c
43
+#define MFT_ICTRL 0x0e
44
+#define MFT_ICLR 0x10
45
+#define MFT_IEN 0x12
46
+#define MFT_CPA 0x14
47
+#define MFT_CPB 0x16
48
+#define MFT_CPCFG 0x18
49
+#define MFT_INASEL 0x1a
50
+#define MFT_INBSEL 0x1c
51
+
52
+#define MFT_MCTRL_ALL 0x64
53
+#define MFT_ICLR_ALL 0x3f
54
+#define MFT_IEN_ALL 0x3f
55
+#define MFT_CPCFG_EQ_MODE 0x44
56
+
57
+#define MFT_CKC_C2CSEL BIT(3)
58
+#define MFT_CKC_C1CSEL BIT(0)
59
+
60
+#define MFT_ICTRL_TFPND BIT(5)
61
+#define MFT_ICTRL_TEPND BIT(4)
62
+#define MFT_ICTRL_TDPND BIT(3)
63
+#define MFT_ICTRL_TCPND BIT(2)
64
+#define MFT_ICTRL_TBPND BIT(1)
65
+#define MFT_ICTRL_TAPND BIT(0)
66
+
67
+#define MFT_MAX_CNT 0xffff
68
+#define MFT_TIMEOUT 0x5000
69
+
70
+#define DEFAULT_RPM 19800
71
+#define DEFAULT_PRSC 255
72
+#define MFT_PULSE_PER_REVOLUTION 2
73
+
74
+#define MAX_ERROR 1
75
+
76
typedef struct PWMModule {
77
int irq;
78
uint64_t base_addr;
79
@@ -XXX,XX +XXX,XX @@ static uint64_t pwm_get_duty(QTestState *qts, int module_index, int pwm_index)
80
return pwm_qom_get(qts, path, name);
81
}
39
}
82
40
83
+static void mft_qom_set(QTestState *qts, int index, const char *name,
41
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
84
+ uint32_t value)
42
+ float_status *status)
85
+{
43
+{
86
+ QDict *response;
44
+ status->float_3nan_prop_rule = rule;
87
+ char *path = g_strdup_printf("/machine/soc/mft[%d]", index);
88
+
89
+ g_test_message("Setting properties %s of mft[%d] with value %u",
90
+ name, index, value);
91
+ response = qtest_qmp(qts, "{ 'execute': 'qom-set',"
92
+ " 'arguments': { 'path': %s, "
93
+ " 'property': %s, 'value': %u}}",
94
+ path, name, value);
95
+ /* The qom set message returns successfully. */
96
+ g_assert_true(qdict_haskey(response, "return"));
97
+}
45
+}
98
+
46
+
99
static uint32_t get_pll(uint32_t con)
47
static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
float_status *status)
100
{
49
{
101
return REF_HZ * PLL_FBDV(con) / (PLL_INDV(con) * PLL_OTDV1(con)
50
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
102
* PLL_OTDV2(con));
51
return status->float_2nan_prop_rule;
103
}
52
}
104
53
105
-static uint64_t read_pclk(QTestState *qts)
54
+static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
106
+static uint64_t read_pclk(QTestState *qts, bool mft)
55
+{
56
+ return status->float_3nan_prop_rule;
57
+}
58
+
59
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
107
{
60
{
108
uint64_t freq = REF_HZ;
61
return status->float_infzeronan_rule;
109
uint32_t clksel = qtest_readl(qts, CLK_BA + CLKSEL);
62
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
110
uint32_t pllcon;
63
index XXXXXXX..XXXXXXX 100644
111
uint32_t clkdiv1 = qtest_readl(qts, CLK_BA + CLKDIV1);
64
--- a/include/fpu/softfloat-types.h
112
uint32_t clkdiv2 = qtest_readl(qts, CLK_BA + CLKDIV2);
65
+++ b/include/fpu/softfloat-types.h
113
+ uint32_t apbdiv = mft ? APB4CKDIV(clkdiv2) : APB3CKDIV(clkdiv2);
66
@@ -XXX,XX +XXX,XX @@ this code that are retained.
114
67
#ifndef SOFTFLOAT_TYPES_H
115
switch (CPUCKSEL(clksel)) {
68
#define SOFTFLOAT_TYPES_H
116
case 0:
69
117
@@ -XXX,XX +XXX,XX @@ static uint64_t read_pclk(QTestState *qts)
70
+#include "hw/registerfields.h"
118
g_assert_not_reached();
71
+
72
/*
73
* Software IEC/IEEE floating-point types.
74
*/
75
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
76
float_2nan_prop_x87,
77
} Float2NaNPropRule;
78
79
+/*
80
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
81
+ * architectures have different rules for which input NaN is
82
+ * propagated to the output when there is more than one NaN on the
83
+ * input.
84
+ *
85
+ * If default_nan_mode is enabled then it is valid not to set a NaN
86
+ * propagation rule, because the softfloat code guarantees not to try
87
+ * to pick a NaN to propagate in default NaN mode. When not in
88
+ * default-NaN mode, it is an error for the target not to set the rule
89
+ * in float_status if it uses a muladd, and we will assert if we need
90
+ * to handle an input NaN and no rule was selected.
91
+ *
92
+ * The naming scheme for Float3NaNPropRule values is:
93
+ * float_3nan_prop_s_abc:
94
+ * = "Prefer SNaN over QNaN, then operand A over B over C"
95
+ * float_3nan_prop_abc:
96
+ * = "Prefer A over B over C regardless of SNaN vs QNAN"
97
+ *
98
+ * For QEMU, the multiply-add operation is A * B + C.
99
+ */
100
+
101
+/*
102
+ * We set the Float3NaNPropRule enum values up so we can select the
103
+ * right value in pickNaNMulAdd in a data driven way.
104
+ */
105
+FIELD(3NAN, 1ST, 0, 2) /* which operand is most preferred ? */
106
+FIELD(3NAN, 2ND, 2, 2) /* which operand is next most preferred ? */
107
+FIELD(3NAN, 3RD, 4, 2) /* which operand is least preferred ? */
108
+FIELD(3NAN, SNAN, 6, 1) /* do we prefer SNaN over QNaN ? */
109
+
110
+#define PROPRULE(X, Y, Z) \
111
+ ((X << R_3NAN_1ST_SHIFT) | (Y << R_3NAN_2ND_SHIFT) | (Z << R_3NAN_3RD_SHIFT))
112
+
113
+typedef enum __attribute__((__packed__)) {
114
+ float_3nan_prop_none = 0, /* No propagation rule specified */
115
+ float_3nan_prop_abc = PROPRULE(0, 1, 2),
116
+ float_3nan_prop_acb = PROPRULE(0, 2, 1),
117
+ float_3nan_prop_bac = PROPRULE(1, 0, 2),
118
+ float_3nan_prop_bca = PROPRULE(1, 2, 0),
119
+ float_3nan_prop_cab = PROPRULE(2, 0, 1),
120
+ float_3nan_prop_cba = PROPRULE(2, 1, 0),
121
+ float_3nan_prop_s_abc = float_3nan_prop_abc | R_3NAN_SNAN_MASK,
122
+ float_3nan_prop_s_acb = float_3nan_prop_acb | R_3NAN_SNAN_MASK,
123
+ float_3nan_prop_s_bac = float_3nan_prop_bac | R_3NAN_SNAN_MASK,
124
+ float_3nan_prop_s_bca = float_3nan_prop_bca | R_3NAN_SNAN_MASK,
125
+ float_3nan_prop_s_cab = float_3nan_prop_cab | R_3NAN_SNAN_MASK,
126
+ float_3nan_prop_s_cba = float_3nan_prop_cba | R_3NAN_SNAN_MASK,
127
+} Float3NaNPropRule;
128
+
129
+#undef PROPRULE
130
+
131
/*
132
* Rule for result of fused multiply-add 0 * Inf + NaN.
133
* This must be a NaN, but implementations differ on whether this
134
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
135
FloatRoundMode float_rounding_mode;
136
FloatX80RoundPrec floatx80_rounding_precision;
137
Float2NaNPropRule float_2nan_prop_rule;
138
+ Float3NaNPropRule float_3nan_prop_rule;
139
FloatInfZeroNaNRule float_infzeronan_rule;
140
bool tininess_before_rounding;
141
/* should denormalised results go to zero and set the inexact flag? */
142
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
143
index XXXXXXX..XXXXXXX 100644
144
--- a/fpu/softfloat-specialize.c.inc
145
+++ b/fpu/softfloat-specialize.c.inc
146
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
147
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
148
bool infzero, bool have_snan, float_status *status)
149
{
150
+ FloatClass cls[3] = { a_cls, b_cls, c_cls };
151
+ Float3NaNPropRule rule = status->float_3nan_prop_rule;
152
+ int which;
153
+
154
/*
155
* We guarantee not to require the target to tell us how to
156
* pick a NaN if we're always returning the default NaN.
157
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
158
}
119
}
159
}
120
160
121
- freq >>= (CLK2CKDIV(clkdiv1) + CLK4CKDIV(clkdiv1) + APB3CKDIV(clkdiv2));
161
+ if (rule == float_3nan_prop_none) {
122
+ freq >>= (CLK2CKDIV(clkdiv1) + CLK4CKDIV(clkdiv1) + apbdiv);
162
#if defined(TARGET_ARM)
123
163
-
124
return freq;
164
- /* This looks different from the ARM ARM pseudocode, because the ARM ARM
165
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
166
- */
167
- if (is_snan(c_cls)) {
168
- return 2;
169
- } else if (is_snan(a_cls)) {
170
- return 0;
171
- } else if (is_snan(b_cls)) {
172
- return 1;
173
- } else if (is_qnan(c_cls)) {
174
- return 2;
175
- } else if (is_qnan(a_cls)) {
176
- return 0;
177
- } else {
178
- return 1;
179
- }
180
+ /*
181
+ * This looks different from the ARM ARM pseudocode, because the ARM ARM
182
+ * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
183
+ */
184
+ rule = float_3nan_prop_s_cab;
185
#elif defined(TARGET_MIPS)
186
- if (snan_bit_is_one(status)) {
187
- /* Prefer sNaN over qNaN, in the a, b, c order. */
188
- if (is_snan(a_cls)) {
189
- return 0;
190
- } else if (is_snan(b_cls)) {
191
- return 1;
192
- } else if (is_snan(c_cls)) {
193
- return 2;
194
- } else if (is_qnan(a_cls)) {
195
- return 0;
196
- } else if (is_qnan(b_cls)) {
197
- return 1;
198
+ if (snan_bit_is_one(status)) {
199
+ rule = float_3nan_prop_s_abc;
200
} else {
201
- return 2;
202
+ rule = float_3nan_prop_s_cab;
203
}
204
- } else {
205
- /* Prefer sNaN over qNaN, in the c, a, b order. */
206
- if (is_snan(c_cls)) {
207
- return 2;
208
- } else if (is_snan(a_cls)) {
209
- return 0;
210
- } else if (is_snan(b_cls)) {
211
- return 1;
212
- } else if (is_qnan(c_cls)) {
213
- return 2;
214
- } else if (is_qnan(a_cls)) {
215
- return 0;
216
- } else {
217
- return 1;
218
- }
219
- }
220
#elif defined(TARGET_LOONGARCH64)
221
- /* Prefer sNaN over qNaN, in the c, a, b order. */
222
- if (is_snan(c_cls)) {
223
- return 2;
224
- } else if (is_snan(a_cls)) {
225
- return 0;
226
- } else if (is_snan(b_cls)) {
227
- return 1;
228
- } else if (is_qnan(c_cls)) {
229
- return 2;
230
- } else if (is_qnan(a_cls)) {
231
- return 0;
232
- } else {
233
- return 1;
234
- }
235
+ rule = float_3nan_prop_s_cab;
236
#elif defined(TARGET_PPC)
237
- /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
238
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
239
- */
240
- if (is_nan(a_cls)) {
241
- return 0;
242
- } else if (is_nan(c_cls)) {
243
- return 2;
244
- } else {
245
- return 1;
246
- }
247
+ /*
248
+ * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
249
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
250
+ */
251
+ rule = float_3nan_prop_acb;
252
#elif defined(TARGET_S390X)
253
- if (is_snan(a_cls)) {
254
- return 0;
255
- } else if (is_snan(b_cls)) {
256
- return 1;
257
- } else if (is_snan(c_cls)) {
258
- return 2;
259
- } else if (is_qnan(a_cls)) {
260
- return 0;
261
- } else if (is_qnan(b_cls)) {
262
- return 1;
263
- } else {
264
- return 2;
265
- }
266
+ rule = float_3nan_prop_s_abc;
267
#elif defined(TARGET_SPARC)
268
- /* Prefer SNaN over QNaN, order C, B, A. */
269
- if (is_snan(c_cls)) {
270
- return 2;
271
- } else if (is_snan(b_cls)) {
272
- return 1;
273
- } else if (is_snan(a_cls)) {
274
- return 0;
275
- } else if (is_qnan(c_cls)) {
276
- return 2;
277
- } else if (is_qnan(b_cls)) {
278
- return 1;
279
- } else {
280
- return 0;
281
- }
282
+ rule = float_3nan_prop_s_cba;
283
#elif defined(TARGET_XTENSA)
284
- /*
285
- * For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
286
- * an input NaN if we have one (ie c).
287
- */
288
- if (status->use_first_nan) {
289
- if (is_nan(a_cls)) {
290
- return 0;
291
- } else if (is_nan(b_cls)) {
292
- return 1;
293
+ if (status->use_first_nan) {
294
+ rule = float_3nan_prop_abc;
295
} else {
296
- return 2;
297
+ rule = float_3nan_prop_cba;
298
}
299
- } else {
300
- if (is_nan(c_cls)) {
301
- return 2;
302
- } else if (is_nan(b_cls)) {
303
- return 1;
304
- } else {
305
- return 0;
306
- }
307
- }
308
#else
309
- /* A default implementation: prefer a to b to c.
310
- * This is unlikely to actually match any real implementation.
311
- */
312
- if (is_nan(a_cls)) {
313
- return 0;
314
- } else if (is_nan(b_cls)) {
315
- return 1;
316
- } else {
317
- return 2;
318
- }
319
+ rule = float_3nan_prop_abc;
320
#endif
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;
125
}
337
}
126
@@ -XXX,XX +XXX,XX @@ static uint32_t pwm_selector(uint32_t csr)
338
127
static uint64_t pwm_compute_freq(QTestState *qts, uint32_t ppr, uint32_t csr,
339
/*----------------------------------------------------------------------------
128
uint32_t cnr)
129
{
130
- return read_pclk(qts) / ((ppr + 1) * pwm_selector(csr) * (cnr + 1));
131
+ return read_pclk(qts, false) / ((ppr + 1) * pwm_selector(csr) * (cnr + 1));
132
}
133
134
static uint64_t pwm_compute_duty(uint32_t cnr, uint32_t cmr, bool inverted)
135
@@ -XXX,XX +XXX,XX @@ static void pwm_write(QTestState *qts, const TestData *td, unsigned offset,
136
qtest_writel(qts, td->module->base_addr + offset, value);
137
}
138
139
+static uint8_t mft_readb(QTestState *qts, int index, unsigned offset)
140
+{
141
+ return qtest_readb(qts, MFT_BA(index) + offset);
142
+}
143
+
144
+static uint16_t mft_readw(QTestState *qts, int index, unsigned offset)
145
+{
146
+ return qtest_readw(qts, MFT_BA(index) + offset);
147
+}
148
+
149
+static void mft_writeb(QTestState *qts, int index, unsigned offset,
150
+ uint8_t value)
151
+{
152
+ qtest_writeb(qts, MFT_BA(index) + offset, value);
153
+}
154
+
155
+static void mft_writew(QTestState *qts, int index, unsigned offset,
156
+ uint16_t value)
157
+{
158
+ return qtest_writew(qts, MFT_BA(index) + offset, value);
159
+}
160
+
161
static uint32_t pwm_read_ppr(QTestState *qts, const TestData *td)
162
{
163
return extract32(pwm_read(qts, td, PPR), ppr_base[pwm_index(td->pwm)], 8);
164
@@ -XXX,XX +XXX,XX @@ static void pwm_write_cmr(QTestState *qts, const TestData *td, uint32_t value)
165
pwm_write(qts, td, td->pwm->cmr_offset, value);
166
}
167
168
+static int mft_compute_index(const TestData *td)
169
+{
170
+ int index = pwm_module_index(td->module) * ARRAY_SIZE(pwm_list) +
171
+ pwm_index(td->pwm);
172
+
173
+ g_assert_cmpint(index, <,
174
+ ARRAY_SIZE(pwm_module_list) * ARRAY_SIZE(pwm_list));
175
+
176
+ return index;
177
+}
178
+
179
+static void mft_reset_counters(QTestState *qts, int index)
180
+{
181
+ mft_writew(qts, index, MFT_CNT1, MFT_MAX_CNT);
182
+ mft_writew(qts, index, MFT_CNT2, MFT_MAX_CNT);
183
+ mft_writew(qts, index, MFT_CRA, MFT_MAX_CNT);
184
+ mft_writew(qts, index, MFT_CRB, MFT_MAX_CNT);
185
+ mft_writew(qts, index, MFT_CPA, MFT_MAX_CNT - MFT_TIMEOUT);
186
+ mft_writew(qts, index, MFT_CPB, MFT_MAX_CNT - MFT_TIMEOUT);
187
+}
188
+
189
+static void mft_init(QTestState *qts, const TestData *td)
190
+{
191
+ int index = mft_compute_index(td);
192
+
193
+ /* Enable everything */
194
+ mft_writeb(qts, index, MFT_CKC, 0);
195
+ mft_writeb(qts, index, MFT_ICLR, MFT_ICLR_ALL);
196
+ mft_writeb(qts, index, MFT_MCTRL, MFT_MCTRL_ALL);
197
+ mft_writeb(qts, index, MFT_IEN, MFT_IEN_ALL);
198
+ mft_writeb(qts, index, MFT_INASEL, 0);
199
+ mft_writeb(qts, index, MFT_INBSEL, 0);
200
+
201
+ /* Set cpcfg to use EQ mode, same as kernel driver */
202
+ mft_writeb(qts, index, MFT_CPCFG, MFT_CPCFG_EQ_MODE);
203
+
204
+ /* Write default counters, timeout and prescaler */
205
+ mft_reset_counters(qts, index);
206
+ mft_writeb(qts, index, MFT_PRSC, DEFAULT_PRSC);
207
+
208
+ /* Write default max rpm via QMP */
209
+ mft_qom_set(qts, index, "max_rpm[0]", DEFAULT_RPM);
210
+ mft_qom_set(qts, index, "max_rpm[1]", DEFAULT_RPM);
211
+}
212
+
213
+static int32_t mft_compute_cnt(uint32_t rpm, uint64_t clk)
214
+{
215
+ uint64_t cnt;
216
+
217
+ if (rpm == 0) {
218
+ return -1;
219
+ }
220
+
221
+ cnt = clk * 60 / ((DEFAULT_PRSC + 1) * rpm * MFT_PULSE_PER_REVOLUTION);
222
+ if (cnt >= MFT_TIMEOUT) {
223
+ return -1;
224
+ }
225
+ return MFT_MAX_CNT - cnt;
226
+}
227
+
228
+static void mft_verify_rpm(QTestState *qts, const TestData *td, uint64_t duty)
229
+{
230
+ int index = mft_compute_index(td);
231
+ uint16_t cnt, cr;
232
+ uint32_t rpm = DEFAULT_RPM * duty / MAX_DUTY;
233
+ uint64_t clk = read_pclk(qts, true);
234
+ int32_t expected_cnt = mft_compute_cnt(rpm, clk);
235
+
236
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
237
+ g_test_message(
238
+ "verifying rpm for mft[%d]: clk: %lu, duty: %lu, rpm: %u, cnt: %d",
239
+ index, clk, duty, rpm, expected_cnt);
240
+
241
+ /* Verify rpm for fan A */
242
+ /* Stop capture */
243
+ mft_writeb(qts, index, MFT_CKC, 0);
244
+ mft_writeb(qts, index, MFT_ICLR, MFT_ICLR_ALL);
245
+ mft_reset_counters(qts, index);
246
+ g_assert_cmphex(mft_readw(qts, index, MFT_CNT1), ==, MFT_MAX_CNT);
247
+ g_assert_cmphex(mft_readw(qts, index, MFT_CRA), ==, MFT_MAX_CNT);
248
+ g_assert_cmphex(mft_readw(qts, index, MFT_CPA), ==,
249
+ MFT_MAX_CNT - MFT_TIMEOUT);
250
+ /* Start capture */
251
+ mft_writeb(qts, index, MFT_CKC, MFT_CKC_C1CSEL);
252
+ g_assert_true(qtest_get_irq(qts, MFT_IRQ(index)));
253
+ if (expected_cnt == -1) {
254
+ g_assert_cmphex(mft_readb(qts, index, MFT_ICTRL), ==, MFT_ICTRL_TEPND);
255
+ } else {
256
+ g_assert_cmphex(mft_readb(qts, index, MFT_ICTRL), ==, MFT_ICTRL_TAPND);
257
+ cnt = mft_readw(qts, index, MFT_CNT1);
258
+ /*
259
+ * Due to error in clock measurement and rounding, we might have a small
260
+ * error in measuring RPM.
261
+ */
262
+ g_assert_cmphex(cnt + MAX_ERROR, >=, expected_cnt);
263
+ g_assert_cmphex(cnt, <=, expected_cnt + MAX_ERROR);
264
+ cr = mft_readw(qts, index, MFT_CRA);
265
+ g_assert_cmphex(cnt, ==, cr);
266
+ }
267
+
268
+ /* Verify rpm for fan B */
269
+
270
+ qtest_irq_intercept_out(qts, "/machine/soc/a9mpcore/gic");
271
+}
272
+
273
/* Check pwm registers can be reset to default value */
274
static void test_init(gconstpointer test_data)
275
{
276
const TestData *td = test_data;
277
- QTestState *qts = qtest_init("-machine quanta-gsj");
278
+ QTestState *qts = qtest_init("-machine npcm750-evb");
279
int module = pwm_module_index(td->module);
280
int pwm = pwm_index(td->pwm);
281
282
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
283
static void test_oneshot(gconstpointer test_data)
284
{
285
const TestData *td = test_data;
286
- QTestState *qts = qtest_init("-machine quanta-gsj");
287
+ QTestState *qts = qtest_init("-machine npcm750-evb");
288
int module = pwm_module_index(td->module);
289
int pwm = pwm_index(td->pwm);
290
uint32_t ppr, csr, pcr;
291
@@ -XXX,XX +XXX,XX @@ static void test_oneshot(gconstpointer test_data)
292
static void test_toggle(gconstpointer test_data)
293
{
294
const TestData *td = test_data;
295
- QTestState *qts = qtest_init("-machine quanta-gsj");
296
+ QTestState *qts = qtest_init("-machine npcm750-evb");
297
int module = pwm_module_index(td->module);
298
int pwm = pwm_index(td->pwm);
299
uint32_t ppr, csr, pcr, cnr, cmr;
300
int i, j, k, l;
301
uint64_t expected_freq, expected_duty;
302
303
+ mft_init(qts, td);
304
+
305
pcr = CH_EN | CH_MOD;
306
for (i = 0; i < ARRAY_SIZE(ppr_list); ++i) {
307
ppr = ppr_list[i];
308
@@ -XXX,XX +XXX,XX @@ static void test_toggle(gconstpointer test_data)
309
==, expected_freq);
310
}
311
312
+ /* Test MFT's RPM is correct. */
313
+ mft_verify_rpm(qts, td, expected_duty);
314
+
315
/* Test inverted mode */
316
expected_duty = pwm_compute_duty(cnr, cmr, true);
317
pwm_write_pcr(qts, td, pcr | CH_INV);
318
--
340
--
319
2.20.1
341
2.34.1
320
321
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for propagating NaNs in
2
the muladd case. In meson.build we put -DTARGET_ARM in fpcflags, and
3
so we should select here the Arm rule of float_3nan_prop_s_cab.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-17-peter.maydell@linaro.org
8
---
9
tests/fp/fp-bench.c | 1 +
10
tests/fp/fp-test.c | 1 +
11
2 files changed, 2 insertions(+)
12
13
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/fp/fp-bench.c
16
+++ b/tests/fp/fp-bench.c
17
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
18
* doesn't specify match those used by the Arm architecture.
19
*/
20
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
22
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
23
24
f = bench_funcs[operation][precision];
25
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/fp/fp-test.c
28
+++ b/tests/fp/fp-test.c
29
@@ -XXX,XX +XXX,XX @@ void run_test(void)
30
* doesn't specify match those used by the Arm architecture.
31
*/
32
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
33
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
34
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
35
36
genCases_setLevel(test_level);
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-18-peter.maydell@linaro.org
7
---
8
target/arm/cpu.c | 5 +++++
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 6 insertions(+), 7 deletions(-)
11
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
17
* * tininess-before-rounding
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
20
+ * * 3-input NaN propagation prefers SNaN over QNaN, and then
21
+ * operand C over A over B (see FPProcessNaNs3() pseudocode,
22
+ * but note that for QEMU muladd is a * b + c, whereas for
23
+ * the pseudocode function the arguments are in the order c, a, b.
24
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
25
* and the input NaN if it is signalling
26
*/
27
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
28
{
29
set_float_detect_tininess(float_tininess_before_rounding, s);
30
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
31
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
32
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
33
}
34
35
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
36
index XXXXXXX..XXXXXXX 100644
37
--- a/fpu/softfloat-specialize.c.inc
38
+++ b/fpu/softfloat-specialize.c.inc
39
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
40
}
41
42
if (rule == float_3nan_prop_none) {
43
-#if defined(TARGET_ARM)
44
- /*
45
- * This looks different from the ARM ARM pseudocode, because the ARM ARM
46
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
47
- */
48
- rule = float_3nan_prop_s_cab;
49
-#elif defined(TARGET_MIPS)
50
+#if defined(TARGET_MIPS)
51
if (snan_bit_is_one(status)) {
52
rule = float_3nan_prop_s_abc;
53
} else {
54
--
55
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for loongarch, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-19-peter.maydell@linaro.org
7
---
8
target/loongarch/tcg/fpu_helper.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/loongarch/tcg/fpu_helper.c
15
+++ b/target/loongarch/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
17
* case sets InvalidOp and returns the input value 'c'
18
*/
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
21
}
22
23
int ieee_ex_to_loongarch(int xcpt)
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_LOONGARCH64)
33
- rule = float_3nan_prop_s_cab;
34
#elif defined(TARGET_PPC)
35
/*
36
* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for PPC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-20-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 8 ++++++++
9
fpu/softfloat-specialize.c.inc | 6 ------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * NaN propagation for fused multiply-add:
22
+ * if fRA is a NaN return it; otherwise if fRB is a NaN return it;
23
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
24
+ * whereas QEMU labels the operands as (a * b) + c.
25
+ */
26
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->fp_status);
27
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->vec_status);
28
/*
29
* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
30
* to return an input NaN if we have one (ie c) rather than generating
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
} else {
37
rule = float_3nan_prop_s_cab;
38
}
39
-#elif defined(TARGET_PPC)
40
- /*
41
- * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
42
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
43
- */
44
- rule = float_3nan_prop_acb;
45
#elif defined(TARGET_S390X)
46
rule = float_3nan_prop_s_abc;
47
#elif defined(TARGET_SPARC)
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for s390x, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-21-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
21
set_float_infzeronan_rule(float_infzeronan_dnan_always,
22
&env->fpu_status);
23
/* fall through */
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_S390X)
33
- rule = float_3nan_prop_s_abc;
34
#elif defined(TARGET_SPARC)
35
rule = float_3nan_prop_s_cba;
36
#elif defined(TARGET_XTENSA)
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for SPARC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-22-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For fused-multiply add, prefer SNaN over QNaN, then C->B->A */
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
22
/* For inf * 0 + NaN, return the input NaN */
23
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
} else {
31
rule = float_3nan_prop_s_cab;
32
}
33
-#elif defined(TARGET_SPARC)
34
- rule = float_3nan_prop_s_cba;
35
#elif defined(TARGET_XTENSA)
36
if (status->use_first_nan) {
37
rule = float_3nan_prop_abc;
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-23-peter.maydell@linaro.org
7
---
8
target/mips/fpu_helper.h | 4 ++++
9
target/mips/msa.c | 3 +++
10
fpu/softfloat-specialize.c.inc | 8 +-------
11
3 files changed, 8 insertions(+), 7 deletions(-)
12
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/mips/fpu_helper.h
16
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
18
{
19
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
20
FloatInfZeroNaNRule izn_rule;
21
+ Float3NaNPropRule nan3_rule;
22
23
/*
24
* With nan2008, SNaNs are silenced in the usual way.
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
26
*/
27
izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
28
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
29
+ nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
30
+ set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
31
+
32
}
33
34
static inline void restore_fp_status(CPUMIPSState *env)
35
diff --git a/target/mips/msa.c b/target/mips/msa.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/mips/msa.c
38
+++ b/target/mips/msa.c
39
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
40
set_float_2nan_prop_rule(float_2nan_prop_s_ab,
41
&env->active_tc.msa_fp_status);
42
43
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab,
44
+ &env->active_tc.msa_fp_status);
45
+
46
/* clear float_status exception flags */
47
set_float_exception_flags(0, &env->active_tc.msa_fp_status);
48
49
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
50
index XXXXXXX..XXXXXXX 100644
51
--- a/fpu/softfloat-specialize.c.inc
52
+++ b/fpu/softfloat-specialize.c.inc
53
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
54
}
55
56
if (rule == float_3nan_prop_none) {
57
-#if defined(TARGET_MIPS)
58
- if (snan_bit_is_one(status)) {
59
- rule = float_3nan_prop_s_abc;
60
- } else {
61
- rule = float_3nan_prop_s_cab;
62
- }
63
-#elif defined(TARGET_XTENSA)
64
+#if defined(TARGET_XTENSA)
65
if (status->use_first_nan) {
66
rule = float_3nan_prop_abc;
67
} else {
68
--
69
2.34.1
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
Set the Float3NaNPropRule explicitly for xtensa, and remove the
2
ifdef from pickNaNMulAdd().
2
3
3
Prior to commit f2ce39b4f067 a MachineClass kvm_type method
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
only needed to be registered to ensure it would be executed.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
With commit f2ce39b4f067 a kvm-type machine property must also
6
Message-id: 20241202131347.498124-24-peter.maydell@linaro.org
6
be specified. hw/arm/virt relies on the kvm_type method to pass
7
---
7
its selected IPA limit to KVM, but this is not exposed as a
8
target/xtensa/fpu_helper.c | 2 ++
8
machine property. Restore the previous functionality of invoking
9
fpu/softfloat-specialize.c.inc | 8 --------
9
kvm_type when it's present.
10
2 files changed, 2 insertions(+), 8 deletions(-)
10
11
11
Fixes: f2ce39b4f067 ("vl: make qemu_get_machine_opts static")
12
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
12
Signed-off-by: Andrew Jones <drjones@redhat.com>
13
Reviewed-by: Eric Auger <eric.auger@redhat.com>
14
Message-id: 20210310135218.255205-2-drjones@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
include/hw/boards.h | 1 +
18
accel/kvm/kvm-all.c | 2 ++
19
2 files changed, 3 insertions(+)
20
21
diff --git a/include/hw/boards.h b/include/hw/boards.h
22
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/boards.h
14
--- a/target/xtensa/fpu_helper.c
24
+++ b/include/hw/boards.h
15
+++ b/target/xtensa/fpu_helper.c
25
@@ -XXX,XX +XXX,XX @@ typedef struct {
16
@@ -XXX,XX +XXX,XX @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
26
* @kvm_type:
17
set_use_first_nan(use_first, &env->fp_status);
27
* Return the type of KVM corresponding to the kvm-type string option or
18
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
28
* computed based on other criteria such as the host kernel capabilities.
19
&env->fp_status);
29
+ * kvm-type may be NULL if it is not needed.
20
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
30
* @numa_mem_supported:
21
+ &env->fp_status);
31
* true if '--numa node.mem' option is supported and false otherwise
22
}
32
* @smp_parse:
23
33
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
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
34
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
35
--- a/accel/kvm/kvm-all.c
27
--- a/fpu/softfloat-specialize.c.inc
36
+++ b/accel/kvm/kvm-all.c
28
+++ b/fpu/softfloat-specialize.c.inc
37
@@ -XXX,XX +XXX,XX @@ static int kvm_init(MachineState *ms)
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
38
"kvm-type",
39
&error_abort);
40
type = mc->kvm_type(ms, kvm_type);
41
+ } else if (mc->kvm_type) {
42
+ type = mc->kvm_type(ms, NULL);
43
}
30
}
44
31
45
do {
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);
46
--
45
--
47
2.20.1
46
2.34.1
48
49
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Set the Float3NaNPropRule explicitly for i386. We had no
2
i386-specific behaviour in the old ifdef ladder, so we were using the
3
default "prefer a then b then c" fallback; this is actually the
4
correct per-the-spec handling for i386.
2
5
3
If the SSECounter link is absent, we set an error message
4
in sse_timer_realize() but forgot to propagate this error.
5
Add the missing 'return'.
6
7
Fixes: CID 1450755 (Null pointer dereferences)
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210312001845.1562670-1-f4bug@amsat.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-25-peter.maydell@linaro.org
12
---
9
---
13
hw/timer/sse-timer.c | 1 +
10
target/i386/tcg/fpu_helper.c | 1 +
14
1 file changed, 1 insertion(+)
11
1 file changed, 1 insertion(+)
15
12
16
diff --git a/hw/timer/sse-timer.c b/hw/timer/sse-timer.c
13
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/timer/sse-timer.c
15
--- a/target/i386/tcg/fpu_helper.c
19
+++ b/hw/timer/sse-timer.c
16
+++ b/target/i386/tcg/fpu_helper.c
20
@@ -XXX,XX +XXX,XX @@ static void sse_timer_realize(DeviceState *dev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
21
18
* there are multiple input NaNs they are selected in the order a, b, c.
22
if (!s->counter) {
19
*/
23
error_setg(errp, "counter property was not set");
20
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
24
+ return;
21
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
25
}
22
}
26
23
27
s->counter_notifier.notify = sse_timer_counter_callback;
24
static inline uint8_t save_exception_flags(CPUX86State *env)
28
--
25
--
29
2.20.1
26
2.34.1
30
31
diff view generated by jsdifflib
1
For a long time now the UI layer has guaranteed that the console
1
Set the Float3NaNPropRule explicitly for HPPA, and remove the
2
surface is always 32 bits per pixel. Remove the legacy dead
2
ifdef from pickNaNMulAdd().
3
code from the pl110 display device which was handling the
3
4
possibility that the console surface was some other format.
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.
5
12
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210211141515.8755-2-peter.maydell@linaro.org
15
Message-id: 20241202131347.498124-26-peter.maydell@linaro.org
9
---
16
---
10
hw/display/pl110.c | 53 +++++++---------------------------------------
17
target/hppa/fpu_helper.c | 8 ++++++++
11
1 file changed, 8 insertions(+), 45 deletions(-)
18
fpu/softfloat-specialize.c.inc | 4 ----
19
2 files changed, 8 insertions(+), 4 deletions(-)
12
20
13
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
21
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/display/pl110.c
23
--- a/target/hppa/fpu_helper.c
16
+++ b/hw/display/pl110.c
24
+++ b/target/hppa/fpu_helper.c
17
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
25
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
18
pl111_id
26
* HPPA does note implement a CPU reset method at all...
19
};
27
*/
20
28
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
21
-#define BITS 8
29
+ /*
22
-#include "pl110_template.h"
30
+ * TODO: The HPPA architecture reference only documents its NaN
23
-#define BITS 15
31
+ * propagation rule for 2-operand operations. Testing on real hardware
24
-#include "pl110_template.h"
32
+ * might be necessary to confirm whether this order for muladd is correct.
25
-#define BITS 16
33
+ * Not preferring the SNaN is almost certainly incorrect as it diverges
26
-#include "pl110_template.h"
34
+ * from the documented rules for 2-operand operations.
27
-#define BITS 24
35
+ */
28
-#include "pl110_template.h"
36
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
29
#define BITS 32
37
/* For inf * 0 + NaN, return the input NaN */
30
#include "pl110_template.h"
38
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
31
39
}
32
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
40
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
33
PL110State *s = (PL110State *)opaque;
41
index XXXXXXX..XXXXXXX 100644
34
SysBusDevice *sbd;
42
--- a/fpu/softfloat-specialize.c.inc
35
DisplaySurface *surface = qemu_console_surface(s->con);
43
+++ b/fpu/softfloat-specialize.c.inc
36
- drawfn* fntable;
44
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
37
drawfn fn;
38
- int dest_width;
39
int src_width;
40
int bpp_offset;
41
int first;
42
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
43
44
sbd = SYS_BUS_DEVICE(s);
45
46
- switch (surface_bits_per_pixel(surface)) {
47
- case 0:
48
- return;
49
- case 8:
50
- fntable = pl110_draw_fn_8;
51
- dest_width = 1;
52
- break;
53
- case 15:
54
- fntable = pl110_draw_fn_15;
55
- dest_width = 2;
56
- break;
57
- case 16:
58
- fntable = pl110_draw_fn_16;
59
- dest_width = 2;
60
- break;
61
- case 24:
62
- fntable = pl110_draw_fn_24;
63
- dest_width = 3;
64
- break;
65
- case 32:
66
- fntable = pl110_draw_fn_32;
67
- dest_width = 4;
68
- break;
69
- default:
70
- fprintf(stderr, "pl110: Bad color depth\n");
71
- exit(1);
72
- }
73
if (s->cr & PL110_CR_BGR)
74
bpp_offset = 0;
75
else
76
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
77
}
45
}
78
}
46
}
79
47
80
- if (s->cr & PL110_CR_BEBO)
48
- if (rule == float_3nan_prop_none) {
81
- fn = fntable[s->bpp + 8 + bpp_offset];
49
- rule = float_3nan_prop_abc;
82
- else if (s->cr & PL110_CR_BEPO)
50
- }
83
- fn = fntable[s->bpp + 16 + bpp_offset];
51
-
84
- else
52
assert(rule != float_3nan_prop_none);
85
- fn = fntable[s->bpp + bpp_offset];
53
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
86
+ if (s->cr & PL110_CR_BEBO) {
54
/* We have at least one SNaN input and should prefer it */
87
+ fn = pl110_draw_fn_32[s->bpp + 8 + bpp_offset];
88
+ } else if (s->cr & PL110_CR_BEPO) {
89
+ fn = pl110_draw_fn_32[s->bpp + 16 + bpp_offset];
90
+ } else {
91
+ fn = pl110_draw_fn_32[s->bpp + bpp_offset];
92
+ }
93
94
src_width = s->cols;
95
switch (s->bpp) {
96
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
97
src_width <<= 2;
98
break;
99
}
100
- dest_width *= s->cols;
101
first = 0;
102
if (s->invalidate) {
103
framebuffer_update_memory_section(&s->fbsection,
104
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
105
106
framebuffer_update_display(surface, &s->fbsection,
107
s->cols, s->rows,
108
- src_width, dest_width, 0,
109
+ src_width, s->cols * 4, 0,
110
s->invalidate,
111
fn, s->palette,
112
&first, &last);
113
--
55
--
114
2.20.1
56
2.34.1
115
116
diff view generated by jsdifflib
New patch
1
The use_first_nan field in float_status was an xtensa-specific way to
2
select at runtime from two different NaN propagation rules. Now that
3
xtensa is using the target-agnostic NaN propagation rule selection
4
that we've just added, we can remove use_first_nan, because there is
5
no longer any code that reads it.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20241202131347.498124-27-peter.maydell@linaro.org
10
---
11
include/fpu/softfloat-helpers.h | 5 -----
12
include/fpu/softfloat-types.h | 1 -
13
target/xtensa/fpu_helper.c | 1 -
14
3 files changed, 7 deletions(-)
15
16
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/fpu/softfloat-helpers.h
19
+++ b/include/fpu/softfloat-helpers.h
20
@@ -XXX,XX +XXX,XX @@ static inline void set_snan_bit_is_one(bool val, float_status *status)
21
status->snan_bit_is_one = val;
22
}
23
24
-static inline void set_use_first_nan(bool val, float_status *status)
25
-{
26
- status->use_first_nan = val;
27
-}
28
-
29
static inline void set_no_signaling_nans(bool val, float_status *status)
30
{
31
status->no_signaling_nans = val;
32
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/fpu/softfloat-types.h
35
+++ b/include/fpu/softfloat-types.h
36
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
37
* softfloat-specialize.inc.c)
38
*/
39
bool snan_bit_is_one;
40
- bool use_first_nan;
41
bool no_signaling_nans;
42
/* should overflowed results subtract re_bias to its exponent? */
43
bool rebias_overflow;
44
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/xtensa/fpu_helper.c
47
+++ b/target/xtensa/fpu_helper.c
48
@@ -XXX,XX +XXX,XX @@ static const struct {
49
50
void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
51
{
52
- set_use_first_nan(use_first, &env->fp_status);
53
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
54
&env->fp_status);
55
set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
56
--
57
2.34.1
diff view generated by jsdifflib
New patch
1
Currently m68k_cpu_reset_hold() calls floatx80_default_nan(NULL)
2
to get the NaN bit pattern to reset the FPU registers. This
3
works because it happens that our implementation of
4
floatx80_default_nan() doesn't actually look at the float_status
5
pointer except for TARGET_MIPS. However, this isn't guaranteed,
6
and to be able to remove the ifdef in floatx80_default_nan()
7
we're going to need a real float_status here.
1
8
9
Rearrange m68k_cpu_reset_hold() so that we initialize env->fp_status
10
earlier, and thus can pass it to floatx80_default_nan().
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20241202131347.498124-28-peter.maydell@linaro.org
15
---
16
target/m68k/cpu.c | 12 +++++++-----
17
1 file changed, 7 insertions(+), 5 deletions(-)
18
19
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/m68k/cpu.c
22
+++ b/target/m68k/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
24
CPUState *cs = CPU(obj);
25
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(obj);
26
CPUM68KState *env = cpu_env(cs);
27
- floatx80 nan = floatx80_default_nan(NULL);
28
+ floatx80 nan;
29
int i;
30
31
if (mcc->parent_phases.hold) {
32
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
33
#else
34
cpu_m68k_set_sr(env, SR_S | SR_I);
35
#endif
36
- for (i = 0; i < 8; i++) {
37
- env->fregs[i].d = nan;
38
- }
39
- cpu_m68k_set_fpcr(env, 0);
40
/*
41
* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
42
* 3.4 FLOATING-POINT INSTRUCTION DETAILS
43
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
44
* preceding paragraph for nonsignaling NaNs.
45
*/
46
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
47
+
48
+ nan = floatx80_default_nan(&env->fp_status);
49
+ for (i = 0; i < 8; i++) {
50
+ env->fregs[i].d = nan;
51
+ }
52
+ cpu_m68k_set_fpcr(env, 0);
53
env->fpsr = 0;
54
55
/* TODO: We should set PC from the interrupt vector. */
56
--
57
2.34.1
diff view generated by jsdifflib
New patch
1
We create our 128-bit default NaN by calling parts64_default_nan()
2
and then adjusting the result. We can do the same trick for creating
3
the floatx80 default NaN, which lets us drop a target ifdef.
1
4
5
floatx80 is used only by:
6
i386
7
m68k
8
arm nwfpe old floating-point emulation emulation support
9
(which is essentially dead, especially the parts involving floatx80)
10
PPC (only in the xsrqpxp instruction, which just rounds an input
11
value by converting to floatx80 and back, so will never generate
12
the default NaN)
13
14
The floatx80 default NaN as currently implemented is:
15
m68k: sign = 0, exp = 1...1, int = 1, frac = 1....1
16
i386: sign = 1, exp = 1...1, int = 1, frac = 10...0
17
18
These are the same as the parts64_default_nan for these architectures.
19
20
This is technically a possible behaviour change for arm linux-user
21
nwfpe emulation emulation, because the default NaN will now have the
22
sign bit clear. But we were already generating a different floatx80
23
default NaN from the real kernel emulation we are supposedly
24
following, which appears to use an all-bits-1 value:
25
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L267
26
27
This won't affect the only "real" use of the nwfpe emulation, which
28
is ancient binaries that used it as part of the old floating point
29
calling convention; that only uses loads and stores of 32 and 64 bit
30
floats, not any of the floatx80 behaviour the original hardware had.
31
We also get the nwfpe float64 default NaN value wrong:
32
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L166
33
so if we ever cared about this obscure corner the right fix would be
34
to correct that so nwfpe used its own default-NaN setting rather
35
than the Arm VFP one.
36
37
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
38
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
39
Message-id: 20241202131347.498124-29-peter.maydell@linaro.org
40
---
41
fpu/softfloat-specialize.c.inc | 20 ++++++++++----------
42
1 file changed, 10 insertions(+), 10 deletions(-)
43
44
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
45
index XXXXXXX..XXXXXXX 100644
46
--- a/fpu/softfloat-specialize.c.inc
47
+++ b/fpu/softfloat-specialize.c.inc
48
@@ -XXX,XX +XXX,XX @@ static void parts128_silence_nan(FloatParts128 *p, float_status *status)
49
floatx80 floatx80_default_nan(float_status *status)
50
{
51
floatx80 r;
52
+ /*
53
+ * Extrapolate from the choices made by parts64_default_nan to fill
54
+ * in the floatx80 format. We assume that floatx80's explicit
55
+ * integer bit is always set (this is true for i386 and m68k,
56
+ * which are the only real users of this format).
57
+ */
58
+ FloatParts64 p64;
59
+ parts64_default_nan(&p64, status);
60
61
- /* None of the targets that have snan_bit_is_one use floatx80. */
62
- assert(!snan_bit_is_one(status));
63
-#if defined(TARGET_M68K)
64
- r.low = UINT64_C(0xFFFFFFFFFFFFFFFF);
65
- r.high = 0x7FFF;
66
-#else
67
- /* X86 */
68
- r.low = UINT64_C(0xC000000000000000);
69
- r.high = 0xFFFF;
70
-#endif
71
+ r.high = 0x7FFF | (p64.sign << 15);
72
+ r.low = (1ULL << DECOMPOSED_BINARY_POINT) | p64.frac;
73
return r;
74
}
75
76
--
77
2.34.1
diff view generated by jsdifflib
New patch
1
In target/loongarch's helper_fclass_s() and helper_fclass_d() we pass
2
a zero-initialized float_status struct to float32_is_quiet_nan() and
3
float64_is_quiet_nan(), with the cryptic comment "for
4
snan_bit_is_one".
1
5
6
This pattern appears to have been copied from target/riscv, where it
7
is used because the functions there do not have ready access to the
8
CPU state struct. The comment presumably refers to the fact that the
9
main reason the is_quiet_nan() functions want the float_state is
10
because they want to know about the snan_bit_is_one config.
11
12
In the loongarch helpers, though, we have the CPU state struct
13
to hand. Use the usual env->fp_status here. This avoids our needing
14
to track that we need to update the initializer of the local
15
float_status structs when the core softfloat code adds new
16
options for targets to configure their behaviour.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20241202131347.498124-30-peter.maydell@linaro.org
21
---
22
target/loongarch/tcg/fpu_helper.c | 6 ++----
23
1 file changed, 2 insertions(+), 4 deletions(-)
24
25
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/loongarch/tcg/fpu_helper.c
28
+++ b/target/loongarch/tcg/fpu_helper.c
29
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
30
} else if (float32_is_zero_or_denormal(f)) {
31
return sign ? 1 << 4 : 1 << 8;
32
} else if (float32_is_any_nan(f)) {
33
- float_status s = { }; /* for snan_bit_is_one */
34
- return float32_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
35
+ return float32_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
36
} else {
37
return sign ? 1 << 3 : 1 << 7;
38
}
39
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
40
} else if (float64_is_zero_or_denormal(f)) {
41
return sign ? 1 << 4 : 1 << 8;
42
} else if (float64_is_any_nan(f)) {
43
- float_status s = { }; /* for snan_bit_is_one */
44
- return float64_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
45
+ return float64_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
46
} else {
47
return sign ? 1 << 3 : 1 << 7;
48
}
49
--
50
2.34.1
diff view generated by jsdifflib
New patch
1
In the frem helper, we have a local float_status because we want to
2
execute the floatx80_div() with a custom rounding mode. Instead of
3
zero-initializing the local float_status and then having to set it up
4
with the m68k standard behaviour (including the NaN propagation rule
5
and copying the rounding precision from env->fp_status), initialize
6
it as a complete copy of env->fp_status. This will avoid our having
7
to add new code in this function for every new config knob we add
8
to fp_status.
1
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-31-peter.maydell@linaro.org
13
---
14
target/m68k/fpu_helper.c | 6 ++----
15
1 file changed, 2 insertions(+), 4 deletions(-)
16
17
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/m68k/fpu_helper.c
20
+++ b/target/m68k/fpu_helper.c
21
@@ -XXX,XX +XXX,XX @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
22
23
fp_rem = floatx80_rem(val1->d, val0->d, &env->fp_status);
24
if (!floatx80_is_any_nan(fp_rem)) {
25
- float_status fp_status = { };
26
+ /* Use local temporary fp_status to set different rounding mode */
27
+ float_status fp_status = env->fp_status;
28
uint32_t quotient;
29
int sign;
30
31
/* Calculate quotient directly using round to nearest mode */
32
- set_float_2nan_prop_rule(float_2nan_prop_ab, &fp_status);
33
set_float_rounding_mode(float_round_nearest_even, &fp_status);
34
- set_floatx80_rounding_precision(
35
- get_floatx80_rounding_precision(&env->fp_status), &fp_status);
36
fp_quot.d = floatx80_div(val1->d, val0->d, &fp_status);
37
38
sign = extractFloatx80Sign(fp_quot.d);
39
--
40
2.34.1
diff view generated by jsdifflib
1
We're about to move code from the template header into pxa2xx_lcd.c.
1
In cf_fpu_gdb_get_reg() and cf_fpu_gdb_set_reg() we do the conversion
2
Before doing that, make coding style fixes so checkpatch doesn't
2
from float64 to floatx80 using a scratch float_status, because we
3
complain about the patch which moves the code. This commit fixes
3
don't want the conversion to affect the CPU's floating point exception
4
missing braces in the SKIP_PIXEL() macro definition and in if()
4
status. Currently we use a zero-initialized float_status. This will
5
statements.
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.
6
9
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210211141515.8755-8-peter.maydell@linaro.org
12
Message-id: 20241202131347.498124-32-peter.maydell@linaro.org
10
---
13
---
11
hw/display/pxa2xx_template.h | 47 +++++++++++++++++++++---------------
14
target/m68k/helper.c | 6 ++++--
12
1 file changed, 28 insertions(+), 19 deletions(-)
15
1 file changed, 4 insertions(+), 2 deletions(-)
13
16
14
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
17
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/display/pxa2xx_template.h
19
--- a/target/m68k/helper.c
17
+++ b/hw/display/pxa2xx_template.h
20
+++ b/target/m68k/helper.c
18
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
19
* Framebuffer format conversion routines.
22
CPUM68KState *env = &cpu->env;
20
*/
23
21
24
if (n < 8) {
22
-# define SKIP_PIXEL(to)        to += deststep
25
- float_status s = {};
23
+# define SKIP_PIXEL(to) do { to += deststep; } while (0)
26
+ /* Use scratch float_status so any exceptions don't change CPU state */
24
# define COPY_PIXEL(to, from) \
27
+ float_status s = env->fp_status;
25
do { \
28
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
26
*(uint32_t *) to = from; \
27
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16t(void *opaque,
28
data >>= 5;
29
r = (data & 0x1f) << 3;
30
data >>= 5;
31
- if (data & 1)
32
+ if (data & 1) {
33
SKIP_PIXEL(dest);
34
- else
35
+ } else {
36
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
37
+ }
38
data >>= 1;
39
b = (data & 0x1f) << 3;
40
data >>= 5;
41
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16t(void *opaque,
42
data >>= 5;
43
r = (data & 0x1f) << 3;
44
data >>= 5;
45
- if (data & 1)
46
+ if (data & 1) {
47
SKIP_PIXEL(dest);
48
- else
49
+ } else {
50
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
51
+ }
52
width -= 2;
53
src += 4;
54
}
29
}
55
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19(void *opaque,
30
switch (n) {
56
data >>= 6;
31
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
57
r = (data & 0x3f) << 2;
32
CPUM68KState *env = &cpu->env;
58
data >>= 6;
33
59
- if (data & 1)
34
if (n < 8) {
60
+ if (data & 1) {
35
- float_status s = {};
61
SKIP_PIXEL(dest);
36
+ /* Use scratch float_status so any exceptions don't change CPU state */
62
- else
37
+ float_status s = env->fp_status;
63
+ } else {
38
env->fregs[n].d = float64_to_floatx80(ldq_be_p(mem_buf), &s);
64
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
39
return 8;
65
+ }
66
width -= 1;
67
src += 4;
68
}
69
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
70
data[0] >>= 6;
71
r = (data[0] & 0x3f) << 2;
72
data[0] >>= 6;
73
- if (data[0] & 1)
74
+ if (data[0] & 1) {
75
SKIP_PIXEL(dest);
76
- else
77
+ } else {
78
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
79
+ }
80
data[0] >>= 6;
81
b = (data[0] & 0x3f) << 2;
82
data[0] >>= 6;
83
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
84
data[1] >>= 4;
85
r = (data[1] & 0x3f) << 2;
86
data[1] >>= 6;
87
- if (data[1] & 1)
88
+ if (data[1] & 1) {
89
SKIP_PIXEL(dest);
90
- else
91
+ } else {
92
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
93
+ }
94
data[1] >>= 6;
95
b = (data[1] & 0x3f) << 2;
96
data[1] >>= 6;
97
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
98
data[1] >>= 6;
99
r = ((data[2] & 0x3) << 6) | (data[1] << 2);
100
data[2] >>= 2;
101
- if (data[2] & 1)
102
+ if (data[2] & 1) {
103
SKIP_PIXEL(dest);
104
- else
105
+ } else {
106
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
107
+ }
108
data[2] >>= 6;
109
b = (data[2] & 0x3f) << 2;
110
data[2] >>= 6;
111
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
112
data[2] >>= 6;
113
r = data[2] << 2;
114
data[2] >>= 6;
115
- if (data[2] & 1)
116
+ if (data[2] & 1) {
117
SKIP_PIXEL(dest);
118
- else
119
+ } else {
120
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
121
+ }
122
width -= 4;
123
}
124
}
125
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line24t(void *opaque,
126
data >>= 8;
127
r = data & 0xff;
128
data >>= 8;
129
- if (data & 1)
130
+ if (data & 1) {
131
SKIP_PIXEL(dest);
132
- else
133
+ } else {
134
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
135
+ }
136
width -= 1;
137
src += 4;
138
}
139
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line25(void *opaque,
140
data >>= 8;
141
r = data & 0xff;
142
data >>= 8;
143
- if (data & 1)
144
+ if (data & 1) {
145
SKIP_PIXEL(dest);
146
- else
147
+ } else {
148
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
149
+ }
150
width -= 1;
151
src += 4;
152
}
40
}
153
--
41
--
154
2.20.1
42
2.34.1
155
156
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
In the helper functions flcmps and flcmpd we use a scratch float_status
2
so that we don't change the CPU state if the comparison raises any
3
floating point exception flags. Instead of zero-initializing this
4
scratch float_status, initialize it as a copy of env->fp_status. This
5
avoids the need to explicitly initialize settings like the NaN
6
propagation rule or others we might add to softfloat in future.
2
7
3
This patch adds fan_splitters (split IRQs) in NPCM7XX boards. Each fan
8
To do this we need to pass the CPU env pointer in to the helper.
4
splitter corresponds to 1 PWM output and can connect to multiple fan
5
inputs (MFT devices).
6
In NPCM7XX boards(NPCM750 EVB and Quanta GSJ boards), we initializes
7
these splitters and connect them to their corresponding modules
8
according their specific device trees.
9
9
10
Reviewed-by: Doug Evans <dje@google.com>
11
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
12
Signed-off-by: Hao Wu <wuhaotsh@google.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20210311180855.149764-5-wuhaotsh@google.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-33-peter.maydell@linaro.org
16
---
13
---
17
include/hw/arm/npcm7xx.h | 11 ++++-
14
target/sparc/helper.h | 4 ++--
18
hw/arm/npcm7xx_boards.c | 99 ++++++++++++++++++++++++++++++++++++++++
15
target/sparc/fop_helper.c | 8 ++++----
19
2 files changed, 109 insertions(+), 1 deletion(-)
16
target/sparc/translate.c | 4 ++--
17
3 files changed, 8 insertions(+), 8 deletions(-)
20
18
21
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
19
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
22
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/npcm7xx.h
21
--- a/target/sparc/helper.h
24
+++ b/include/hw/arm/npcm7xx.h
22
+++ b/target/sparc/helper.h
25
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
26
24
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
27
#include "hw/boards.h"
25
DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
28
#include "hw/adc/npcm7xx_adc.h"
26
DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
29
+#include "hw/core/split-irq.h"
27
-DEF_HELPER_FLAGS_2(flcmps, TCG_CALL_NO_RWG_SE, i32, f32, f32)
30
#include "hw/cpu/a9mpcore.h"
28
-DEF_HELPER_FLAGS_2(flcmpd, TCG_CALL_NO_RWG_SE, i32, f64, f64)
31
#include "hw/gpio/npcm7xx_gpio.h"
29
+DEF_HELPER_FLAGS_3(flcmps, TCG_CALL_NO_RWG_SE, i32, env, f32, f32)
32
#include "hw/i2c/npcm7xx_smbus.h"
30
+DEF_HELPER_FLAGS_3(flcmpd, TCG_CALL_NO_RWG_SE, i32, env, f64, f64)
33
@@ -XXX,XX +XXX,XX @@
31
DEF_HELPER_2(raise_exception, noreturn, env, int)
34
#define NPCM7XX_GIC_CPU_IF_ADDR (0xf03fe100) /* GIC within A9 */
32
35
#define NPCM7XX_BOARD_SETUP_ADDR (0xffff1000) /* Boot ROM */
33
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
36
34
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
37
+#define NPCM7XX_NR_PWM_MODULES 2
38
+
39
typedef struct NPCM7xxMachine {
40
MachineState parent;
41
+ /*
42
+ * PWM fan splitter. each splitter connects to one PWM output and
43
+ * multiple MFT inputs.
44
+ */
45
+ SplitIRQ fan_splitter[NPCM7XX_NR_PWM_MODULES *
46
+ NPCM7XX_PWM_PER_MODULE];
47
} NPCM7xxMachine;
48
49
#define TYPE_NPCM7XX_MACHINE MACHINE_TYPE_NAME("npcm7xx")
50
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
51
NPCM7xxCLKState clk;
52
NPCM7xxTimerCtrlState tim[3];
53
NPCM7xxADCState adc;
54
- NPCM7xxPWMState pwm[2];
55
+ NPCM7xxPWMState pwm[NPCM7XX_NR_PWM_MODULES];
56
NPCM7xxMFTState mft[8];
57
NPCM7xxOTPState key_storage;
58
NPCM7xxOTPState fuse_array;
59
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
60
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/npcm7xx_boards.c
36
--- a/target/sparc/fop_helper.c
62
+++ b/hw/arm/npcm7xx_boards.c
37
+++ b/target/sparc/fop_helper.c
63
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@ uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
64
#include "hw/core/cpu.h"
39
return finish_fcmp(env, r, GETPC());
65
#include "hw/i2c/smbus_eeprom.h"
66
#include "hw/loader.h"
67
+#include "hw/qdev-core.h"
68
#include "hw/qdev-properties.h"
69
#include "qapi/error.h"
70
#include "qemu-common.h"
71
@@ -XXX,XX +XXX,XX @@ static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
72
i2c_slave_realize_and_unref(i2c_dev, i2c_bus, &error_abort);
73
}
40
}
74
41
75
+static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
42
-uint32_t helper_flcmps(float32 src1, float32 src2)
76
+ NPCM7xxState *soc, const int *fan_counts)
43
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
77
+{
78
+ SplitIRQ *splitters = machine->fan_splitter;
79
+
80
+ /*
81
+ * PWM 0~3 belong to module 0 output 0~3.
82
+ * PWM 4~7 belong to module 1 output 0~3.
83
+ */
84
+ for (int i = 0; i < NPCM7XX_NR_PWM_MODULES; ++i) {
85
+ for (int j = 0; j < NPCM7XX_PWM_PER_MODULE; ++j) {
86
+ int splitter_no = i * NPCM7XX_PWM_PER_MODULE + j;
87
+ DeviceState *splitter;
88
+
89
+ if (fan_counts[splitter_no] < 1) {
90
+ continue;
91
+ }
92
+ object_initialize_child(OBJECT(machine), "fan-splitter[*]",
93
+ &splitters[splitter_no], TYPE_SPLIT_IRQ);
94
+ splitter = DEVICE(&splitters[splitter_no]);
95
+ qdev_prop_set_uint16(splitter, "num-lines",
96
+ fan_counts[splitter_no]);
97
+ qdev_realize(splitter, NULL, &error_abort);
98
+ qdev_connect_gpio_out_named(DEVICE(&soc->pwm[i]), "duty-gpio-out",
99
+ j, qdev_get_gpio_in(splitter, 0));
100
+ }
101
+ }
102
+}
103
+
104
+static void npcm7xx_connect_pwm_fan(NPCM7xxState *soc, SplitIRQ *splitter,
105
+ int fan_no, int output_no)
106
+{
107
+ DeviceState *fan;
108
+ int fan_input;
109
+ qemu_irq fan_duty_gpio;
110
+
111
+ g_assert(fan_no >= 0 && fan_no <= NPCM7XX_MFT_MAX_FAN_INPUT);
112
+ /*
113
+ * Fan 0~1 belong to module 0 input 0~1.
114
+ * Fan 2~3 belong to module 1 input 0~1.
115
+ * ...
116
+ * Fan 14~15 belong to module 7 input 0~1.
117
+ * Fan 16~17 belong to module 0 input 2~3.
118
+ * Fan 18~19 belong to module 1 input 2~3.
119
+ */
120
+ if (fan_no < 16) {
121
+ fan = DEVICE(&soc->mft[fan_no / 2]);
122
+ fan_input = fan_no % 2;
123
+ } else {
124
+ fan = DEVICE(&soc->mft[(fan_no - 16) / 2]);
125
+ fan_input = fan_no % 2 + 2;
126
+ }
127
+
128
+ /* Connect the Fan to PWM module */
129
+ fan_duty_gpio = qdev_get_gpio_in_named(fan, "duty", fan_input);
130
+ qdev_connect_gpio_out(DEVICE(splitter), output_no, fan_duty_gpio);
131
+}
132
+
133
static void npcm750_evb_i2c_init(NPCM7xxState *soc)
134
{
44
{
135
/* lm75 temperature sensor on SVB, tmp105 is compatible */
45
/*
136
@@ -XXX,XX +XXX,XX @@ static void npcm750_evb_i2c_init(NPCM7xxState *soc)
46
* FLCMP never raises an exception nor modifies any FSR fields.
137
i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
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();
138
}
56
}
139
57
140
+static void npcm750_evb_fan_init(NPCM7xxMachine *machine, NPCM7xxState *soc)
58
-uint32_t helper_flcmpd(float64 src1, float64 src2)
141
+{
59
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
142
+ SplitIRQ *splitter = machine->fan_splitter;
143
+ static const int fan_counts[] = {2, 2, 2, 2, 2, 2, 2, 2};
144
+
145
+ npcm7xx_init_pwm_splitter(machine, soc, fan_counts);
146
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x00, 0);
147
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x01, 1);
148
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x02, 0);
149
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x03, 1);
150
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x04, 0);
151
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x05, 1);
152
+ npcm7xx_connect_pwm_fan(soc, &splitter[3], 0x06, 0);
153
+ npcm7xx_connect_pwm_fan(soc, &splitter[3], 0x07, 1);
154
+ npcm7xx_connect_pwm_fan(soc, &splitter[4], 0x08, 0);
155
+ npcm7xx_connect_pwm_fan(soc, &splitter[4], 0x09, 1);
156
+ npcm7xx_connect_pwm_fan(soc, &splitter[5], 0x0a, 0);
157
+ npcm7xx_connect_pwm_fan(soc, &splitter[5], 0x0b, 1);
158
+ npcm7xx_connect_pwm_fan(soc, &splitter[6], 0x0c, 0);
159
+ npcm7xx_connect_pwm_fan(soc, &splitter[6], 0x0d, 1);
160
+ npcm7xx_connect_pwm_fan(soc, &splitter[7], 0x0e, 0);
161
+ npcm7xx_connect_pwm_fan(soc, &splitter[7], 0x0f, 1);
162
+}
163
+
164
static void quanta_gsj_i2c_init(NPCM7xxState *soc)
165
{
60
{
166
/* GSJ machine have 4 max31725 temperature sensors, tmp105 is compatible. */
61
- float_status discard = { };
167
@@ -XXX,XX +XXX,XX @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
62
+ float_status discard = env->fp_status;
168
/* TODO: Add additional i2c devices. */
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);
169
}
77
}
170
78
171
+static void quanta_gsj_fan_init(NPCM7xxMachine *machine, NPCM7xxState *soc)
79
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPd(DisasContext *dc, arg_FLCMPd *a)
172
+{
80
173
+ SplitIRQ *splitter = machine->fan_splitter;
81
src1 = gen_load_fpr_D(dc, a->rs1);
174
+ static const int fan_counts[] = {2, 2, 2, 0, 0, 0, 0, 0};
82
src2 = gen_load_fpr_D(dc, a->rs2);
175
+
83
- gen_helper_flcmpd(cpu_fcc[a->cc], src1, src2);
176
+ npcm7xx_init_pwm_splitter(machine, soc, fan_counts);
84
+ gen_helper_flcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
177
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x00, 0);
85
return advance_pc(dc);
178
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x01, 1);
179
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x02, 0);
180
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x03, 1);
181
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x04, 0);
182
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x05, 1);
183
+}
184
+
185
static void npcm750_evb_init(MachineState *machine)
186
{
187
NPCM7xxState *soc;
188
@@ -XXX,XX +XXX,XX @@ static void npcm750_evb_init(MachineState *machine)
189
npcm7xx_load_bootrom(machine, soc);
190
npcm7xx_connect_flash(&soc->fiu[0], 0, "w25q256", drive_get(IF_MTD, 0, 0));
191
npcm750_evb_i2c_init(soc);
192
+ npcm750_evb_fan_init(NPCM7XX_MACHINE(machine), soc);
193
npcm7xx_load_kernel(machine, soc);
194
}
86
}
195
87
196
@@ -XXX,XX +XXX,XX @@ static void quanta_gsj_init(MachineState *machine)
197
npcm7xx_connect_flash(&soc->fiu[0], 0, "mx25l25635e",
198
drive_get(IF_MTD, 0, 0));
199
quanta_gsj_i2c_init(soc);
200
+ quanta_gsj_fan_init(NPCM7XX_MACHINE(machine), soc);
201
npcm7xx_load_kernel(machine, soc);
202
}
203
204
--
88
--
205
2.20.1
89
2.34.1
206
207
diff view generated by jsdifflib
New patch
1
In the helper_compute_fprf functions, we pass a dummy float_status
2
in to the is_signaling_nan() function. This is unnecessary, because
3
we have convenient access to the CPU env pointer here and that
4
is already set up with the correct values for the snan_bit_is_one
5
and no_signaling_nans config settings. is_signaling_nan() doesn't
6
ever update the fp_status with any exception flags, so there is
7
no reason not to use env->fp_status here.
1
8
9
Use env->fp_status instead of the dummy fp_status.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20241202131347.498124-34-peter.maydell@linaro.org
14
---
15
target/ppc/fpu_helper.c | 3 +--
16
1 file changed, 1 insertion(+), 2 deletions(-)
17
18
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/ppc/fpu_helper.c
21
+++ b/target/ppc/fpu_helper.c
22
@@ -XXX,XX +XXX,XX @@ void helper_compute_fprf_##tp(CPUPPCState *env, tp arg) \
23
} else if (tp##_is_infinity(arg)) { \
24
fprf = neg ? 0x09 << FPSCR_FPRF : 0x05 << FPSCR_FPRF; \
25
} else { \
26
- float_status dummy = { }; /* snan_bit_is_one = 0 */ \
27
- if (tp##_is_signaling_nan(arg, &dummy)) { \
28
+ if (tp##_is_signaling_nan(arg, &env->fp_status)) { \
29
fprf = 0x00 << FPSCR_FPRF; \
30
} else { \
31
fprf = 0x11 << FPSCR_FPRF; \
32
--
33
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
With the reduction operations, we intentionally increase maxsz to
3
Now that float_status has a bunch of fp parameters,
4
the next power of 2, so as to fill out the reduction tree correctly.
4
it is easier to copy an existing structure than create
5
Since e2e7168a214b, oprsz must equal maxsz, with exceptions for small
5
one from scratch. Begin by copying the structure that
6
vectors, so this triggers an assertion for vector sizes > 32 that are
6
corresponds to the FPSR and make only the adjustments
7
not themselves a power of 2.
7
required for BFloat16 semantics.
8
9
Pass the power-of-two value in the simd_data field instead.
10
8
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210309155305.11301-9-richard.henderson@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
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
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
14
---
16
target/arm/sve_helper.c | 2 +-
15
target/arm/tcg/vec_helper.c | 20 +++++++-------------
17
target/arm/translate-sve.c | 2 +-
16
1 file changed, 7 insertions(+), 13 deletions(-)
18
2 files changed, 2 insertions(+), 2 deletions(-)
19
17
20
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
18
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/sve_helper.c
20
--- a/target/arm/tcg/vec_helper.c
23
+++ b/target/arm/sve_helper.c
21
+++ b/target/arm/tcg/vec_helper.c
24
@@ -XXX,XX +XXX,XX @@ static TYPE NAME##_reduce(TYPE *data, float_status *status, uintptr_t n) \
22
@@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
25
} \
23
* no effect on AArch32 instructions.
26
uint64_t HELPER(NAME)(void *vn, void *vg, void *vs, uint32_t desc) \
24
*/
27
{ \
25
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
28
- uintptr_t i, oprsz = simd_oprsz(desc), maxsz = simd_maxsz(desc); \
26
- *statusp = (float_status){
29
+ uintptr_t i, oprsz = simd_oprsz(desc), maxsz = simd_data(desc); \
27
- .tininess_before_rounding = float_tininess_before_rounding,
30
TYPE data[sizeof(ARMVectorReg) / sizeof(TYPE)]; \
28
- .float_rounding_mode = float_round_to_odd_inf,
31
for (i = 0; i < oprsz; ) { \
29
- .flush_to_zero = true,
32
uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
30
- .flush_inputs_to_zero = true,
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
31
- .default_nan_mode = true,
34
index XXXXXXX..XXXXXXX 100644
32
- };
35
--- a/target/arm/translate-sve.c
33
+
36
+++ b/target/arm/translate-sve.c
34
+ *statusp = env->vfp.fp_status;
37
@@ -XXX,XX +XXX,XX @@ static void do_reduce(DisasContext *s, arg_rpr_esz *a,
35
+ set_default_nan_mode(true, statusp);
38
{
36
39
unsigned vsz = vec_full_reg_size(s);
37
if (ebf) {
40
unsigned p2vsz = pow2ceil(vsz);
38
- float_status *fpst = &env->vfp.fp_status;
41
- TCGv_i32 t_desc = tcg_const_i32(simd_desc(vsz, p2vsz, 0));
39
- set_flush_to_zero(get_flush_to_zero(fpst), statusp);
42
+ TCGv_i32 t_desc = tcg_const_i32(simd_desc(vsz, vsz, p2vsz));
40
- set_flush_inputs_to_zero(get_flush_inputs_to_zero(fpst), statusp);
43
TCGv_ptr t_zn, t_pg, status;
41
- set_float_rounding_mode(get_float_rounding_mode(fpst), statusp);
44
TCGv_i64 temp;
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
}
45
54
46
--
55
--
47
2.20.1
56
2.34.1
48
57
49
58
diff view generated by jsdifflib
1
The template header is now included only once; just inline its contents
1
Currently we hardcode the default NaN value in parts64_default_nan()
2
in hw/display/pxa2xx_lcd.c.
2
using a compile-time ifdef ladder. This is awkward for two cases:
3
* for single-QEMU-binary we can't hard-code target-specifics like this
4
* for Arm FEAT_AFP the default NaN value depends on FPCR.AH
5
(specifically the sign bit is different)
6
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.
3
14
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210211141515.8755-10-peter.maydell@linaro.org
17
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
7
---
18
---
8
hw/display/pxa2xx_template.h | 434 -----------------------------------
19
include/fpu/softfloat-helpers.h | 11 +++++++
9
hw/display/pxa2xx_lcd.c | 427 +++++++++++++++++++++++++++++++++-
20
include/fpu/softfloat-types.h | 10 ++++++
10
2 files changed, 425 insertions(+), 436 deletions(-)
21
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
11
delete mode 100644 hw/display/pxa2xx_template.h
22
3 files changed, 54 insertions(+), 22 deletions(-)
12
23
13
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
24
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
14
deleted file mode 100644
15
index XXXXXXX..XXXXXXX
16
--- a/hw/display/pxa2xx_template.h
17
+++ /dev/null
18
@@ -XXX,XX +XXX,XX @@
19
-/*
20
- * Intel XScale PXA255/270 LCDC emulation.
21
- *
22
- * Copyright (c) 2006 Openedhand Ltd.
23
- * Written by Andrzej Zaborowski <balrog@zabor.org>
24
- *
25
- * This code is licensed under the GPLv2.
26
- *
27
- * Framebuffer format conversion routines.
28
- */
29
-
30
-# define SKIP_PIXEL(to) do { to += deststep; } while (0)
31
-# define COPY_PIXEL(to, from) \
32
- do { \
33
- *(uint32_t *) to = from; \
34
- SKIP_PIXEL(to); \
35
- } while (0)
36
-
37
-#ifdef HOST_WORDS_BIGENDIAN
38
-# define SWAP_WORDS 1
39
-#endif
40
-
41
-#define FN_2(x) FN(x + 1) FN(x)
42
-#define FN_4(x) FN_2(x + 2) FN_2(x)
43
-
44
-static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src,
45
- int width, int deststep)
46
-{
47
- uint32_t *palette = opaque;
48
- uint32_t data;
49
- while (width > 0) {
50
- data = *(uint32_t *) src;
51
-#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
52
-#ifdef SWAP_WORDS
53
- FN_4(12)
54
- FN_4(8)
55
- FN_4(4)
56
- FN_4(0)
57
-#else
58
- FN_4(0)
59
- FN_4(4)
60
- FN_4(8)
61
- FN_4(12)
62
-#endif
63
-#undef FN
64
- width -= 16;
65
- src += 4;
66
- }
67
-}
68
-
69
-static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src,
70
- int width, int deststep)
71
-{
72
- uint32_t *palette = opaque;
73
- uint32_t data;
74
- while (width > 0) {
75
- data = *(uint32_t *) src;
76
-#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
77
-#ifdef SWAP_WORDS
78
- FN_2(6)
79
- FN_2(4)
80
- FN_2(2)
81
- FN_2(0)
82
-#else
83
- FN_2(0)
84
- FN_2(2)
85
- FN_2(4)
86
- FN_2(6)
87
-#endif
88
-#undef FN
89
- width -= 8;
90
- src += 4;
91
- }
92
-}
93
-
94
-static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src,
95
- int width, int deststep)
96
-{
97
- uint32_t *palette = opaque;
98
- uint32_t data;
99
- while (width > 0) {
100
- data = *(uint32_t *) src;
101
-#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
102
-#ifdef SWAP_WORDS
103
- FN(24)
104
- FN(16)
105
- FN(8)
106
- FN(0)
107
-#else
108
- FN(0)
109
- FN(8)
110
- FN(16)
111
- FN(24)
112
-#endif
113
-#undef FN
114
- width -= 4;
115
- src += 4;
116
- }
117
-}
118
-
119
-static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src,
120
- int width, int deststep)
121
-{
122
- uint32_t data;
123
- unsigned int r, g, b;
124
- while (width > 0) {
125
- data = *(uint32_t *) src;
126
-#ifdef SWAP_WORDS
127
- data = bswap32(data);
128
-#endif
129
- b = (data & 0x1f) << 3;
130
- data >>= 5;
131
- g = (data & 0x3f) << 2;
132
- data >>= 6;
133
- r = (data & 0x1f) << 3;
134
- data >>= 5;
135
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
136
- b = (data & 0x1f) << 3;
137
- data >>= 5;
138
- g = (data & 0x3f) << 2;
139
- data >>= 6;
140
- r = (data & 0x1f) << 3;
141
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
142
- width -= 2;
143
- src += 4;
144
- }
145
-}
146
-
147
-static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src,
148
- int width, int deststep)
149
-{
150
- uint32_t data;
151
- unsigned int r, g, b;
152
- while (width > 0) {
153
- data = *(uint32_t *) src;
154
-#ifdef SWAP_WORDS
155
- data = bswap32(data);
156
-#endif
157
- b = (data & 0x1f) << 3;
158
- data >>= 5;
159
- g = (data & 0x1f) << 3;
160
- data >>= 5;
161
- r = (data & 0x1f) << 3;
162
- data >>= 5;
163
- if (data & 1) {
164
- SKIP_PIXEL(dest);
165
- } else {
166
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
167
- }
168
- data >>= 1;
169
- b = (data & 0x1f) << 3;
170
- data >>= 5;
171
- g = (data & 0x1f) << 3;
172
- data >>= 5;
173
- r = (data & 0x1f) << 3;
174
- data >>= 5;
175
- if (data & 1) {
176
- SKIP_PIXEL(dest);
177
- } else {
178
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
179
- }
180
- width -= 2;
181
- src += 4;
182
- }
183
-}
184
-
185
-static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src,
186
- int width, int deststep)
187
-{
188
- uint32_t data;
189
- unsigned int r, g, b;
190
- while (width > 0) {
191
- data = *(uint32_t *) src;
192
-#ifdef SWAP_WORDS
193
- data = bswap32(data);
194
-#endif
195
- b = (data & 0x3f) << 2;
196
- data >>= 6;
197
- g = (data & 0x3f) << 2;
198
- data >>= 6;
199
- r = (data & 0x3f) << 2;
200
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
201
- width -= 1;
202
- src += 4;
203
- }
204
-}
205
-
206
-/* The wicked packed format */
207
-static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src,
208
- int width, int deststep)
209
-{
210
- uint32_t data[3];
211
- unsigned int r, g, b;
212
- while (width > 0) {
213
- data[0] = *(uint32_t *) src;
214
- src += 4;
215
- data[1] = *(uint32_t *) src;
216
- src += 4;
217
- data[2] = *(uint32_t *) src;
218
- src += 4;
219
-#ifdef SWAP_WORDS
220
- data[0] = bswap32(data[0]);
221
- data[1] = bswap32(data[1]);
222
- data[2] = bswap32(data[2]);
223
-#endif
224
- b = (data[0] & 0x3f) << 2;
225
- data[0] >>= 6;
226
- g = (data[0] & 0x3f) << 2;
227
- data[0] >>= 6;
228
- r = (data[0] & 0x3f) << 2;
229
- data[0] >>= 12;
230
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
231
- b = (data[0] & 0x3f) << 2;
232
- data[0] >>= 6;
233
- g = ((data[1] & 0xf) << 4) | (data[0] << 2);
234
- data[1] >>= 4;
235
- r = (data[1] & 0x3f) << 2;
236
- data[1] >>= 12;
237
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
238
- b = (data[1] & 0x3f) << 2;
239
- data[1] >>= 6;
240
- g = (data[1] & 0x3f) << 2;
241
- data[1] >>= 6;
242
- r = ((data[2] & 0x3) << 6) | (data[1] << 2);
243
- data[2] >>= 8;
244
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
245
- b = (data[2] & 0x3f) << 2;
246
- data[2] >>= 6;
247
- g = (data[2] & 0x3f) << 2;
248
- data[2] >>= 6;
249
- r = data[2] << 2;
250
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
251
- width -= 4;
252
- }
253
-}
254
-
255
-static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src,
256
- int width, int deststep)
257
-{
258
- uint32_t data;
259
- unsigned int r, g, b;
260
- while (width > 0) {
261
- data = *(uint32_t *) src;
262
-#ifdef SWAP_WORDS
263
- data = bswap32(data);
264
-#endif
265
- b = (data & 0x3f) << 2;
266
- data >>= 6;
267
- g = (data & 0x3f) << 2;
268
- data >>= 6;
269
- r = (data & 0x3f) << 2;
270
- data >>= 6;
271
- if (data & 1) {
272
- SKIP_PIXEL(dest);
273
- } else {
274
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
275
- }
276
- width -= 1;
277
- src += 4;
278
- }
279
-}
280
-
281
-/* The wicked packed format */
282
-static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src,
283
- int width, int deststep)
284
-{
285
- uint32_t data[3];
286
- unsigned int r, g, b;
287
- while (width > 0) {
288
- data[0] = *(uint32_t *) src;
289
- src += 4;
290
- data[1] = *(uint32_t *) src;
291
- src += 4;
292
- data[2] = *(uint32_t *) src;
293
- src += 4;
294
-# ifdef SWAP_WORDS
295
- data[0] = bswap32(data[0]);
296
- data[1] = bswap32(data[1]);
297
- data[2] = bswap32(data[2]);
298
-# endif
299
- b = (data[0] & 0x3f) << 2;
300
- data[0] >>= 6;
301
- g = (data[0] & 0x3f) << 2;
302
- data[0] >>= 6;
303
- r = (data[0] & 0x3f) << 2;
304
- data[0] >>= 6;
305
- if (data[0] & 1) {
306
- SKIP_PIXEL(dest);
307
- } else {
308
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
309
- }
310
- data[0] >>= 6;
311
- b = (data[0] & 0x3f) << 2;
312
- data[0] >>= 6;
313
- g = ((data[1] & 0xf) << 4) | (data[0] << 2);
314
- data[1] >>= 4;
315
- r = (data[1] & 0x3f) << 2;
316
- data[1] >>= 6;
317
- if (data[1] & 1) {
318
- SKIP_PIXEL(dest);
319
- } else {
320
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
321
- }
322
- data[1] >>= 6;
323
- b = (data[1] & 0x3f) << 2;
324
- data[1] >>= 6;
325
- g = (data[1] & 0x3f) << 2;
326
- data[1] >>= 6;
327
- r = ((data[2] & 0x3) << 6) | (data[1] << 2);
328
- data[2] >>= 2;
329
- if (data[2] & 1) {
330
- SKIP_PIXEL(dest);
331
- } else {
332
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
333
- }
334
- data[2] >>= 6;
335
- b = (data[2] & 0x3f) << 2;
336
- data[2] >>= 6;
337
- g = (data[2] & 0x3f) << 2;
338
- data[2] >>= 6;
339
- r = data[2] << 2;
340
- data[2] >>= 6;
341
- if (data[2] & 1) {
342
- SKIP_PIXEL(dest);
343
- } else {
344
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
345
- }
346
- width -= 4;
347
- }
348
-}
349
-
350
-static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src,
351
- int width, int deststep)
352
-{
353
- uint32_t data;
354
- unsigned int r, g, b;
355
- while (width > 0) {
356
- data = *(uint32_t *) src;
357
-#ifdef SWAP_WORDS
358
- data = bswap32(data);
359
-#endif
360
- b = data & 0xff;
361
- data >>= 8;
362
- g = data & 0xff;
363
- data >>= 8;
364
- r = data & 0xff;
365
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
366
- width -= 1;
367
- src += 4;
368
- }
369
-}
370
-
371
-static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src,
372
- int width, int deststep)
373
-{
374
- uint32_t data;
375
- unsigned int r, g, b;
376
- while (width > 0) {
377
- data = *(uint32_t *) src;
378
-#ifdef SWAP_WORDS
379
- data = bswap32(data);
380
-#endif
381
- b = (data & 0x7f) << 1;
382
- data >>= 7;
383
- g = data & 0xff;
384
- data >>= 8;
385
- r = data & 0xff;
386
- data >>= 8;
387
- if (data & 1) {
388
- SKIP_PIXEL(dest);
389
- } else {
390
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
391
- }
392
- width -= 1;
393
- src += 4;
394
- }
395
-}
396
-
397
-static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src,
398
- int width, int deststep)
399
-{
400
- uint32_t data;
401
- unsigned int r, g, b;
402
- while (width > 0) {
403
- data = *(uint32_t *) src;
404
-#ifdef SWAP_WORDS
405
- data = bswap32(data);
406
-#endif
407
- b = data & 0xff;
408
- data >>= 8;
409
- g = data & 0xff;
410
- data >>= 8;
411
- r = data & 0xff;
412
- data >>= 8;
413
- if (data & 1) {
414
- SKIP_PIXEL(dest);
415
- } else {
416
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
417
- }
418
- width -= 1;
419
- src += 4;
420
- }
421
-}
422
-
423
-/* Overlay planes disabled, no transparency */
424
-static drawfn pxa2xx_draw_fn_32[16] = {
425
- [0 ... 0xf] = NULL,
426
- [pxa_lcdc_2bpp] = pxa2xx_draw_line2,
427
- [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
428
- [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
429
- [pxa_lcdc_16bpp] = pxa2xx_draw_line16,
430
- [pxa_lcdc_18bpp] = pxa2xx_draw_line18,
431
- [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p,
432
- [pxa_lcdc_24bpp] = pxa2xx_draw_line24,
433
-};
434
-
435
-/* Overlay planes enabled, transparency used */
436
-static drawfn pxa2xx_draw_fn_32t[16] = {
437
- [0 ... 0xf] = NULL,
438
- [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
439
- [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
440
- [pxa_lcdc_16bpp] = pxa2xx_draw_line16t,
441
- [pxa_lcdc_19bpp] = pxa2xx_draw_line19,
442
- [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p,
443
- [pxa_lcdc_24bpp] = pxa2xx_draw_line24t,
444
- [pxa_lcdc_25bpp] = pxa2xx_draw_line25,
445
-};
446
-
447
-#undef COPY_PIXEL
448
-#undef SKIP_PIXEL
449
-
450
-#ifdef SWAP_WORDS
451
-# undef SWAP_WORDS
452
-#endif
453
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
454
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
455
--- a/hw/display/pxa2xx_lcd.c
26
--- a/include/fpu/softfloat-helpers.h
456
+++ b/hw/display/pxa2xx_lcd.c
27
+++ b/include/fpu/softfloat-helpers.h
457
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED {
28
@@ -XXX,XX +XXX,XX @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
458
/* Size of a pixel in the QEMU UI output surface, in bytes */
29
status->float_infzeronan_rule = rule;
459
#define DEST_PIXEL_WIDTH 4
30
}
460
31
461
-#define BITS 32
32
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
462
-#include "pxa2xx_template.h"
33
+ float_status *status)
463
+/* Line drawing code to handle the various possible guest pixel formats */
464
+
465
+# define SKIP_PIXEL(to) do { to += deststep; } while (0)
466
+# define COPY_PIXEL(to, from) \
467
+ do { \
468
+ *(uint32_t *) to = from; \
469
+ SKIP_PIXEL(to); \
470
+ } while (0)
471
+
472
+#ifdef HOST_WORDS_BIGENDIAN
473
+# define SWAP_WORDS 1
474
+#endif
475
+
476
+#define FN_2(x) FN(x + 1) FN(x)
477
+#define FN_4(x) FN_2(x + 2) FN_2(x)
478
+
479
+static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src,
480
+ int width, int deststep)
481
+{
34
+{
482
+ uint32_t *palette = opaque;
35
+ status->default_nan_pattern = dnan_pattern;
483
+ uint32_t data;
484
+ while (width > 0) {
485
+ data = *(uint32_t *) src;
486
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
487
+#ifdef SWAP_WORDS
488
+ FN_4(12)
489
+ FN_4(8)
490
+ FN_4(4)
491
+ FN_4(0)
492
+#else
493
+ FN_4(0)
494
+ FN_4(4)
495
+ FN_4(8)
496
+ FN_4(12)
497
+#endif
498
+#undef FN
499
+ width -= 16;
500
+ src += 4;
501
+ }
502
+}
36
+}
503
+
37
+
504
+static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src,
38
static inline void set_flush_to_zero(bool val, float_status *status)
505
+ int width, int deststep)
39
{
40
status->flush_to_zero = val;
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)
506
+{
46
+{
507
+ uint32_t *palette = opaque;
47
+ return status->default_nan_pattern;
508
+ uint32_t data;
509
+ while (width > 0) {
510
+ data = *(uint32_t *) src;
511
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
512
+#ifdef SWAP_WORDS
513
+ FN_2(6)
514
+ FN_2(4)
515
+ FN_2(2)
516
+ FN_2(0)
517
+#else
518
+ FN_2(0)
519
+ FN_2(2)
520
+ FN_2(4)
521
+ FN_2(6)
522
+#endif
523
+#undef FN
524
+ width -= 8;
525
+ src += 4;
526
+ }
527
+}
48
+}
528
+
49
+
529
+static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src,
50
static inline bool get_flush_to_zero(float_status *status)
530
+ int width, int deststep)
51
{
531
+{
52
return status->flush_to_zero;
532
+ uint32_t *palette = opaque;
53
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
533
+ uint32_t data;
54
index XXXXXXX..XXXXXXX 100644
534
+ while (width > 0) {
55
--- a/include/fpu/softfloat-types.h
535
+ data = *(uint32_t *) src;
56
+++ b/include/fpu/softfloat-types.h
536
+#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
57
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
537
+#ifdef SWAP_WORDS
58
/* should denormalised inputs go to zero and set the input_denormal flag? */
538
+ FN(24)
59
bool flush_inputs_to_zero;
539
+ FN(16)
60
bool default_nan_mode;
540
+ FN(8)
61
+ /*
541
+ FN(0)
62
+ * The pattern to use for the default NaN. Here the high bit specifies
542
+#else
63
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
543
+ FN(0)
64
+ * fractional part. The low bits of the fractional part are copies of bit 0.
544
+ FN(8)
65
+ * The exponent of the default NaN is (as for any NaN) always all 1s.
545
+ FN(16)
66
+ * Note that a value of 0 here is not a valid NaN. The target must set
546
+ FN(24)
67
+ * this to the correct non-zero value, or we will assert when trying to
547
+#endif
68
+ * create a default NaN.
548
+#undef FN
69
+ */
549
+ width -= 4;
70
+ uint8_t default_nan_pattern;
550
+ src += 4;
71
/*
72
* The flags below are not used on all specializations and may
73
* constant fold away (see snan_bit_is_one()/no_signalling_nans() in
74
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
75
index XXXXXXX..XXXXXXX 100644
76
--- a/fpu/softfloat-specialize.c.inc
77
+++ b/fpu/softfloat-specialize.c.inc
78
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
79
{
80
bool sign = 0;
81
uint64_t frac;
82
+ uint8_t dnan_pattern = status->default_nan_pattern;
83
84
+ if (dnan_pattern == 0) {
85
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
86
- /* !snan_bit_is_one, set all bits */
87
- frac = (1ULL << DECOMPOSED_BINARY_POINT) - 1;
88
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
89
+ /* Sign bit clear, all frac bits set */
90
+ dnan_pattern = 0b01111111;
91
+#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
92
|| defined(TARGET_MICROBLAZE)
93
- /* !snan_bit_is_one, set sign and msb */
94
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
95
- sign = 1;
96
+ /* Sign bit set, most significant frac bit set */
97
+ dnan_pattern = 0b11000000;
98
#elif defined(TARGET_HPPA)
99
- /* snan_bit_is_one, set msb-1. */
100
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 2);
101
+ /* Sign bit clear, msb-1 frac bit set */
102
+ dnan_pattern = 0b00100000;
103
#elif defined(TARGET_HEXAGON)
104
- sign = 1;
105
- frac = ~0ULL;
106
+ /* Sign bit set, all frac bits set. */
107
+ dnan_pattern = 0b11111111;
108
#else
109
- /*
110
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
111
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
112
- * do not have floating-point.
113
- */
114
- if (snan_bit_is_one(status)) {
115
- /* set all bits other than msb */
116
- frac = (1ULL << (DECOMPOSED_BINARY_POINT - 1)) - 1;
117
- } else {
118
- /* set msb */
119
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
120
- }
121
+ /*
122
+ * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
123
+ * S390, SH4, TriCore, and Xtensa. Our other supported targets
124
+ * do not have floating-point.
125
+ */
126
+ if (snan_bit_is_one(status)) {
127
+ /* sign bit clear, set all frac bits other than msb */
128
+ dnan_pattern = 0b00111111;
129
+ } else {
130
+ /* sign bit clear, set frac msb */
131
+ dnan_pattern = 0b01000000;
132
+ }
133
#endif
551
+ }
134
+ }
552
+}
135
+ assert(dnan_pattern != 0);
553
+
136
+
554
+static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src,
137
+ sign = dnan_pattern >> 7;
555
+ int width, int deststep)
138
+ /*
556
+{
139
+ * Place default_nan_pattern [6:0] into bits [62:56],
557
+ uint32_t data;
140
+ * and replecate bit [0] down into [55:0]
558
+ unsigned int r, g, b;
141
+ */
559
+ while (width > 0) {
142
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
560
+ data = *(uint32_t *) src;
143
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
561
+#ifdef SWAP_WORDS
144
562
+ data = bswap32(data);
145
*p = (FloatParts64) {
563
+#endif
146
.cls = float_class_qnan,
564
+ b = (data & 0x1f) << 3;
565
+ data >>= 5;
566
+ g = (data & 0x3f) << 2;
567
+ data >>= 6;
568
+ r = (data & 0x1f) << 3;
569
+ data >>= 5;
570
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
571
+ b = (data & 0x1f) << 3;
572
+ data >>= 5;
573
+ g = (data & 0x3f) << 2;
574
+ data >>= 6;
575
+ r = (data & 0x1f) << 3;
576
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
577
+ width -= 2;
578
+ src += 4;
579
+ }
580
+}
581
+
582
+static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src,
583
+ int width, int deststep)
584
+{
585
+ uint32_t data;
586
+ unsigned int r, g, b;
587
+ while (width > 0) {
588
+ data = *(uint32_t *) src;
589
+#ifdef SWAP_WORDS
590
+ data = bswap32(data);
591
+#endif
592
+ b = (data & 0x1f) << 3;
593
+ data >>= 5;
594
+ g = (data & 0x1f) << 3;
595
+ data >>= 5;
596
+ r = (data & 0x1f) << 3;
597
+ data >>= 5;
598
+ if (data & 1) {
599
+ SKIP_PIXEL(dest);
600
+ } else {
601
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
602
+ }
603
+ data >>= 1;
604
+ b = (data & 0x1f) << 3;
605
+ data >>= 5;
606
+ g = (data & 0x1f) << 3;
607
+ data >>= 5;
608
+ r = (data & 0x1f) << 3;
609
+ data >>= 5;
610
+ if (data & 1) {
611
+ SKIP_PIXEL(dest);
612
+ } else {
613
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
614
+ }
615
+ width -= 2;
616
+ src += 4;
617
+ }
618
+}
619
+
620
+static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src,
621
+ int width, int deststep)
622
+{
623
+ uint32_t data;
624
+ unsigned int r, g, b;
625
+ while (width > 0) {
626
+ data = *(uint32_t *) src;
627
+#ifdef SWAP_WORDS
628
+ data = bswap32(data);
629
+#endif
630
+ b = (data & 0x3f) << 2;
631
+ data >>= 6;
632
+ g = (data & 0x3f) << 2;
633
+ data >>= 6;
634
+ r = (data & 0x3f) << 2;
635
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
636
+ width -= 1;
637
+ src += 4;
638
+ }
639
+}
640
+
641
+/* The wicked packed format */
642
+static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src,
643
+ int width, int deststep)
644
+{
645
+ uint32_t data[3];
646
+ unsigned int r, g, b;
647
+ while (width > 0) {
648
+ data[0] = *(uint32_t *) src;
649
+ src += 4;
650
+ data[1] = *(uint32_t *) src;
651
+ src += 4;
652
+ data[2] = *(uint32_t *) src;
653
+ src += 4;
654
+#ifdef SWAP_WORDS
655
+ data[0] = bswap32(data[0]);
656
+ data[1] = bswap32(data[1]);
657
+ data[2] = bswap32(data[2]);
658
+#endif
659
+ b = (data[0] & 0x3f) << 2;
660
+ data[0] >>= 6;
661
+ g = (data[0] & 0x3f) << 2;
662
+ data[0] >>= 6;
663
+ r = (data[0] & 0x3f) << 2;
664
+ data[0] >>= 12;
665
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
666
+ b = (data[0] & 0x3f) << 2;
667
+ data[0] >>= 6;
668
+ g = ((data[1] & 0xf) << 4) | (data[0] << 2);
669
+ data[1] >>= 4;
670
+ r = (data[1] & 0x3f) << 2;
671
+ data[1] >>= 12;
672
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
673
+ b = (data[1] & 0x3f) << 2;
674
+ data[1] >>= 6;
675
+ g = (data[1] & 0x3f) << 2;
676
+ data[1] >>= 6;
677
+ r = ((data[2] & 0x3) << 6) | (data[1] << 2);
678
+ data[2] >>= 8;
679
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
680
+ b = (data[2] & 0x3f) << 2;
681
+ data[2] >>= 6;
682
+ g = (data[2] & 0x3f) << 2;
683
+ data[2] >>= 6;
684
+ r = data[2] << 2;
685
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
686
+ width -= 4;
687
+ }
688
+}
689
+
690
+static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src,
691
+ int width, int deststep)
692
+{
693
+ uint32_t data;
694
+ unsigned int r, g, b;
695
+ while (width > 0) {
696
+ data = *(uint32_t *) src;
697
+#ifdef SWAP_WORDS
698
+ data = bswap32(data);
699
+#endif
700
+ b = (data & 0x3f) << 2;
701
+ data >>= 6;
702
+ g = (data & 0x3f) << 2;
703
+ data >>= 6;
704
+ r = (data & 0x3f) << 2;
705
+ data >>= 6;
706
+ if (data & 1) {
707
+ SKIP_PIXEL(dest);
708
+ } else {
709
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
710
+ }
711
+ width -= 1;
712
+ src += 4;
713
+ }
714
+}
715
+
716
+/* The wicked packed format */
717
+static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src,
718
+ int width, int deststep)
719
+{
720
+ uint32_t data[3];
721
+ unsigned int r, g, b;
722
+ while (width > 0) {
723
+ data[0] = *(uint32_t *) src;
724
+ src += 4;
725
+ data[1] = *(uint32_t *) src;
726
+ src += 4;
727
+ data[2] = *(uint32_t *) src;
728
+ src += 4;
729
+# ifdef SWAP_WORDS
730
+ data[0] = bswap32(data[0]);
731
+ data[1] = bswap32(data[1]);
732
+ data[2] = bswap32(data[2]);
733
+# endif
734
+ b = (data[0] & 0x3f) << 2;
735
+ data[0] >>= 6;
736
+ g = (data[0] & 0x3f) << 2;
737
+ data[0] >>= 6;
738
+ r = (data[0] & 0x3f) << 2;
739
+ data[0] >>= 6;
740
+ if (data[0] & 1) {
741
+ SKIP_PIXEL(dest);
742
+ } else {
743
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
744
+ }
745
+ data[0] >>= 6;
746
+ b = (data[0] & 0x3f) << 2;
747
+ data[0] >>= 6;
748
+ g = ((data[1] & 0xf) << 4) | (data[0] << 2);
749
+ data[1] >>= 4;
750
+ r = (data[1] & 0x3f) << 2;
751
+ data[1] >>= 6;
752
+ if (data[1] & 1) {
753
+ SKIP_PIXEL(dest);
754
+ } else {
755
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
756
+ }
757
+ data[1] >>= 6;
758
+ b = (data[1] & 0x3f) << 2;
759
+ data[1] >>= 6;
760
+ g = (data[1] & 0x3f) << 2;
761
+ data[1] >>= 6;
762
+ r = ((data[2] & 0x3) << 6) | (data[1] << 2);
763
+ data[2] >>= 2;
764
+ if (data[2] & 1) {
765
+ SKIP_PIXEL(dest);
766
+ } else {
767
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
768
+ }
769
+ data[2] >>= 6;
770
+ b = (data[2] & 0x3f) << 2;
771
+ data[2] >>= 6;
772
+ g = (data[2] & 0x3f) << 2;
773
+ data[2] >>= 6;
774
+ r = data[2] << 2;
775
+ data[2] >>= 6;
776
+ if (data[2] & 1) {
777
+ SKIP_PIXEL(dest);
778
+ } else {
779
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
780
+ }
781
+ width -= 4;
782
+ }
783
+}
784
+
785
+static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src,
786
+ int width, int deststep)
787
+{
788
+ uint32_t data;
789
+ unsigned int r, g, b;
790
+ while (width > 0) {
791
+ data = *(uint32_t *) src;
792
+#ifdef SWAP_WORDS
793
+ data = bswap32(data);
794
+#endif
795
+ b = data & 0xff;
796
+ data >>= 8;
797
+ g = data & 0xff;
798
+ data >>= 8;
799
+ r = data & 0xff;
800
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
801
+ width -= 1;
802
+ src += 4;
803
+ }
804
+}
805
+
806
+static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src,
807
+ int width, int deststep)
808
+{
809
+ uint32_t data;
810
+ unsigned int r, g, b;
811
+ while (width > 0) {
812
+ data = *(uint32_t *) src;
813
+#ifdef SWAP_WORDS
814
+ data = bswap32(data);
815
+#endif
816
+ b = (data & 0x7f) << 1;
817
+ data >>= 7;
818
+ g = data & 0xff;
819
+ data >>= 8;
820
+ r = data & 0xff;
821
+ data >>= 8;
822
+ if (data & 1) {
823
+ SKIP_PIXEL(dest);
824
+ } else {
825
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
826
+ }
827
+ width -= 1;
828
+ src += 4;
829
+ }
830
+}
831
+
832
+static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src,
833
+ int width, int deststep)
834
+{
835
+ uint32_t data;
836
+ unsigned int r, g, b;
837
+ while (width > 0) {
838
+ data = *(uint32_t *) src;
839
+#ifdef SWAP_WORDS
840
+ data = bswap32(data);
841
+#endif
842
+ b = data & 0xff;
843
+ data >>= 8;
844
+ g = data & 0xff;
845
+ data >>= 8;
846
+ r = data & 0xff;
847
+ data >>= 8;
848
+ if (data & 1) {
849
+ SKIP_PIXEL(dest);
850
+ } else {
851
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
852
+ }
853
+ width -= 1;
854
+ src += 4;
855
+ }
856
+}
857
+
858
+/* Overlay planes disabled, no transparency */
859
+static drawfn pxa2xx_draw_fn_32[16] = {
860
+ [0 ... 0xf] = NULL,
861
+ [pxa_lcdc_2bpp] = pxa2xx_draw_line2,
862
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
863
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
864
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16,
865
+ [pxa_lcdc_18bpp] = pxa2xx_draw_line18,
866
+ [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p,
867
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24,
868
+};
869
+
870
+/* Overlay planes enabled, transparency used */
871
+static drawfn pxa2xx_draw_fn_32t[16] = {
872
+ [0 ... 0xf] = NULL,
873
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
874
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
875
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16t,
876
+ [pxa_lcdc_19bpp] = pxa2xx_draw_line19,
877
+ [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p,
878
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24t,
879
+ [pxa_lcdc_25bpp] = pxa2xx_draw_line25,
880
+};
881
+
882
+#undef COPY_PIXEL
883
+#undef SKIP_PIXEL
884
+
885
+#ifdef SWAP_WORDS
886
+# undef SWAP_WORDS
887
+#endif
888
889
/* Route internal interrupt lines to the global IC */
890
static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
891
--
147
--
892
2.20.1
148
2.34.1
893
894
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the tests/fp code.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-36-peter.maydell@linaro.org
6
---
7
tests/fp/fp-bench.c | 1 +
8
tests/fp/fp-test-log2.c | 1 +
9
tests/fp/fp-test.c | 1 +
10
3 files changed, 3 insertions(+)
11
12
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/fp/fp-bench.c
15
+++ b/tests/fp/fp-bench.c
16
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
17
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
18
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
19
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
20
+ set_float_default_nan_pattern(0b01000000, &soft_status);
21
22
f = bench_funcs[operation][precision];
23
g_assert(f);
24
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/tests/fp/fp-test-log2.c
27
+++ b/tests/fp/fp-test-log2.c
28
@@ -XXX,XX +XXX,XX @@ int main(int ac, char **av)
29
int i;
30
31
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
32
+ set_float_default_nan_pattern(0b01000000, &qsf);
33
set_float_rounding_mode(float_round_nearest_even, &qsf);
34
35
test.d = 0.0;
36
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/fp/fp-test.c
39
+++ b/tests/fp/fp-test.c
40
@@ -XXX,XX +XXX,XX @@ void run_test(void)
41
*/
42
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
43
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
44
+ set_float_default_nan_pattern(0b01000000, &qsf);
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
46
47
genCases_setLevel(test_level);
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-37-peter.maydell@linaro.org
7
---
8
target/microblaze/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/microblaze/cpu.c
15
+++ b/target/microblaze/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_reset_hold(Object *obj, ResetType type)
17
* this architecture.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
23
#if defined(CONFIG_USER_ONLY)
24
/* start in user mode with interrupts enabled. */
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
34
- || defined(TARGET_MICROBLAZE)
35
+#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
/* Sign bit set, most significant frac bit set */
37
dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-38-peter.maydell@linaro.org
7
---
8
target/i386/tcg/fpu_helper.c | 4 ++++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 4 insertions(+), 3 deletions(-)
11
12
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/i386/tcg/fpu_helper.c
15
+++ b/target/i386/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
17
*/
18
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
19
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
+ set_float_default_nan_pattern(0b11000000, &env->mmx_status);
23
+ set_float_default_nan_pattern(0b11000000, &env->sse_status);
24
}
25
26
static inline uint8_t save_exception_flags(CPUX86State *env)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
index XXXXXXX..XXXXXXX 100644
29
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
32
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
/* Sign bit clear, all frac bits set */
34
dnan_pattern = 0b01111111;
35
-#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
- /* Sign bit set, most significant frac bit set */
37
- dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
/* Sign bit clear, msb-1 frac bit set */
40
dnan_pattern = 0b00100000;
41
--
42
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-39-peter.maydell@linaro.org
7
---
8
target/hppa/fpu_helper.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 2 insertions(+), 3 deletions(-)
11
12
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/hppa/fpu_helper.c
15
+++ b/target/hppa/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
17
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
18
/* For inf * 0 + NaN, return the input NaN */
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ /* Default NaN: sign bit clear, msb-1 frac bit set */
21
+ set_float_default_nan_pattern(0b00100000, &env->fp_status);
22
}
23
24
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_HPPA)
34
- /* Sign bit clear, msb-1 frac bit set */
35
- dnan_pattern = 0b00100000;
36
#elif defined(TARGET_HEXAGON)
37
/* Sign bit set, all frac bits set. */
38
dnan_pattern = 0b11111111;
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the alpha target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-40-peter.maydell@linaro.org
6
---
7
target/alpha/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/alpha/cpu.c
13
+++ b/target/alpha/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_initfn(Object *obj)
15
* operand in Fa. That is float_2nan_prop_ba.
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
18
+ /* Default NaN: sign bit clear, msb frac bit set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
#if defined(CONFIG_USER_ONLY)
21
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
22
cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD
23
--
24
2.34.1
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
Set the default NaN pattern explicitly for the arm target.
2
This includes setting it for the old linux-user nwfpe emulation.
3
For nwfpe, our default doesn't match the real kernel, but we
4
avoid making a behaviour change in this commit.
2
5
3
Currently the emulated EMAC for sun8i always traverses the transmit queue
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
from the head when transferring packets. It searches for a list of consecutive
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
descriptors whichs are flagged as ready for processing and transmits their payloads
8
Message-id: 20241202131347.498124-41-peter.maydell@linaro.org
6
accordingly. The controller stops processing once it finds a descriptor that is not
9
---
7
marked ready.
10
linux-user/arm/nwfpe/fpa11.c | 5 +++++
11
target/arm/cpu.c | 2 ++
12
2 files changed, 7 insertions(+)
8
13
9
While the above behaviour works in most situations, it is not the same as the actual
14
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
10
EMAC in hardware. Actual hardware uses the TX_CUR_DESC register value to keep track
11
of the last position in the transmit queue and continues processing from that position
12
when software triggers the start of DMA processing. The currently emulated behaviour can
13
lead to packet loss on transmit when software fills the transmit queue with ready
14
descriptors that overlap the tail of the circular list.
15
16
This commit modifies the emulated EMAC for sun8i such that it processes
17
the transmit queue using the TX_CUR_DESC register in the same way as hardware.
18
19
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20210310195820.21950-2-nieklinnenbank@gmail.com
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
24
hw/net/allwinner-sun8i-emac.c | 62 +++++++++++++++++++----------------
25
1 file changed, 34 insertions(+), 28 deletions(-)
26
27
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
28
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/net/allwinner-sun8i-emac.c
16
--- a/linux-user/arm/nwfpe/fpa11.c
30
+++ b/hw/net/allwinner-sun8i-emac.c
17
+++ b/linux-user/arm/nwfpe/fpa11.c
31
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_update_irq(AwSun8iEmacState *s)
18
@@ -XXX,XX +XXX,XX @@ void resetFPA11(void)
32
qemu_set_irq(s->irq, (s->int_sta & s->int_en) != 0);
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);
33
}
27
}
34
28
35
-static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
29
void SetRoundingMode(const unsigned int opcode)
36
- FrameDescriptor *desc,
30
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
37
- size_t min_size)
31
index XXXXXXX..XXXXXXX 100644
38
+static bool allwinner_sun8i_emac_desc_owned(FrameDescriptor *desc,
32
--- a/target/arm/cpu.c
39
+ size_t min_buf_size)
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)
40
{
41
{
41
- uint32_t paddr = desc->next;
42
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
42
-
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
43
- dma_memory_read(&s->dma_as, paddr, desc, sizeof(*desc));
44
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
44
-
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
45
- if ((desc->status & DESC_STATUS_CTL) &&
46
+ set_float_default_nan_pattern(0b01000000, s);
46
- (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) {
47
- return paddr;
48
- } else {
49
- return 0;
50
- }
51
+ return (desc->status & DESC_STATUS_CTL) && (min_buf_size == 0 ||
52
+ (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_buf_size);
53
}
47
}
54
48
55
-static uint32_t allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
49
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
56
- FrameDescriptor *desc,
57
- uint32_t start_addr,
58
- size_t min_size)
59
+static void allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
60
+ FrameDescriptor *desc,
61
+ uint32_t phys_addr)
62
+{
63
+ dma_memory_read(&s->dma_as, phys_addr, desc, sizeof(*desc));
64
+}
65
+
66
+static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
67
+ FrameDescriptor *desc)
68
+{
69
+ const uint32_t nxt = desc->next;
70
+ allwinner_sun8i_emac_get_desc(s, desc, nxt);
71
+ return nxt;
72
+}
73
+
74
+static uint32_t allwinner_sun8i_emac_find_desc(AwSun8iEmacState *s,
75
+ FrameDescriptor *desc,
76
+ uint32_t start_addr,
77
+ size_t min_size)
78
{
79
uint32_t desc_addr = start_addr;
80
81
/* Note that the list is a cycle. Last entry points back to the head. */
82
while (desc_addr != 0) {
83
- dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc));
84
+ allwinner_sun8i_emac_get_desc(s, desc, desc_addr);
85
86
- if ((desc->status & DESC_STATUS_CTL) &&
87
- (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) {
88
+ if (allwinner_sun8i_emac_desc_owned(desc, min_size)) {
89
return desc_addr;
90
} else if (desc->next == start_addr) {
91
break;
92
@@ -XXX,XX +XXX,XX @@ static uint32_t allwinner_sun8i_emac_rx_desc(AwSun8iEmacState *s,
93
FrameDescriptor *desc,
94
size_t min_size)
95
{
96
- return allwinner_sun8i_emac_get_desc(s, desc, s->rx_desc_curr, min_size);
97
+ return allwinner_sun8i_emac_find_desc(s, desc, s->rx_desc_curr, min_size);
98
}
99
100
static uint32_t allwinner_sun8i_emac_tx_desc(AwSun8iEmacState *s,
101
- FrameDescriptor *desc,
102
- size_t min_size)
103
+ FrameDescriptor *desc)
104
{
105
- return allwinner_sun8i_emac_get_desc(s, desc, s->tx_desc_head, min_size);
106
+ allwinner_sun8i_emac_get_desc(s, desc, s->tx_desc_curr);
107
+ return s->tx_desc_curr;
108
}
109
110
static void allwinner_sun8i_emac_flush_desc(AwSun8iEmacState *s,
111
@@ -XXX,XX +XXX,XX @@ static ssize_t allwinner_sun8i_emac_receive(NetClientState *nc,
112
bytes_left -= desc_bytes;
113
114
/* Move to the next descriptor */
115
- s->rx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc, 64);
116
+ s->rx_desc_curr = allwinner_sun8i_emac_find_desc(s, &desc, desc.next,
117
+ AW_SUN8I_EMAC_MIN_PKT_SZ);
118
if (!s->rx_desc_curr) {
119
/* Not enough buffer space available */
120
s->int_sta |= INT_STA_RX_BUF_UA;
121
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s)
122
size_t transmitted = 0;
123
static uint8_t packet_buf[2048];
124
125
- s->tx_desc_curr = allwinner_sun8i_emac_tx_desc(s, &desc, 0);
126
+ s->tx_desc_curr = allwinner_sun8i_emac_tx_desc(s, &desc);
127
128
/* Read all transmit descriptors */
129
- while (s->tx_desc_curr != 0) {
130
+ while (allwinner_sun8i_emac_desc_owned(&desc, 0)) {
131
132
/* Read from physical memory into packet buffer */
133
bytes = desc.status2 & DESC_STATUS2_BUF_SIZE_MASK;
134
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s)
135
packet_bytes = 0;
136
transmitted++;
137
}
138
- s->tx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc, 0);
139
+ s->tx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc);
140
}
141
142
/* Raise transmit completed interrupt */
143
--
50
--
144
2.20.1
51
2.34.1
145
146
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
We're about to move code from the template header into pxa2xx_lcd.c.
1
Set the default NaN pattern explicitly for MIPS. Note that this
2
Before doing that, make coding style fixes so checkpatch doesn't
2
is our only target which currently changes the default NaN
3
complain about the patch which moves the code. This commit is
3
at runtime (which it was previously doing indirectly when it
4
whitespace changes only:
4
changed the snan_bit_is_one setting).
5
* avoid hard-coded tabs
6
* fix ident on function prototypes
7
* no newline before open brace on array definitions
8
5
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210211141515.8755-9-peter.maydell@linaro.org
8
Message-id: 20241202131347.498124-44-peter.maydell@linaro.org
12
---
9
---
13
hw/display/pxa2xx_template.h | 66 +++++++++++++++++-------------------
10
target/mips/fpu_helper.h | 7 +++++++
14
1 file changed, 32 insertions(+), 34 deletions(-)
11
target/mips/msa.c | 3 +++
12
2 files changed, 10 insertions(+)
15
13
16
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
14
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/display/pxa2xx_template.h
16
--- a/target/mips/fpu_helper.h
19
+++ b/hw/display/pxa2xx_template.h
17
+++ b/target/mips/fpu_helper.h
20
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
21
} while (0)
19
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
22
20
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
23
#ifdef HOST_WORDS_BIGENDIAN
21
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
24
-# define SWAP_WORDS    1
22
+ /*
25
+# define SWAP_WORDS 1
23
+ * With nan2008, the default NaN value has the sign bit clear and the
26
#endif
24
+ * frac msb set; with the older mode, the sign bit is clear, and all
27
25
+ * frac bits except the msb are set.
28
-#define FN_2(x)        FN(x + 1) FN(x)
26
+ */
29
-#define FN_4(x)        FN_2(x + 2) FN_2(x)
27
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
30
+#define FN_2(x) FN(x + 1) FN(x)
28
+ &env->active_fpu.fp_status);
31
+#define FN_4(x) FN_2(x + 2) FN_2(x)
29
32
33
-static void pxa2xx_draw_line2(void *opaque,
34
- uint8_t *dest, const uint8_t *src, int width, int deststep)
35
+static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src,
36
+ int width, int deststep)
37
{
38
uint32_t *palette = opaque;
39
uint32_t data;
40
while (width > 0) {
41
data = *(uint32_t *) src;
42
-#define FN(x)        COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
43
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
44
#ifdef SWAP_WORDS
45
FN_4(12)
46
FN_4(8)
47
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line2(void *opaque,
48
}
49
}
30
}
50
31
51
-static void pxa2xx_draw_line4(void *opaque,
32
diff --git a/target/mips/msa.c b/target/mips/msa.c
52
- uint8_t *dest, const uint8_t *src, int width, int deststep)
33
index XXXXXXX..XXXXXXX 100644
53
+static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src,
34
--- a/target/mips/msa.c
54
+ int width, int deststep)
35
+++ b/target/mips/msa.c
55
{
36
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
56
uint32_t *palette = opaque;
37
/* Inf * 0 + NaN returns the input NaN */
57
uint32_t data;
38
set_float_infzeronan_rule(float_infzeronan_dnan_never,
58
while (width > 0) {
39
&env->active_tc.msa_fp_status);
59
data = *(uint32_t *) src;
40
+ /* Default NaN: sign bit clear, frac msb set */
60
-#define FN(x)        COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
41
+ set_float_default_nan_pattern(0b01000000,
61
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
42
+ &env->active_tc.msa_fp_status);
62
#ifdef SWAP_WORDS
63
FN_2(6)
64
FN_2(4)
65
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line4(void *opaque,
66
}
67
}
43
}
68
69
-static void pxa2xx_draw_line8(void *opaque,
70
- uint8_t *dest, const uint8_t *src, int width, int deststep)
71
+static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src,
72
+ int width, int deststep)
73
{
74
uint32_t *palette = opaque;
75
uint32_t data;
76
while (width > 0) {
77
data = *(uint32_t *) src;
78
-#define FN(x)        COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
79
+#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
80
#ifdef SWAP_WORDS
81
FN(24)
82
FN(16)
83
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line8(void *opaque,
84
}
85
}
86
87
-static void pxa2xx_draw_line16(void *opaque,
88
- uint8_t *dest, const uint8_t *src, int width, int deststep)
89
+static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src,
90
+ int width, int deststep)
91
{
92
uint32_t data;
93
unsigned int r, g, b;
94
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16(void *opaque,
95
}
96
}
97
98
-static void pxa2xx_draw_line16t(void *opaque,
99
- uint8_t *dest, const uint8_t *src, int width, int deststep)
100
+static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src,
101
+ int width, int deststep)
102
{
103
uint32_t data;
104
unsigned int r, g, b;
105
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16t(void *opaque,
106
}
107
}
108
109
-static void pxa2xx_draw_line18(void *opaque,
110
- uint8_t *dest, const uint8_t *src, int width, int deststep)
111
+static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src,
112
+ int width, int deststep)
113
{
114
uint32_t data;
115
unsigned int r, g, b;
116
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line18(void *opaque,
117
}
118
119
/* The wicked packed format */
120
-static void pxa2xx_draw_line18p(void *opaque,
121
- uint8_t *dest, const uint8_t *src, int width, int deststep)
122
+static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src,
123
+ int width, int deststep)
124
{
125
uint32_t data[3];
126
unsigned int r, g, b;
127
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line18p(void *opaque,
128
}
129
}
130
131
-static void pxa2xx_draw_line19(void *opaque,
132
- uint8_t *dest, const uint8_t *src, int width, int deststep)
133
+static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src,
134
+ int width, int deststep)
135
{
136
uint32_t data;
137
unsigned int r, g, b;
138
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19(void *opaque,
139
}
140
141
/* The wicked packed format */
142
-static void pxa2xx_draw_line19p(void *opaque,
143
- uint8_t *dest, const uint8_t *src, int width, int deststep)
144
+static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src,
145
+ int width, int deststep)
146
{
147
uint32_t data[3];
148
unsigned int r, g, b;
149
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
150
}
151
}
152
153
-static void pxa2xx_draw_line24(void *opaque,
154
- uint8_t *dest, const uint8_t *src, int width, int deststep)
155
+static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src,
156
+ int width, int deststep)
157
{
158
uint32_t data;
159
unsigned int r, g, b;
160
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line24(void *opaque,
161
}
162
}
163
164
-static void pxa2xx_draw_line24t(void *opaque,
165
- uint8_t *dest, const uint8_t *src, int width, int deststep)
166
+static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src,
167
+ int width, int deststep)
168
{
169
uint32_t data;
170
unsigned int r, g, b;
171
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line24t(void *opaque,
172
}
173
}
174
175
-static void pxa2xx_draw_line25(void *opaque,
176
- uint8_t *dest, const uint8_t *src, int width, int deststep)
177
+static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src,
178
+ int width, int deststep)
179
{
180
uint32_t data;
181
unsigned int r, g, b;
182
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line25(void *opaque,
183
}
184
185
/* Overlay planes disabled, no transparency */
186
-static drawfn pxa2xx_draw_fn_32[16] =
187
-{
188
+static drawfn pxa2xx_draw_fn_32[16] = {
189
[0 ... 0xf] = NULL,
190
[pxa_lcdc_2bpp] = pxa2xx_draw_line2,
191
[pxa_lcdc_4bpp] = pxa2xx_draw_line4,
192
@@ -XXX,XX +XXX,XX @@ static drawfn pxa2xx_draw_fn_32[16] =
193
};
194
195
/* Overlay planes enabled, transparency used */
196
-static drawfn pxa2xx_draw_fn_32t[16] =
197
-{
198
+static drawfn pxa2xx_draw_fn_32t[16] = {
199
[0 ... 0xf] = NULL,
200
[pxa_lcdc_4bpp] = pxa2xx_draw_line4,
201
[pxa_lcdc_8bpp] = pxa2xx_draw_line8,
202
--
44
--
203
2.20.1
45
2.34.1
204
205
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for openrisc.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-45-peter.maydell@linaro.org
6
---
7
target/openrisc/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/openrisc/cpu.c
13
+++ b/target/openrisc/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
15
*/
16
set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
17
18
+ /* Default NaN: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
20
21
#ifndef CONFIG_USER_ONLY
22
cpu->env.picmr = 0x00000000;
23
--
24
2.34.1
diff view generated by jsdifflib
1
Since the dest_width is now always 4 because the output surface is
1
Set the default NaN pattern explicitly for ppc.
2
32bpp, we can replace the dest_width state field with a constant.
3
2
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210211141515.8755-6-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-46-peter.maydell@linaro.org
7
---
6
---
8
hw/display/pxa2xx_lcd.c | 20 +++++++++++---------
7
target/ppc/cpu_init.c | 4 ++++
9
1 file changed, 11 insertions(+), 9 deletions(-)
8
1 file changed, 4 insertions(+)
10
9
11
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
10
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
12
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/pxa2xx_lcd.c
12
--- a/target/ppc/cpu_init.c
14
+++ b/hw/display/pxa2xx_lcd.c
13
+++ b/target/ppc/cpu_init.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED {
14
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
16
#define LDCMD_SOFINT    (1 << 22)
15
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
17
#define LDCMD_PAL    (1 << 26)
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
18
17
19
+/* Size of a pixel in the QEMU UI output surface, in bytes */
18
+ /* Default NaN: sign bit clear, set frac msb */
20
+#define DEST_PIXEL_WIDTH 4
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
+ set_float_default_nan_pattern(0b01000000, &env->vec_status);
21
+
21
+
22
#define BITS 32
22
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
23
#include "pxa2xx_template.h"
23
ppc_spr_t *spr = &env->spr_cb[i];
24
25
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
26
else if (s->bpp > pxa_lcdc_8bpp)
27
src_width *= 2;
28
29
- dest_width = s->xres * s->dest_width;
30
+ dest_width = s->xres * DEST_PIXEL_WIDTH;
31
*miny = 0;
32
if (s->invalidated) {
33
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
34
addr, s->yres, src_width);
35
}
36
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
37
- src_width, dest_width, s->dest_width,
38
+ src_width, dest_width, DEST_PIXEL_WIDTH,
39
s->invalidated,
40
fn, s->dma_ch[0].palette, miny, maxy);
41
}
42
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
43
else if (s->bpp > pxa_lcdc_8bpp)
44
src_width *= 2;
45
46
- dest_width = s->yres * s->dest_width;
47
+ dest_width = s->yres * DEST_PIXEL_WIDTH;
48
*miny = 0;
49
if (s->invalidated) {
50
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
51
addr, s->yres, src_width);
52
}
53
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
54
- src_width, s->dest_width, -dest_width,
55
+ src_width, DEST_PIXEL_WIDTH, -dest_width,
56
s->invalidated,
57
fn, s->dma_ch[0].palette,
58
miny, maxy);
59
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
60
src_width *= 2;
61
}
62
63
- dest_width = s->xres * s->dest_width;
64
+ dest_width = s->xres * DEST_PIXEL_WIDTH;
65
*miny = 0;
66
if (s->invalidated) {
67
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
68
addr, s->yres, src_width);
69
}
70
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
71
- src_width, -dest_width, -s->dest_width,
72
+ src_width, -dest_width, -DEST_PIXEL_WIDTH,
73
s->invalidated,
74
fn, s->dma_ch[0].palette, miny, maxy);
75
}
76
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
77
src_width *= 2;
78
}
79
80
- dest_width = s->yres * s->dest_width;
81
+ dest_width = s->yres * DEST_PIXEL_WIDTH;
82
*miny = 0;
83
if (s->invalidated) {
84
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
85
addr, s->yres, src_width);
86
}
87
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
88
- src_width, -s->dest_width, dest_width,
89
+ src_width, -DEST_PIXEL_WIDTH, dest_width,
90
s->invalidated,
91
fn, s->dma_ch[0].palette,
92
miny, maxy);
93
@@ -XXX,XX +XXX,XX @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
94
memory_region_add_subregion(sysmem, base, &s->iomem);
95
96
s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
97
- s->dest_width = 4;
98
99
vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
100
24
101
--
25
--
102
2.20.1
26
2.34.1
103
104
diff view generated by jsdifflib
1
Now that BITS is always 32, expand out all its uses in the template
1
Set the default NaN pattern explicitly for sh4. Note that sh4
2
header, including removing now-useless uses of the glue() macro.
2
is one of the only three targets (the others being HPPA and
3
sometimes MIPS) that has snan_bit_is_one set.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210211141515.8755-7-peter.maydell@linaro.org
7
Message-id: 20241202131347.498124-47-peter.maydell@linaro.org
7
---
8
---
8
hw/display/pxa2xx_template.h | 110 ++++++++++++++---------------------
9
target/sh4/cpu.c | 2 ++
9
1 file changed, 45 insertions(+), 65 deletions(-)
10
1 file changed, 2 insertions(+)
10
11
11
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
12
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/pxa2xx_template.h
14
--- a/target/sh4/cpu.c
14
+++ b/hw/display/pxa2xx_template.h
15
+++ b/target/sh4/cpu.c
15
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_reset_hold(Object *obj, ResetType type)
16
*/
17
set_flush_to_zero(1, &env->fp_status);
17
18
#endif
18
# define SKIP_PIXEL(to)        to += deststep
19
set_default_nan_mode(1, &env->fp_status);
19
-#if BITS == 8
20
+ /* sign bit clear, set all frac bits other than msb */
20
-# define COPY_PIXEL(to, from) do { *to = from; SKIP_PIXEL(to); } while (0)
21
+ set_float_default_nan_pattern(0b00111111, &env->fp_status);
21
-#elif BITS == 15 || BITS == 16
22
-# define COPY_PIXEL(to, from) \
23
- do { \
24
- *(uint16_t *) to = from; \
25
- SKIP_PIXEL(to); \
26
- } while (0)
27
-#elif BITS == 24
28
-# define COPY_PIXEL(to, from) \
29
- do { \
30
- *(uint16_t *) to = from; \
31
- *(to + 2) = (from) >> 16; \
32
- SKIP_PIXEL(to); \
33
- } while (0)
34
-#elif BITS == 32
35
# define COPY_PIXEL(to, from) \
36
do { \
37
*(uint32_t *) to = from; \
38
SKIP_PIXEL(to); \
39
} while (0)
40
-#else
41
-# error unknown bit depth
42
-#endif
43
44
#ifdef HOST_WORDS_BIGENDIAN
45
# define SWAP_WORDS    1
46
@@ -XXX,XX +XXX,XX @@
47
#define FN_2(x)        FN(x + 1) FN(x)
48
#define FN_4(x)        FN_2(x + 2) FN_2(x)
49
50
-static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
51
+static void pxa2xx_draw_line2(void *opaque,
52
uint8_t *dest, const uint8_t *src, int width, int deststep)
53
{
54
uint32_t *palette = opaque;
55
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
56
}
57
}
22
}
58
23
59
-static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
24
static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
60
+static void pxa2xx_draw_line4(void *opaque,
61
uint8_t *dest, const uint8_t *src, int width, int deststep)
62
{
63
uint32_t *palette = opaque;
64
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
65
}
66
}
67
68
-static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
69
+static void pxa2xx_draw_line8(void *opaque,
70
uint8_t *dest, const uint8_t *src, int width, int deststep)
71
{
72
uint32_t *palette = opaque;
73
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
74
}
75
}
76
77
-static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
78
+static void pxa2xx_draw_line16(void *opaque,
79
uint8_t *dest, const uint8_t *src, int width, int deststep)
80
{
81
uint32_t data;
82
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
83
data >>= 6;
84
r = (data & 0x1f) << 3;
85
data >>= 5;
86
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
87
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
88
b = (data & 0x1f) << 3;
89
data >>= 5;
90
g = (data & 0x3f) << 2;
91
data >>= 6;
92
r = (data & 0x1f) << 3;
93
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
94
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
95
width -= 2;
96
src += 4;
97
}
98
}
99
100
-static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
101
+static void pxa2xx_draw_line16t(void *opaque,
102
uint8_t *dest, const uint8_t *src, int width, int deststep)
103
{
104
uint32_t data;
105
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
106
if (data & 1)
107
SKIP_PIXEL(dest);
108
else
109
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
110
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
111
data >>= 1;
112
b = (data & 0x1f) << 3;
113
data >>= 5;
114
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
115
if (data & 1)
116
SKIP_PIXEL(dest);
117
else
118
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
119
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
120
width -= 2;
121
src += 4;
122
}
123
}
124
125
-static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
126
+static void pxa2xx_draw_line18(void *opaque,
127
uint8_t *dest, const uint8_t *src, int width, int deststep)
128
{
129
uint32_t data;
130
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
131
g = (data & 0x3f) << 2;
132
data >>= 6;
133
r = (data & 0x3f) << 2;
134
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
135
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
136
width -= 1;
137
src += 4;
138
}
139
}
140
141
/* The wicked packed format */
142
-static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
143
+static void pxa2xx_draw_line18p(void *opaque,
144
uint8_t *dest, const uint8_t *src, int width, int deststep)
145
{
146
uint32_t data[3];
147
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
148
data[0] >>= 6;
149
r = (data[0] & 0x3f) << 2;
150
data[0] >>= 12;
151
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
152
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
153
b = (data[0] & 0x3f) << 2;
154
data[0] >>= 6;
155
g = ((data[1] & 0xf) << 4) | (data[0] << 2);
156
data[1] >>= 4;
157
r = (data[1] & 0x3f) << 2;
158
data[1] >>= 12;
159
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
160
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
161
b = (data[1] & 0x3f) << 2;
162
data[1] >>= 6;
163
g = (data[1] & 0x3f) << 2;
164
data[1] >>= 6;
165
r = ((data[2] & 0x3) << 6) | (data[1] << 2);
166
data[2] >>= 8;
167
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
168
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
169
b = (data[2] & 0x3f) << 2;
170
data[2] >>= 6;
171
g = (data[2] & 0x3f) << 2;
172
data[2] >>= 6;
173
r = data[2] << 2;
174
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
175
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
176
width -= 4;
177
}
178
}
179
180
-static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
181
+static void pxa2xx_draw_line19(void *opaque,
182
uint8_t *dest, const uint8_t *src, int width, int deststep)
183
{
184
uint32_t data;
185
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
186
if (data & 1)
187
SKIP_PIXEL(dest);
188
else
189
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
190
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
191
width -= 1;
192
src += 4;
193
}
194
}
195
196
/* The wicked packed format */
197
-static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
198
+static void pxa2xx_draw_line19p(void *opaque,
199
uint8_t *dest, const uint8_t *src, int width, int deststep)
200
{
201
uint32_t data[3];
202
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
203
if (data[0] & 1)
204
SKIP_PIXEL(dest);
205
else
206
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
207
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
208
data[0] >>= 6;
209
b = (data[0] & 0x3f) << 2;
210
data[0] >>= 6;
211
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
212
if (data[1] & 1)
213
SKIP_PIXEL(dest);
214
else
215
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
216
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
217
data[1] >>= 6;
218
b = (data[1] & 0x3f) << 2;
219
data[1] >>= 6;
220
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
221
if (data[2] & 1)
222
SKIP_PIXEL(dest);
223
else
224
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
225
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
226
data[2] >>= 6;
227
b = (data[2] & 0x3f) << 2;
228
data[2] >>= 6;
229
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
230
if (data[2] & 1)
231
SKIP_PIXEL(dest);
232
else
233
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
234
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
235
width -= 4;
236
}
237
}
238
239
-static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
240
+static void pxa2xx_draw_line24(void *opaque,
241
uint8_t *dest, const uint8_t *src, int width, int deststep)
242
{
243
uint32_t data;
244
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
245
g = data & 0xff;
246
data >>= 8;
247
r = data & 0xff;
248
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
249
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
250
width -= 1;
251
src += 4;
252
}
253
}
254
255
-static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
256
+static void pxa2xx_draw_line24t(void *opaque,
257
uint8_t *dest, const uint8_t *src, int width, int deststep)
258
{
259
uint32_t data;
260
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
261
if (data & 1)
262
SKIP_PIXEL(dest);
263
else
264
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
265
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
266
width -= 1;
267
src += 4;
268
}
269
}
270
271
-static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
272
+static void pxa2xx_draw_line25(void *opaque,
273
uint8_t *dest, const uint8_t *src, int width, int deststep)
274
{
275
uint32_t data;
276
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
277
if (data & 1)
278
SKIP_PIXEL(dest);
279
else
280
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
281
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
282
width -= 1;
283
src += 4;
284
}
285
}
286
287
/* Overlay planes disabled, no transparency */
288
-static drawfn glue(pxa2xx_draw_fn_, BITS)[16] =
289
+static drawfn pxa2xx_draw_fn_32[16] =
290
{
291
[0 ... 0xf] = NULL,
292
- [pxa_lcdc_2bpp] = glue(pxa2xx_draw_line2_, BITS),
293
- [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
294
- [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
295
- [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16_, BITS),
296
- [pxa_lcdc_18bpp] = glue(pxa2xx_draw_line18_, BITS),
297
- [pxa_lcdc_18pbpp] = glue(pxa2xx_draw_line18p_, BITS),
298
- [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24_, BITS),
299
+ [pxa_lcdc_2bpp] = pxa2xx_draw_line2,
300
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
301
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
302
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16,
303
+ [pxa_lcdc_18bpp] = pxa2xx_draw_line18,
304
+ [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p,
305
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24,
306
};
307
308
/* Overlay planes enabled, transparency used */
309
-static drawfn glue(glue(pxa2xx_draw_fn_, BITS), t)[16] =
310
+static drawfn pxa2xx_draw_fn_32t[16] =
311
{
312
[0 ... 0xf] = NULL,
313
- [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
314
- [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
315
- [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16t_, BITS),
316
- [pxa_lcdc_19bpp] = glue(pxa2xx_draw_line19_, BITS),
317
- [pxa_lcdc_19pbpp] = glue(pxa2xx_draw_line19p_, BITS),
318
- [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24t_, BITS),
319
- [pxa_lcdc_25bpp] = glue(pxa2xx_draw_line25_, BITS),
320
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
321
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
322
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16t,
323
+ [pxa_lcdc_19bpp] = pxa2xx_draw_line19,
324
+ [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p,
325
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24t,
326
+ [pxa_lcdc_25bpp] = pxa2xx_draw_line25,
327
};
328
329
-#undef BITS
330
#undef COPY_PIXEL
331
#undef SKIP_PIXEL
332
333
--
25
--
334
2.20.1
26
2.34.1
335
336
diff view generated by jsdifflib
1
For a long time now the UI layer has guaranteed that the console
1
Set the default NaN pattern explicitly for rx.
2
surface is always 32 bits per pixel. Remove the legacy dead code
3
from the pxa2xx_lcd display device which was handling the possibility
4
that the console surface was some other format.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210211141515.8755-5-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-48-peter.maydell@linaro.org
9
---
6
---
10
hw/display/pxa2xx_lcd.c | 79 +++++++++--------------------------------
7
target/rx/cpu.c | 2 ++
11
1 file changed, 17 insertions(+), 62 deletions(-)
8
1 file changed, 2 insertions(+)
12
9
13
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
10
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/display/pxa2xx_lcd.c
12
--- a/target/rx/cpu.c
16
+++ b/hw/display/pxa2xx_lcd.c
13
+++ b/target/rx/cpu.c
17
@@ -XXX,XX +XXX,XX @@ struct PXA2xxLCDState {
14
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_reset_hold(Object *obj, ResetType type)
18
15
* then prefer dest over source", which is float_2nan_prop_s_ab.
19
int invalidated;
16
*/
20
QemuConsole *con;
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
21
- drawfn *line_fn[2];
18
+ /* Default NaN value: sign bit clear, set frac msb */
22
int dest_width;
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
23
int xres, yres;
24
int pal_for;
25
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED {
26
#define LDCMD_SOFINT    (1 << 22)
27
#define LDCMD_PAL    (1 << 26)
28
29
+#define BITS 32
30
+#include "pxa2xx_template.h"
31
+
32
/* Route internal interrupt lines to the global IC */
33
static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
34
{
35
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
36
}
37
}
20
}
38
21
39
+static inline drawfn pxa2xx_drawfn(PXA2xxLCDState *s)
22
static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
40
+{
41
+ if (s->transp) {
42
+ return pxa2xx_draw_fn_32t[s->bpp];
43
+ } else {
44
+ return pxa2xx_draw_fn_32[s->bpp];
45
+ }
46
+}
47
+
48
static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
49
hwaddr addr, int *miny, int *maxy)
50
{
51
DisplaySurface *surface = qemu_console_surface(s->con);
52
int src_width, dest_width;
53
- drawfn fn = NULL;
54
- if (s->dest_width)
55
- fn = s->line_fn[s->transp][s->bpp];
56
+ drawfn fn = pxa2xx_drawfn(s);
57
if (!fn)
58
return;
59
60
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
61
{
62
DisplaySurface *surface = qemu_console_surface(s->con);
63
int src_width, dest_width;
64
- drawfn fn = NULL;
65
- if (s->dest_width)
66
- fn = s->line_fn[s->transp][s->bpp];
67
+ drawfn fn = pxa2xx_drawfn(s);
68
if (!fn)
69
return;
70
71
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
72
{
73
DisplaySurface *surface = qemu_console_surface(s->con);
74
int src_width, dest_width;
75
- drawfn fn = NULL;
76
- if (s->dest_width) {
77
- fn = s->line_fn[s->transp][s->bpp];
78
- }
79
+ drawfn fn = pxa2xx_drawfn(s);
80
if (!fn) {
81
return;
82
}
83
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
84
{
85
DisplaySurface *surface = qemu_console_surface(s->con);
86
int src_width, dest_width;
87
- drawfn fn = NULL;
88
- if (s->dest_width) {
89
- fn = s->line_fn[s->transp][s->bpp];
90
- }
91
+ drawfn fn = pxa2xx_drawfn(s);
92
if (!fn) {
93
return;
94
}
95
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pxa2xx_lcdc = {
96
}
97
};
98
99
-#define BITS 8
100
-#include "pxa2xx_template.h"
101
-#define BITS 15
102
-#include "pxa2xx_template.h"
103
-#define BITS 16
104
-#include "pxa2xx_template.h"
105
-#define BITS 24
106
-#include "pxa2xx_template.h"
107
-#define BITS 32
108
-#include "pxa2xx_template.h"
109
-
110
static const GraphicHwOps pxa2xx_ops = {
111
.invalidate = pxa2xx_invalidate_display,
112
.gfx_update = pxa2xx_update_display,
113
@@ -XXX,XX +XXX,XX @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
114
hwaddr base, qemu_irq irq)
115
{
116
PXA2xxLCDState *s;
117
- DisplaySurface *surface;
118
119
s = (PXA2xxLCDState *) g_malloc0(sizeof(PXA2xxLCDState));
120
s->invalidated = 1;
121
@@ -XXX,XX +XXX,XX @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
122
memory_region_add_subregion(sysmem, base, &s->iomem);
123
124
s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
125
- surface = qemu_console_surface(s->con);
126
-
127
- switch (surface_bits_per_pixel(surface)) {
128
- case 0:
129
- s->dest_width = 0;
130
- break;
131
- case 8:
132
- s->line_fn[0] = pxa2xx_draw_fn_8;
133
- s->line_fn[1] = pxa2xx_draw_fn_8t;
134
- s->dest_width = 1;
135
- break;
136
- case 15:
137
- s->line_fn[0] = pxa2xx_draw_fn_15;
138
- s->line_fn[1] = pxa2xx_draw_fn_15t;
139
- s->dest_width = 2;
140
- break;
141
- case 16:
142
- s->line_fn[0] = pxa2xx_draw_fn_16;
143
- s->line_fn[1] = pxa2xx_draw_fn_16t;
144
- s->dest_width = 2;
145
- break;
146
- case 24:
147
- s->line_fn[0] = pxa2xx_draw_fn_24;
148
- s->line_fn[1] = pxa2xx_draw_fn_24t;
149
- s->dest_width = 3;
150
- break;
151
- case 32:
152
- s->line_fn[0] = pxa2xx_draw_fn_32;
153
- s->line_fn[1] = pxa2xx_draw_fn_32t;
154
- s->dest_width = 4;
155
- break;
156
- default:
157
- fprintf(stderr, "%s: Bad color depth\n", __func__);
158
- exit(1);
159
- }
160
+ s->dest_width = 4;
161
162
vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
163
164
--
23
--
165
2.20.1
24
2.34.1
166
167
diff view generated by jsdifflib
1
BITS is always 32, so remove all uses of it from the template header,
1
Set the default NaN pattern explicitly for s390x.
2
by dropping the trailing '32' from the draw function names and
3
not constructing the name of rgb_to_pixel32() via the glue() macro.
4
2
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210211141515.8755-4-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-49-peter.maydell@linaro.org
8
---
6
---
9
hw/display/pl110_template.h | 20 +++----
7
target/s390x/cpu.c | 2 ++
10
hw/display/pl110.c | 113 ++++++++++++++++++------------------
8
1 file changed, 2 insertions(+)
11
2 files changed, 65 insertions(+), 68 deletions(-)
12
9
13
diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h
10
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/display/pl110_template.h
12
--- a/target/s390x/cpu.c
16
+++ b/hw/display/pl110_template.h
13
+++ b/target/s390x/cpu.c
17
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
18
#endif
15
set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
19
16
set_float_infzeronan_rule(float_infzeronan_dnan_always,
20
#if ORDER == 0
17
&env->fpu_status);
21
-#define NAME glue(glue(lblp_, BORDER), BITS)
18
+ /* Default NaN value: sign bit clear, frac msb set */
22
+#define NAME glue(lblp_, BORDER)
19
+ set_float_default_nan_pattern(0b01000000, &env->fpu_status);
23
#ifdef HOST_WORDS_BIGENDIAN
20
/* fall through */
24
#define SWAP_WORDS 1
21
case RESET_TYPE_S390_CPU_NORMAL:
25
#endif
22
env->psw.mask &= ~PSW_MASK_RI;
26
#elif ORDER == 1
27
-#define NAME glue(glue(bbbp_, BORDER), BITS)
28
+#define NAME glue(bbbp_, BORDER)
29
#ifndef HOST_WORDS_BIGENDIAN
30
#define SWAP_WORDS 1
31
#endif
32
#else
33
#define SWAP_PIXELS 1
34
-#define NAME glue(glue(lbbp_, BORDER), BITS)
35
+#define NAME glue(lbbp_, BORDER)
36
#ifdef HOST_WORDS_BIGENDIAN
37
#define SWAP_WORDS 1
38
#endif
39
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_
40
MSB = (data & 0x1f) << 3;
41
data >>= 5;
42
#endif
43
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
44
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
45
LSB = (data & 0x1f) << 3;
46
data >>= 5;
47
g = (data & 0x3f) << 2;
48
data >>= 6;
49
MSB = (data & 0x1f) << 3;
50
data >>= 5;
51
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
52
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
53
#undef MSB
54
#undef LSB
55
width -= 2;
56
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_
57
g = (data >> 16) & 0xff;
58
MSB = (data >> 8) & 0xff;
59
#endif
60
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
61
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
62
#undef MSB
63
#undef LSB
64
width--;
65
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const ui
66
data >>= 5;
67
MSB = (data & 0x1f) << 3;
68
data >>= 5;
69
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
70
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
71
LSB = (data & 0x1f) << 3;
72
data >>= 5;
73
g = (data & 0x1f) << 3;
74
data >>= 5;
75
MSB = (data & 0x1f) << 3;
76
data >>= 6;
77
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
78
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
79
#undef MSB
80
#undef LSB
81
width -= 2;
82
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_
83
data >>= 4;
84
MSB = (data & 0xf) << 4;
85
data >>= 8;
86
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
87
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
88
LSB = (data & 0xf) << 4;
89
data >>= 4;
90
g = (data & 0xf) << 4;
91
data >>= 4;
92
MSB = (data & 0xf) << 4;
93
data >>= 8;
94
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
95
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
96
#undef MSB
97
#undef LSB
98
width -= 2;
99
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/display/pl110.c
102
+++ b/hw/display/pl110.c
103
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
104
pl111_id
105
};
106
107
-#define BITS 32
108
#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
109
110
#undef RGB
111
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
112
#include "pl110_template.h"
113
#undef BORDER
114
115
-static drawfn pl110_draw_fn_32[48] = {
116
- pl110_draw_line1_lblp_bgr32,
117
- pl110_draw_line2_lblp_bgr32,
118
- pl110_draw_line4_lblp_bgr32,
119
- pl110_draw_line8_lblp_bgr32,
120
- pl110_draw_line16_555_lblp_bgr32,
121
- pl110_draw_line32_lblp_bgr32,
122
- pl110_draw_line16_lblp_bgr32,
123
- pl110_draw_line12_lblp_bgr32,
124
-
125
- pl110_draw_line1_bbbp_bgr32,
126
- pl110_draw_line2_bbbp_bgr32,
127
- pl110_draw_line4_bbbp_bgr32,
128
- pl110_draw_line8_bbbp_bgr32,
129
- pl110_draw_line16_555_bbbp_bgr32,
130
- pl110_draw_line32_bbbp_bgr32,
131
- pl110_draw_line16_bbbp_bgr32,
132
- pl110_draw_line12_bbbp_bgr32,
133
-
134
- pl110_draw_line1_lbbp_bgr32,
135
- pl110_draw_line2_lbbp_bgr32,
136
- pl110_draw_line4_lbbp_bgr32,
137
- pl110_draw_line8_lbbp_bgr32,
138
- pl110_draw_line16_555_lbbp_bgr32,
139
- pl110_draw_line32_lbbp_bgr32,
140
- pl110_draw_line16_lbbp_bgr32,
141
- pl110_draw_line12_lbbp_bgr32,
142
-
143
- pl110_draw_line1_lblp_rgb32,
144
- pl110_draw_line2_lblp_rgb32,
145
- pl110_draw_line4_lblp_rgb32,
146
- pl110_draw_line8_lblp_rgb32,
147
- pl110_draw_line16_555_lblp_rgb32,
148
- pl110_draw_line32_lblp_rgb32,
149
- pl110_draw_line16_lblp_rgb32,
150
- pl110_draw_line12_lblp_rgb32,
151
-
152
- pl110_draw_line1_bbbp_rgb32,
153
- pl110_draw_line2_bbbp_rgb32,
154
- pl110_draw_line4_bbbp_rgb32,
155
- pl110_draw_line8_bbbp_rgb32,
156
- pl110_draw_line16_555_bbbp_rgb32,
157
- pl110_draw_line32_bbbp_rgb32,
158
- pl110_draw_line16_bbbp_rgb32,
159
- pl110_draw_line12_bbbp_rgb32,
160
-
161
- pl110_draw_line1_lbbp_rgb32,
162
- pl110_draw_line2_lbbp_rgb32,
163
- pl110_draw_line4_lbbp_rgb32,
164
- pl110_draw_line8_lbbp_rgb32,
165
- pl110_draw_line16_555_lbbp_rgb32,
166
- pl110_draw_line32_lbbp_rgb32,
167
- pl110_draw_line16_lbbp_rgb32,
168
- pl110_draw_line12_lbbp_rgb32,
169
-};
170
-
171
-#undef BITS
172
#undef COPY_PIXEL
173
174
+static drawfn pl110_draw_fn_32[48] = {
175
+ pl110_draw_line1_lblp_bgr,
176
+ pl110_draw_line2_lblp_bgr,
177
+ pl110_draw_line4_lblp_bgr,
178
+ pl110_draw_line8_lblp_bgr,
179
+ pl110_draw_line16_555_lblp_bgr,
180
+ pl110_draw_line32_lblp_bgr,
181
+ pl110_draw_line16_lblp_bgr,
182
+ pl110_draw_line12_lblp_bgr,
183
+
184
+ pl110_draw_line1_bbbp_bgr,
185
+ pl110_draw_line2_bbbp_bgr,
186
+ pl110_draw_line4_bbbp_bgr,
187
+ pl110_draw_line8_bbbp_bgr,
188
+ pl110_draw_line16_555_bbbp_bgr,
189
+ pl110_draw_line32_bbbp_bgr,
190
+ pl110_draw_line16_bbbp_bgr,
191
+ pl110_draw_line12_bbbp_bgr,
192
+
193
+ pl110_draw_line1_lbbp_bgr,
194
+ pl110_draw_line2_lbbp_bgr,
195
+ pl110_draw_line4_lbbp_bgr,
196
+ pl110_draw_line8_lbbp_bgr,
197
+ pl110_draw_line16_555_lbbp_bgr,
198
+ pl110_draw_line32_lbbp_bgr,
199
+ pl110_draw_line16_lbbp_bgr,
200
+ pl110_draw_line12_lbbp_bgr,
201
+
202
+ pl110_draw_line1_lblp_rgb,
203
+ pl110_draw_line2_lblp_rgb,
204
+ pl110_draw_line4_lblp_rgb,
205
+ pl110_draw_line8_lblp_rgb,
206
+ pl110_draw_line16_555_lblp_rgb,
207
+ pl110_draw_line32_lblp_rgb,
208
+ pl110_draw_line16_lblp_rgb,
209
+ pl110_draw_line12_lblp_rgb,
210
+
211
+ pl110_draw_line1_bbbp_rgb,
212
+ pl110_draw_line2_bbbp_rgb,
213
+ pl110_draw_line4_bbbp_rgb,
214
+ pl110_draw_line8_bbbp_rgb,
215
+ pl110_draw_line16_555_bbbp_rgb,
216
+ pl110_draw_line32_bbbp_rgb,
217
+ pl110_draw_line16_bbbp_rgb,
218
+ pl110_draw_line12_bbbp_rgb,
219
+
220
+ pl110_draw_line1_lbbp_rgb,
221
+ pl110_draw_line2_lbbp_rgb,
222
+ pl110_draw_line4_lbbp_rgb,
223
+ pl110_draw_line8_lbbp_rgb,
224
+ pl110_draw_line16_555_lbbp_rgb,
225
+ pl110_draw_line32_lbbp_rgb,
226
+ pl110_draw_line16_lbbp_rgb,
227
+ pl110_draw_line12_lbbp_rgb,
228
+};
229
230
static int pl110_enabled(PL110State *s)
231
{
232
--
23
--
233
2.20.1
24
2.34.1
234
235
diff view generated by jsdifflib
1
The pl110_template.h header has a doubly-nested multiple-include pattern:
1
Set the default NaN pattern explicitly for SPARC, and remove
2
* pl110.c includes it once for each host bit depth (now always 32)
2
the ifdef from parts64_default_nan.
3
* every time it is included, it includes itself 6 times, to account
4
for multiple guest device pixel and byte orders
5
6
Now we only have to deal with 32-bit host bit depths, we can move the
7
code corresponding to the outer layer of this double-nesting to be
8
directly in pl110.c and reduce the template header to a single layer
9
of nesting.
10
3
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210211141515.8755-3-peter.maydell@linaro.org
6
Message-id: 20241202131347.498124-50-peter.maydell@linaro.org
14
---
7
---
15
hw/display/pl110_template.h | 100 +-----------------------------------
8
target/sparc/cpu.c | 2 ++
16
hw/display/pl110.c | 79 ++++++++++++++++++++++++++++
9
fpu/softfloat-specialize.c.inc | 5 +----
17
2 files changed, 80 insertions(+), 99 deletions(-)
10
2 files changed, 3 insertions(+), 4 deletions(-)
18
11
19
diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/display/pl110_template.h
14
--- a/target/sparc/cpu.c
22
+++ b/hw/display/pl110_template.h
15
+++ b/target/sparc/cpu.c
23
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
24
*/
17
set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
25
18
/* For inf * 0 + NaN, return the input NaN */
26
#ifndef ORDER
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
27
-
20
+ /* Default NaN value: sign bit clear, all frac bits set */
28
-#if BITS == 8
21
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
29
-#define COPY_PIXEL(to, from) *(to++) = from
22
30
-#elif BITS == 15 || BITS == 16
23
cpu_exec_realizefn(cs, &local_err);
31
-#define COPY_PIXEL(to, from) do { *(uint16_t *)to = from; to += 2; } while (0)
24
if (local_err != NULL) {
32
-#elif BITS == 24
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
33
-#define COPY_PIXEL(to, from) \
34
- do { \
35
- *(to++) = from; \
36
- *(to++) = (from) >> 8; \
37
- *(to++) = (from) >> 16; \
38
- } while (0)
39
-#elif BITS == 32
40
-#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
41
-#else
42
-#error unknown bit depth
43
+#error "pl110_template.h is only for inclusion by pl110.c"
44
#endif
45
46
-#undef RGB
47
-#define BORDER bgr
48
-#define ORDER 0
49
-#include "pl110_template.h"
50
-#define ORDER 1
51
-#include "pl110_template.h"
52
-#define ORDER 2
53
-#include "pl110_template.h"
54
-#undef BORDER
55
-#define RGB
56
-#define BORDER rgb
57
-#define ORDER 0
58
-#include "pl110_template.h"
59
-#define ORDER 1
60
-#include "pl110_template.h"
61
-#define ORDER 2
62
-#include "pl110_template.h"
63
-#undef BORDER
64
-
65
-static drawfn glue(pl110_draw_fn_,BITS)[48] =
66
-{
67
- glue(pl110_draw_line1_lblp_bgr,BITS),
68
- glue(pl110_draw_line2_lblp_bgr,BITS),
69
- glue(pl110_draw_line4_lblp_bgr,BITS),
70
- glue(pl110_draw_line8_lblp_bgr,BITS),
71
- glue(pl110_draw_line16_555_lblp_bgr,BITS),
72
- glue(pl110_draw_line32_lblp_bgr,BITS),
73
- glue(pl110_draw_line16_lblp_bgr,BITS),
74
- glue(pl110_draw_line12_lblp_bgr,BITS),
75
-
76
- glue(pl110_draw_line1_bbbp_bgr,BITS),
77
- glue(pl110_draw_line2_bbbp_bgr,BITS),
78
- glue(pl110_draw_line4_bbbp_bgr,BITS),
79
- glue(pl110_draw_line8_bbbp_bgr,BITS),
80
- glue(pl110_draw_line16_555_bbbp_bgr,BITS),
81
- glue(pl110_draw_line32_bbbp_bgr,BITS),
82
- glue(pl110_draw_line16_bbbp_bgr,BITS),
83
- glue(pl110_draw_line12_bbbp_bgr,BITS),
84
-
85
- glue(pl110_draw_line1_lbbp_bgr,BITS),
86
- glue(pl110_draw_line2_lbbp_bgr,BITS),
87
- glue(pl110_draw_line4_lbbp_bgr,BITS),
88
- glue(pl110_draw_line8_lbbp_bgr,BITS),
89
- glue(pl110_draw_line16_555_lbbp_bgr,BITS),
90
- glue(pl110_draw_line32_lbbp_bgr,BITS),
91
- glue(pl110_draw_line16_lbbp_bgr,BITS),
92
- glue(pl110_draw_line12_lbbp_bgr,BITS),
93
-
94
- glue(pl110_draw_line1_lblp_rgb,BITS),
95
- glue(pl110_draw_line2_lblp_rgb,BITS),
96
- glue(pl110_draw_line4_lblp_rgb,BITS),
97
- glue(pl110_draw_line8_lblp_rgb,BITS),
98
- glue(pl110_draw_line16_555_lblp_rgb,BITS),
99
- glue(pl110_draw_line32_lblp_rgb,BITS),
100
- glue(pl110_draw_line16_lblp_rgb,BITS),
101
- glue(pl110_draw_line12_lblp_rgb,BITS),
102
-
103
- glue(pl110_draw_line1_bbbp_rgb,BITS),
104
- glue(pl110_draw_line2_bbbp_rgb,BITS),
105
- glue(pl110_draw_line4_bbbp_rgb,BITS),
106
- glue(pl110_draw_line8_bbbp_rgb,BITS),
107
- glue(pl110_draw_line16_555_bbbp_rgb,BITS),
108
- glue(pl110_draw_line32_bbbp_rgb,BITS),
109
- glue(pl110_draw_line16_bbbp_rgb,BITS),
110
- glue(pl110_draw_line12_bbbp_rgb,BITS),
111
-
112
- glue(pl110_draw_line1_lbbp_rgb,BITS),
113
- glue(pl110_draw_line2_lbbp_rgb,BITS),
114
- glue(pl110_draw_line4_lbbp_rgb,BITS),
115
- glue(pl110_draw_line8_lbbp_rgb,BITS),
116
- glue(pl110_draw_line16_555_lbbp_rgb,BITS),
117
- glue(pl110_draw_line32_lbbp_rgb,BITS),
118
- glue(pl110_draw_line16_lbbp_rgb,BITS),
119
- glue(pl110_draw_line12_lbbp_rgb,BITS),
120
-};
121
-
122
-#undef BITS
123
-#undef COPY_PIXEL
124
-
125
-#else
126
-
127
#if ORDER == 0
128
#define NAME glue(glue(lblp_, BORDER), BITS)
129
#ifdef HOST_WORDS_BIGENDIAN
130
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_
131
#undef NAME
132
#undef SWAP_WORDS
133
#undef ORDER
134
-
135
-#endif
136
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
137
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
138
--- a/hw/display/pl110.c
27
--- a/fpu/softfloat-specialize.c.inc
139
+++ b/hw/display/pl110.c
28
+++ b/fpu/softfloat-specialize.c.inc
140
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
141
};
30
uint8_t dnan_pattern = status->default_nan_pattern;
142
31
143
#define BITS 32
32
if (dnan_pattern == 0) {
144
+#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
33
-#if defined(TARGET_SPARC)
145
+
34
- /* Sign bit clear, all frac bits set */
146
+#undef RGB
35
- dnan_pattern = 0b01111111;
147
+#define BORDER bgr
36
-#elif defined(TARGET_HEXAGON)
148
+#define ORDER 0
37
+#if defined(TARGET_HEXAGON)
149
#include "pl110_template.h"
38
/* Sign bit set, all frac bits set. */
150
+#define ORDER 1
39
dnan_pattern = 0b11111111;
151
+#include "pl110_template.h"
40
#else
152
+#define ORDER 2
153
+#include "pl110_template.h"
154
+#undef BORDER
155
+#define RGB
156
+#define BORDER rgb
157
+#define ORDER 0
158
+#include "pl110_template.h"
159
+#define ORDER 1
160
+#include "pl110_template.h"
161
+#define ORDER 2
162
+#include "pl110_template.h"
163
+#undef BORDER
164
+
165
+static drawfn pl110_draw_fn_32[48] = {
166
+ pl110_draw_line1_lblp_bgr32,
167
+ pl110_draw_line2_lblp_bgr32,
168
+ pl110_draw_line4_lblp_bgr32,
169
+ pl110_draw_line8_lblp_bgr32,
170
+ pl110_draw_line16_555_lblp_bgr32,
171
+ pl110_draw_line32_lblp_bgr32,
172
+ pl110_draw_line16_lblp_bgr32,
173
+ pl110_draw_line12_lblp_bgr32,
174
+
175
+ pl110_draw_line1_bbbp_bgr32,
176
+ pl110_draw_line2_bbbp_bgr32,
177
+ pl110_draw_line4_bbbp_bgr32,
178
+ pl110_draw_line8_bbbp_bgr32,
179
+ pl110_draw_line16_555_bbbp_bgr32,
180
+ pl110_draw_line32_bbbp_bgr32,
181
+ pl110_draw_line16_bbbp_bgr32,
182
+ pl110_draw_line12_bbbp_bgr32,
183
+
184
+ pl110_draw_line1_lbbp_bgr32,
185
+ pl110_draw_line2_lbbp_bgr32,
186
+ pl110_draw_line4_lbbp_bgr32,
187
+ pl110_draw_line8_lbbp_bgr32,
188
+ pl110_draw_line16_555_lbbp_bgr32,
189
+ pl110_draw_line32_lbbp_bgr32,
190
+ pl110_draw_line16_lbbp_bgr32,
191
+ pl110_draw_line12_lbbp_bgr32,
192
+
193
+ pl110_draw_line1_lblp_rgb32,
194
+ pl110_draw_line2_lblp_rgb32,
195
+ pl110_draw_line4_lblp_rgb32,
196
+ pl110_draw_line8_lblp_rgb32,
197
+ pl110_draw_line16_555_lblp_rgb32,
198
+ pl110_draw_line32_lblp_rgb32,
199
+ pl110_draw_line16_lblp_rgb32,
200
+ pl110_draw_line12_lblp_rgb32,
201
+
202
+ pl110_draw_line1_bbbp_rgb32,
203
+ pl110_draw_line2_bbbp_rgb32,
204
+ pl110_draw_line4_bbbp_rgb32,
205
+ pl110_draw_line8_bbbp_rgb32,
206
+ pl110_draw_line16_555_bbbp_rgb32,
207
+ pl110_draw_line32_bbbp_rgb32,
208
+ pl110_draw_line16_bbbp_rgb32,
209
+ pl110_draw_line12_bbbp_rgb32,
210
+
211
+ pl110_draw_line1_lbbp_rgb32,
212
+ pl110_draw_line2_lbbp_rgb32,
213
+ pl110_draw_line4_lbbp_rgb32,
214
+ pl110_draw_line8_lbbp_rgb32,
215
+ pl110_draw_line16_555_lbbp_rgb32,
216
+ pl110_draw_line32_lbbp_rgb32,
217
+ pl110_draw_line16_lbbp_rgb32,
218
+ pl110_draw_line12_lbbp_rgb32,
219
+};
220
+
221
+#undef BITS
222
+#undef COPY_PIXEL
223
+
224
225
static int pl110_enabled(PL110State *s)
226
{
227
--
41
--
228
2.20.1
42
2.34.1
229
230
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Set the default NaN pattern explicitly for xtensa.
2
2
3
With -Werror=maybe-uninitialized configuration we get
4
../hw/i386/intel_iommu.c: In function ‘vtd_context_device_invalidate’:
5
../hw/i386/intel_iommu.c:1888:10: error: ‘mask’ may be used
6
uninitialized in this function [-Werror=maybe-uninitialized]
7
1888 | mask = ~mask;
8
| ~~~~~^~~~~~~
9
10
Add a g_assert_not_reached() to avoid the error.
11
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Peter Xu <peterx@redhat.com>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Message-id: 20210309102742.30442-2-eric.auger@redhat.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-51-peter.maydell@linaro.org
17
---
6
---
18
hw/i386/intel_iommu.c | 2 ++
7
target/xtensa/cpu.c | 2 ++
19
1 file changed, 2 insertions(+)
8
1 file changed, 2 insertions(+)
20
9
21
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
10
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
22
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/i386/intel_iommu.c
12
--- a/target/xtensa/cpu.c
24
+++ b/hw/i386/intel_iommu.c
13
+++ b/target/xtensa/cpu.c
25
@@ -XXX,XX +XXX,XX @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
14
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
26
case 3:
15
/* For inf * 0 + NaN, return the input NaN */
27
mask = 7; /* Mask bit 2:0 in the SID field */
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
28
break;
17
set_no_signaling_nans(!dfpu, &env->fp_status);
29
+ default:
18
+ /* Default NaN value: sign bit clear, set frac msb */
30
+ g_assert_not_reached();
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
31
}
20
xtensa_use_first_nan(env, !dfpu);
32
mask = ~mask;
21
}
33
22
34
--
23
--
35
2.20.1
24
2.34.1
36
37
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
Set the default NaN pattern explicitly for hexagon.
2
Remove the ifdef from parts64_default_nan(); the only
3
remaining unconverted targets all use the default case.
2
4
3
The virt machine already checks KVM_CAP_ARM_VM_IPA_SIZE to get the
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
upper bound of the IPA size. If that bound is lower than the highest
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
possible GPA for the machine, then QEMU will error out. However, the
7
Message-id: 20241202131347.498124-52-peter.maydell@linaro.org
6
IPA is set to 40 when the highest GPA is less than or equal to 40,
8
---
7
even when KVM may support an IPA limit as low as 32. This means KVM
9
target/hexagon/cpu.c | 2 ++
8
may fail the VM creation unnecessarily. Additionally, 40 is selected
10
fpu/softfloat-specialize.c.inc | 5 -----
9
with the value 0, which means use the default, and that gets around
11
2 files changed, 2 insertions(+), 5 deletions(-)
10
a check in some versions of KVM, causing a difficult to debug fail.
11
Always use the IPA size that corresponds to the highest possible GPA,
12
unless it's lower than 32, in which case use 32. Also, we must still
13
use 0 when KVM only supports the legacy fixed 40 bit IPA.
14
12
15
Suggested-by: Marc Zyngier <maz@kernel.org>
13
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
16
Signed-off-by: Andrew Jones <drjones@redhat.com>
17
Reviewed-by: Eric Auger <eric.auger@redhat.com>
18
Reviewed-by: Marc Zyngier <maz@kernel.org>
19
Message-id: 20210310135218.255205-3-drjones@redhat.com
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
target/arm/kvm_arm.h | 6 ++++--
23
hw/arm/virt.c | 23 ++++++++++++++++-------
24
target/arm/kvm.c | 4 +++-
25
3 files changed, 23 insertions(+), 10 deletions(-)
26
27
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
28
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/kvm_arm.h
15
--- a/target/hexagon/cpu.c
30
+++ b/target/arm/kvm_arm.h
16
+++ b/target/hexagon/cpu.c
31
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_sve_supported(void);
17
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
32
/**
18
33
* kvm_arm_get_max_vm_ipa_size:
19
set_default_nan_mode(1, &env->fp_status);
34
* @ms: Machine state handle
20
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
35
+ * @fixed_ipa: True when the IPA limit is fixed at 40. This is the case
21
+ /* Default NaN value: sign bit set, all frac bits set */
36
+ * for legacy KVM.
22
+ set_float_default_nan_pattern(0b11111111, &env->fp_status);
37
*
38
* Returns the number of bits in the IPA address space supported by KVM
39
*/
40
-int kvm_arm_get_max_vm_ipa_size(MachineState *ms);
41
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa);
42
43
/**
44
* kvm_arm_sync_mpstate_to_kvm:
45
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_add_vcpu_properties(Object *obj)
46
g_assert_not_reached();
47
}
23
}
48
24
49
-static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
25
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
50
+static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa)
26
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
51
{
52
g_assert_not_reached();
53
}
54
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
55
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/virt.c
28
--- a/fpu/softfloat-specialize.c.inc
57
+++ b/hw/arm/virt.c
29
+++ b/fpu/softfloat-specialize.c.inc
58
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
30
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
59
static int virt_kvm_type(MachineState *ms, const char *type_str)
31
uint8_t dnan_pattern = status->default_nan_pattern;
60
{
32
61
VirtMachineState *vms = VIRT_MACHINE(ms);
33
if (dnan_pattern == 0) {
62
- int max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms);
34
-#if defined(TARGET_HEXAGON)
63
- int requested_pa_size;
35
- /* Sign bit set, all frac bits set. */
64
+ int max_vm_pa_size, requested_pa_size;
36
- dnan_pattern = 0b11111111;
65
+ bool fixed_ipa;
37
-#else
66
+
38
/*
67
+ max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms, &fixed_ipa);
39
* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
68
40
* S390, SH4, TriCore, and Xtensa. Our other supported targets
69
/* we freeze the memory map to compute the highest gpa */
41
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
70
virt_set_memmap(vms);
42
/* sign bit clear, set frac msb */
71
43
dnan_pattern = 0b01000000;
72
requested_pa_size = 64 - clz64(vms->highest_gpa);
44
}
73
45
-#endif
74
+ /*
75
+ * KVM requires the IPA size to be at least 32 bits.
76
+ */
77
+ if (requested_pa_size < 32) {
78
+ requested_pa_size = 32;
79
+ }
80
+
81
if (requested_pa_size > max_vm_pa_size) {
82
error_report("-m and ,maxmem option values "
83
"require an IPA range (%d bits) larger than "
84
"the one supported by the host (%d bits)",
85
requested_pa_size, max_vm_pa_size);
86
- exit(1);
87
+ exit(1);
88
}
46
}
89
/*
47
assert(dnan_pattern != 0);
90
- * By default we return 0 which corresponds to an implicit legacy
91
- * 40b IPA setting. Otherwise we return the actual requested PA
92
- * logsize
93
+ * We return the requested PA log size, unless KVM only supports
94
+ * the implicit legacy 40b IPA setting, in which case the kvm_type
95
+ * must be 0.
96
*/
97
- return requested_pa_size > 40 ? requested_pa_size : 0;
98
+ return fixed_ipa ? 0 : requested_pa_size;
99
}
100
101
static void virt_machine_class_init(ObjectClass *oc, void *data)
102
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/kvm.c
105
+++ b/target/arm/kvm.c
106
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_pmu_supported(void)
107
return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3);
108
}
109
110
-int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
111
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa)
112
{
113
KVMState *s = KVM_STATE(ms->accelerator);
114
int ret;
115
116
ret = kvm_check_extension(s, KVM_CAP_ARM_VM_IPA_SIZE);
117
+ *fixed_ipa = ret <= 0;
118
+
119
return ret > 0 ? ret : 40;
120
}
121
48
122
--
49
--
123
2.20.1
50
2.34.1
124
125
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
Set the default NaN pattern explicitly for riscv.
2
2
3
Previously the ARMBIAN_ARTIFACTS_CACHED pre-condition was added to allow running
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
tests that have already existing armbian.com artifacts stored in the local avocado cache,
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
but do not have working URLs to download a fresh copy.
5
Message-id: 20241202131347.498124-53-peter.maydell@linaro.org
6
---
7
target/riscv/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
6
9
7
At this time of writing the URLs for artifacts on the armbian.com server are updated and working.
10
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
8
Any future broken URLs will result in a skipped acceptance test, for example:
9
10
(1/5) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi:
11
CANCEL: Missing asset https://apt.armbian.com/pool/main/l/linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb (0.53 s)
12
13
This commits removes the ARMBIAN_ARTIFACTS_CACHED pre-condition such that
14
the acceptance tests for the orangepi-pc and cubieboard machines can run.
15
16
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
17
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
18
Message-id: 20210310195820.21950-6-nieklinnenbank@gmail.com
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
tests/acceptance/boot_linux_console.py | 12 ------------
22
tests/acceptance/replay_kernel.py | 2 --
23
2 files changed, 14 deletions(-)
24
25
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
26
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/acceptance/boot_linux_console.py
12
--- a/target/riscv/cpu.c
28
+++ b/tests/acceptance/boot_linux_console.py
13
+++ b/target/riscv/cpu.c
29
@@ -XXX,XX +XXX,XX @@ def test_arm_exynos4210_initrd(self):
14
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
30
self.wait_for_console_pattern('Boot successful.')
15
cs->exception_index = RISCV_EXCP_NONE;
31
# TODO user command, for now the uart is stuck
16
env->load_res = -1;
32
17
set_default_nan_mode(1, &env->fp_status);
33
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
18
+ /* Default NaN value: sign bit clear, frac msb set */
34
- 'Test artifacts fetched from unreliable apt.armbian.com')
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
35
def test_arm_cubieboard_initrd(self):
20
env->vill = true;
36
"""
21
37
:avocado: tags=arch:arm
22
#ifndef CONFIG_USER_ONLY
38
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
39
'system-control@1c00000')
40
# cubieboard's reboot is not functioning; omit reboot test.
41
42
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
43
- 'Test artifacts fetched from unreliable apt.armbian.com')
44
def test_arm_cubieboard_sata(self):
45
"""
46
:avocado: tags=arch:arm
47
@@ -XXX,XX +XXX,XX @@ def test_arm_quanta_gsj_initrd(self):
48
self.wait_for_console_pattern(
49
'Give root password for system maintenance')
50
51
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
52
- 'Test artifacts fetched from unreliable apt.armbian.com')
53
def test_arm_orangepi(self):
54
"""
55
:avocado: tags=arch:arm
56
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi(self):
57
console_pattern = 'Kernel command line: %s' % kernel_command_line
58
self.wait_for_console_pattern(console_pattern)
59
60
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
61
- 'Test artifacts fetched from unreliable apt.armbian.com')
62
def test_arm_orangepi_initrd(self):
63
"""
64
:avocado: tags=arch:arm
65
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_initrd(self):
66
# Wait for VM to shut down gracefully
67
self.vm.wait()
68
69
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
70
- 'Test artifacts fetched from unreliable apt.armbian.com')
71
def test_arm_orangepi_sd(self):
72
"""
73
:avocado: tags=arch:arm
74
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
75
# Wait for VM to shut down gracefully
76
self.vm.wait()
77
78
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
79
- 'Test artifacts fetched from unreliable apt.armbian.com')
80
@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
81
def test_arm_orangepi_bionic_20_08(self):
82
"""
83
diff --git a/tests/acceptance/replay_kernel.py b/tests/acceptance/replay_kernel.py
84
index XXXXXXX..XXXXXXX 100644
85
--- a/tests/acceptance/replay_kernel.py
86
+++ b/tests/acceptance/replay_kernel.py
87
@@ -XXX,XX +XXX,XX @@ def test_arm_virt(self):
88
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=1)
89
90
@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
91
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
92
- 'Test artifacts fetched from unreliable apt.armbian.com')
93
def test_arm_cubieboard_initrd(self):
94
"""
95
:avocado: tags=arch:arm
96
--
23
--
97
2.20.1
24
2.34.1
98
99
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Set the default NaN pattern explicitly for tricore.
2
2
3
Unmap notifiers work with an address mask assuming an
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
invalidation range of a power of 2. Nothing mandates this
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
in the VIRTIO-IOMMU spec.
5
Message-id: 20241202131347.498124-54-peter.maydell@linaro.org
6
---
7
target/tricore/helper.c | 2 ++
8
1 file changed, 2 insertions(+)
6
9
7
So in case the range is not a power of 2, split it into
10
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
8
several invalidations.
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Peter Xu <peterx@redhat.com>
12
Message-id: 20210309102742.30442-4-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/virtio/virtio-iommu.c | 19 ++++++++++++++++---
16
1 file changed, 16 insertions(+), 3 deletions(-)
17
18
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
19
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/virtio/virtio-iommu.c
12
--- a/target/tricore/helper.c
21
+++ b/hw/virtio/virtio-iommu.c
13
+++ b/target/tricore/helper.c
22
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start,
14
@@ -XXX,XX +XXX,XX @@ void fpu_set_state(CPUTriCoreState *env)
23
hwaddr virt_end)
15
set_flush_to_zero(1, &env->fp_status);
24
{
16
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
25
IOMMUTLBEvent event;
17
set_default_nan_mode(1, &env->fp_status);
26
+ uint64_t delta = virt_end - virt_start;
18
+ /* Default NaN pattern: sign bit clear, frac msb set */
27
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
28
if (!(mr->iommu_notify_flags & IOMMU_NOTIFIER_UNMAP)) {
29
return;
30
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start,
31
32
event.type = IOMMU_NOTIFIER_UNMAP;
33
event.entry.target_as = &address_space_memory;
34
- event.entry.addr_mask = virt_end - virt_start;
35
- event.entry.iova = virt_start;
36
event.entry.perm = IOMMU_NONE;
37
event.entry.translated_addr = 0;
38
+ event.entry.addr_mask = delta;
39
+ event.entry.iova = virt_start;
40
41
- memory_region_notify_iommu(mr, 0, event);
42
+ if (delta == UINT64_MAX) {
43
+ memory_region_notify_iommu(mr, 0, event);
44
+ }
45
+
46
+
47
+ while (virt_start != virt_end + 1) {
48
+ uint64_t mask = dma_aligned_pow2_mask(virt_start, virt_end, 64);
49
+
50
+ event.entry.addr_mask = mask;
51
+ event.entry.iova = virt_start;
52
+ memory_region_notify_iommu(mr, 0, event);
53
+ virt_start += mask + 1;
54
+ }
55
}
20
}
56
21
57
static gboolean virtio_iommu_notify_unmap_cb(gpointer key, gpointer value,
22
uint32_t psw_read(CPUTriCoreState *env)
58
--
23
--
59
2.20.1
24
2.34.1
60
61
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
Now that all our targets have bene converted to explicitly specify
2
their pattern for the default NaN value we can remove the remaining
3
fallback code in parts64_default_nan().
2
4
3
The linux kernel 4.20.7 binary for sunxi has been removed from apt.armbian.com:
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-55-peter.maydell@linaro.org
8
---
9
fpu/softfloat-specialize.c.inc | 14 --------------
10
1 file changed, 14 deletions(-)
4
11
5
$ ARMBIAN_ARTIFACTS_CACHED=yes AVOCADO_ALLOW_LARGE_STORAGE=yes avocado --show=app,console run -t machine:orangepi-pc tests/acceptance/boot_linux_console.py
12
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
6
Fetching asset from tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi
7
...
8
(1/6) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi:
9
CANCEL: Missing asset https://apt.armbian.com/pool/main/l/linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb (0.55 s)
10
11
This commit updates the sunxi kernel to 5.10.16 for the acceptance
12
tests of the orangepi-pc and cubieboard machines.
13
14
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
15
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
16
Message-id: 20210310195820.21950-5-nieklinnenbank@gmail.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
tests/acceptance/boot_linux_console.py | 40 +++++++++++++-------------
20
tests/acceptance/replay_kernel.py | 8 +++---
21
2 files changed, 24 insertions(+), 24 deletions(-)
22
23
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
24
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
25
--- a/tests/acceptance/boot_linux_console.py
14
--- a/fpu/softfloat-specialize.c.inc
26
+++ b/tests/acceptance/boot_linux_console.py
15
+++ b/fpu/softfloat-specialize.c.inc
27
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
16
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
28
:avocado: tags=machine:cubieboard
17
uint64_t frac;
29
"""
18
uint8_t dnan_pattern = status->default_nan_pattern;
30
deb_url = ('https://apt.armbian.com/pool/main/l/'
19
31
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
20
- if (dnan_pattern == 0) {
32
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
21
- /*
33
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
22
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
34
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
23
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
35
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
24
- * do not have floating-point.
36
kernel_path = self.extract_from_deb(deb_path,
25
- */
37
- '/boot/vmlinuz-4.20.7-sunxi')
26
- if (snan_bit_is_one(status)) {
38
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
27
- /* sign bit clear, set all frac bits other than msb */
39
+ '/boot/vmlinuz-5.10.16-sunxi')
28
- dnan_pattern = 0b00111111;
40
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
29
- } else {
41
dtb_path = self.extract_from_deb(deb_path, dtb_path)
30
- /* sign bit clear, set frac msb */
42
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
31
- dnan_pattern = 0b01000000;
43
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
32
- }
44
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_sata(self):
33
- }
45
:avocado: tags=machine:cubieboard
34
assert(dnan_pattern != 0);
46
"""
35
47
deb_url = ('https://apt.armbian.com/pool/main/l/'
36
sign = dnan_pattern >> 7;
48
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
49
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
50
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
51
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
52
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
53
kernel_path = self.extract_from_deb(deb_path,
54
- '/boot/vmlinuz-4.20.7-sunxi')
55
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
56
+ '/boot/vmlinuz-5.10.16-sunxi')
57
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
58
dtb_path = self.extract_from_deb(deb_path, dtb_path)
59
rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
60
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
61
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi(self):
62
:avocado: tags=machine:orangepi-pc
63
"""
64
deb_url = ('https://apt.armbian.com/pool/main/l/'
65
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
66
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
67
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
68
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
69
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
70
kernel_path = self.extract_from_deb(deb_path,
71
- '/boot/vmlinuz-4.20.7-sunxi')
72
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
73
+ '/boot/vmlinuz-5.10.16-sunxi')
74
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
75
dtb_path = self.extract_from_deb(deb_path, dtb_path)
76
77
self.vm.set_console()
78
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_initrd(self):
79
:avocado: tags=machine:orangepi-pc
80
"""
81
deb_url = ('https://apt.armbian.com/pool/main/l/'
82
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
83
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
84
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
85
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
86
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
87
kernel_path = self.extract_from_deb(deb_path,
88
- '/boot/vmlinuz-4.20.7-sunxi')
89
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
90
+ '/boot/vmlinuz-5.10.16-sunxi')
91
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
92
dtb_path = self.extract_from_deb(deb_path, dtb_path)
93
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
94
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
95
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
96
:avocado: tags=device:sd
97
"""
98
deb_url = ('https://apt.armbian.com/pool/main/l/'
99
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
100
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
101
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
102
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
103
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
104
kernel_path = self.extract_from_deb(deb_path,
105
- '/boot/vmlinuz-4.20.7-sunxi')
106
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
107
+ '/boot/vmlinuz-5.10.16-sunxi')
108
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
109
dtb_path = self.extract_from_deb(deb_path, dtb_path)
110
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
111
'kci-2019.02/armel/base/rootfs.ext2.xz')
112
diff --git a/tests/acceptance/replay_kernel.py b/tests/acceptance/replay_kernel.py
113
index XXXXXXX..XXXXXXX 100644
114
--- a/tests/acceptance/replay_kernel.py
115
+++ b/tests/acceptance/replay_kernel.py
116
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
117
:avocado: tags=machine:cubieboard
118
"""
119
deb_url = ('https://apt.armbian.com/pool/main/l/'
120
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
121
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
122
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
123
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
124
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
125
kernel_path = self.extract_from_deb(deb_path,
126
- '/boot/vmlinuz-4.20.7-sunxi')
127
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
128
+ '/boot/vmlinuz-5.10.16-sunxi')
129
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
130
dtb_path = self.extract_from_deb(deb_path, dtb_path)
131
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
132
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
133
--
37
--
134
2.20.1
38
2.34.1
135
136
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 adds GPIOs in NPCM7xx PWM module for its duty values.
3
Inline pickNaNMulAdd into its only caller. This makes
4
The purpose of this is to connect it to the MFT module to provide
4
one assert redundant with the immediately preceding IF.
5
an input for measuring a PWM fan's RPM. Each PWM module has
6
NPCM7XX_PWM_PER_MODULE of GPIOs, each one corresponds to
7
one PWM instance and can connect to multiple fan instances in MFT.
8
5
9
Reviewed-by: Doug Evans <dje@google.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Signed-off-by: Hao Wu <wuhaotsh@google.com>
8
Message-id: 20241203203949.483774-3-richard.henderson@linaro.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
[PMM: keep comment from old code in new location]
13
Message-id: 20210311180855.149764-2-wuhaotsh@google.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
11
---
16
include/hw/misc/npcm7xx_pwm.h | 4 +++-
12
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
17
hw/misc/npcm7xx_pwm.c | 4 ++++
13
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
18
2 files changed, 7 insertions(+), 1 deletion(-)
14
2 files changed, 40 insertions(+), 55 deletions(-)
19
15
20
diff --git a/include/hw/misc/npcm7xx_pwm.h b/include/hw/misc/npcm7xx_pwm.h
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/misc/npcm7xx_pwm.h
18
--- a/fpu/softfloat-parts.c.inc
23
+++ b/include/hw/misc/npcm7xx_pwm.h
19
+++ b/fpu/softfloat-parts.c.inc
24
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxPWM {
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
25
* @iomem: Memory region through which registers are accessed.
21
}
26
* @clock: The PWM clock.
22
27
* @pwm: The PWM channels owned by this module.
23
if (s->default_nan_mode) {
28
+ * @duty_gpio_out: The duty cycle of each PWM channels as a output GPIO.
24
+ /*
29
* @ppr: The prescaler register.
25
+ * We guarantee not to require the target to tell us how to
30
* @csr: The clock selector register.
26
+ * pick a NaN if we're always returning the default NaN.
31
* @pcr: The control register.
27
+ * But if we're not in default-NaN mode then the target must
32
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxPWMState {
28
+ * specify.
33
MemoryRegion iomem;
29
+ */
34
30
which = 3;
35
Clock *clock;
31
+ } else if (infzero) {
36
- NPCM7xxPWM pwm[NPCM7XX_PWM_PER_MODULE];
32
+ /*
37
+ NPCM7xxPWM pwm[NPCM7XX_PWM_PER_MODULE];
33
+ * Inf * 0 + NaN -- some implementations return the
38
+ qemu_irq duty_gpio_out[NPCM7XX_PWM_PER_MODULE];
34
+ * default NaN here, and some return the input NaN.
39
35
+ */
40
uint32_t ppr;
36
+ switch (s->float_infzeronan_rule) {
41
uint32_t csr;
37
+ case float_infzeronan_dnan_never:
42
diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c
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
43
index XXXXXXX..XXXXXXX 100644
71
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/misc/npcm7xx_pwm.c
72
--- a/fpu/softfloat-specialize.c.inc
45
+++ b/hw/misc/npcm7xx_pwm.c
73
+++ b/fpu/softfloat-specialize.c.inc
46
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_update_duty(NPCM7xxPWM *p)
74
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
47
trace_npcm7xx_pwm_update_duty(DEVICE(p->module)->canonical_path,
48
p->index, p->duty, duty);
49
p->duty = duty;
50
+ qemu_set_irq(p->module->duty_gpio_out[p->index], p->duty);
51
}
75
}
52
}
76
}
53
77
54
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_init(Object *obj)
78
-/*----------------------------------------------------------------------------
55
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
79
-| Select which NaN to propagate for a three-input operation.
56
int i;
80
-| For the moment we assume that no CPU needs the 'larger significand'
57
81
-| information.
58
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->pwm) != NPCM7XX_PWM_PER_MODULE);
82
-| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
59
for (i = 0; i < NPCM7XX_PWM_PER_MODULE; i++) {
83
-*----------------------------------------------------------------------------*/
60
NPCM7xxPWM *p = &s->pwm[i];
84
-static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
61
p->module = s;
85
- bool infzero, bool have_snan, float_status *status)
62
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_init(Object *obj)
86
-{
63
object_property_add_uint32_ptr(obj, "duty[*]",
87
- FloatClass cls[3] = { a_cls, b_cls, c_cls };
64
&s->pwm[i].duty, OBJ_PROP_FLAG_READ);
88
- Float3NaNPropRule rule = status->float_3nan_prop_rule;
65
}
89
- int which;
66
+ qdev_init_gpio_out_named(DEVICE(s), s->duty_gpio_out,
90
-
67
+ "duty-gpio-out", NPCM7XX_PWM_PER_MODULE);
91
- /*
68
}
92
- * We guarantee not to require the target to tell us how to
69
93
- * pick a NaN if we're always returning the default NaN.
70
static const VMStateDescription vmstate_npcm7xx_pwm = {
94
- * But if we're not in default-NaN mode then the target must
95
- * specify.
96
- */
97
- assert(!status->default_nan_mode);
98
-
99
- if (infzero) {
100
- /*
101
- * Inf * 0 + NaN -- some implementations return the default NaN here,
102
- * and some return the input NaN.
103
- */
104
- switch (status->float_infzeronan_rule) {
105
- case float_infzeronan_dnan_never:
106
- return 2;
107
- case float_infzeronan_dnan_always:
108
- return 3;
109
- case float_infzeronan_dnan_if_qnan:
110
- return is_qnan(c_cls) ? 3 : 2;
111
- default:
112
- g_assert_not_reached();
113
- }
114
- }
115
-
116
- assert(rule != float_3nan_prop_none);
117
- if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
118
- /* We have at least one SNaN input and should prefer it */
119
- do {
120
- which = rule & R_3NAN_1ST_MASK;
121
- rule >>= R_3NAN_1ST_LENGTH;
122
- } while (!is_snan(cls[which]));
123
- } else {
124
- do {
125
- which = rule & R_3NAN_1ST_MASK;
126
- rule >>= R_3NAN_1ST_LENGTH;
127
- } while (!is_nan(cls[which]));
128
- }
129
- return which;
130
-}
131
-
132
/*----------------------------------------------------------------------------
133
| Returns 1 if the double-precision floating-point value `a' is a quiet
134
| NaN; otherwise returns 0.
71
--
135
--
72
2.20.1
136
2.34.1
73
137
74
138
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since b64ee454a4a0, all predicate operations should be
3
Remove "3" as a special case for which and simply
4
using these field macros for predicates.
4
branch to return the desired value.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210309155305.11301-8-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241203203949.483774-4-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
target/arm/sve_helper.c | 4 ++--
11
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
12
target/arm/translate-sve.c | 7 ++++---
12
1 file changed, 10 insertions(+), 10 deletions(-)
13
2 files changed, 6 insertions(+), 5 deletions(-)
14
13
15
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/sve_helper.c
16
--- a/fpu/softfloat-parts.c.inc
18
+++ b/target/arm/sve_helper.c
17
+++ b/fpu/softfloat-parts.c.inc
19
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(sve_cntp)(void *vn, void *vg, uint32_t pred_desc)
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
20
19
* But if we're not in default-NaN mode then the target must
21
uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
20
* specify.
22
{
21
*/
23
- uintptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
22
- which = 3;
24
- intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
23
+ goto default_nan;
25
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
24
} else if (infzero) {
26
+ intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
25
/*
27
uint64_t esz_mask = pred_esz_masks[esz];
26
* Inf * 0 + NaN -- some implementations return the
28
ARMPredicateReg *d = vd;
27
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
29
uint32_t flags;
28
*/
30
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
29
switch (s->float_infzeronan_rule) {
31
index XXXXXXX..XXXXXXX 100644
30
case float_infzeronan_dnan_never:
32
--- a/target/arm/translate-sve.c
31
- which = 2;
33
+++ b/target/arm/translate-sve.c
32
break;
34
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
33
case float_infzeronan_dnan_always:
35
TCGv_i64 op0, op1, t0, t1, tmax;
34
- which = 3;
36
TCGv_i32 t2, t3;
35
- break;
37
TCGv_ptr ptr;
36
+ goto default_nan;
38
- unsigned desc, vsz = vec_full_reg_size(s);
37
case float_infzeronan_dnan_if_qnan:
39
+ unsigned vsz = vec_full_reg_size(s);
38
- which = is_qnan(c->cls) ? 3 : 2;
40
+ unsigned desc = 0;
39
+ if (is_qnan(c->cls)) {
41
TCGCond cond;
40
+ goto default_nan;
42
41
+ }
43
if (!sve_access_check(s)) {
42
break;
44
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
43
default:
45
/* Scale elements to bits. */
44
g_assert_not_reached();
46
tcg_gen_shli_i32(t2, t2, a->esz);
45
}
47
46
+ which = 2;
48
- desc = (vsz / 8) - 2;
47
} else {
49
- desc = deposit32(desc, SIMD_DATA_SHIFT, 2, a->esz);
48
FloatClass cls[3] = { a->cls, b->cls, c->cls };
50
+ desc = FIELD_DP32(desc, PREDDESC, OPRSZ, vsz / 8);
49
Float3NaNPropRule rule = s->float_3nan_prop_rule;
51
+ desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz);
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
52
t3 = tcg_const_i32(desc);
51
}
53
52
}
54
ptr = tcg_temp_new_ptr();
53
54
- if (which == 3) {
55
- parts_default_nan(a, s);
56
- return a;
57
- }
58
-
59
switch (which) {
60
case 0:
61
break;
62
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
63
parts_silence_nan(a, s);
64
}
65
return a;
66
+
67
+ default_nan:
68
+ parts_default_nan(a, s);
69
+ return a;
70
}
71
72
/*
55
--
73
--
56
2.20.1
74
2.34.1
57
75
58
76
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Missed out on compressing the second half of a predicate
3
Assign the pointer return value to 'a' directly,
4
with length vl % 512 > 256.
4
rather than going through an intermediary index.
5
5
6
Adjust all of the x + (y << s) to x | (y << s) as a
7
general style fix. Drop the extract64 because the input
8
uint64_t are known to be already zero-extended from the
9
current size of the predicate.
10
11
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210309155305.11301-2-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
target/arm/sve_helper.c | 30 +++++++++++++++++++++---------
11
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
18
1 file changed, 21 insertions(+), 9 deletions(-)
12
1 file changed, 10 insertions(+), 22 deletions(-)
19
13
20
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/sve_helper.c
16
--- a/fpu/softfloat-parts.c.inc
23
+++ b/target/arm/sve_helper.c
17
+++ b/fpu/softfloat-parts.c.inc
24
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
25
if (oprsz <= 8) {
19
FloatPartsN *c, float_status *s,
26
l = compress_bits(n[0] >> odd, esz);
20
int ab_mask, int abc_mask)
27
h = compress_bits(m[0] >> odd, esz);
21
{
28
- d[0] = extract64(l + (h << (4 * oprsz)), 0, 8 * oprsz);
22
- int which;
29
+ d[0] = l | (h << (4 * oprsz));
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;
30
} else {
35
} else {
31
ARMPredicateReg tmp_m;
36
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
32
intptr_t oprsz_16 = oprsz / 16;
37
+ FloatPartsN *val[3] = { a, b, c };
33
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
38
Float3NaNPropRule rule = s->float_3nan_prop_rule;
34
h = n[2 * i + 1];
39
35
l = compress_bits(l >> odd, esz);
40
assert(rule != float_3nan_prop_none);
36
h = compress_bits(h >> odd, esz);
41
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
37
- d[i] = l + (h << 32);
42
/* We have at least one SNaN input and should prefer it */
38
+ d[i] = l | (h << 32);
43
do {
39
}
44
- which = rule & R_3NAN_1ST_MASK;
40
45
+ ret = val[rule & R_3NAN_1ST_MASK];
41
- /* For VL which is not a power of 2, the results from M do not
46
rule >>= R_3NAN_1ST_LENGTH;
42
- align nicely with the uint64_t for D. Put the aligned results
47
- } while (!is_snan(cls[which]));
43
- from M into TMP_M and then copy it into place afterward. */
48
+ } while (!is_snan(ret->cls));
44
+ /*
45
+ * For VL which is not a multiple of 512, the results from M do not
46
+ * align nicely with the uint64_t for D. Put the aligned results
47
+ * from M into TMP_M and then copy it into place afterward.
48
+ */
49
if (oprsz & 15) {
50
- d[i] = compress_bits(n[2 * i] >> odd, esz);
51
+ int final_shift = (oprsz & 15) * 2;
52
+
53
+ l = n[2 * i + 0];
54
+ h = n[2 * i + 1];
55
+ l = compress_bits(l >> odd, esz);
56
+ h = compress_bits(h >> odd, esz);
57
+ d[i] = l | (h << final_shift);
58
59
for (i = 0; i < oprsz_16; i++) {
60
l = m[2 * i + 0];
61
h = m[2 * i + 1];
62
l = compress_bits(l >> odd, esz);
63
h = compress_bits(h >> odd, esz);
64
- tmp_m.p[i] = l + (h << 32);
65
+ tmp_m.p[i] = l | (h << 32);
66
}
67
- tmp_m.p[i] = compress_bits(m[2 * i] >> odd, esz);
68
+ l = m[2 * i + 0];
69
+ h = m[2 * i + 1];
70
+ l = compress_bits(l >> odd, esz);
71
+ h = compress_bits(h >> odd, esz);
72
+ tmp_m.p[i] = l | (h << final_shift);
73
74
swap_memmove(vd + oprsz / 2, &tmp_m, oprsz / 2);
75
} else {
49
} else {
76
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
50
do {
77
h = m[2 * i + 1];
51
- which = rule & R_3NAN_1ST_MASK;
78
l = compress_bits(l >> odd, esz);
52
+ ret = val[rule & R_3NAN_1ST_MASK];
79
h = compress_bits(h >> odd, esz);
53
rule >>= R_3NAN_1ST_LENGTH;
80
- d[oprsz_16 + i] = l + (h << 32);
54
- } while (!is_nan(cls[which]));
81
+ d[oprsz_16 + i] = l | (h << 32);
55
+ } while (!is_nan(ret->cls));
82
}
83
}
56
}
84
}
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);
85
--
81
--
86
2.20.1
82
2.34.1
87
83
88
84
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
If the asid is not set, do not attempt to locate the key directly
3
While all indices into val[] should be in [0-2], the mask
4
as all inserted keys have a valid asid.
4
applied is two bits. To help static analysis see there is
5
no possibility of read beyond the end of the array, pad the
6
array to 4 entries, with the final being (implicitly) NULL.
5
7
6
Use g_hash_table_foreach_remove instead.
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Message-id: 20241203203949.483774-6-richard.henderson@linaro.org
9
Message-id: 20210309102742.30442-5-eric.auger@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
hw/arm/smmu-common.c | 2 +-
13
fpu/softfloat-parts.c.inc | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
15
16
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/smmu-common.c
18
--- a/fpu/softfloat-parts.c.inc
19
+++ b/hw/arm/smmu-common.c
19
+++ b/fpu/softfloat-parts.c.inc
20
@@ -XXX,XX +XXX,XX @@ inline void
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
21
smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
21
}
22
uint8_t tg, uint64_t num_pages, uint8_t ttl)
22
ret = c;
23
{
23
} else {
24
- if (ttl && (num_pages == 1)) {
24
- FloatPartsN *val[3] = { a, b, c };
25
+ if (ttl && (num_pages == 1) && (asid >= 0)) {
25
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
26
SMMUIOTLBKey key = smmu_get_iotlb_key(asid, iova, tg, ttl);
26
Float3NaNPropRule rule = s->float_3nan_prop_rule;
27
27
28
g_hash_table_remove(s->iotlb, &key);
28
assert(rule != float_3nan_prop_none);
29
--
29
--
30
2.20.1
30
2.34.1
31
31
32
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since b64ee454a4a0, all predicate operations should be
3
This function is part of the public interface and
4
using these field macros for predicates.
4
is not "specialized" to any target in any way.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210309155305.11301-6-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/sve_helper.c | 30 ++++++++++++++----------------
11
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
12
target/arm/translate-sve.c | 4 ++--
12
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
13
2 files changed, 16 insertions(+), 18 deletions(-)
13
2 files changed, 52 insertions(+), 52 deletions(-)
14
14
15
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/sve_helper.c
17
--- a/fpu/softfloat.c
18
+++ b/target/arm/sve_helper.c
18
+++ b/fpu/softfloat.c
19
@@ -XXX,XX +XXX,XX @@ static uint32_t do_zero(ARMPredicateReg *d, intptr_t oprsz)
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
20
void HELPER(sve_brkpa)(void *vd, void *vn, void *vm, void *vg,
20
*zExpPtr = 1 - shiftCount;
21
uint32_t pred_desc)
22
{
23
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
24
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
25
if (last_active_pred(vn, vg, oprsz)) {
26
compute_brk_z(vd, vm, vg, oprsz, true);
27
} else {
28
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_brkpa)(void *vd, void *vn, void *vm, void *vg,
29
uint32_t HELPER(sve_brkpas)(void *vd, void *vn, void *vm, void *vg,
30
uint32_t pred_desc)
31
{
32
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
33
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
34
if (last_active_pred(vn, vg, oprsz)) {
35
return compute_brks_z(vd, vm, vg, oprsz, true);
36
} else {
37
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_brkpas)(void *vd, void *vn, void *vm, void *vg,
38
void HELPER(sve_brkpb)(void *vd, void *vn, void *vm, void *vg,
39
uint32_t pred_desc)
40
{
41
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
42
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
43
if (last_active_pred(vn, vg, oprsz)) {
44
compute_brk_z(vd, vm, vg, oprsz, false);
45
} else {
46
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_brkpb)(void *vd, void *vn, void *vm, void *vg,
47
uint32_t HELPER(sve_brkpbs)(void *vd, void *vn, void *vm, void *vg,
48
uint32_t pred_desc)
49
{
50
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
51
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
52
if (last_active_pred(vn, vg, oprsz)) {
53
return compute_brks_z(vd, vm, vg, oprsz, false);
54
} else {
55
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_brkpbs)(void *vd, void *vn, void *vm, void *vg,
56
57
void HELPER(sve_brka_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
58
{
59
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
60
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
61
compute_brk_z(vd, vn, vg, oprsz, true);
62
}
21
}
63
22
64
uint32_t HELPER(sve_brkas_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
23
+/*----------------------------------------------------------------------------
65
{
24
+| Takes two extended double-precision floating-point values `a' and `b', one
66
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
25
+| of which is a NaN, and returns the appropriate NaN result. If either `a' or
67
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
26
+| `b' is a signaling NaN, the invalid exception is raised.
68
return compute_brks_z(vd, vn, vg, oprsz, true);
27
+*----------------------------------------------------------------------------*/
28
+
29
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
30
+{
31
+ bool aIsLargerSignificand;
32
+ FloatClass a_cls, b_cls;
33
+
34
+ /* This is not complete, but is good enough for pickNaN. */
35
+ a_cls = (!floatx80_is_any_nan(a)
36
+ ? float_class_normal
37
+ : floatx80_is_signaling_nan(a, status)
38
+ ? float_class_snan
39
+ : float_class_qnan);
40
+ b_cls = (!floatx80_is_any_nan(b)
41
+ ? float_class_normal
42
+ : floatx80_is_signaling_nan(b, status)
43
+ ? float_class_snan
44
+ : float_class_qnan);
45
+
46
+ if (is_snan(a_cls) || is_snan(b_cls)) {
47
+ float_raise(float_flag_invalid, status);
48
+ }
49
+
50
+ if (status->default_nan_mode) {
51
+ return floatx80_default_nan(status);
52
+ }
53
+
54
+ if (a.low < b.low) {
55
+ aIsLargerSignificand = 0;
56
+ } else if (b.low < a.low) {
57
+ aIsLargerSignificand = 1;
58
+ } else {
59
+ aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
60
+ }
61
+
62
+ if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
63
+ if (is_snan(b_cls)) {
64
+ return floatx80_silence_nan(b, status);
65
+ }
66
+ return b;
67
+ } else {
68
+ if (is_snan(a_cls)) {
69
+ return floatx80_silence_nan(a, status);
70
+ }
71
+ return a;
72
+ }
73
+}
74
+
75
/*----------------------------------------------------------------------------
76
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
77
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
78
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
79
index XXXXXXX..XXXXXXX 100644
80
--- a/fpu/softfloat-specialize.c.inc
81
+++ b/fpu/softfloat-specialize.c.inc
82
@@ -XXX,XX +XXX,XX @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
83
return a;
69
}
84
}
70
85
71
void HELPER(sve_brkb_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
86
-/*----------------------------------------------------------------------------
72
{
87
-| Takes two extended double-precision floating-point values `a' and `b', one
73
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
88
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
74
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
89
-| `b' is a signaling NaN, the invalid exception is raised.
75
compute_brk_z(vd, vn, vg, oprsz, false);
90
-*----------------------------------------------------------------------------*/
76
}
77
78
uint32_t HELPER(sve_brkbs_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
79
{
80
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
81
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
82
return compute_brks_z(vd, vn, vg, oprsz, false);
83
}
84
85
void HELPER(sve_brka_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
86
{
87
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
88
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
89
compute_brk_m(vd, vn, vg, oprsz, true);
90
}
91
92
uint32_t HELPER(sve_brkas_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
93
{
94
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
95
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
96
return compute_brks_m(vd, vn, vg, oprsz, true);
97
}
98
99
void HELPER(sve_brkb_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
100
{
101
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
102
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
103
compute_brk_m(vd, vn, vg, oprsz, false);
104
}
105
106
uint32_t HELPER(sve_brkbs_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
107
{
108
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
109
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
110
return compute_brks_m(vd, vn, vg, oprsz, false);
111
}
112
113
void HELPER(sve_brkn)(void *vd, void *vn, void *vg, uint32_t pred_desc)
114
{
115
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
116
-
91
-
117
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
92
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
118
if (!last_active_pred(vn, vg, oprsz)) {
93
-{
119
do_zero(vd, oprsz);
94
- bool aIsLargerSignificand;
120
}
95
- FloatClass a_cls, b_cls;
121
@@ -XXX,XX +XXX,XX @@ static uint32_t predtest_ones(ARMPredicateReg *d, intptr_t oprsz,
122
123
uint32_t HELPER(sve_brkns)(void *vd, void *vn, void *vg, uint32_t pred_desc)
124
{
125
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
126
-
96
-
127
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
97
- /* This is not complete, but is good enough for pickNaN. */
128
if (last_active_pred(vn, vg, oprsz)) {
98
- a_cls = (!floatx80_is_any_nan(a)
129
return predtest_ones(vd, oprsz, -1);
99
- ? float_class_normal
130
} else {
100
- : floatx80_is_signaling_nan(a, status)
131
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
101
- ? float_class_snan
132
index XXXXXXX..XXXXXXX 100644
102
- : float_class_qnan);
133
--- a/target/arm/translate-sve.c
103
- b_cls = (!floatx80_is_any_nan(b)
134
+++ b/target/arm/translate-sve.c
104
- ? float_class_normal
135
@@ -XXX,XX +XXX,XX @@ static bool do_brk3(DisasContext *s, arg_rprr_s *a,
105
- : floatx80_is_signaling_nan(b, status)
136
TCGv_ptr n = tcg_temp_new_ptr();
106
- ? float_class_snan
137
TCGv_ptr m = tcg_temp_new_ptr();
107
- : float_class_qnan);
138
TCGv_ptr g = tcg_temp_new_ptr();
108
-
139
- TCGv_i32 t = tcg_const_i32(vsz - 2);
109
- if (is_snan(a_cls) || is_snan(b_cls)) {
140
+ TCGv_i32 t = tcg_const_i32(FIELD_DP32(0, PREDDESC, OPRSZ, vsz));
110
- float_raise(float_flag_invalid, status);
141
111
- }
142
tcg_gen_addi_ptr(d, cpu_env, pred_full_reg_offset(s, a->rd));
112
-
143
tcg_gen_addi_ptr(n, cpu_env, pred_full_reg_offset(s, a->rn));
113
- if (status->default_nan_mode) {
144
@@ -XXX,XX +XXX,XX @@ static bool do_brk2(DisasContext *s, arg_rpr_s *a,
114
- return floatx80_default_nan(status);
145
TCGv_ptr d = tcg_temp_new_ptr();
115
- }
146
TCGv_ptr n = tcg_temp_new_ptr();
116
-
147
TCGv_ptr g = tcg_temp_new_ptr();
117
- if (a.low < b.low) {
148
- TCGv_i32 t = tcg_const_i32(vsz - 2);
118
- aIsLargerSignificand = 0;
149
+ TCGv_i32 t = tcg_const_i32(FIELD_DP32(0, PREDDESC, OPRSZ, vsz));
119
- } else if (b.low < a.low) {
150
120
- aIsLargerSignificand = 1;
151
tcg_gen_addi_ptr(d, cpu_env, pred_full_reg_offset(s, a->rd));
121
- } else {
152
tcg_gen_addi_ptr(n, cpu_env, pred_full_reg_offset(s, a->rn));
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.
153
--
141
--
154
2.20.1
142
2.34.1
155
156
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since b64ee454a4a0, all predicate operations should be
3
Unpacking and repacking the parts may be slightly more work
4
using these field macros for predicates.
4
than we did before, but we get to reuse more code. For a
5
code path handling exceptional values, this is an improvement.
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210309155305.11301-5-richard.henderson@linaro.org
8
Message-id: 20241203203949.483774-8-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/sve_helper.c | 6 +++---
12
fpu/softfloat.c | 43 +++++--------------------------------------
12
target/arm/translate-sve.c | 7 +++----
13
1 file changed, 5 insertions(+), 38 deletions(-)
13
2 files changed, 6 insertions(+), 7 deletions(-)
14
14
15
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/sve_helper.c
17
--- a/fpu/softfloat.c
18
+++ b/target/arm/sve_helper.c
18
+++ b/fpu/softfloat.c
19
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_compact_d)(void *vd, void *vn, void *vg, uint32_t desc)
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
20
*/
20
21
int32_t HELPER(sve_last_active_element)(void *vg, uint32_t pred_desc)
21
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
22
{
22
{
23
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
23
- bool aIsLargerSignificand;
24
- intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
24
- FloatClass a_cls, b_cls;
25
+ intptr_t words = DIV_ROUND_UP(FIELD_EX32(pred_desc, PREDDESC, OPRSZ), 8);
25
+ FloatParts128 pa, pb, *pr;
26
+ intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
26
27
27
- /* This is not complete, but is good enough for pickNaN. */
28
- return last_active_element(vg, DIV_ROUND_UP(oprsz, 8), esz);
28
- a_cls = (!floatx80_is_any_nan(a)
29
+ return last_active_element(vg, words, esz);
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);
30
}
70
}
31
71
32
void HELPER(sve_splice)(void *vd, void *vn, void *vm, void *vg, uint32_t desc)
72
/*----------------------------------------------------------------------------
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-sve.c
36
+++ b/target/arm/translate-sve.c
37
@@ -XXX,XX +XXX,XX @@ static void find_last_active(DisasContext *s, TCGv_i32 ret, int esz, int pg)
38
*/
39
TCGv_ptr t_p = tcg_temp_new_ptr();
40
TCGv_i32 t_desc;
41
- unsigned vsz = pred_full_reg_size(s);
42
- unsigned desc;
43
+ unsigned desc = 0;
44
45
- desc = vsz - 2;
46
- desc = deposit32(desc, SIMD_DATA_SHIFT, 2, esz);
47
+ desc = FIELD_DP32(desc, PREDDESC, OPRSZ, pred_full_reg_size(s));
48
+ desc = FIELD_DP32(desc, PREDDESC, ESZ, esz);
49
50
tcg_gen_addi_ptr(t_p, cpu_env, pred_full_reg_offset(s, pg));
51
t_desc = tcg_const_i32(desc);
52
--
73
--
53
2.20.1
74
2.34.1
54
55
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Currently get_naturally_aligned_size() is used by the intel iommu
3
Inline pickNaN into its only caller. This makes one assert
4
to compute the maximum invalidation range based on @size which is
4
redundant with the immediately preceding IF.
5
a power of 2 while being aligned with the @start address and less
5
6
than the maximum range defined by @gaw.
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
This helper is also useful for other iommu devices (virtio-iommu,
8
Message-id: 20241203203949.483774-9-richard.henderson@linaro.org
9
SMMUv3) to make sure IOMMU UNMAP notifiers only are called with
10
power of 2 range sizes.
11
12
Let's move this latter into dma-helpers.c and rename it into
13
dma_aligned_pow2_mask(). Also rewrite the helper so that it
14
accomodates UINT64_MAX values for the size mask and max mask.
15
It now returns a mask instead of a size. Change the caller.
16
17
Signed-off-by: Eric Auger <eric.auger@redhat.com>
18
Reviewed-by: Peter Xu <peterx@redhat.com>
19
Message-id: 20210309102742.30442-3-eric.auger@redhat.com
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
10
---
22
include/sysemu/dma.h | 12 ++++++++++++
11
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
23
hw/i386/intel_iommu.c | 30 +++++++-----------------------
12
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
24
softmmu/dma-helpers.c | 26 ++++++++++++++++++++++++++
13
2 files changed, 73 insertions(+), 105 deletions(-)
25
3 files changed, 45 insertions(+), 23 deletions(-)
14
26
15
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
27
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
28
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
29
--- a/include/sysemu/dma.h
17
--- a/fpu/softfloat-parts.c.inc
30
+++ b/include/sysemu/dma.h
18
+++ b/fpu/softfloat-parts.c.inc
31
@@ -XXX,XX +XXX,XX @@ uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
19
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
32
void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
20
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
33
QEMUSGList *sg, enum BlockAcctType type);
21
float_status *s)
34
22
{
35
+/**
23
+ int cmp, which;
36
+ * dma_aligned_pow2_mask: Return the address bit mask of the largest
37
+ * power of 2 size less or equal than @end - @start + 1, aligned with @start,
38
+ * and bounded by 1 << @max_addr_bits bits.
39
+ *
40
+ * @start: range start address
41
+ * @end: range end address (greater than @start)
42
+ * @max_addr_bits: max address bits (<= 64)
43
+ */
44
+uint64_t dma_aligned_pow2_mask(uint64_t start, uint64_t end,
45
+ int max_addr_bits);
46
+
24
+
47
#endif
25
if (is_snan(a->cls) || is_snan(b->cls)) {
48
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
27
}
28
29
if (s->default_nan_mode) {
30
parts_default_nan(a, s);
31
- } else {
32
- int cmp = frac_cmp(a, b);
33
- if (cmp == 0) {
34
- cmp = a->sign < b->sign;
35
- }
36
+ return a;
37
+ }
38
39
- if (pickNaN(a->cls, b->cls, cmp > 0, s)) {
40
- a = b;
41
- }
42
+ cmp = frac_cmp(a, b);
43
+ if (cmp == 0) {
44
+ cmp = a->sign < b->sign;
45
+ }
46
+
47
+ switch (s->float_2nan_prop_rule) {
48
+ case float_2nan_prop_s_ab:
49
if (is_snan(a->cls)) {
50
- parts_silence_nan(a, s);
51
+ which = 0;
52
+ } else if (is_snan(b->cls)) {
53
+ which = 1;
54
+ } else if (is_qnan(a->cls)) {
55
+ which = 0;
56
+ } else {
57
+ which = 1;
58
}
59
+ break;
60
+ case float_2nan_prop_s_ba:
61
+ if (is_snan(b->cls)) {
62
+ which = 1;
63
+ } else if (is_snan(a->cls)) {
64
+ which = 0;
65
+ } else if (is_qnan(b->cls)) {
66
+ which = 1;
67
+ } else {
68
+ which = 0;
69
+ }
70
+ break;
71
+ case float_2nan_prop_ab:
72
+ which = is_nan(a->cls) ? 0 : 1;
73
+ break;
74
+ case float_2nan_prop_ba:
75
+ which = is_nan(b->cls) ? 1 : 0;
76
+ break;
77
+ case float_2nan_prop_x87:
78
+ /*
79
+ * This implements x87 NaN propagation rules:
80
+ * SNaN + QNaN => return the QNaN
81
+ * two SNaNs => return the one with the larger significand, silenced
82
+ * two QNaNs => return the one with the larger significand
83
+ * SNaN and a non-NaN => return the SNaN, silenced
84
+ * QNaN and a non-NaN => return the QNaN
85
+ *
86
+ * If we get down to comparing significands and they are the same,
87
+ * return the NaN with the positive sign bit (if any).
88
+ */
89
+ if (is_snan(a->cls)) {
90
+ if (is_snan(b->cls)) {
91
+ which = cmp > 0 ? 0 : 1;
92
+ } else {
93
+ which = is_qnan(b->cls) ? 1 : 0;
94
+ }
95
+ } else if (is_qnan(a->cls)) {
96
+ if (is_snan(b->cls) || !is_qnan(b->cls)) {
97
+ which = 0;
98
+ } else {
99
+ which = cmp > 0 ? 0 : 1;
100
+ }
101
+ } else {
102
+ which = 1;
103
+ }
104
+ break;
105
+ default:
106
+ g_assert_not_reached();
107
+ }
108
+
109
+ if (which) {
110
+ a = b;
111
+ }
112
+ if (is_snan(a->cls)) {
113
+ parts_silence_nan(a, s);
114
}
115
return a;
116
}
117
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
49
index XXXXXXX..XXXXXXX 100644
118
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/i386/intel_iommu.c
119
--- a/fpu/softfloat-specialize.c.inc
51
+++ b/hw/i386/intel_iommu.c
120
+++ b/fpu/softfloat-specialize.c.inc
52
@@ -XXX,XX +XXX,XX @@
121
@@ -XXX,XX +XXX,XX @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
53
#include "hw/i386/x86-iommu.h"
122
}
54
#include "hw/pci-host/q35.h"
55
#include "sysemu/kvm.h"
56
+#include "sysemu/dma.h"
57
#include "sysemu/sysemu.h"
58
#include "hw/i386/apic_internal.h"
59
#include "kvm/kvm_i386.h"
60
@@ -XXX,XX +XXX,XX @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
61
return vtd_dev_as;
62
}
123
}
63
124
64
-static uint64_t get_naturally_aligned_size(uint64_t start,
125
-/*----------------------------------------------------------------------------
65
- uint64_t size, int gaw)
126
-| Select which NaN to propagate for a two-input operation.
127
-| IEEE754 doesn't specify all the details of this, so the
128
-| algorithm is target-specific.
129
-| The routine is passed various bits of information about the
130
-| two NaNs and should return 0 to select NaN a and 1 for NaN b.
131
-| Note that signalling NaNs are always squashed to quiet NaNs
132
-| by the caller, by calling floatXX_silence_nan() before
133
-| returning them.
134
-|
135
-| aIsLargerSignificand is only valid if both a and b are NaNs
136
-| of some kind, and is true if a has the larger significand,
137
-| or if both a and b have the same significand but a is
138
-| positive but b is negative. It is only needed for the x87
139
-| tie-break rule.
140
-*----------------------------------------------------------------------------*/
141
-
142
-static int pickNaN(FloatClass a_cls, FloatClass b_cls,
143
- bool aIsLargerSignificand, float_status *status)
66
-{
144
-{
67
- uint64_t max_mask = 1ULL << gaw;
145
- /*
68
- uint64_t alignment = start ? start & -start : max_mask;
146
- * We guarantee not to require the target to tell us how to
147
- * pick a NaN if we're always returning the default NaN.
148
- * But if we're not in default-NaN mode then the target must
149
- * specify via set_float_2nan_prop_rule().
150
- */
151
- assert(!status->default_nan_mode);
69
-
152
-
70
- alignment = MIN(alignment, max_mask);
153
- switch (status->float_2nan_prop_rule) {
71
- size = MIN(size, max_mask);
154
- case float_2nan_prop_s_ab:
72
-
155
- if (is_snan(a_cls)) {
73
- if (alignment <= size) {
156
- return 0;
74
- /* Increase the alignment of start */
157
- } else if (is_snan(b_cls)) {
75
- return alignment;
158
- return 1;
76
- } else {
159
- } else if (is_qnan(a_cls)) {
77
- /* Find the largest page mask from size */
160
- return 0;
78
- return 1ULL << (63 - clz64(size));
161
- } else {
162
- return 1;
163
- }
164
- break;
165
- case float_2nan_prop_s_ba:
166
- if (is_snan(b_cls)) {
167
- return 1;
168
- } else if (is_snan(a_cls)) {
169
- return 0;
170
- } else if (is_qnan(b_cls)) {
171
- return 1;
172
- } else {
173
- return 0;
174
- }
175
- break;
176
- case float_2nan_prop_ab:
177
- if (is_nan(a_cls)) {
178
- return 0;
179
- } else {
180
- return 1;
181
- }
182
- break;
183
- case float_2nan_prop_ba:
184
- if (is_nan(b_cls)) {
185
- return 1;
186
- } else {
187
- return 0;
188
- }
189
- break;
190
- case float_2nan_prop_x87:
191
- /*
192
- * This implements x87 NaN propagation rules:
193
- * SNaN + QNaN => return the QNaN
194
- * two SNaNs => return the one with the larger significand, silenced
195
- * two QNaNs => return the one with the larger significand
196
- * SNaN and a non-NaN => return the SNaN, silenced
197
- * QNaN and a non-NaN => return the QNaN
198
- *
199
- * If we get down to comparing significands and they are the same,
200
- * return the NaN with the positive sign bit (if any).
201
- */
202
- if (is_snan(a_cls)) {
203
- if (is_snan(b_cls)) {
204
- return aIsLargerSignificand ? 0 : 1;
205
- }
206
- return is_qnan(b_cls) ? 1 : 0;
207
- } else if (is_qnan(a_cls)) {
208
- if (is_snan(b_cls) || !is_qnan(b_cls)) {
209
- return 0;
210
- } else {
211
- return aIsLargerSignificand ? 0 : 1;
212
- }
213
- } else {
214
- return 1;
215
- }
216
- default:
217
- g_assert_not_reached();
79
- }
218
- }
80
-}
219
-}
81
-
220
-
82
/* Unmap the whole range in the notifier's scope. */
221
/*----------------------------------------------------------------------------
83
static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
222
| Returns 1 if the double-precision floating-point value `a' is a quiet
84
{
223
| NaN; otherwise returns 0.
85
@@ -XXX,XX +XXX,XX @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
86
87
while (remain >= VTD_PAGE_SIZE) {
88
IOMMUTLBEvent event;
89
- uint64_t mask = get_naturally_aligned_size(start, remain, s->aw_bits);
90
+ uint64_t mask = dma_aligned_pow2_mask(start, end, s->aw_bits);
91
+ uint64_t size = mask + 1;
92
93
- assert(mask);
94
+ assert(size);
95
96
event.type = IOMMU_NOTIFIER_UNMAP;
97
event.entry.iova = start;
98
- event.entry.addr_mask = mask - 1;
99
+ event.entry.addr_mask = mask;
100
event.entry.target_as = &address_space_memory;
101
event.entry.perm = IOMMU_NONE;
102
/* This field is meaningless for unmap */
103
@@ -XXX,XX +XXX,XX @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
104
105
memory_region_notify_iommu_one(n, &event);
106
107
- start += mask;
108
- remain -= mask;
109
+ start += size;
110
+ remain -= size;
111
}
112
113
assert(!remain);
114
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/softmmu/dma-helpers.c
117
+++ b/softmmu/dma-helpers.c
118
@@ -XXX,XX +XXX,XX @@ void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
119
{
120
block_acct_start(blk_get_stats(blk), cookie, sg->size, type);
121
}
122
+
123
+uint64_t dma_aligned_pow2_mask(uint64_t start, uint64_t end, int max_addr_bits)
124
+{
125
+ uint64_t max_mask = UINT64_MAX, addr_mask = end - start;
126
+ uint64_t alignment_mask, size_mask;
127
+
128
+ if (max_addr_bits != 64) {
129
+ max_mask = (1ULL << max_addr_bits) - 1;
130
+ }
131
+
132
+ alignment_mask = start ? (start & -start) - 1 : max_mask;
133
+ alignment_mask = MIN(alignment_mask, max_mask);
134
+ size_mask = MIN(addr_mask, max_mask);
135
+
136
+ if (alignment_mask <= size_mask) {
137
+ /* Increase the alignment of start */
138
+ return alignment_mask;
139
+ } else {
140
+ /* Find the largest page mask from size */
141
+ if (addr_mask == UINT64_MAX) {
142
+ return UINT64_MAX;
143
+ }
144
+ return (1ULL << (63 - clz64(addr_mask + 1))) - 1;
145
+ }
146
+}
147
+
148
--
224
--
149
2.20.1
225
2.34.1
150
226
151
227
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since b64ee454a4a0, all predicate operations should be
3
Remember if there was an SNaN, and use that to simplify
4
using these field macros for predicates.
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: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210309155305.11301-7-richard.henderson@linaro.org
8
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
target/arm/sve_helper.c | 6 +++---
14
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
12
target/arm/translate-sve.c | 6 +++---
15
1 file changed, 12 insertions(+), 20 deletions(-)
13
2 files changed, 6 insertions(+), 6 deletions(-)
14
16
15
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
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/target/arm/sve_helper.c
19
--- a/fpu/softfloat-parts.c.inc
18
+++ b/target/arm/sve_helper.c
20
+++ b/fpu/softfloat-parts.c.inc
19
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_brkns)(void *vd, void *vn, void *vg, uint32_t pred_desc)
21
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
20
22
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
21
uint64_t HELPER(sve_cntp)(void *vn, void *vg, uint32_t pred_desc)
23
float_status *s)
22
{
24
{
23
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
25
+ bool have_snan = false;
24
- intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
26
int cmp, which;
25
+ intptr_t words = DIV_ROUND_UP(FIELD_EX32(pred_desc, PREDDESC, OPRSZ), 8);
27
26
+ intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
28
if (is_snan(a->cls) || is_snan(b->cls)) {
27
uint64_t *n = vn, *g = vg, sum = 0, mask = pred_esz_masks[esz];
29
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
28
intptr_t i;
30
+ have_snan = true;
29
30
- for (i = 0; i < DIV_ROUND_UP(oprsz, 8); ++i) {
31
+ for (i = 0; i < words; ++i) {
32
uint64_t t = n[i] & g[i] & mask;
33
sum += ctpop64(t);
34
}
31
}
35
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
32
36
index XXXXXXX..XXXXXXX 100644
33
if (s->default_nan_mode) {
37
--- a/target/arm/translate-sve.c
34
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
38
+++ b/target/arm/translate-sve.c
35
39
@@ -XXX,XX +XXX,XX @@ static void do_cntp(DisasContext *s, TCGv_i64 val, int esz, int pn, int pg)
36
switch (s->float_2nan_prop_rule) {
40
} else {
37
case float_2nan_prop_s_ab:
41
TCGv_ptr t_pn = tcg_temp_new_ptr();
38
- if (is_snan(a->cls)) {
42
TCGv_ptr t_pg = tcg_temp_new_ptr();
39
- which = 0;
43
- unsigned desc;
40
- } else if (is_snan(b->cls)) {
44
+ unsigned desc = 0;
41
- which = 1;
45
TCGv_i32 t_desc;
42
- } else if (is_qnan(a->cls)) {
46
43
- which = 0;
47
- desc = psz - 2;
44
- } else {
48
- desc = deposit32(desc, SIMD_DATA_SHIFT, 2, esz);
45
- which = 1;
49
+ desc = FIELD_DP32(desc, PREDDESC, OPRSZ, psz);
46
+ if (have_snan) {
50
+ desc = FIELD_DP32(desc, PREDDESC, ESZ, esz);
47
+ which = is_snan(a->cls) ? 0 : 1;
51
48
+ break;
52
tcg_gen_addi_ptr(t_pn, cpu_env, pred_full_reg_offset(s, pn));
49
}
53
tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
50
- break;
51
- case float_2nan_prop_s_ba:
52
- if (is_snan(b->cls)) {
53
- which = 1;
54
- } else if (is_snan(a->cls)) {
55
- which = 0;
56
- } else if (is_qnan(b->cls)) {
57
- which = 1;
58
- } else {
59
- which = 0;
60
- }
61
- break;
62
+ /* fall through */
63
case float_2nan_prop_ab:
64
which = is_nan(a->cls) ? 0 : 1;
65
break;
66
+ case float_2nan_prop_s_ba:
67
+ if (have_snan) {
68
+ which = is_snan(b->cls) ? 1 : 0;
69
+ break;
70
+ }
71
+ /* fall through */
72
case float_2nan_prop_ba:
73
which = is_nan(b->cls) ? 1 : 0;
74
break;
54
--
75
--
55
2.20.1
76
2.34.1
56
57
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Wrote too much with low-half zip (zip1) with vl % 512 != 0.
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.
4
8
5
Adjust all of the x + (y << s) to x | (y << s) as a style fix.
6
7
We only ever have exact overlap between D, M, and N. Therefore
8
we only need a single temporary, and we do not need to check for
9
partial overlap.
10
11
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210309155305.11301-3-richard.henderson@linaro.org
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
13
---
17
target/arm/sve_helper.c | 25 ++++++++++++++-----------
14
fpu/softfloat-parts.c.inc | 19 +++++++++----------
18
1 file changed, 14 insertions(+), 11 deletions(-)
15
1 file changed, 9 insertions(+), 10 deletions(-)
19
16
20
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/sve_helper.c
19
--- a/fpu/softfloat-parts.c.inc
23
+++ b/target/arm/sve_helper.c
20
+++ b/fpu/softfloat-parts.c.inc
24
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
21
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
25
intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
22
return a;
26
int esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
23
}
27
intptr_t high = FIELD_EX32(pred_desc, PREDDESC, DATA);
24
28
+ int esize = 1 << esz;
25
- cmp = frac_cmp(a, b);
29
uint64_t *d = vd;
26
- if (cmp == 0) {
30
intptr_t i;
27
- cmp = a->sign < b->sign;
31
28
- }
32
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
29
-
33
mm = extract64(mm, high * half, half);
30
switch (s->float_2nan_prop_rule) {
34
nn = expand_bits(nn, esz);
31
case float_2nan_prop_s_ab:
35
mm = expand_bits(mm, esz);
32
if (have_snan) {
36
- d[0] = nn + (mm << (1 << esz));
33
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
37
+ d[0] = nn | (mm << esize);
34
* return the NaN with the positive sign bit (if any).
38
} else {
35
*/
39
- ARMPredicateReg tmp_n, tmp_m;
36
if (is_snan(a->cls)) {
40
+ ARMPredicateReg tmp;
37
- if (is_snan(b->cls)) {
41
38
- which = cmp > 0 ? 0 : 1;
42
/* We produce output faster than we consume input.
39
- } else {
43
Therefore we must be mindful of possible overlap. */
40
+ if (!is_snan(b->cls)) {
44
- if ((vn - vd) < (uintptr_t)oprsz) {
41
which = is_qnan(b->cls) ? 1 : 0;
45
- vn = memcpy(&tmp_n, vn, oprsz);
42
+ break;
46
- }
43
}
47
- if ((vm - vd) < (uintptr_t)oprsz) {
44
} else if (is_qnan(a->cls)) {
48
- vm = memcpy(&tmp_m, vm, oprsz);
45
if (is_snan(b->cls) || !is_qnan(b->cls)) {
49
+ if (vd == vn) {
46
which = 0;
50
+ vn = memcpy(&tmp, vn, oprsz);
47
- } else {
51
+ if (vd == vm) {
48
- which = cmp > 0 ? 0 : 1;
52
+ vm = vn;
49
+ break;
53
+ }
54
+ } else if (vd == vm) {
55
+ vm = memcpy(&tmp, vm, oprsz);
56
}
57
if (high) {
58
high = oprsz >> 1;
59
}
60
61
- if ((high & 3) == 0) {
62
+ if ((oprsz & 7) == 0) {
63
uint32_t *n = vn, *m = vm;
64
high >>= 2;
65
66
- for (i = 0; i < DIV_ROUND_UP(oprsz, 8); i++) {
67
+ for (i = 0; i < oprsz / 8; i++) {
68
uint64_t nn = n[H4(high + i)];
69
uint64_t mm = m[H4(high + i)];
70
71
nn = expand_bits(nn, esz);
72
mm = expand_bits(mm, esz);
73
- d[i] = nn + (mm << (1 << esz));
74
+ d[i] = nn | (mm << esize);
75
}
50
}
76
} else {
51
} else {
77
uint8_t *n = vn, *m = vm;
52
which = 1;
78
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
53
+ break;
79
80
nn = expand_bits(nn, esz);
81
mm = expand_bits(mm, esz);
82
- d16[H2(i)] = nn + (mm << (1 << esz));
83
+ d16[H2(i)] = nn | (mm << esize);
84
}
85
}
54
}
86
}
55
+ cmp = frac_cmp(a, b);
56
+ if (cmp == 0) {
57
+ cmp = a->sign < b->sign;
58
+ }
59
+ which = cmp > 0 ? 0 : 1;
60
break;
61
default:
62
g_assert_not_reached();
87
--
63
--
88
2.20.1
64
2.34.1
89
90
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
If the whole SID range (32b) is invalidated (SMMU_CMD_CFGI_ALL),
3
Replace the "index" selecting between A and B with a result variable
4
@end overflows and we fail to handle the command properly.
4
of the proper type. This improves clarity within the function.
5
5
6
Once this gets fixed, the current code really is awkward in the
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
sense it loops over the whole range instead of removing the
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
currently cached configs through a hash table lookup.
8
Message-id: 20241203203949.483774-12-richard.henderson@linaro.org
9
10
Fix both the overflow and the lookup.
11
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20210309102742.30442-7-eric.auger@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
hw/arm/smmu-internal.h | 5 +++++
11
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
18
hw/arm/smmuv3.c | 34 ++++++++++++++++++++--------------
12
1 file changed, 13 insertions(+), 15 deletions(-)
19
2 files changed, 25 insertions(+), 14 deletions(-)
20
13
21
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/smmu-internal.h
16
--- a/fpu/softfloat-parts.c.inc
24
+++ b/hw/arm/smmu-internal.h
17
+++ b/fpu/softfloat-parts.c.inc
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBPageInvInfo {
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
26
uint64_t mask;
19
float_status *s)
27
} SMMUIOTLBPageInvInfo;
28
29
+typedef struct SMMUSIDRange {
30
+ uint32_t start;
31
+ uint32_t end;
32
+} SMMUSIDRange;
33
+
34
#endif
35
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/arm/smmuv3.c
38
+++ b/hw/arm/smmuv3.c
39
@@ -XXX,XX +XXX,XX @@
40
41
#include "hw/arm/smmuv3.h"
42
#include "smmuv3-internal.h"
43
+#include "smmu-internal.h"
44
45
/**
46
* smmuv3_trigger_irq - pulse @irq if enabled and update
47
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
48
}
49
}
50
51
+static gboolean
52
+smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data)
53
+{
54
+ SMMUDevice *sdev = (SMMUDevice *)key;
55
+ uint32_t sid = smmu_get_sid(sdev);
56
+ SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
57
+
58
+ if (sid < sid_range->start || sid > sid_range->end) {
59
+ return false;
60
+ }
61
+ trace_smmuv3_config_cache_inv(sid);
62
+ return true;
63
+}
64
+
65
static int smmuv3_cmdq_consume(SMMUv3State *s)
66
{
20
{
67
SMMUState *bs = ARM_SMMU(s);
21
bool have_snan = false;
68
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
22
- int cmp, which;
23
+ FloatPartsN *ret;
24
+ int cmp;
25
26
if (is_snan(a->cls) || is_snan(b->cls)) {
27
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
28
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
29
switch (s->float_2nan_prop_rule) {
30
case float_2nan_prop_s_ab:
31
if (have_snan) {
32
- which = is_snan(a->cls) ? 0 : 1;
33
+ ret = is_snan(a->cls) ? a : b;
34
break;
69
}
35
}
70
case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */
36
/* fall through */
71
{
37
case float_2nan_prop_ab:
72
- uint32_t start = CMD_SID(&cmd), end, i;
38
- which = is_nan(a->cls) ? 0 : 1;
73
+ uint32_t start = CMD_SID(&cmd);
39
+ ret = is_nan(a->cls) ? a : b;
74
uint8_t range = CMD_STE_RANGE(&cmd);
40
break;
75
+ uint64_t end = start + (1ULL << (range + 1)) - 1;
41
case float_2nan_prop_s_ba:
76
+ SMMUSIDRange sid_range = {start, end};
42
if (have_snan) {
77
43
- which = is_snan(b->cls) ? 1 : 0;
78
if (CMD_SSEC(&cmd)) {
44
+ ret = is_snan(b->cls) ? b : a;
79
cmd_error = SMMU_CERROR_ILL;
45
break;
46
}
47
/* fall through */
48
case float_2nan_prop_ba:
49
- which = is_nan(b->cls) ? 1 : 0;
50
+ ret = is_nan(b->cls) ? b : a;
51
break;
52
case float_2nan_prop_x87:
53
/*
54
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
55
*/
56
if (is_snan(a->cls)) {
57
if (!is_snan(b->cls)) {
58
- which = is_qnan(b->cls) ? 1 : 0;
59
+ ret = is_qnan(b->cls) ? b : a;
80
break;
60
break;
81
}
61
}
82
-
62
} else if (is_qnan(a->cls)) {
83
- end = start + (1 << (range + 1)) - 1;
63
if (is_snan(b->cls) || !is_qnan(b->cls)) {
84
trace_smmuv3_cmdq_cfgi_ste_range(start, end);
64
- which = 0;
85
-
65
+ ret = a;
86
- for (i = start; i <= end; i++) {
66
break;
87
- IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, i);
67
}
88
- SMMUDevice *sdev;
68
} else {
89
-
69
- which = 1;
90
- if (!mr) {
70
+ ret = b;
91
- continue;
92
- }
93
- sdev = container_of(mr, SMMUDevice, iommu);
94
- smmuv3_flush_config(sdev);
95
- }
96
+ g_hash_table_foreach_remove(bs->configs, smmuv3_invalidate_ste,
97
+ &sid_range);
98
break;
71
break;
99
}
72
}
100
case SMMU_CMD_CFGI_CD:
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;
94
}
95
96
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
101
--
97
--
102
2.20.1
98
2.34.1
103
99
104
100
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
The image for Armbian 19.11.3 bionic has been removed from the armbian server.
3
I'm migrating to Qualcomm's new open source email infrastructure, so
4
Without the image as input the test arm_orangepi_bionic_19_11 cannot run.
4
update my email address, and update the mailmap to match.
5
5
6
This commit removes the test completely and merges the code of the generic function
6
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
7
do_test_arm_orangepi_uboot_armbian back with the 20.08 test.
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
8
8
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
9
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20210310195820.21950-3-nieklinnenbank@gmail.com
11
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
tests/acceptance/boot_linux_console.py | 72 ++++++++------------------
14
MAINTAINERS | 2 +-
15
1 file changed, 23 insertions(+), 49 deletions(-)
15
.mailmap | 5 +++--
16
2 files changed, 4 insertions(+), 3 deletions(-)
16
17
17
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
18
diff --git a/MAINTAINERS b/MAINTAINERS
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/acceptance/boot_linux_console.py
20
--- a/MAINTAINERS
20
+++ b/tests/acceptance/boot_linux_console.py
21
+++ b/MAINTAINERS
21
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
22
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
22
# Wait for VM to shut down gracefully
23
SBSA-REF
23
self.vm.wait()
24
M: Radoslaw Biernacki <rad@semihalf.com>
24
25
M: Peter Maydell <peter.maydell@linaro.org>
25
- def do_test_arm_orangepi_uboot_armbian(self, image_path):
26
-R: Leif Lindholm <quic_llindhol@quicinc.com>
26
+ @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
27
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
27
+ 'Test artifacts fetched from unreliable apt.armbian.com')
28
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
28
+ @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
29
L: qemu-arm@nongnu.org
29
+ def test_arm_orangepi_bionic_20_08(self):
30
S: Maintained
30
+ """
31
diff --git a/.mailmap b/.mailmap
31
+ :avocado: tags=arch:arm
32
index XXXXXXX..XXXXXXX 100644
32
+ :avocado: tags=machine:orangepi-pc
33
--- a/.mailmap
33
+ :avocado: tags=device:sd
34
+++ b/.mailmap
34
+ """
35
@@ -XXX,XX +XXX,XX @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
35
+
36
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
36
+ # This test download a 275 MiB compressed image and expand it
37
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
37
+ # to 1036 MiB, but the underlying filesystem is 1552 MiB...
38
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
38
+ # As we expand it to 2 GiB we are safe.
39
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
39
+
40
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
40
+ image_url = ('https://dl.armbian.com/orangepipc/archive/'
41
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
41
+ 'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
42
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
42
+ image_hash = ('b4d6775f5673486329e45a0586bf06b6'
43
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
43
+ 'dbe792199fd182ac6b9c7bb6c7d3e6dd')
44
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
44
+ image_path_xz = self.fetch_asset(image_url, asset_hash=image_hash,
45
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
45
+ algorithm='sha256')
46
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
46
+ image_path = archive.extract(image_path_xz, self.workdir)
47
+ image_pow2ceil_expand(image_path)
48
+
49
self.vm.set_console()
50
self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw',
51
'-nic', 'user',
52
@@ -XXX,XX +XXX,XX @@ def do_test_arm_orangepi_uboot_armbian(self, image_path):
53
'to <orangepipc>')
54
self.wait_for_console_pattern('Starting Load Kernel Modules...')
55
56
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
57
- 'Test artifacts fetched from unreliable apt.armbian.com')
58
- @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
59
- @skipUnless(P7ZIP_AVAILABLE, '7z not installed')
60
- def test_arm_orangepi_bionic_19_11(self):
61
- """
62
- :avocado: tags=arch:arm
63
- :avocado: tags=machine:orangepi-pc
64
- :avocado: tags=device:sd
65
- """
66
-
67
- # This test download a 196MB compressed image and expand it to 1GB
68
- image_url = ('https://dl.armbian.com/orangepipc/archive/'
69
- 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.7z')
70
- image_hash = '196a8ffb72b0123d92cea4a070894813d305c71e'
71
- image_path_7z = self.fetch_asset(image_url, asset_hash=image_hash)
72
- image_name = 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.img'
73
- image_path = os.path.join(self.workdir, image_name)
74
- process.run("7z e -o%s %s" % (self.workdir, image_path_7z))
75
- image_pow2ceil_expand(image_path)
76
-
77
- self.do_test_arm_orangepi_uboot_armbian(image_path)
78
-
79
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
80
- 'Test artifacts fetched from unreliable apt.armbian.com')
81
- @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
82
- def test_arm_orangepi_bionic_20_08(self):
83
- """
84
- :avocado: tags=arch:arm
85
- :avocado: tags=machine:orangepi-pc
86
- :avocado: tags=device:sd
87
- """
88
-
89
- # This test download a 275 MiB compressed image and expand it
90
- # to 1036 MiB, but the underlying filesystem is 1552 MiB...
91
- # As we expand it to 2 GiB we are safe.
92
-
93
- image_url = ('https://dl.armbian.com/orangepipc/archive/'
94
- 'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
95
- image_hash = ('b4d6775f5673486329e45a0586bf06b6'
96
- 'dbe792199fd182ac6b9c7bb6c7d3e6dd')
97
- image_path_xz = self.fetch_asset(image_url, asset_hash=image_hash,
98
- algorithm='sha256')
99
- image_path = archive.extract(image_path_xz, self.workdir)
100
- image_pow2ceil_expand(image_path)
101
-
102
- self.do_test_arm_orangepi_uboot_armbian(image_path)
103
-
104
@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
105
def test_arm_orangepi_uboot_netbsd9(self):
106
"""
107
--
47
--
108
2.20.1
48
2.34.1
109
49
110
50
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
2
2
3
Convert all sid printouts to sid=0x%x.
3
Previously, maintainer role was paused due to inactive email id. Commit id:
4
c009d715721861984c4987bcc78b7ee183e86d75.
4
5
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Message-id: 20210309102742.30442-8-eric.auger@redhat.com
8
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
hw/arm/trace-events | 24 ++++++++++++------------
11
MAINTAINERS | 2 ++
11
1 file changed, 12 insertions(+), 12 deletions(-)
12
1 file changed, 2 insertions(+)
12
13
13
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
14
diff --git a/MAINTAINERS b/MAINTAINERS
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/trace-events
16
--- a/MAINTAINERS
16
+++ b/hw/arm/trace-events
17
+++ b/MAINTAINERS
17
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_opcode(const char *opcode) "<--- %s"
18
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-sb16-test.c
18
smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d "
19
19
smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error on %s command execution: %d"
20
Xilinx CAN
20
smmuv3_write_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
21
M: Francisco Iglesias <francisco.iglesias@amd.com>
21
-smmuv3_record_event(const char *type, uint32_t sid) "%s sid=%d"
22
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
22
-smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "SID:0x%x features:0x%x, sid_split:0x%x"
23
S: Maintained
23
+smmuv3_record_event(const char *type, uint32_t sid) "%s sid=0x%x"
24
F: hw/net/can/xlnx-*
24
+smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "sid=0x%x features:0x%x, sid_split:0x%x"
25
F: include/hw/net/xlnx-*
25
smmuv3_find_ste_2lvl(uint64_t strtab_base, uint64_t l1ptr, int l1_ste_offset, uint64_t l2ptr, int l2_ste_offset, int max_l2_ste) "strtab_base:0x%"PRIx64" l1ptr:0x%"PRIx64" l1_off:0x%x, l2ptr:0x%"PRIx64" l2_off:0x%x max_l2_ste:%d"
26
@@ -XXX,XX +XXX,XX @@ F: include/hw/rx/
26
smmuv3_get_ste(uint64_t addr) "STE addr: 0x%"PRIx64
27
CAN bus subsystem and hardware
27
-smmuv3_translate_disable(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d bypass (smmu disabled) iova:0x%"PRIx64" is_write=%d"
28
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
28
-smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d STE bypass iova:0x%"PRIx64" is_write=%d"
29
M: Francisco Iglesias <francisco.iglesias@amd.com>
29
-smmuv3_translate_abort(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d abort on iova:0x%"PRIx64" is_write=%d"
30
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
30
-smmuv3_translate_success(const char *n, uint16_t sid, uint64_t iova, uint64_t translated, int perm) "%s sid=%d iova=0x%"PRIx64" translated=0x%"PRIx64" perm=0x%x"
31
S: Maintained
31
+smmuv3_translate_disable(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=0x%x bypass (smmu disabled) iova:0x%"PRIx64" is_write=%d"
32
W: https://canbus.pages.fel.cvut.cz/
32
+smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=0x%x STE bypass iova:0x%"PRIx64" is_write=%d"
33
F: net/can/*
33
+smmuv3_translate_abort(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=0x%x abort on iova:0x%"PRIx64" is_write=%d"
34
+smmuv3_translate_success(const char *n, uint16_t sid, uint64_t iova, uint64_t translated, int perm) "%s sid=0x%x iova=0x%"PRIx64" translated=0x%"PRIx64" perm=0x%x"
35
smmuv3_get_cd(uint64_t addr) "CD addr: 0x%"PRIx64
36
smmuv3_decode_cd(uint32_t oas) "oas=%d"
37
smmuv3_decode_cd_tt(int i, uint32_t tsz, uint64_t ttb, uint32_t granule_sz, bool had) "TT[%d]:tsz:%d ttb:0x%"PRIx64" granule_sz:%d had:%d"
38
-smmuv3_cmdq_cfgi_ste(int streamid) "streamid =%d"
39
+smmuv3_cmdq_cfgi_ste(int streamid) "streamid= 0x%x"
40
smmuv3_cmdq_cfgi_ste_range(int start, int end) "start=0x%x - end=0x%x"
41
-smmuv3_cmdq_cfgi_cd(uint32_t sid) "streamid = %d"
42
-smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid %d (hits=%d, misses=%d, hit rate=%d)"
43
-smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid %d (hits=%d, misses=%d, hit rate=%d)"
44
-smmuv3_s1_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t num_pages, uint8_t ttl, bool leaf) "vmid =%d asid =%d addr=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" ttl=%d leaf=%d"
45
+smmuv3_cmdq_cfgi_cd(uint32_t sid) "sid=0x%x"
46
+smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid=0x%x (hits=%d, misses=%d, hit rate=%d)"
47
+smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid=0x%x (hits=%d, misses=%d, hit rate=%d)"
48
+smmuv3_s1_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t num_pages, uint8_t ttl, bool leaf) "vmid=%d asid=%d addr=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" ttl=%d leaf=%d"
49
smmuv3_cmdq_tlbi_nh(void) ""
50
smmuv3_cmdq_tlbi_nh_asid(uint16_t asid) "asid=%d"
51
-smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid %d"
52
+smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
53
smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s"
54
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
55
smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint64_t iova, uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64
56
--
34
--
57
2.20.1
35
2.34.1
58
59
diff view generated by jsdifflib