1
First arm pullreq of 5.0!
1
First arm pullreq of the cycle; this is mostly my softfloat NaN
2
handling series. (Lots more in my to-review queue, but I don't
3
like pullreqs growing too close to a hundred patches at a time :-))
2
4
3
The following changes since commit 084a398bf8aa7634738e6c6c0103236ee1b3b72f:
5
thanks
6
-- PMM
4
7
5
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2019-12-13 18:14:07 +0000)
8
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
9
10
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
6
11
7
are available in the Git repository at:
12
are available in the Git repository at:
8
13
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191216-1
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
10
15
11
for you to fetch changes up to f80741d107673f162e3b097fc76a1590036cc9d1:
16
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
12
17
13
target/arm: ensure we use current exception state after SCR update (2019-12-16 10:52:58 +0000)
18
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
14
19
15
----------------------------------------------------------------
20
----------------------------------------------------------------
16
target-arm queue:
21
target-arm queue:
17
* Add support for Cortex-M7 CPU
22
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
18
* exynos4210_gic: Suppress gcc9 format-truncation warnings
23
* fpu: Make muladd NaN handling runtime-selected, not compile-time
19
* aspeed: Various minor bug fixes and improvements
24
* fpu: Make default NaN pattern runtime-selected, not compile-time
20
* aspeed: Add support for the tacoma-bmc board
25
* fpu: Minor NaN-related cleanups
21
* Honour HCR_EL32.TID1 and .TID2 trapping requirements
26
* MAINTAINERS: email address updates
22
* Handle trapping to EL2 of AArch32 VMRS instructions
23
* Handle AArch32 CP15 trapping via HSTR_EL2
24
* Add support for missing Jazelle system registers
25
* arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on
26
* Add support for DC CVAP & DC CVADP instructions
27
* Fix assertion when SCR.NS is changed in Secure-SVC &c
28
* enable SHPC native hot plug in arm ACPI
29
27
30
----------------------------------------------------------------
28
----------------------------------------------------------------
31
Alex Bennée (1):
29
Bernhard Beschow (5):
32
target/arm: ensure we use current exception state after SCR update
30
hw/net/lan9118: Extract lan9118_phy
31
hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations
32
hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register
33
hw/net/lan9118_phy: Reuse MII constants
34
hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement
33
35
34
Beata Michalska (4):
36
Leif Lindholm (1):
35
tcg: cputlb: Add probe_read
37
MAINTAINERS: update email address for Leif Lindholm
36
Memory: Enable writeback for given memory region
37
migration: ram: Switch to ram block writeback
38
target/arm: Add support for DC CVAP & DC CVADP ins
39
38
40
Christophe Lyon (1):
39
Peter Maydell (54):
41
target/arm: Add support for cortex-m7 CPU
40
fpu: handle raising Invalid for infzero in pick_nan_muladd
41
fpu: Check for default_nan_mode before calling pickNaNMulAdd
42
softfloat: Allow runtime choice of inf * 0 + NaN result
43
tests/fp: Explicitly set inf-zero-nan rule
44
target/arm: Set FloatInfZeroNaNRule explicitly
45
target/s390: Set FloatInfZeroNaNRule explicitly
46
target/ppc: Set FloatInfZeroNaNRule explicitly
47
target/mips: Set FloatInfZeroNaNRule explicitly
48
target/sparc: Set FloatInfZeroNaNRule explicitly
49
target/xtensa: Set FloatInfZeroNaNRule explicitly
50
target/x86: Set FloatInfZeroNaNRule explicitly
51
target/loongarch: Set FloatInfZeroNaNRule explicitly
52
target/hppa: Set FloatInfZeroNaNRule explicitly
53
softfloat: Pass have_snan to pickNaNMulAdd
54
softfloat: Allow runtime choice of NaN propagation for muladd
55
tests/fp: Explicitly set 3-NaN propagation rule
56
target/arm: Set Float3NaNPropRule explicitly
57
target/loongarch: Set Float3NaNPropRule explicitly
58
target/ppc: Set Float3NaNPropRule explicitly
59
target/s390x: Set Float3NaNPropRule explicitly
60
target/sparc: Set Float3NaNPropRule explicitly
61
target/mips: Set Float3NaNPropRule explicitly
62
target/xtensa: Set Float3NaNPropRule explicitly
63
target/i386: Set Float3NaNPropRule explicitly
64
target/hppa: Set Float3NaNPropRule explicitly
65
fpu: Remove use_first_nan field from float_status
66
target/m68k: Don't pass NULL float_status to floatx80_default_nan()
67
softfloat: Create floatx80 default NaN from parts64_default_nan
68
target/loongarch: Use normal float_status in fclass_s and fclass_d helpers
69
target/m68k: In frem helper, initialize local float_status from env->fp_status
70
target/m68k: Init local float_status from env fp_status in gdb get/set reg
71
target/sparc: Initialize local scratch float_status from env->fp_status
72
target/ppc: Use env->fp_status in helper_compute_fprf functions
73
fpu: Allow runtime choice of default NaN value
74
tests/fp: Set default NaN pattern explicitly
75
target/microblaze: Set default NaN pattern explicitly
76
target/i386: Set default NaN pattern explicitly
77
target/hppa: Set default NaN pattern explicitly
78
target/alpha: Set default NaN pattern explicitly
79
target/arm: Set default NaN pattern explicitly
80
target/loongarch: Set default NaN pattern explicitly
81
target/m68k: Set default NaN pattern explicitly
82
target/mips: Set default NaN pattern explicitly
83
target/openrisc: Set default NaN pattern explicitly
84
target/ppc: Set default NaN pattern explicitly
85
target/sh4: Set default NaN pattern explicitly
86
target/rx: Set default NaN pattern explicitly
87
target/s390x: Set default NaN pattern explicitly
88
target/sparc: Set default NaN pattern explicitly
89
target/xtensa: Set default NaN pattern explicitly
90
target/hexagon: Set default NaN pattern explicitly
91
target/riscv: Set default NaN pattern explicitly
92
target/tricore: Set default NaN pattern explicitly
93
fpu: Remove default handling for dnan_pattern
42
94
43
Cédric Le Goater (12):
95
Richard Henderson (11):
44
aspeed/i2c: Add support for pool buffer transfers
96
target/arm: Copy entire float_status in is_ebf
45
aspeed/i2c: Check SRAM enablement on AST2500
97
softfloat: Inline pickNaNMulAdd
46
aspeed: Add a DRAM memory region at the SoC level
98
softfloat: Use goto for default nan case in pick_nan_muladd
47
aspeed/i2c: Add support for DMA transfers
99
softfloat: Remove which from parts_pick_nan_muladd
48
aspeed/i2c: Add trace events
100
softfloat: Pad array size in pick_nan_muladd
49
aspeed/smc: Restore default AHB window mapping at reset
101
softfloat: Move propagateFloatx80NaN to softfloat.c
50
aspeed/smc: Do not map disabled segment on the AST2600
102
softfloat: Use parts_pick_nan in propagateFloatx80NaN
51
aspeed/smc: Add AST2600 timings registers
103
softfloat: Inline pickNaN
52
aspeed: Remove AspeedBoardConfig array and use AspeedMachineClass
104
softfloat: Share code between parts_pick_nan cases
53
aspeed: Add support for the tacoma-bmc board
105
softfloat: Sink frac_cmp in parts_pick_nan until needed
54
aspeed: Change the "scu" property definition
106
softfloat: Replace WHICH with RET in parts_pick_nan
55
aspeed: Change the "nic" property definition
56
107
57
David Gibson (1):
108
Vikram Garhwal (1):
58
exynos4210_gic: Suppress gcc9 format-truncation warnings
109
MAINTAINERS: Add correct email address for Vikram Garhwal
59
110
60
Heyi Guo (2):
111
MAINTAINERS | 4 +-
61
hw/arm/acpi: simplify AML bit and/or statement
112
include/fpu/softfloat-helpers.h | 38 +++-
62
hw/arm/acpi: enable SHPC native hot plug
113
include/fpu/softfloat-types.h | 89 +++++++-
63
114
include/hw/net/imx_fec.h | 9 +-
64
Joel Stanley (4):
115
include/hw/net/lan9118_phy.h | 37 ++++
65
aspeed/sdmc: Make ast2600 default 1G
116
include/hw/net/mii.h | 6 +
66
aspeed/scu: Fix W1C behavior
117
target/mips/fpu_helper.h | 20 ++
67
watchdog/aspeed: Improve watchdog timeout message
118
target/sparc/helper.h | 4 +-
68
watchdog/aspeed: Fix AST2600 frequency behaviour
119
fpu/softfloat.c | 19 ++
69
120
hw/net/imx_fec.c | 146 ++------------
70
Marc Zyngier (5):
121
hw/net/lan9118.c | 137 ++-----------
71
target/arm: Honor HCR_EL2.TID2 trapping requirements
122
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
72
target/arm: Honor HCR_EL2.TID1 trapping requirements
123
linux-user/arm/nwfpe/fpa11.c | 5 +
73
target/arm: Handle trapping to EL2 of AArch32 VMRS instructions
124
target/alpha/cpu.c | 2 +
74
target/arm: Handle AArch32 CP15 trapping via HSTR_EL2
125
target/arm/cpu.c | 10 +
75
target/arm: Add support for missing Jazelle system registers
126
target/arm/tcg/vec_helper.c | 20 +-
76
127
target/hexagon/cpu.c | 2 +
77
Niek Linnenbank (1):
128
target/hppa/fpu_helper.c | 12 ++
78
arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on()
129
target/i386/tcg/fpu_helper.c | 12 ++
79
130
target/loongarch/tcg/fpu_helper.c | 14 +-
80
PanNengyuan (1):
131
target/m68k/cpu.c | 14 +-
81
gpio: fix memory leak in aspeed_gpio_init()
132
target/m68k/fpu_helper.c | 6 +-
82
133
target/m68k/helper.c | 6 +-
83
Philippe Mathieu-Daudé (2):
134
target/microblaze/cpu.c | 2 +
84
hw/arm/sbsa-ref: Simplify by moving the gic in the machine state
135
target/mips/msa.c | 10 +
85
hw/arm/virt: Simplify by moving the gic in the machine state
136
target/openrisc/cpu.c | 2 +
86
137
target/ppc/cpu_init.c | 19 ++
87
include/exec/exec-all.h | 6 +
138
target/ppc/fpu_helper.c | 3 +-
88
include/exec/memory.h | 6 +
139
target/riscv/cpu.c | 2 +
89
include/exec/ram_addr.h | 8 +
140
target/rx/cpu.c | 2 +
90
include/hw/arm/aspeed.h | 24 +--
141
target/s390x/cpu.c | 5 +
91
include/hw/arm/aspeed_soc.h | 1 +
142
target/sh4/cpu.c | 2 +
92
include/hw/arm/virt.h | 1 +
143
target/sparc/cpu.c | 6 +
93
include/hw/i2c/aspeed_i2c.h | 16 ++
144
target/sparc/fop_helper.c | 8 +-
94
include/hw/ssi/aspeed_smc.h | 1 +
145
target/sparc/translate.c | 4 +-
95
include/hw/watchdog/wdt_aspeed.h | 1 +
146
target/tricore/helper.c | 2 +
96
include/qemu/cutils.h | 1 +
147
target/xtensa/cpu.c | 4 +
97
target/arm/cpu.h | 20 +-
148
target/xtensa/fpu_helper.c | 3 +-
98
target/arm/helper.h | 3 +
149
tests/fp/fp-bench.c | 7 +
99
target/arm/translate.h | 2 +
150
tests/fp/fp-test-log2.c | 1 +
100
exec.c | 36 ++++
151
tests/fp/fp-test.c | 7 +
101
hw/arm/aspeed.c | 271 +++++++++++++----------
152
fpu/softfloat-parts.c.inc | 152 +++++++++++---
102
hw/arm/aspeed_ast2600.c | 25 ++-
153
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
103
hw/arm/aspeed_soc.c | 22 +-
154
.mailmap | 5 +-
104
hw/arm/sbsa-ref.c | 86 ++++----
155
hw/net/Kconfig | 5 +
105
hw/arm/virt-acpi-build.c | 21 +-
156
hw/net/meson.build | 1 +
106
hw/arm/virt.c | 109 +++++-----
157
hw/net/trace-events | 10 +-
107
hw/gpio/aspeed_gpio.c | 1 +
158
47 files changed, 778 insertions(+), 730 deletions(-)
108
hw/i2c/aspeed_i2c.c | 439 +++++++++++++++++++++++++++++++++++---
159
create mode 100644 include/hw/net/lan9118_phy.h
109
hw/intc/exynos4210_gic.c | 9 +-
160
create mode 100644 hw/net/lan9118_phy.c
110
hw/misc/aspeed_scu.c | 19 +-
111
hw/misc/aspeed_sdmc.c | 6 +-
112
hw/net/ftgmac100.c | 19 +-
113
hw/ssi/aspeed_smc.c | 63 ++++--
114
hw/timer/aspeed_timer.c | 17 +-
115
hw/watchdog/wdt_aspeed.c | 41 ++--
116
linux-user/elfload.c | 2 +
117
memory.c | 12 ++
118
migration/ram.c | 5 +-
119
target/arm/arm-powerctl.c | 3 +
120
target/arm/cpu.c | 33 +++
121
target/arm/cpu64.c | 1 +
122
target/arm/helper.c | 170 ++++++++++++++-
123
target/arm/op_helper.c | 22 ++
124
target/arm/translate-vfp.inc.c | 20 +-
125
target/arm/translate.c | 9 +-
126
target/arm/vfp_helper.c | 29 +++
127
util/cutils.c | 38 ++++
128
hw/i2c/trace-events | 9 +
129
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
130
tests/data/acpi/virt/DSDT.memhp | Bin 19807 -> 19799 bytes
131
tests/data/acpi/virt/DSDT.numamem | Bin 18470 -> 18462 bytes
132
45 files changed, 1273 insertions(+), 354 deletions(-)
133
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Add an option to trigger memory writeback to sync given memory region
3
A very similar implementation of the same device exists in imx_fec. Prepare for
4
with the corresponding backing store, case one is available.
4
a common implementation by extracting a device model into its own files.
5
This extends the support for persistent memory, allowing syncing on-demand.
6
5
7
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
6
Some migration state has been moved into the new device model which breaks
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
migration compatibility for the following machines:
9
Message-id: 20191121000843.24844-3-beata.michalska@linaro.org
8
* smdkc210
9
* realview-*
10
* vexpress-*
11
* kzm
12
* mps2-*
13
14
While breaking migration ABI, fix the size of the MII registers to be 16 bit,
15
as defined by IEEE 802.3u.
16
17
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
18
Tested-by: Guenter Roeck <linux@roeck-us.net>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Message-id: 20241102125724.532843-2-shentey@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
22
---
12
include/exec/memory.h | 6 ++++++
23
include/hw/net/lan9118_phy.h | 37 ++++++++
13
include/exec/ram_addr.h | 8 ++++++++
24
hw/net/lan9118.c | 137 +++++-----------------------
14
include/qemu/cutils.h | 1 +
25
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
15
exec.c | 36 ++++++++++++++++++++++++++++++++++++
26
hw/net/Kconfig | 4 +
16
memory.c | 12 ++++++++++++
27
hw/net/meson.build | 1 +
17
util/cutils.c | 38 ++++++++++++++++++++++++++++++++++++++
28
5 files changed, 233 insertions(+), 115 deletions(-)
18
6 files changed, 101 insertions(+)
29
create mode 100644 include/hw/net/lan9118_phy.h
30
create mode 100644 hw/net/lan9118_phy.c
19
31
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
32
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/hw/net/lan9118_phy.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * SMSC LAN9118 PHY emulation
40
+ *
41
+ * Copyright (c) 2009 CodeSourcery, LLC.
42
+ * Written by Paul Brook
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.
46
+ */
47
+
48
+#ifndef HW_NET_LAN9118_PHY_H
49
+#define HW_NET_LAN9118_PHY_H
50
+
51
+#include "qom/object.h"
52
+#include "hw/sysbus.h"
53
+
54
+#define TYPE_LAN9118_PHY "lan9118-phy"
55
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
56
+
57
+typedef struct Lan9118PhyState {
58
+ SysBusDevice parent_obj;
59
+
60
+ uint16_t status;
61
+ uint16_t control;
62
+ uint16_t advertise;
63
+ uint16_t ints;
64
+ uint16_t int_mask;
65
+ qemu_irq irq;
66
+ bool link_down;
67
+} Lan9118PhyState;
68
+
69
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down);
70
+void lan9118_phy_reset(Lan9118PhyState *s);
71
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg);
72
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val);
73
+
74
+#endif
75
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
21
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/memory.h
77
--- a/hw/net/lan9118.c
23
+++ b/include/exec/memory.h
78
+++ b/hw/net/lan9118.c
24
@@ -XXX,XX +XXX,XX @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
25
*/
26
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
27
Error **errp);
28
+/**
29
+ * memory_region_do_writeback: Trigger writeback for selected address range
30
+ * [addr, addr + size]
31
+ *
32
+ */
33
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size);
34
35
/**
36
* memory_region_set_log: Turn dirty logging on or off for a region.
37
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/exec/ram_addr.h
40
+++ b/include/exec/ram_addr.h
41
@@ -XXX,XX +XXX,XX @@ void qemu_ram_free(RAMBlock *block);
42
43
int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
44
45
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length);
46
+
47
+/* Clear whole block of mem */
48
+static inline void qemu_ram_block_writeback(RAMBlock *block)
49
+{
50
+ qemu_ram_writeback(block, 0, block->used_length);
51
+}
52
+
53
#define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1)
54
#define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE))
55
56
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/include/qemu/cutils.h
59
+++ b/include/qemu/cutils.h
60
@@ -XXX,XX +XXX,XX @@ const char *qemu_strchrnul(const char *s, int c);
61
#endif
62
time_t mktimegm(struct tm *tm);
63
int qemu_fdatasync(int fd);
64
+int qemu_msync(void *addr, size_t length, int fd);
65
int fcntl_setfl(int fd, int flag);
66
int qemu_parse_fd(const char *param);
67
int qemu_strtoi(const char *nptr, const char **endptr, int base,
68
diff --git a/exec.c b/exec.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/exec.c
71
+++ b/exec.c
72
@@ -XXX,XX +XXX,XX @@
79
@@ -XXX,XX +XXX,XX @@
73
#include "exec/ram_addr.h"
80
#include "net/net.h"
74
#include "exec/log.h"
81
#include "net/eth.h"
75
82
#include "hw/irq.h"
76
+#include "qemu/pmem.h"
83
+#include "hw/net/lan9118_phy.h"
77
+
84
#include "hw/net/lan9118.h"
78
#include "migration/vmstate.h"
85
#include "hw/ptimer.h"
79
86
#include "hw/qdev-properties.h"
80
#include "qemu/range.h"
87
@@ -XXX,XX +XXX,XX @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
81
@@ -XXX,XX +XXX,XX @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
88
#define MAC_CR_RXEN 0x00000004
82
return 0;
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);
83
}
141
}
84
142
85
+/*
143
-static void phy_update_irq(lan9118_state *s)
86
+ * Trigger sync on the given ram block for range [start, start + length]
144
+static void lan9118_update_irq(void *opaque, int n, int level)
87
+ * with the backing store if one is available.
145
{
88
+ * Otherwise no-op.
146
- if (s->phy_int & s->phy_int_mask) {
89
+ * @Note: this is supposed to be a synchronous op.
147
+ lan9118_state *s = opaque;
90
+ */
148
+
91
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length)
149
+ if (level) {
92
+{
150
s->int_sts |= PHY_INT;
93
+ void *addr = ramblock_ptr(block, start);
151
} else {
94
+
152
s->int_sts &= ~PHY_INT;
95
+ /* The requested range should fit in within the block range */
153
@@ -XXX,XX +XXX,XX @@ static void phy_update_irq(lan9118_state *s)
96
+ g_assert((start + length) <= block->used_length);
154
lan9118_update(s);
97
+
155
}
98
+#ifdef CONFIG_LIBPMEM
156
99
+ /* The lack of support for pmem should not block the sync */
157
-static void phy_update_link(lan9118_state *s)
100
+ if (ramblock_is_pmem(block)) {
158
-{
101
+ pmem_persist(addr, length);
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)) {
102
+ return;
304
+ return;
103
+ }
305
+ }
104
+#endif
306
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
105
+ if (block->fd >= 0) {
307
+
106
+ /**
308
memory_region_init_io(&s->mmio, OBJECT(dev), mem_ops, s,
107
+ * Case there is no support for PMEM or the memory has not been
309
"lan9118-mmio", 0x100);
108
+ * specified as persistent (or is not one) - use the msync.
310
sysbus_init_mmio(sbd, &s->mmio);
109
+ * Less optimal but still achieves the same goal
311
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
110
+ */
312
new file mode 100644
111
+ if (qemu_msync(addr, length, block->fd)) {
313
index XXXXXXX..XXXXXXX
112
+ warn_report("%s: failed to sync memory range: start: "
314
--- /dev/null
113
+ RAM_ADDR_FMT " length: " RAM_ADDR_FMT,
315
+++ b/hw/net/lan9118_phy.c
114
+ __func__, start, length);
316
@@ -XXX,XX +XXX,XX @@
317
+/*
318
+ * SMSC LAN9118 PHY emulation
319
+ *
320
+ * Copyright (c) 2009 CodeSourcery, LLC.
321
+ * Written by Paul Brook
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.
327
+ */
328
+
329
+#include "qemu/osdep.h"
330
+#include "hw/net/lan9118_phy.h"
331
+#include "hw/irq.h"
332
+#include "hw/resettable.h"
333
+#include "migration/vmstate.h"
334
+#include "qemu/log.h"
335
+
336
+#define PHY_INT_ENERGYON (1 << 7)
337
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
338
+#define PHY_INT_FAULT (1 << 5)
339
+#define PHY_INT_DOWN (1 << 4)
340
+#define PHY_INT_AUTONEG_LP (1 << 3)
341
+#define PHY_INT_PARFAULT (1 << 2)
342
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
343
+
344
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
345
+{
346
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
347
+}
348
+
349
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
350
+{
351
+ uint16_t val;
352
+
353
+ switch (reg) {
354
+ case 0: /* Basic Control */
355
+ return s->control;
356
+ case 1: /* Basic Status */
357
+ return s->status;
358
+ case 2: /* ID1 */
359
+ return 0x0007;
360
+ case 3: /* ID2 */
361
+ return 0xc0d1;
362
+ case 4: /* Auto-neg advertisement */
363
+ return s->advertise;
364
+ case 5: /* Auto-neg Link Partner Ability */
365
+ return 0x0f71;
366
+ case 6: /* Auto-neg Expansion */
367
+ return 1;
368
+ /* TODO 17, 18, 27, 29, 30, 31 */
369
+ case 29: /* Interrupt source. */
370
+ val = s->ints;
371
+ s->ints = 0;
372
+ lan9118_phy_update_irq(s);
373
+ return val;
374
+ case 30: /* Interrupt mask */
375
+ return s->int_mask;
376
+ default:
377
+ qemu_log_mask(LOG_GUEST_ERROR,
378
+ "lan9118_phy_read: PHY read reg %d\n", reg);
379
+ return 0;
380
+ }
381
+}
382
+
383
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
384
+{
385
+ switch (reg) {
386
+ case 0: /* Basic Control */
387
+ if (val & 0x8000) {
388
+ lan9118_phy_reset(s);
389
+ break;
115
+ }
390
+ }
391
+ s->control = val & 0x7980;
392
+ /* Complete autonegotiation immediately. */
393
+ if (val & 0x1000) {
394
+ s->status |= 0x0020;
395
+ }
396
+ break;
397
+ case 4: /* Auto-neg advertisement */
398
+ s->advertise = (val & 0x2d7f) | 0x80;
399
+ break;
400
+ /* TODO 17, 18, 27, 31 */
401
+ case 30: /* Interrupt mask */
402
+ s->int_mask = val & 0xff;
403
+ lan9118_phy_update_irq(s);
404
+ break;
405
+ default:
406
+ qemu_log_mask(LOG_GUEST_ERROR,
407
+ "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
116
+ }
408
+ }
117
+}
409
+}
118
+
410
+
119
/* Called with ram_list.mutex held */
411
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
120
static void dirty_memory_extend(ram_addr_t old_ram_size,
412
+{
121
ram_addr_t new_ram_size)
413
+ s->link_down = link_down;
122
diff --git a/memory.c b/memory.c
414
+
415
+ /* Autonegotiation status mirrors link status. */
416
+ if (link_down) {
417
+ s->status &= ~0x0024;
418
+ s->ints |= PHY_INT_DOWN;
419
+ } else {
420
+ s->status |= 0x0024;
421
+ s->ints |= PHY_INT_ENERGYON;
422
+ s->ints |= PHY_INT_AUTONEG_COMPLETE;
423
+ }
424
+ lan9118_phy_update_irq(s);
425
+}
426
+
427
+void lan9118_phy_reset(Lan9118PhyState *s)
428
+{
429
+ s->control = 0x3000;
430
+ s->status = 0x7809;
431
+ s->advertise = 0x01e1;
432
+ s->int_mask = 0;
433
+ s->ints = 0;
434
+ lan9118_phy_update_link(s, s->link_down);
435
+}
436
+
437
+static void lan9118_phy_reset_hold(Object *obj, ResetType type)
438
+{
439
+ Lan9118PhyState *s = LAN9118_PHY(obj);
440
+
441
+ lan9118_phy_reset(s);
442
+}
443
+
444
+static void lan9118_phy_init(Object *obj)
445
+{
446
+ Lan9118PhyState *s = LAN9118_PHY(obj);
447
+
448
+ qdev_init_gpio_out(DEVICE(s), &s->irq, 1);
449
+}
450
+
451
+static const VMStateDescription vmstate_lan9118_phy = {
452
+ .name = "lan9118-phy",
453
+ .version_id = 1,
454
+ .minimum_version_id = 1,
455
+ .fields = (const VMStateField[]) {
456
+ VMSTATE_UINT16(control, Lan9118PhyState),
457
+ VMSTATE_UINT16(status, Lan9118PhyState),
458
+ VMSTATE_UINT16(advertise, Lan9118PhyState),
459
+ VMSTATE_UINT16(ints, Lan9118PhyState),
460
+ VMSTATE_UINT16(int_mask, Lan9118PhyState),
461
+ VMSTATE_BOOL(link_down, Lan9118PhyState),
462
+ VMSTATE_END_OF_LIST()
463
+ }
464
+};
465
+
466
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
467
+{
468
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
469
+ DeviceClass *dc = DEVICE_CLASS(klass);
470
+
471
+ rc->phases.hold = lan9118_phy_reset_hold;
472
+ dc->vmsd = &vmstate_lan9118_phy;
473
+}
474
+
475
+static const TypeInfo types[] = {
476
+ {
477
+ .name = TYPE_LAN9118_PHY,
478
+ .parent = TYPE_SYS_BUS_DEVICE,
479
+ .instance_size = sizeof(Lan9118PhyState),
480
+ .instance_init = lan9118_phy_init,
481
+ .class_init = lan9118_phy_class_init,
482
+ }
483
+};
484
+
485
+DEFINE_TYPES(types)
486
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
123
index XXXXXXX..XXXXXXX 100644
487
index XXXXXXX..XXXXXXX 100644
124
--- a/memory.c
488
--- a/hw/net/Kconfig
125
+++ b/memory.c
489
+++ b/hw/net/Kconfig
126
@@ -XXX,XX +XXX,XX @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
490
@@ -XXX,XX +XXX,XX @@ config VMXNET3_PCI
127
qemu_ram_resize(mr->ram_block, newsize, errp);
491
config SMC91C111
128
}
492
bool
129
493
130
+
494
+config LAN9118_PHY
131
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
495
+ bool
132
+{
496
+
133
+ /*
497
config LAN9118
134
+ * Might be extended case needed to cover
498
bool
135
+ * different types of memory regions
499
+ select LAN9118_PHY
136
+ */
500
select PTIMER
137
+ if (mr->ram_block && mr->dirty_log_mask) {
501
138
+ qemu_ram_writeback(mr->ram_block, addr, size);
502
config NE2000_ISA
139
+ }
503
diff --git a/hw/net/meson.build b/hw/net/meson.build
140
+}
141
+
142
/*
143
* Call proper memory listeners about the change on the newly
144
* added/removed CoalescedMemoryRange.
145
diff --git a/util/cutils.c b/util/cutils.c
146
index XXXXXXX..XXXXXXX 100644
504
index XXXXXXX..XXXXXXX 100644
147
--- a/util/cutils.c
505
--- a/hw/net/meson.build
148
+++ b/util/cutils.c
506
+++ b/hw/net/meson.build
149
@@ -XXX,XX +XXX,XX @@ int qemu_fdatasync(int fd)
507
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('vmxnet3.c'))
150
#endif
508
151
}
509
system_ss.add(when: 'CONFIG_SMC91C111', if_true: files('smc91c111.c'))
152
510
system_ss.add(when: 'CONFIG_LAN9118', if_true: files('lan9118.c'))
153
+/**
511
+system_ss.add(when: 'CONFIG_LAN9118_PHY', if_true: files('lan9118_phy.c'))
154
+ * Sync changes made to the memory mapped file back to the backing
512
system_ss.add(when: 'CONFIG_NE2000_ISA', if_true: files('ne2000-isa.c'))
155
+ * storage. For POSIX compliant systems this will fallback
513
system_ss.add(when: 'CONFIG_OPENCORES_ETH', if_true: files('opencores_eth.c'))
156
+ * to regular msync call. Otherwise it will trigger whole file sync
514
system_ss.add(when: 'CONFIG_XGMAC', if_true: files('xgmac.c'))
157
+ * (including the metadata case there is no support to skip that otherwise)
158
+ *
159
+ * @addr - start of the memory area to be synced
160
+ * @length - length of the are to be synced
161
+ * @fd - file descriptor for the file to be synced
162
+ * (mandatory only for POSIX non-compliant systems)
163
+ */
164
+int qemu_msync(void *addr, size_t length, int fd)
165
+{
166
+#ifdef CONFIG_POSIX
167
+ size_t align_mask = ~(qemu_real_host_page_size - 1);
168
+
169
+ /**
170
+ * There are no strict reqs as per the length of mapping
171
+ * to be synced. Still the length needs to follow the address
172
+ * alignment changes. Additionally - round the size to the multiple
173
+ * of PAGE_SIZE
174
+ */
175
+ length += ((uintptr_t)addr & (qemu_real_host_page_size - 1));
176
+ length = (length + ~align_mask) & align_mask;
177
+
178
+ addr = (void *)((uintptr_t)addr & align_mask);
179
+
180
+ return msync(addr, length, MS_SYNC);
181
+#else /* CONFIG_POSIX */
182
+ /**
183
+ * Perform the sync based on the file descriptor
184
+ * The sync range will most probably be wider than the one
185
+ * requested - but it will still get the job done
186
+ */
187
+ return qemu_fdatasync(fd);
188
+#endif /* CONFIG_POSIX */
189
+}
190
+
191
#ifndef _WIN32
192
/* Sets a specific flag */
193
int fcntl_setfl(int fd, int flag)
194
--
515
--
195
2.20.1
516
2.34.1
196
197
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
The I2C controller of the Aspeed AST2500 and AST2600 SoCs supports DMA
3
imx_fec models the same PHY as lan9118_phy. The code is almost the same with
4
transfers to and from DRAM.
4
imx_fec having more logging and tracing. Merge these improvements into
5
lan9118_phy and reuse in imx_fec to fix the code duplication.
5
6
6
A pair of registers defines the buffer address and the length of the
7
Some migration state how resides in the new device model which breaks migration
7
DMA transfer. The address should be aligned on 4 bytes and the maximum
8
compatibility for the following machines:
8
length should not exceed 4K. The receive or transmit DMA transfer can
9
* imx25-pdk
9
then be initiated with specific bits in the Command/Status register of
10
* sabrelite
10
the controller.
11
* mcimx7d-sabre
12
* mcimx6ul-evk
11
13
12
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
13
Reviewed-by: Joel Stanley <joel@jms.id.au>
15
Tested-by: Guenter Roeck <linux@roeck-us.net>
14
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Cédric Le Goater <clg@kaod.org>
17
Message-id: 20241102125724.532843-3-shentey@gmail.com
16
Message-id: 20191119141211.25716-5-clg@kaod.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
---
19
include/hw/i2c/aspeed_i2c.h | 5 ++
20
include/hw/net/imx_fec.h | 9 ++-
20
hw/arm/aspeed_ast2600.c | 5 ++
21
hw/net/imx_fec.c | 146 ++++-----------------------------------
21
hw/arm/aspeed_soc.c | 5 ++
22
hw/net/lan9118_phy.c | 82 ++++++++++++++++------
22
hw/i2c/aspeed_i2c.c | 126 +++++++++++++++++++++++++++++++++++-
23
hw/net/Kconfig | 1 +
23
4 files changed, 138 insertions(+), 3 deletions(-)
24
hw/net/trace-events | 10 +--
25
5 files changed, 85 insertions(+), 163 deletions(-)
24
26
25
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
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/include/hw/i2c/aspeed_i2c.h
29
--- a/include/hw/net/imx_fec.h
28
+++ b/include/hw/i2c/aspeed_i2c.h
30
+++ b/include/hw/net/imx_fec.h
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
30
uint32_t cmd;
32
#define TYPE_IMX_ENET "imx.enet"
31
uint32_t buf;
33
32
uint32_t pool_ctrl;
34
#include "hw/sysbus.h"
33
+ uint32_t dma_addr;
35
+#include "hw/net/lan9118_phy.h"
34
+ uint32_t dma_len;
36
+#include "hw/irq.h"
35
} AspeedI2CBus;
37
#include "net/net.h"
36
38
37
typedef struct AspeedI2CState {
39
#define ENET_EIR 1
38
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
40
@@ -XXX,XX +XXX,XX @@ struct IMXFECState {
39
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
41
uint32_t tx_descriptor[ENET_TX_RING_NUM];
40
42
uint32_t tx_ring_num;
41
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
43
42
+ MemoryRegion *dram_mr;
44
- uint32_t phy_status;
43
+ AddressSpace dram_as;
45
- uint32_t phy_control;
44
} AspeedI2CState;
46
- uint32_t phy_advertise;
45
47
- uint32_t phy_int;
46
#define ASPEED_I2C_CLASS(klass) \
48
- uint32_t phy_int_mask;
47
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
49
+ Lan9118PhyState mii;
48
hwaddr pool_base;
50
+ IRQState mii_irq;
49
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
51
uint32_t phy_num;
50
bool check_sram;
52
bool phy_connected;
51
+ bool has_dma;
53
struct IMXFECState *phy_consumer;
52
54
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
53
} AspeedI2CClass;
54
55
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
56
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/aspeed_ast2600.c
56
--- a/hw/net/imx_fec.c
58
+++ b/hw/arm/aspeed_ast2600.c
57
+++ b/hw/net/imx_fec.c
59
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
58
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth_txdescs = {
60
}
59
61
60
static const VMStateDescription vmstate_imx_eth = {
62
/* I2C */
61
.name = TYPE_IMX_FEC,
63
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
64
+ if (err) {
65
+ error_propagate(errp, err);
66
+ return;
67
+ }
68
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
69
if (err) {
70
error_propagate(errp, err);
71
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/arm/aspeed_soc.c
74
+++ b/hw/arm/aspeed_soc.c
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
76
}
77
78
/* I2C */
79
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
80
+ if (err) {
81
+ error_propagate(errp, err);
82
+ return;
83
+ }
84
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
85
if (err) {
86
error_propagate(errp, err);
87
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/i2c/aspeed_i2c.c
90
+++ b/hw/i2c/aspeed_i2c.c
91
@@ -XXX,XX +XXX,XX @@
92
#include "migration/vmstate.h"
93
#include "qemu/log.h"
94
#include "qemu/module.h"
95
+#include "qemu/error-report.h"
96
+#include "qapi/error.h"
97
#include "hw/i2c/aspeed_i2c.h"
98
#include "hw/irq.h"
99
+#include "hw/qdev-properties.h"
100
101
/* I2C Global Register */
102
103
@@ -XXX,XX +XXX,XX @@
104
#define I2CD_BYTE_BUF_TX_MASK 0xff
105
#define I2CD_BYTE_BUF_RX_SHIFT 8
106
#define I2CD_BYTE_BUF_RX_MASK 0xff
107
-
108
+#define I2CD_DMA_ADDR 0x24 /* DMA Buffer Address */
109
+#define I2CD_DMA_LEN 0x28 /* DMA Transfer Length < 4KB */
110
111
static inline bool aspeed_i2c_bus_is_master(AspeedI2CBus *bus)
112
{
113
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
114
unsigned size)
115
{
116
AspeedI2CBus *bus = opaque;
117
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
118
119
switch (offset) {
120
case I2CD_FUN_CTRL_REG:
121
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
122
return bus->buf;
123
case I2CD_CMD_REG:
124
return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
125
+ case I2CD_DMA_ADDR:
126
+ if (!aic->has_dma) {
127
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
128
+ return -1;
129
+ }
130
+ return bus->dma_addr;
131
+ case I2CD_DMA_LEN:
132
+ if (!aic->has_dma) {
133
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
134
+ return -1;
135
+ }
136
+ return bus->dma_len;
137
default:
138
qemu_log_mask(LOG_GUEST_ERROR,
139
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
140
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
141
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
142
}
143
144
+static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data)
145
+{
146
+ MemTxResult result;
147
+ AspeedI2CState *s = bus->controller;
148
+
149
+ result = address_space_read(&s->dram_as, bus->dma_addr,
150
+ MEMTXATTRS_UNSPECIFIED, data, 1);
151
+ if (result != MEMTX_OK) {
152
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n",
153
+ __func__, bus->dma_addr);
154
+ return -1;
155
+ }
156
+
157
+ bus->dma_addr++;
158
+ bus->dma_len--;
159
+ return 0;
160
+}
161
+
162
static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
163
{
164
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
165
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
166
}
167
}
168
bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
169
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
170
+ while (bus->dma_len) {
171
+ uint8_t data;
172
+ aspeed_i2c_dma_read(bus, &data);
173
+ ret = i2c_send(bus->bus, data);
174
+ if (ret) {
175
+ break;
176
+ }
177
+ }
178
+ bus->cmd &= ~I2CD_TX_DMA_ENABLE;
179
} else {
180
ret = i2c_send(bus->bus, bus->buf);
181
}
182
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
183
bus->pool_ctrl &= ~(0xff << 24);
184
bus->pool_ctrl |= (i & 0xff) << 24;
185
bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
186
+ } else if (bus->cmd & I2CD_RX_DMA_ENABLE) {
187
+ uint8_t data;
188
+
189
+ while (bus->dma_len) {
190
+ MemTxResult result;
191
+
192
+ data = i2c_recv(bus->bus);
193
+ result = address_space_write(&s->dram_as, bus->dma_addr,
194
+ MEMTXATTRS_UNSPECIFIED, &data, 1);
195
+ if (result != MEMTX_OK) {
196
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
197
+ __func__, bus->dma_addr);
198
+ return;
199
+ }
200
+ bus->dma_addr++;
201
+ bus->dma_len--;
202
+ }
203
+ bus->cmd &= ~I2CD_RX_DMA_ENABLE;
204
} else {
205
data = i2c_recv(bus->bus);
206
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
207
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
208
uint8_t *pool_base = aic->bus_pool_base(bus);
209
210
return pool_base[0];
211
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
212
+ uint8_t data;
213
+
214
+ aspeed_i2c_dma_read(bus, &data);
215
+ return data;
216
} else {
217
return bus->buf;
218
}
219
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
220
*/
221
pool_start++;
222
}
223
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
224
+ if (bus->dma_len == 0) {
225
+ bus->cmd &= ~I2CD_M_TX_CMD;
226
+ }
227
} else {
228
bus->cmd &= ~I2CD_M_TX_CMD;
229
}
230
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
231
break;
232
}
233
234
+ if (!aic->has_dma &&
235
+ value & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE)) {
236
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
237
+ break;
238
+ }
239
+
240
aspeed_i2c_bus_handle_cmd(bus, value);
241
aspeed_i2c_bus_raise_interrupt(bus);
242
break;
243
+ case I2CD_DMA_ADDR:
244
+ if (!aic->has_dma) {
245
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
246
+ break;
247
+ }
248
+
249
+ bus->dma_addr = value & 0xfffffffc;
250
+ break;
251
+
252
+ case I2CD_DMA_LEN:
253
+ if (!aic->has_dma) {
254
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
255
+ break;
256
+ }
257
+
258
+ bus->dma_len = value & 0xfff;
259
+ if (!bus->dma_len) {
260
+ qemu_log_mask(LOG_UNIMP, "%s: invalid DMA length\n", __func__);
261
+ }
262
+ break;
263
264
default:
265
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
266
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_pool_ops = {
267
268
static const VMStateDescription aspeed_i2c_bus_vmstate = {
269
.name = TYPE_ASPEED_I2C,
270
- .version_id = 2,
62
- .version_id = 2,
271
- .minimum_version_id = 2,
63
- .minimum_version_id = 2,
272
+ .version_id = 3,
64
+ .version_id = 3,
273
+ .minimum_version_id = 3,
65
+ .minimum_version_id = 3,
274
.fields = (VMStateField[]) {
66
.fields = (const VMStateField[]) {
275
VMSTATE_UINT8(id, AspeedI2CBus),
67
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
276
VMSTATE_UINT32(ctrl, AspeedI2CBus),
68
VMSTATE_UINT32(rx_descriptor, IMXFECState),
277
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
69
VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
278
VMSTATE_UINT32(cmd, AspeedI2CBus),
70
- VMSTATE_UINT32(phy_status, IMXFECState),
279
VMSTATE_UINT32(buf, AspeedI2CBus),
71
- VMSTATE_UINT32(phy_control, IMXFECState),
280
VMSTATE_UINT32(pool_ctrl, AspeedI2CBus),
72
- VMSTATE_UINT32(phy_advertise, IMXFECState),
281
+ VMSTATE_UINT32(dma_addr, AspeedI2CBus),
73
- VMSTATE_UINT32(phy_int, IMXFECState),
282
+ VMSTATE_UINT32(dma_len, AspeedI2CBus),
74
- VMSTATE_UINT32(phy_int_mask, IMXFECState),
283
VMSTATE_END_OF_LIST()
75
VMSTATE_END_OF_LIST()
76
},
77
.subsections = (const VMStateDescription * const []) {
78
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth = {
79
},
80
};
81
82
-#define PHY_INT_ENERGYON (1 << 7)
83
-#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
84
-#define PHY_INT_FAULT (1 << 5)
85
-#define PHY_INT_DOWN (1 << 4)
86
-#define PHY_INT_AUTONEG_LP (1 << 3)
87
-#define PHY_INT_PARFAULT (1 << 2)
88
-#define PHY_INT_AUTONEG_PAGE (1 << 1)
89
-
90
static void imx_eth_update(IMXFECState *s);
91
92
/*
93
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s);
94
* For now we don't handle any GPIO/interrupt line, so the OS will
95
* have to poll for the PHY status.
96
*/
97
-static void imx_phy_update_irq(IMXFECState *s)
98
+static void imx_phy_update_irq(void *opaque, int n, int level)
99
{
100
- imx_eth_update(s);
101
-}
102
-
103
-static void imx_phy_update_link(IMXFECState *s)
104
-{
105
- /* Autonegotiation status mirrors link status. */
106
- if (qemu_get_queue(s->nic)->link_down) {
107
- trace_imx_phy_update_link("down");
108
- s->phy_status &= ~0x0024;
109
- s->phy_int |= PHY_INT_DOWN;
110
- } else {
111
- trace_imx_phy_update_link("up");
112
- s->phy_status |= 0x0024;
113
- s->phy_int |= PHY_INT_ENERGYON;
114
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
115
- }
116
- imx_phy_update_irq(s);
117
+ imx_eth_update(opaque);
118
}
119
120
static void imx_eth_set_link(NetClientState *nc)
121
{
122
- imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
123
-}
124
-
125
-static void imx_phy_reset(IMXFECState *s)
126
-{
127
- trace_imx_phy_reset();
128
-
129
- s->phy_status = 0x7809;
130
- s->phy_control = 0x3000;
131
- s->phy_advertise = 0x01e1;
132
- s->phy_int_mask = 0;
133
- s->phy_int = 0;
134
- imx_phy_update_link(s);
135
+ lan9118_phy_update_link(&IMX_FEC(qemu_get_nic_opaque(nc))->mii,
136
+ nc->link_down);
137
}
138
139
static uint32_t imx_phy_read(IMXFECState *s, int reg)
140
{
141
- uint32_t val;
142
uint32_t phy = reg / 32;
143
144
if (!s->phy_connected) {
145
@@ -XXX,XX +XXX,XX @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
146
147
reg %= 32;
148
149
- switch (reg) {
150
- case 0: /* Basic Control */
151
- val = s->phy_control;
152
- break;
153
- case 1: /* Basic Status */
154
- val = s->phy_status;
155
- break;
156
- case 2: /* ID1 */
157
- val = 0x0007;
158
- break;
159
- case 3: /* ID2 */
160
- val = 0xc0d1;
161
- break;
162
- case 4: /* Auto-neg advertisement */
163
- val = s->phy_advertise;
164
- break;
165
- case 5: /* Auto-neg Link Partner Ability */
166
- val = 0x0f71;
167
- break;
168
- case 6: /* Auto-neg Expansion */
169
- val = 1;
170
- break;
171
- case 29: /* Interrupt source. */
172
- val = s->phy_int;
173
- s->phy_int = 0;
174
- imx_phy_update_irq(s);
175
- break;
176
- case 30: /* Interrupt mask */
177
- val = s->phy_int_mask;
178
- break;
179
- case 17:
180
- case 18:
181
- case 27:
182
- case 31:
183
- qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
184
- TYPE_IMX_FEC, __func__, reg);
185
- val = 0;
186
- break;
187
- default:
188
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
189
- TYPE_IMX_FEC, __func__, reg);
190
- val = 0;
191
- break;
192
- }
193
-
194
- trace_imx_phy_read(val, phy, reg);
195
-
196
- return val;
197
+ return lan9118_phy_read(&s->mii, reg);
198
}
199
200
static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
201
@@ -XXX,XX +XXX,XX @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
202
203
reg %= 32;
204
205
- trace_imx_phy_write(val, phy, reg);
206
-
207
- switch (reg) {
208
- case 0: /* Basic Control */
209
- if (val & 0x8000) {
210
- imx_phy_reset(s);
211
- } else {
212
- s->phy_control = val & 0x7980;
213
- /* Complete autonegotiation immediately. */
214
- if (val & 0x1000) {
215
- s->phy_status |= 0x0020;
216
- }
217
- }
218
- break;
219
- case 4: /* Auto-neg advertisement */
220
- s->phy_advertise = (val & 0x2d7f) | 0x80;
221
- break;
222
- case 30: /* Interrupt mask */
223
- s->phy_int_mask = val & 0xff;
224
- imx_phy_update_irq(s);
225
- break;
226
- case 17:
227
- case 18:
228
- case 27:
229
- case 31:
230
- qemu_log_mask(LOG_UNIMP, "[%s.phy)%s: reg %d not implemented\n",
231
- TYPE_IMX_FEC, __func__, reg);
232
- break;
233
- default:
234
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
235
- TYPE_IMX_FEC, __func__, reg);
236
- break;
237
- }
238
+ lan9118_phy_write(&s->mii, reg, val);
239
}
240
241
static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
242
@@ -XXX,XX +XXX,XX @@ static void imx_eth_reset(DeviceState *d)
243
244
s->rx_descriptor = 0;
245
memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
246
-
247
- /* We also reset the PHY */
248
- imx_phy_reset(s);
249
}
250
251
static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
252
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
253
sysbus_init_irq(sbd, &s->irq[0]);
254
sysbus_init_irq(sbd, &s->irq[1]);
255
256
+ qemu_init_irq(&s->mii_irq, imx_phy_update_irq, s, 0);
257
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
258
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
259
+ return;
260
+ }
261
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
262
+
263
qemu_macaddr_default_if_unset(&s->conf.macaddr);
264
265
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
266
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
267
index XXXXXXX..XXXXXXX 100644
268
--- a/hw/net/lan9118_phy.c
269
+++ b/hw/net/lan9118_phy.c
270
@@ -XXX,XX +XXX,XX @@
271
* Copyright (c) 2009 CodeSourcery, LLC.
272
* Written by Paul Brook
273
*
274
+ * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
275
+ *
276
* This code is licensed under the GNU GPL v2
277
*
278
* Contributions after 2012-01-13 are licensed under the terms of the
279
@@ -XXX,XX +XXX,XX @@
280
#include "hw/resettable.h"
281
#include "migration/vmstate.h"
282
#include "qemu/log.h"
283
+#include "trace.h"
284
285
#define PHY_INT_ENERGYON (1 << 7)
286
#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
287
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
288
289
switch (reg) {
290
case 0: /* Basic Control */
291
- return s->control;
292
+ val = s->control;
293
+ break;
294
case 1: /* Basic Status */
295
- return s->status;
296
+ val = s->status;
297
+ break;
298
case 2: /* ID1 */
299
- return 0x0007;
300
+ val = 0x0007;
301
+ break;
302
case 3: /* ID2 */
303
- return 0xc0d1;
304
+ val = 0xc0d1;
305
+ break;
306
case 4: /* Auto-neg advertisement */
307
- return s->advertise;
308
+ val = s->advertise;
309
+ break;
310
case 5: /* Auto-neg Link Partner Ability */
311
- return 0x0f71;
312
+ val = 0x0f71;
313
+ break;
314
case 6: /* Auto-neg Expansion */
315
- return 1;
316
- /* TODO 17, 18, 27, 29, 30, 31 */
317
+ val = 1;
318
+ break;
319
case 29: /* Interrupt source. */
320
val = s->ints;
321
s->ints = 0;
322
lan9118_phy_update_irq(s);
323
- return val;
324
+ break;
325
case 30: /* Interrupt mask */
326
- return s->int_mask;
327
+ val = s->int_mask;
328
+ break;
329
+ case 17:
330
+ case 18:
331
+ case 27:
332
+ case 31:
333
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
334
+ __func__, reg);
335
+ val = 0;
336
+ break;
337
default:
338
- qemu_log_mask(LOG_GUEST_ERROR,
339
- "lan9118_phy_read: PHY read reg %d\n", reg);
340
- return 0;
341
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
342
+ __func__, reg);
343
+ val = 0;
344
+ break;
284
}
345
}
285
};
346
+
286
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_reset(DeviceState *dev)
347
+ trace_lan9118_phy_read(val, reg);
287
s->busses[i].intr_status = 0;
348
+
288
s->busses[i].cmd = 0;
349
+ return val;
289
s->busses[i].buf = 0;
350
}
290
+ s->busses[i].dma_addr = 0;
351
291
+ s->busses[i].dma_len = 0;
352
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
292
i2c_end_transfer(s->busses[i].bus);
353
{
354
+ trace_lan9118_phy_write(val, reg);
355
+
356
switch (reg) {
357
case 0: /* Basic Control */
358
if (val & 0x8000) {
359
lan9118_phy_reset(s);
360
- break;
361
- }
362
- s->control = val & 0x7980;
363
- /* Complete autonegotiation immediately. */
364
- if (val & 0x1000) {
365
- s->status |= 0x0020;
366
+ } else {
367
+ s->control = val & 0x7980;
368
+ /* Complete autonegotiation immediately. */
369
+ if (val & 0x1000) {
370
+ s->status |= 0x0020;
371
+ }
372
}
373
break;
374
case 4: /* Auto-neg advertisement */
375
s->advertise = (val & 0x2d7f) | 0x80;
376
break;
377
- /* TODO 17, 18, 27, 31 */
378
case 30: /* Interrupt mask */
379
s->int_mask = val & 0xff;
380
lan9118_phy_update_irq(s);
381
break;
382
+ case 17:
383
+ case 18:
384
+ case 27:
385
+ case 31:
386
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
387
+ __func__, reg);
388
+ break;
389
default:
390
- qemu_log_mask(LOG_GUEST_ERROR,
391
- "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
392
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
393
+ __func__, reg);
394
+ break;
293
}
395
}
294
}
396
}
295
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
397
296
memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
398
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
297
"aspeed.i2c-pool", aic->pool_size);
399
298
memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
400
/* Autonegotiation status mirrors link status. */
299
+
401
if (link_down) {
300
+ if (aic->has_dma) {
402
+ trace_lan9118_phy_update_link("down");
301
+ if (!s->dram_mr) {
403
s->status &= ~0x0024;
302
+ error_setg(errp, TYPE_ASPEED_I2C ": 'dram' link not set");
404
s->ints |= PHY_INT_DOWN;
303
+ return;
405
} else {
304
+ }
406
+ trace_lan9118_phy_update_link("up");
305
+
407
s->status |= 0x0024;
306
+ address_space_init(&s->dram_as, s->dram_mr, "dma-dram");
408
s->ints |= PHY_INT_ENERGYON;
307
+ }
409
s->ints |= PHY_INT_AUTONEG_COMPLETE;
308
}
410
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
309
411
310
+static Property aspeed_i2c_properties[] = {
412
void lan9118_phy_reset(Lan9118PhyState *s)
311
+ DEFINE_PROP_LINK("dram", AspeedI2CState, dram_mr,
312
+ TYPE_MEMORY_REGION, MemoryRegion *),
313
+ DEFINE_PROP_END_OF_LIST(),
314
+};
315
+
316
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
317
{
413
{
318
DeviceClass *dc = DEVICE_CLASS(klass);
414
+ trace_lan9118_phy_reset();
319
415
+
320
dc->vmsd = &aspeed_i2c_vmstate;
416
s->control = 0x3000;
321
dc->reset = aspeed_i2c_reset;
417
s->status = 0x7809;
322
+ dc->props = aspeed_i2c_properties;
418
s->advertise = 0x01e1;
323
dc->realize = aspeed_i2c_realize;
419
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_phy = {
324
dc->desc = "Aspeed I2C Controller";
420
.version_id = 1,
325
}
421
.minimum_version_id = 1,
326
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
422
.fields = (const VMStateField[]) {
327
aic->pool_base = 0x200;
423
- VMSTATE_UINT16(control, Lan9118PhyState),
328
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
424
VMSTATE_UINT16(status, Lan9118PhyState),
329
aic->check_sram = true;
425
+ VMSTATE_UINT16(control, Lan9118PhyState),
330
+ aic->has_dma = true;
426
VMSTATE_UINT16(advertise, Lan9118PhyState),
331
}
427
VMSTATE_UINT16(ints, Lan9118PhyState),
332
428
VMSTATE_UINT16(int_mask, Lan9118PhyState),
333
static const TypeInfo aspeed_2500_i2c_info = {
429
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
334
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
430
index XXXXXXX..XXXXXXX 100644
335
aic->pool_size = 0x200;
431
--- a/hw/net/Kconfig
336
aic->pool_base = 0xC00;
432
+++ b/hw/net/Kconfig
337
aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
433
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_SUN8I_EMAC
338
+ aic->has_dma = true;
434
339
}
435
config IMX_FEC
340
436
bool
341
static const TypeInfo aspeed_2600_i2c_info = {
437
+ select LAN9118_PHY
438
439
config CADENCE
440
bool
441
diff --git a/hw/net/trace-events b/hw/net/trace-events
442
index XXXXXXX..XXXXXXX 100644
443
--- a/hw/net/trace-events
444
+++ b/hw/net/trace-events
445
@@ -XXX,XX +XXX,XX @@ allwinner_sun8i_emac_set_link(bool active) "Set link: active=%u"
446
allwinner_sun8i_emac_read(uint64_t offset, uint64_t val) "MMIO read: offset=0x%" PRIx64 " value=0x%" PRIx64
447
allwinner_sun8i_emac_write(uint64_t offset, uint64_t val) "MMIO write: offset=0x%" PRIx64 " value=0x%" PRIx64
448
449
+# lan9118_phy.c
450
+lan9118_phy_read(uint16_t val, int reg) "[0x%02x] -> 0x%04" PRIx16
451
+lan9118_phy_write(uint16_t val, int reg) "[0x%02x] <- 0x%04" PRIx16
452
+lan9118_phy_update_link(const char *s) "%s"
453
+lan9118_phy_reset(void) ""
454
+
455
# lance.c
456
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x"
457
lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x"
458
@@ -XXX,XX +XXX,XX @@ i82596_set_multicast(uint16_t count) "Added %d multicast entries"
459
i82596_channel_attention(void *s) "%p: Received CHANNEL ATTENTION"
460
461
# imx_fec.c
462
-imx_phy_read(uint32_t val, int phy, int reg) "0x%04"PRIx32" <= phy[%d].reg[%d]"
463
imx_phy_read_num(int phy, int configured) "read request from unconfigured phy %d (configured %d)"
464
-imx_phy_write(uint32_t val, int phy, int reg) "0x%04"PRIx32" => phy[%d].reg[%d]"
465
imx_phy_write_num(int phy, int configured) "write request to unconfigured phy %d (configured %d)"
466
-imx_phy_update_link(const char *s) "%s"
467
-imx_phy_reset(void) ""
468
imx_fec_read_bd(uint64_t addr, int flags, int len, int data) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x"
469
imx_enet_read_bd(uint64_t addr, int flags, int len, int data, int options, int status) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x option 0x%04x status 0x%04x"
470
imx_eth_tx_bd_busy(void) "tx_bd ran out of descriptors to transmit"
342
--
471
--
343
2.20.1
472
2.34.1
344
345
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
After the introduction of generic PCIe root port and PCIe-PCI bridge,
3
Turns 0x70 into 0xe0 (== 0x70 << 1) which adds the missing MII_ANLPAR_TX and
4
we will also have SHPC controller on ARM, so just enable SHPC native
4
fixes the MSB of selector field to be zero, as specified in the datasheet.
5
hot plug.
6
5
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
6
Fixes: 2a424990170b "LAN9118 emulation"
8
7
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
8
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
10
Message-id: 20241102125724.532843-4-shentey@gmail.com
12
Cc: Igor Mammedov <imammedo@redhat.com>
13
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
16
Message-id: 20191209063719.23086-3-guoheyi@huawei.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
12
---
19
hw/arm/virt-acpi-build.c | 7 ++++++-
13
hw/net/lan9118_phy.c | 2 +-
20
tests/data/acpi/virt/DSDT | Bin 18462 -> 18462 bytes
14
1 file changed, 1 insertion(+), 1 deletion(-)
21
tests/data/acpi/virt/DSDT.memhp | Bin 19799 -> 19799 bytes
22
tests/data/acpi/virt/DSDT.numamem | Bin 18462 -> 18462 bytes
23
4 files changed, 6 insertions(+), 1 deletion(-)
24
15
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
18
--- a/hw/net/lan9118_phy.c
28
+++ b/hw/arm/virt-acpi-build.c
19
+++ b/hw/net/lan9118_phy.c
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
20
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
21
val = s->advertise;
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
22
break;
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
23
case 5: /* Auto-neg Link Partner Ability */
33
- aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
24
- val = 0x0f71;
34
+
25
+ val = 0x0fe1;
35
+ /*
26
break;
36
+ * Allow OS control for all 5 features:
27
case 6: /* Auto-neg Expansion */
37
+ * PCIeHotplug SHPCHotplug PME AER PCIeCapability.
28
val = 1;
38
+ */
39
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F),
40
aml_name("CTRL")));
41
42
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
43
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
44
index XXXXXXX..XXXXXXX 100644
45
GIT binary patch
46
delta 28
47
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
48
49
delta 28
50
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
51
52
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
53
index XXXXXXX..XXXXXXX 100644
54
GIT binary patch
55
delta 28
56
kcmcaUi}Cs_MlP3NmymE@1_mbija=*8809zbbeqQp0Eq|*2mk;8
57
58
delta 28
59
kcmcaUi}Cs_MlP3NmymE@1_ma@ja=*87-cu_beqQp0ErX{2mk;8
60
61
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
62
index XXXXXXX..XXXXXXX 100644
63
GIT binary patch
64
delta 28
65
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
66
67
delta 28
68
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
69
70
--
29
--
71
2.20.1
30
2.34.1
72
73
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
The AST2600 control register sneakily changed the meaning of bit 4
3
Prefer named constants over magic values for better readability.
4
without anyone noticing. It no longer controls the 1MHz vs APB clock
5
select, and instead always runs at 1MHz.
6
4
7
The AST2500 was always 1MHz too, but it retained bit 4, making it read
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
only. We can model both using the same fixed 1MHz calculation.
6
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
9
7
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
Fixes: 6b2b2a703cad ("hw: wdt_aspeed: Add AST2600 support")
8
Message-id: 20241102125724.532843-5-shentey@gmail.com
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Joel Stanley <joel@jms.id.au>
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Message-id: 20191119141211.25716-10-clg@kaod.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
include/hw/watchdog/wdt_aspeed.h | 1 +
11
include/hw/net/mii.h | 6 +++++
19
hw/watchdog/wdt_aspeed.c | 21 +++++++++++++++++----
12
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
20
2 files changed, 18 insertions(+), 4 deletions(-)
13
2 files changed, 46 insertions(+), 23 deletions(-)
21
14
22
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
15
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
23
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/watchdog/wdt_aspeed.h
17
--- a/include/hw/net/mii.h
25
+++ b/include/hw/watchdog/wdt_aspeed.h
18
+++ b/include/hw/net/mii.h
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedWDTClass {
19
@@ -XXX,XX +XXX,XX @@
27
uint32_t ext_pulse_width_mask;
20
#define MII_BMSR_JABBER (1 << 1) /* Jabber detected */
28
uint32_t reset_ctrl_reg;
21
#define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */
29
void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
22
30
+ void (*wdt_reload)(AspeedWDTState *s);
23
+#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */
31
} AspeedWDTClass;
24
#define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */
32
25
#define MII_ANAR_PAUSE (1 << 10) /* Try for pause */
33
#endif /* WDT_ASPEED_H */
26
#define MII_ANAR_TXFD (1 << 8)
34
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
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
35
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/watchdog/wdt_aspeed.c
48
--- a/hw/net/lan9118_phy.c
37
+++ b/hw/watchdog/wdt_aspeed.c
49
+++ b/hw/net/lan9118_phy.c
38
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
50
@@ -XXX,XX +XXX,XX @@
39
51
40
}
52
#include "qemu/osdep.h"
41
53
#include "hw/net/lan9118_phy.h"
42
-static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
54
+#include "hw/net/mii.h"
43
+static void aspeed_wdt_reload(AspeedWDTState *s)
55
#include "hw/irq.h"
44
{
56
#include "hw/resettable.h"
45
uint64_t reload;
57
#include "migration/vmstate.h"
46
58
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
47
- if (pclk) {
59
uint16_t val;
48
+ if (!(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK)) {
60
49
reload = muldiv64(s->regs[WDT_RELOAD_VALUE], NANOSECONDS_PER_SECOND,
61
switch (reg) {
50
s->pclk_freq);
62
- case 0: /* Basic Control */
51
} else {
63
+ case MII_BMCR:
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
64
val = s->control;
53
}
65
break;
54
}
66
- case 1: /* Basic Status */
55
67
+ case MII_BMSR:
56
+static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
68
val = s->status;
57
+{
69
break;
58
+ uint64_t reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL;
70
- case 2: /* ID1 */
59
+
71
- val = 0x0007;
60
+ if (aspeed_wdt_is_enabled(s)) {
72
+ case MII_PHYID1:
61
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
73
+ val = SMSCLAN9118_PHYID1;
62
+ }
74
break;
63
+}
75
- case 3: /* ID2 */
64
+
76
- val = 0xc0d1;
65
+
77
+ case MII_PHYID2:
66
static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
78
+ val = SMSCLAN9118_PHYID2;
67
unsigned size)
79
break;
68
{
80
- case 4: /* Auto-neg advertisement */
69
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
81
+ case MII_ANAR:
70
case WDT_RESTART:
82
val = s->advertise;
71
if ((data & 0xFFFF) == WDT_RESTART_MAGIC) {
83
break;
72
s->regs[WDT_STATUS] = s->regs[WDT_RELOAD_VALUE];
84
- case 5: /* Auto-neg Link Partner Ability */
73
- aspeed_wdt_reload(s, !(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK));
85
- val = 0x0fe1;
74
+ awc->wdt_reload(s);
86
+ case MII_ANLPAR:
87
+ val = MII_ANLPAR_PAUSEASY | MII_ANLPAR_PAUSE | MII_ANLPAR_T4 |
88
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
89
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
90
break;
91
- case 6: /* Auto-neg Expansion */
92
- val = 1;
93
+ case MII_ANER:
94
+ val = MII_ANER_NWAY;
95
break;
96
case 29: /* Interrupt source. */
97
val = s->ints;
98
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
99
trace_lan9118_phy_write(val, reg);
100
101
switch (reg) {
102
- case 0: /* Basic Control */
103
- if (val & 0x8000) {
104
+ case MII_BMCR:
105
+ if (val & MII_BMCR_RESET) {
106
lan9118_phy_reset(s);
107
} else {
108
- s->control = val & 0x7980;
109
+ s->control = val & (MII_BMCR_LOOPBACK | MII_BMCR_SPEED100 |
110
+ MII_BMCR_AUTOEN | MII_BMCR_PDOWN | MII_BMCR_FD |
111
+ MII_BMCR_CTST);
112
/* Complete autonegotiation immediately. */
113
- if (val & 0x1000) {
114
- s->status |= 0x0020;
115
+ if (val & MII_BMCR_AUTOEN) {
116
+ s->status |= MII_BMSR_AN_COMP;
117
}
75
}
118
}
76
break;
119
break;
77
case WDT_CTRL:
120
- case 4: /* Auto-neg advertisement */
78
if (enable && !aspeed_wdt_is_enabled(s)) {
121
- s->advertise = (val & 0x2d7f) | 0x80;
79
s->regs[WDT_CTRL] = data;
122
+ case MII_ANAR:
80
- aspeed_wdt_reload(s, !(data & WDT_CTRL_1MHZ_CLK));
123
+ s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
81
+ awc->wdt_reload(s);
124
+ MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
82
} else if (!enable && aspeed_wdt_is_enabled(s)) {
125
+ MII_ANAR_SELECT))
83
s->regs[WDT_CTRL] = data;
126
+ | MII_ANAR_TX;
84
timer_del(s->timer);
127
break;
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data)
128
case 30: /* Interrupt mask */
86
awc->offset = 0x20;
129
s->int_mask = val & 0xff;
87
awc->ext_pulse_width_mask = 0xff;
130
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
88
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
131
/* Autonegotiation status mirrors link status. */
89
+ awc->wdt_reload = aspeed_wdt_reload;
132
if (link_down) {
90
}
133
trace_lan9118_phy_update_link("down");
91
134
- s->status &= ~0x0024;
92
static const TypeInfo aspeed_2400_wdt_info = {
135
+ s->status &= ~(MII_BMSR_AN_COMP | MII_BMSR_LINK_ST);
93
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
136
s->ints |= PHY_INT_DOWN;
94
awc->ext_pulse_width_mask = 0xfffff;
137
} else {
95
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
138
trace_lan9118_phy_update_link("up");
96
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
139
- s->status |= 0x0024;
97
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
140
+ s->status |= MII_BMSR_AN_COMP | MII_BMSR_LINK_ST;
98
}
141
s->ints |= PHY_INT_ENERGYON;
99
142
s->ints |= PHY_INT_AUTONEG_COMPLETE;
100
static const TypeInfo aspeed_2500_wdt_info = {
143
}
101
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
144
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_reset(Lan9118PhyState *s)
102
awc->ext_pulse_width_mask = 0xfffff; /* TODO */
145
{
103
awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
146
trace_lan9118_phy_reset();
104
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
147
105
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
148
- s->control = 0x3000;
106
}
149
- s->status = 0x7809;
107
150
- s->advertise = 0x01e1;
108
static const TypeInfo aspeed_2600_wdt_info = {
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);
109
--
166
--
110
2.20.1
167
2.34.1
111
112
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
The last argument of AML bit and/or statement is the target variable,
3
The real device advertises this mode and the device model already advertises
4
so we don't need to use a NULL target and then an additional store
4
100 mbps half duplex and 10 mbps full+half duplex. So advertise this mode to
5
operation; using just aml_and() or aml_or() statement is enough.
5
make the model more realistic.
6
6
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
8
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
9
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
Cc: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20241102125724.532843-6-shentey@gmail.com
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
12
Cc: Igor Mammedov <imammedo@redhat.com>
13
Suggested-by: Igor Mammedov <imammedo@redhat.com>
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
16
Message-id: 20191209063719.23086-2-guoheyi@huawei.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
12
---
19
hw/arm/virt-acpi-build.c | 16 ++++++++--------
13
hw/net/lan9118_phy.c | 4 ++--
20
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
14
1 file changed, 2 insertions(+), 2 deletions(-)
21
tests/data/acpi/virt/DSDT.memhp | Bin 19807 -> 19799 bytes
22
tests/data/acpi/virt/DSDT.numamem | Bin 18470 -> 18462 bytes
23
4 files changed, 8 insertions(+), 8 deletions(-)
24
15
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
18
--- a/hw/net/lan9118_phy.c
28
+++ b/hw/arm/virt-acpi-build.c
19
+++ b/hw/net/lan9118_phy.c
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
20
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
21
break;
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
22
case MII_ANAR:
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
23
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
33
- aml_append(ifctx, aml_store(aml_and(aml_name("CTRL"), aml_int(0x1D), NULL),
24
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
34
- aml_name("CTRL")));
25
- MII_ANAR_SELECT))
35
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
26
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
36
+ aml_name("CTRL")));
27
+ MII_ANAR_10 | MII_ANAR_SELECT))
37
28
| MII_ANAR_TX;
38
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
29
break;
39
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x08), NULL),
30
case 30: /* Interrupt mask */
40
- aml_name("CDW1")));
41
+ aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
42
+ aml_name("CDW1")));
43
aml_append(ifctx, ifctx1);
44
45
ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), aml_name("CTRL"))));
46
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x10), NULL),
47
- aml_name("CDW1")));
48
+ aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10),
49
+ aml_name("CDW1")));
50
aml_append(ifctx, ifctx1);
51
52
aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3")));
53
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
54
aml_append(method, ifctx);
55
56
elsectx = aml_else();
57
- aml_append(elsectx, aml_store(aml_or(aml_name("CDW1"), aml_int(4), NULL),
58
- aml_name("CDW1")));
59
+ aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4),
60
+ aml_name("CDW1")));
61
aml_append(elsectx, aml_return(aml_arg(3)));
62
aml_append(method, elsectx);
63
aml_append(dev, method);
64
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
65
index XXXXXXX..XXXXXXX 100644
66
GIT binary patch
67
delta 133
68
zcmZ2BfpOjhMlP3Nmk>D*1_q|2iCof5o%I{lJ2{y;?{412x!p#<jWgaq*qNm(o59&7
69
z+;D-%<VrV7_iE>mARjJS5V=5L(&S9WT970c2Uv;Nq{%?q7$gZ1761tsfcPNsCD{x4
70
MAmS{W8QoPG0j8@bzW@LL
71
72
delta 141
73
zcmbO?fpOUcMlP3Nmk>1%1_q`n6S<_B8XGpMcXBc{-rKy1bGwazA7{LOuro_nHiNTE
74
zxZwi7$(3%F{sq;}AwfP|vJ4<<fzYJMnT!RsAbBnhh%$*ulYv}gkTg_604z}e5&_99
75
R$zCV`m0@An{L@X95dZ+BD!u>!
76
77
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
78
index XXXXXXX..XXXXXXX 100644
79
GIT binary patch
80
delta 132
81
zcmcaVi}Cs_MlP3NmymE@1_ma@iCof*O&is^IGH-{Zr;SX-A2HTGu}VgnWZb6!PzC;
82
zaDm6<N;gaQYUhw3A1+xCxj<mj<V?m|kR%reSc%xA$w1l|Bnc4~00|d>_#p8m*$ep~
83
L;w+mP-Q(B*s{AMU
84
85
delta 140
86
zcmcaUi}C&}MlP3Nmymd01_maViCof*T^rT9IGGynZQjJW-A2HVGu}VgnWZb6!PzC;
87
zaDm_CN;gaYf@<fGARjJS1`xGCXwu|N#)4XqJQoK<nZ%^YK&~-J8Y&?GmM8#;fMk|r
88
QFBE{vurO@?=@!QZ00dYn_y7O^
89
90
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
91
index XXXXXXX..XXXXXXX 100644
92
GIT binary patch
93
delta 133
94
zcmZ2BfpOjhMlP3Nmk>D*1_q|2iCof5o%I{lJ2{y;?{412x!p#<jWgaq*qNm(o59&7
95
z+;D-%<VrV7_iE>mARjJS5V=5L(&S9WT970c2Uv;Nq{%?q7$gZ1761tsfcPNsCD{x4
96
MAmS{W8QoPG0j8@bzW@LL
97
98
delta 141
99
zcmbO?fpOUcMlP3Nmk>1%1_q`n6S<_B8XGpMcXBc{-rKy1bGwazA7{LOuro_nHiNTE
100
zxZwi7$(3%F{sq;}AwfP|vJ4<<fzYJMnT!RsAbBnhh%$*ulYv}gkTg_604z}e5&_99
101
R$zCV`m0@An{L@X95dZ+BD!u>!
102
103
--
31
--
104
2.20.1
32
2.34.1
105
106
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
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
The Aspeed Watchdog and Timer models have a link pointing to the SCU
7
For the cases where the infzero test in pickNaNMulAdd was
4
controller model of the machine.
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
Change the "scu" property definition so that it explicitly sets the
14
For Arm, this looks like it might be a behaviour change because we
7
pointer. The property isn't optional : not being able to set the link
15
used to set float_flag_invalid | float_flag_invalid_imz only if C is
8
is a bug and QEMU should rather abort than exit in this case.
16
a quiet NaN. However, it is not, because Arm target code never looks
17
at float_flag_invalid_imz, and for the (0 * inf) + SNaN case we
18
already raised float_flag_invalid via the "abc_mask &
19
float_cmask_snan" check in pick_nan_muladd.
9
20
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
21
For any target architecture using the "default implementation" at the
11
Reviewed-by: Greg Kurz <groug@kaod.org>
22
bottom of the ifdef, this is a behaviour change but will be fixing a
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
23
bug (where we failed to raise the Invalid exception for (0 * inf +
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
24
QNaN). The architectures using the default case are:
14
Message-id: 20191119141211.25716-17-clg@kaod.org
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
15
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
16
---
37
---
17
hw/arm/aspeed_ast2600.c | 8 ++++----
38
fpu/softfloat-parts.c.inc | 13 +++++++------
18
hw/arm/aspeed_soc.c | 8 ++++----
39
fpu/softfloat-specialize.c.inc | 29 +----------------------------
19
hw/timer/aspeed_timer.c | 17 +++++++++--------
40
2 files changed, 8 insertions(+), 34 deletions(-)
20
hw/watchdog/wdt_aspeed.c | 17 ++++++++---------
21
4 files changed, 25 insertions(+), 25 deletions(-)
22
41
23
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
42
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
24
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/aspeed_ast2600.c
44
--- a/fpu/softfloat-parts.c.inc
26
+++ b/hw/arm/aspeed_ast2600.c
45
+++ b/fpu/softfloat-parts.c.inc
27
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
46
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
28
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
47
int ab_mask, int abc_mask)
29
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
48
{
30
sizeof(s->timerctrl), typename);
49
int which;
31
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
50
+ bool infzero = (ab_mask == float_cmask_infzero);
32
- OBJECT(&s->scu), &error_abort);
51
33
52
if (unlikely(abc_mask & float_cmask_snan)) {
34
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
53
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
35
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
37
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
38
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
39
sizeof(s->wdt[i]), typename);
40
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
41
- OBJECT(&s->scu), &error_abort);
42
}
54
}
43
55
44
for (i = 0; i < sc->macs_num; i++) {
56
- which = pickNaNMulAdd(a->cls, b->cls, c->cls,
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
57
- ab_mask == float_cmask_infzero, s);
46
aspeed_soc_get_irq(s, ASPEED_RTC));
58
+ if (infzero) {
47
59
+ /* This is (0 * inf) + NaN or (inf * 0) + NaN */
48
/* Timer */
60
+ float_raise(float_flag_invalid | float_flag_invalid_imz, s);
49
+ object_property_set_link(OBJECT(&s->timerctrl),
61
+ }
50
+ OBJECT(&s->scu), "scu", &error_abort);
62
+
51
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
63
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
52
if (err) {
64
53
error_propagate(errp, err);
65
if (s->default_nan_mode || which == 3) {
54
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
66
- /*
55
for (i = 0; i < sc->wdts_num; i++) {
67
- * Note that this check is after pickNaNMulAdd so that function
56
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
68
- * has an opportunity to set the Invalid flag for infzero.
57
69
- */
58
+ object_property_set_link(OBJECT(&s->wdt[i]),
70
parts_default_nan(a, s);
59
+ OBJECT(&s->scu), "scu", &error_abort);
71
return a;
60
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
72
}
61
if (err) {
73
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
62
error_propagate(errp, err);
63
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
64
index XXXXXXX..XXXXXXX 100644
74
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/aspeed_soc.c
75
--- a/fpu/softfloat-specialize.c.inc
66
+++ b/hw/arm/aspeed_soc.c
76
+++ b/fpu/softfloat-specialize.c.inc
67
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
77
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
68
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
78
* the default NaN
69
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
79
*/
70
sizeof(s->timerctrl), typename);
80
if (infzero && is_qnan(c_cls)) {
71
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
81
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
72
- OBJECT(&s->scu), &error_abort);
82
return 3;
73
74
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
75
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
76
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
77
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
78
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
79
sizeof(s->wdt[i]), typename);
80
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
81
- OBJECT(&s->scu), &error_abort);
82
}
83
}
83
84
84
for (i = 0; i < sc->macs_num; i++) {
85
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
86
* case sets InvalidOp and returns the default NaN
86
aspeed_soc_get_irq(s, ASPEED_RTC));
87
*/
87
88
if (infzero) {
88
/* Timer */
89
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
89
+ object_property_set_link(OBJECT(&s->timerctrl),
90
return 3;
90
+ OBJECT(&s->scu), "scu", &error_abort);
91
}
91
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
92
/* Prefer sNaN over qNaN, in the a, b, c order. */
92
if (err) {
93
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
93
error_propagate(errp, err);
94
* For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
94
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
95
* case sets InvalidOp and returns the input value 'c'
95
for (i = 0; i < sc->wdts_num; i++) {
96
*/
96
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
97
- if (infzero) {
97
98
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
98
+ object_property_set_link(OBJECT(&s->wdt[i]),
99
- return 2;
99
+ OBJECT(&s->scu), "scu", &error_abort);
100
- }
100
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
101
/* Prefer sNaN over qNaN, in the c, a, b order. */
101
if (err) {
102
if (is_snan(c_cls)) {
102
error_propagate(errp, err);
103
return 2;
103
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
104
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
104
index XXXXXXX..XXXXXXX 100644
105
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
105
--- a/hw/timer/aspeed_timer.c
106
* case sets InvalidOp and returns the input value 'c'
106
+++ b/hw/timer/aspeed_timer.c
107
*/
107
@@ -XXX,XX +XXX,XX @@
108
- if (infzero) {
108
#include "qemu/timer.h"
109
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
109
#include "qemu/log.h"
110
- return 2;
110
#include "qemu/module.h"
111
+#include "hw/qdev-properties.h"
112
#include "trace.h"
113
114
#define TIMER_NR_REGS 4
115
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_realize(DeviceState *dev, Error **errp)
116
int i;
117
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
118
AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
119
- Object *obj;
120
- Error *err = NULL;
121
122
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
123
- if (!obj) {
124
- error_propagate_prepend(errp, err, "required link 'scu' not found: ");
125
- return;
126
- }
111
- }
127
- s->scu = ASPEED_SCU(obj);
112
+
128
+ assert(s->scu);
113
/* Prefer sNaN over qNaN, in the c, a, b order. */
129
114
if (is_snan(c_cls)) {
130
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
115
return 2;
131
aspeed_init_one_timer(s, i);
116
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
132
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_timer_state = {
117
* to return an input NaN if we have one (ie c) rather than generating
118
* a default NaN
119
*/
120
- if (infzero) {
121
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
122
- return 2;
123
- }
124
125
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
126
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
127
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
128
return 1;
133
}
129
}
134
};
130
#elif defined(TARGET_RISCV)
135
131
- /* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */
136
+static Property aspeed_timer_properties[] = {
132
- if (infzero) {
137
+ DEFINE_PROP_LINK("scu", AspeedTimerCtrlState, scu, TYPE_ASPEED_SCU,
133
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
138
+ AspeedSCUState *),
139
+ DEFINE_PROP_END_OF_LIST(),
140
+};
141
+
142
static void timer_class_init(ObjectClass *klass, void *data)
143
{
144
DeviceClass *dc = DEVICE_CLASS(klass);
145
@@ -XXX,XX +XXX,XX @@ static void timer_class_init(ObjectClass *klass, void *data)
146
dc->reset = aspeed_timer_reset;
147
dc->desc = "ASPEED Timer";
148
dc->vmsd = &vmstate_aspeed_timer_state;
149
+ dc->props = aspeed_timer_properties;
150
}
151
152
static const TypeInfo aspeed_timer_info = {
153
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/watchdog/wdt_aspeed.c
156
+++ b/hw/watchdog/wdt_aspeed.c
157
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
158
{
159
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
160
AspeedWDTState *s = ASPEED_WDT(dev);
161
- Error *err = NULL;
162
- Object *obj;
163
164
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
165
- if (!obj) {
166
- error_propagate(errp, err);
167
- error_prepend(errp, "required link 'scu' not found: ");
168
- return;
169
- }
134
- }
170
- s->scu = ASPEED_SCU(obj);
135
return 3; /* default NaN */
171
+ assert(s->scu);
136
#elif defined(TARGET_S390X)
172
137
if (infzero) {
173
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, aspeed_wdt_timer_expired, dev);
138
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
174
139
return 3;
175
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
140
}
176
sysbus_init_mmio(sbd, &s->iomem);
141
177
}
142
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
178
143
return 2;
179
+static Property aspeed_wdt_properties[] = {
144
}
180
+ DEFINE_PROP_LINK("scu", AspeedWDTState, scu, TYPE_ASPEED_SCU,
145
#elif defined(TARGET_SPARC)
181
+ AspeedSCUState *),
146
- /* For (inf,0,nan) return c. */
182
+ DEFINE_PROP_END_OF_LIST(),
147
- if (infzero) {
183
+};
148
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
184
+
149
- return 2;
185
static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
150
- }
186
{
151
/* Prefer SNaN over QNaN, order C, B, A. */
187
DeviceClass *dc = DEVICE_CLASS(klass);
152
if (is_snan(c_cls)) {
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
153
return 2;
189
dc->reset = aspeed_wdt_reset;
154
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
190
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
155
* For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
191
dc->vmsd = &vmstate_aspeed_wdt;
156
* an input NaN if we have one (ie c).
192
+ dc->props = aspeed_wdt_properties;
157
*/
193
}
158
- if (infzero) {
194
159
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
195
static const TypeInfo aspeed_wdt_info = {
160
- return 2;
161
- }
162
if (status->use_first_nan) {
163
if (is_nan(a_cls)) {
164
return 0;
196
--
165
--
197
2.20.1
166
2.34.1
198
199
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: Beata Michalska <beata.michalska@linaro.org>
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
ARMv8.2 introduced support for Data Cache Clean instructions
3
architectures thus do different things:
4
to PoP (point-of-persistence) - DC CVAP and PoDP (point-of-deep-persistence)
4
* some return the default NaN
5
- DV CVADP. Both specify conceptual points in a memory system where all writes
5
* some return the input NaN
6
that are to reach them are considered persistent.
6
* Arm returns the default NaN if the input NaN is quiet,
7
The support provided considers both to be actually the same so there is no
7
and the input NaN if it is signalling
8
distinction between the two. If none is available (there is no backing store
8
9
for given memory) both will result in Data Cache Clean up to the point of
9
We want to make this logic be runtime selected rather than
10
coherency. Otherwise sync for the specified range shall be performed.
10
hardcoded into the binary, because:
11
11
* this will let us have multiple targets in one QEMU binary
12
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
12
* the Arm FEAT_AFP architectural feature includes letting
13
the guest select a NaN propagation rule at runtime
14
15
In this commit we add an enum for the propagation rule, the field in
16
float_status, and the corresponding getters and setters. We change
17
pickNaNMulAdd to honour this, but because all targets still leave
18
this field at its default 0 value, the fallback logic will pick the
19
rule type with the old ifdef ladder.
20
21
Note that four architectures both use the muladd softfloat functions
22
and did not have a branch of the ifdef ladder to specify their
23
behaviour (and so were ending up with the "default" case, probably
24
wrongly): i386, HPPA, SH4 and Tricore. SH4 and Tricore both set
25
default_nan_mode, and so will never get into pickNaNMulAdd(). For
26
HPPA and i386 we retain the same behaviour as the old default-case,
27
which is to not ever return the default NaN. This might not be
28
correct but it is not a behaviour change.
29
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191121000843.24844-5-beata.michalska@linaro.org
32
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
33
---
17
target/arm/cpu.h | 10 ++++++++
34
include/fpu/softfloat-helpers.h | 11 ++++
18
linux-user/elfload.c | 2 ++
35
include/fpu/softfloat-types.h | 23 +++++++++
19
target/arm/cpu64.c | 1 +
36
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
20
target/arm/helper.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
37
3 files changed, 95 insertions(+), 30 deletions(-)
21
4 files changed, 69 insertions(+)
38
22
39
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
41
--- a/include/fpu/softfloat-helpers.h
26
+++ b/target/arm/cpu.h
42
+++ b/include/fpu/softfloat-helpers.h
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
43
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
28
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
44
status->float_2nan_prop_rule = rule;
29
}
45
}
30
46
31
+static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
47
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
+ float_status *status)
32
+{
49
+{
33
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0;
50
+ status->float_infzeronan_rule = rule;
34
+}
51
+}
35
+
52
+
36
+static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
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)
37
+{
61
+{
38
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
62
+ return status->float_infzeronan_rule;
39
+}
63
+}
40
+
64
+
41
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
65
static inline bool get_flush_to_zero(float_status *status)
42
{
66
{
43
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
67
return status->flush_to_zero;
44
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
68
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
45
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
46
--- a/linux-user/elfload.c
70
--- a/include/fpu/softfloat-types.h
47
+++ b/linux-user/elfload.c
71
+++ b/include/fpu/softfloat-types.h
48
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
72
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
49
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
73
float_2nan_prop_x87,
50
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
74
} Float2NaNPropRule;
51
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
75
52
+ GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
76
+/*
53
77
+ * Rule for result of fused multiply-add 0 * Inf + NaN.
54
return hwcaps;
78
+ * This must be a NaN, but implementations differ on whether this
55
}
79
+ * is the input NaN or the default NaN.
56
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
80
+ *
57
ARMCPU *cpu = ARM_CPU(thread_cpu);
81
+ * You don't need to set this if default_nan_mode is enabled.
58
uint32_t hwcaps = 0;
82
+ * When not in default-NaN mode, it is an error for the target
59
83
+ * not to set the rule in float_status if it uses muladd, and we
60
+ GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
84
+ * will assert if we need to handle an input NaN and no rule was
61
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
85
+ * selected.
62
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
86
+ */
63
87
+typedef enum __attribute__((__packed__)) {
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
88
+ /* No propagation rule specified */
89
+ float_infzeronan_none = 0,
90
+ /* Result is never the default NaN (so always the input NaN) */
91
+ float_infzeronan_dnan_never,
92
+ /* Result is always the default NaN */
93
+ float_infzeronan_dnan_always,
94
+ /* Result is the default NaN if the input NaN is quiet */
95
+ float_infzeronan_dnan_if_qnan,
96
+} FloatInfZeroNaNRule;
97
+
98
/*
99
* Floating Point Status. Individual architectures may maintain
100
* several versions of float_status for different functions. The
101
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
102
FloatRoundMode float_rounding_mode;
103
FloatX80RoundPrec floatx80_rounding_precision;
104
Float2NaNPropRule float_2nan_prop_rule;
105
+ FloatInfZeroNaNRule float_infzeronan_rule;
106
bool tininess_before_rounding;
107
/* should denormalised results go to zero and set the inexact flag? */
108
bool flush_to_zero;
109
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
65
index XXXXXXX..XXXXXXX 100644
110
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
111
--- a/fpu/softfloat-specialize.c.inc
67
+++ b/target/arm/cpu64.c
112
+++ b/fpu/softfloat-specialize.c.inc
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
113
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
69
cpu->isar.id_aa64isar0 = t;
114
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
70
115
bool infzero, float_status *status)
71
t = cpu->isar.id_aa64isar1;
116
{
72
+ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
117
+ FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
73
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
118
+
74
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
119
/*
75
t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
120
* We guarantee not to require the target to tell us how to
76
diff --git a/target/arm/helper.c b/target/arm/helper.c
121
* pick a NaN if we're always returning the default NaN.
77
index XXXXXXX..XXXXXXX 100644
122
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
78
--- a/target/arm/helper.c
123
* specify.
79
+++ b/target/arm/helper.c
124
*/
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo rndr_reginfo[] = {
125
assert(!status->default_nan_mode);
81
.access = PL0_R, .readfn = rndr_readfn },
126
+
82
REGINFO_SENTINEL
127
+ if (rule == float_infzeronan_none) {
83
};
128
+ /*
84
+
129
+ * Temporarily fall back to ifdef ladder
85
+#ifndef CONFIG_USER_ONLY
130
+ */
86
+static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
131
#if defined(TARGET_ARM)
87
+ uint64_t value)
132
- /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
88
+{
133
- * the default NaN
89
+ ARMCPU *cpu = env_archcpu(env);
134
- */
90
+ /* CTR_EL0 System register -> DminLine, bits [19:16] */
135
- if (infzero && is_qnan(c_cls)) {
91
+ uint64_t dline_size = 4 << ((cpu->ctr >> 16) & 0xF);
136
- return 3;
92
+ uint64_t vaddr_in = (uint64_t) value;
137
+ /*
93
+ uint64_t vaddr = vaddr_in & ~(dline_size - 1);
138
+ * For ARM, the (inf,zero,qnan) case returns the default NaN,
94
+ void *haddr;
139
+ * but (inf,zero,snan) returns the input NaN.
95
+ int mem_idx = cpu_mmu_index(env, false);
140
+ */
96
+
141
+ rule = float_infzeronan_dnan_if_qnan;
97
+ /* This won't be crossing page boundaries */
142
+#elif defined(TARGET_MIPS)
98
+ haddr = probe_read(env, vaddr, dline_size, mem_idx, GETPC());
143
+ if (snan_bit_is_one(status)) {
99
+ if (haddr) {
144
+ /*
100
+
145
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
101
+ ram_addr_t offset;
146
+ * case sets InvalidOp and returns the default NaN
102
+ MemoryRegion *mr;
147
+ */
103
+
148
+ rule = float_infzeronan_dnan_always;
104
+ /* RCU lock is already being held */
149
+ } else {
105
+ mr = memory_region_from_host(haddr, &offset);
150
+ /*
106
+
151
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
107
+ if (mr) {
152
+ * case sets InvalidOp and returns the input value 'c'
108
+ memory_region_do_writeback(mr, offset, dline_size);
153
+ */
154
+ rule = float_infzeronan_dnan_never;
155
+ }
156
+#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
157
+ defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
158
+ defined(TARGET_I386) || defined(TARGET_LOONGARCH)
159
+ /*
160
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
161
+ * case sets InvalidOp and returns the input value 'c'
162
+ */
163
+ /*
164
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
165
+ * to return an input NaN if we have one (ie c) rather than generating
166
+ * a default NaN
167
+ */
168
+ rule = float_infzeronan_dnan_never;
169
+#elif defined(TARGET_S390X)
170
+ rule = float_infzeronan_dnan_always;
171
+#endif
172
}
173
174
+ if (infzero) {
175
+ /*
176
+ * Inf * 0 + NaN -- some implementations return the default NaN here,
177
+ * and some return the input NaN.
178
+ */
179
+ switch (rule) {
180
+ case float_infzeronan_dnan_never:
181
+ return 2;
182
+ case float_infzeronan_dnan_always:
183
+ return 3;
184
+ case float_infzeronan_dnan_if_qnan:
185
+ return is_qnan(c_cls) ? 3 : 2;
186
+ default:
187
+ g_assert_not_reached();
109
+ }
188
+ }
110
+ }
189
+ }
111
+}
190
+
112
+
191
+#if defined(TARGET_ARM)
113
+static const ARMCPRegInfo dcpop_reg[] = {
192
+
114
+ { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
193
/* This looks different from the ARM ARM pseudocode, because the ARM ARM
115
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
194
* puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
116
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
195
*/
117
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
196
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
118
+ REGINFO_SENTINEL
197
}
119
+};
198
#elif defined(TARGET_MIPS)
120
+
199
if (snan_bit_is_one(status)) {
121
+static const ARMCPRegInfo dcpodp_reg[] = {
200
- /*
122
+ { .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
201
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
123
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
202
- * case sets InvalidOp and returns the default NaN
124
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
203
- */
125
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
204
- if (infzero) {
126
+ REGINFO_SENTINEL
205
- return 3;
127
+};
206
- }
128
+#endif /*CONFIG_USER_ONLY*/
207
/* Prefer sNaN over qNaN, in the a, b, c order. */
129
+
208
if (is_snan(a_cls)) {
130
#endif
209
return 0;
131
210
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
132
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
211
return 2;
133
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
212
}
134
if (cpu_isar_feature(aa64_rndr, cpu)) {
213
} else {
135
define_arm_cp_regs(cpu, rndr_reginfo);
214
- /*
136
}
215
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
137
+#ifndef CONFIG_USER_ONLY
216
- * case sets InvalidOp and returns the input value 'c'
138
+ /* Data Cache clean instructions up to PoP */
217
- */
139
+ if (cpu_isar_feature(aa64_dcpop, cpu)) {
218
/* Prefer sNaN over qNaN, in the c, a, b order. */
140
+ define_one_arm_cp_reg(cpu, dcpop_reg);
219
if (is_snan(c_cls)) {
141
+
220
return 2;
142
+ if (cpu_isar_feature(aa64_dcpodp, cpu)) {
221
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
143
+ define_one_arm_cp_reg(cpu, dcpodp_reg);
222
}
144
+ }
223
}
145
+ }
224
#elif defined(TARGET_LOONGARCH64)
146
+#endif /*CONFIG_USER_ONLY*/
225
- /*
147
#endif
226
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
148
227
- * case sets InvalidOp and returns the input value 'c'
149
/*
228
- */
229
-
230
/* Prefer sNaN over qNaN, in the c, a, b order. */
231
if (is_snan(c_cls)) {
232
return 2;
233
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
234
return 1;
235
}
236
#elif defined(TARGET_PPC)
237
- /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
238
- * to return an input NaN if we have one (ie c) rather than generating
239
- * a default NaN
240
- */
241
-
242
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
243
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
244
*/
245
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
246
return 1;
247
}
248
#elif defined(TARGET_S390X)
249
- if (infzero) {
250
- return 3;
251
- }
252
-
253
if (is_snan(a_cls)) {
254
return 0;
255
} else if (is_snan(b_cls)) {
150
--
256
--
151
2.20.1
257
2.34.1
152
153
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: Marc Zyngier <maz@kernel.org>
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
HCR_EL2.TID2 mandates that access from EL1 to CTR_EL0, CCSIDR_EL1,
3
are NaNs. As a result different architectures have ended up with
4
CCSIDR2_EL1, CLIDR_EL1, CSSELR_EL1 are trapped to EL2, and QEMU
4
different rules for propagating NaNs.
5
completely ignores it, making it impossible for hypervisors to
5
6
virtualize the cache hierarchy.
6
QEMU currently hardcodes the NaN propagation logic into the binary
7
7
because pickNaNMulAdd() has an ifdef ladder for different targets.
8
Do the right thing by trapping to EL2 if HCR_EL2.TID2 is set.
8
We want to make the propagation rule instead be selectable at
9
9
runtime, because:
10
Signed-off-by: Marc Zyngier <maz@kernel.org>
10
* this will let us have multiple targets in one QEMU binary
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.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
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20191201122018.25808-2-maz@kernel.org
26
Message-id: 20241202131347.498124-16-peter.maydell@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
27
---
16
target/arm/helper.c | 31 +++++++++++++++++++++++++++----
28
include/fpu/softfloat-helpers.h | 11 +++
17
1 file changed, 27 insertions(+), 4 deletions(-)
29
include/fpu/softfloat-types.h | 55 +++++++++++
18
30
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
19
diff --git a/target/arm/helper.c b/target/arm/helper.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
20
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
35
--- a/include/fpu/softfloat-helpers.h
22
+++ b/target/arm/helper.c
36
+++ b/include/fpu/softfloat-helpers.h
23
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
37
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
24
raw_write(env, ri, value);
38
status->float_2nan_prop_rule = rule;
25
}
39
}
26
40
27
+static CPAccessResult access_aa64_tid2(CPUARMState *env,
41
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
28
+ const ARMCPRegInfo *ri,
42
+ float_status *status)
29
+ bool isread)
30
+{
43
+{
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID2)) {
44
+ status->float_3nan_prop_rule = rule;
32
+ return CP_ACCESS_TRAP_EL2;
45
+}
46
+
47
static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
float_status *status)
49
{
50
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
51
return status->float_2nan_prop_rule;
52
}
53
54
+static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
55
+{
56
+ return status->float_3nan_prop_rule;
57
+}
58
+
59
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
60
{
61
return status->float_infzeronan_rule;
62
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
63
index XXXXXXX..XXXXXXX 100644
64
--- a/include/fpu/softfloat-types.h
65
+++ b/include/fpu/softfloat-types.h
66
@@ -XXX,XX +XXX,XX @@ this code that are retained.
67
#ifndef SOFTFLOAT_TYPES_H
68
#define SOFTFLOAT_TYPES_H
69
70
+#include "hw/registerfields.h"
71
+
72
/*
73
* Software IEC/IEEE floating-point types.
74
*/
75
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
76
float_2nan_prop_x87,
77
} Float2NaNPropRule;
78
79
+/*
80
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
81
+ * architectures have different rules for which input NaN is
82
+ * propagated to the output when there is more than one NaN on the
83
+ * input.
84
+ *
85
+ * If default_nan_mode is enabled then it is valid not to set a NaN
86
+ * propagation rule, because the softfloat code guarantees not to try
87
+ * to pick a NaN to propagate in default NaN mode. When not in
88
+ * default-NaN mode, it is an error for the target not to set the rule
89
+ * in float_status if it uses a muladd, and we will assert if we need
90
+ * to handle an input NaN and no rule was selected.
91
+ *
92
+ * The naming scheme for Float3NaNPropRule values is:
93
+ * float_3nan_prop_s_abc:
94
+ * = "Prefer SNaN over QNaN, then operand A over B over C"
95
+ * float_3nan_prop_abc:
96
+ * = "Prefer A over B over C regardless of SNaN vs QNAN"
97
+ *
98
+ * For QEMU, the multiply-add operation is A * B + C.
99
+ */
100
+
101
+/*
102
+ * We set the Float3NaNPropRule enum values up so we can select the
103
+ * right value in pickNaNMulAdd in a data driven way.
104
+ */
105
+FIELD(3NAN, 1ST, 0, 2) /* which operand is most preferred ? */
106
+FIELD(3NAN, 2ND, 2, 2) /* which operand is next most preferred ? */
107
+FIELD(3NAN, 3RD, 4, 2) /* which operand is least preferred ? */
108
+FIELD(3NAN, SNAN, 6, 1) /* do we prefer SNaN over QNaN ? */
109
+
110
+#define PROPRULE(X, Y, Z) \
111
+ ((X << R_3NAN_1ST_SHIFT) | (Y << R_3NAN_2ND_SHIFT) | (Z << R_3NAN_3RD_SHIFT))
112
+
113
+typedef enum __attribute__((__packed__)) {
114
+ float_3nan_prop_none = 0, /* No propagation rule specified */
115
+ float_3nan_prop_abc = PROPRULE(0, 1, 2),
116
+ float_3nan_prop_acb = PROPRULE(0, 2, 1),
117
+ float_3nan_prop_bac = PROPRULE(1, 0, 2),
118
+ float_3nan_prop_bca = PROPRULE(1, 2, 0),
119
+ float_3nan_prop_cab = PROPRULE(2, 0, 1),
120
+ float_3nan_prop_cba = PROPRULE(2, 1, 0),
121
+ float_3nan_prop_s_abc = float_3nan_prop_abc | R_3NAN_SNAN_MASK,
122
+ float_3nan_prop_s_acb = float_3nan_prop_acb | R_3NAN_SNAN_MASK,
123
+ float_3nan_prop_s_bac = float_3nan_prop_bac | R_3NAN_SNAN_MASK,
124
+ float_3nan_prop_s_bca = float_3nan_prop_bca | R_3NAN_SNAN_MASK,
125
+ float_3nan_prop_s_cab = float_3nan_prop_cab | R_3NAN_SNAN_MASK,
126
+ float_3nan_prop_s_cba = float_3nan_prop_cba | R_3NAN_SNAN_MASK,
127
+} Float3NaNPropRule;
128
+
129
+#undef PROPRULE
130
+
131
/*
132
* Rule for result of fused multiply-add 0 * Inf + NaN.
133
* This must be a NaN, but implementations differ on whether this
134
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
135
FloatRoundMode float_rounding_mode;
136
FloatX80RoundPrec floatx80_rounding_precision;
137
Float2NaNPropRule float_2nan_prop_rule;
138
+ Float3NaNPropRule float_3nan_prop_rule;
139
FloatInfZeroNaNRule float_infzeronan_rule;
140
bool tininess_before_rounding;
141
/* should denormalised results go to zero and set the inexact flag? */
142
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
143
index XXXXXXX..XXXXXXX 100644
144
--- a/fpu/softfloat-specialize.c.inc
145
+++ b/fpu/softfloat-specialize.c.inc
146
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
147
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
148
bool infzero, bool have_snan, float_status *status)
149
{
150
+ FloatClass cls[3] = { a_cls, b_cls, c_cls };
151
+ Float3NaNPropRule rule = status->float_3nan_prop_rule;
152
+ int which;
153
+
154
/*
155
* We guarantee not to require the target to tell us how to
156
* pick a NaN if we're always returning the default NaN.
157
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
158
}
159
}
160
161
+ if (rule == float_3nan_prop_none) {
162
#if defined(TARGET_ARM)
163
-
164
- /* This looks different from the ARM ARM pseudocode, because the ARM ARM
165
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
166
- */
167
- if (is_snan(c_cls)) {
168
- return 2;
169
- } else if (is_snan(a_cls)) {
170
- return 0;
171
- } else if (is_snan(b_cls)) {
172
- return 1;
173
- } else if (is_qnan(c_cls)) {
174
- return 2;
175
- } else if (is_qnan(a_cls)) {
176
- return 0;
177
- } else {
178
- return 1;
179
- }
180
+ /*
181
+ * This looks different from the ARM ARM pseudocode, because the ARM ARM
182
+ * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
183
+ */
184
+ rule = float_3nan_prop_s_cab;
185
#elif defined(TARGET_MIPS)
186
- if (snan_bit_is_one(status)) {
187
- /* Prefer sNaN over qNaN, in the a, b, c order. */
188
- if (is_snan(a_cls)) {
189
- return 0;
190
- } else if (is_snan(b_cls)) {
191
- return 1;
192
- } else if (is_snan(c_cls)) {
193
- return 2;
194
- } else if (is_qnan(a_cls)) {
195
- return 0;
196
- } else if (is_qnan(b_cls)) {
197
- return 1;
198
+ if (snan_bit_is_one(status)) {
199
+ rule = float_3nan_prop_s_abc;
200
} else {
201
- return 2;
202
+ rule = float_3nan_prop_s_cab;
203
}
204
- } else {
205
- /* Prefer sNaN over qNaN, in the c, a, b order. */
206
- if (is_snan(c_cls)) {
207
- return 2;
208
- } else if (is_snan(a_cls)) {
209
- return 0;
210
- } else if (is_snan(b_cls)) {
211
- return 1;
212
- } else if (is_qnan(c_cls)) {
213
- return 2;
214
- } else if (is_qnan(a_cls)) {
215
- return 0;
216
- } else {
217
- return 1;
218
- }
219
- }
220
#elif defined(TARGET_LOONGARCH64)
221
- /* Prefer sNaN over qNaN, in the c, a, b order. */
222
- if (is_snan(c_cls)) {
223
- return 2;
224
- } else if (is_snan(a_cls)) {
225
- return 0;
226
- } else if (is_snan(b_cls)) {
227
- return 1;
228
- } else if (is_qnan(c_cls)) {
229
- return 2;
230
- } else if (is_qnan(a_cls)) {
231
- return 0;
232
- } else {
233
- return 1;
234
- }
235
+ rule = float_3nan_prop_s_cab;
236
#elif defined(TARGET_PPC)
237
- /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
238
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
239
- */
240
- if (is_nan(a_cls)) {
241
- return 0;
242
- } else if (is_nan(c_cls)) {
243
- return 2;
244
- } else {
245
- return 1;
246
- }
247
+ /*
248
+ * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
249
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
250
+ */
251
+ rule = float_3nan_prop_acb;
252
#elif defined(TARGET_S390X)
253
- if (is_snan(a_cls)) {
254
- return 0;
255
- } else if (is_snan(b_cls)) {
256
- return 1;
257
- } else if (is_snan(c_cls)) {
258
- return 2;
259
- } else if (is_qnan(a_cls)) {
260
- return 0;
261
- } else if (is_qnan(b_cls)) {
262
- return 1;
263
- } else {
264
- return 2;
265
- }
266
+ rule = float_3nan_prop_s_abc;
267
#elif defined(TARGET_SPARC)
268
- /* Prefer SNaN over QNaN, order C, B, A. */
269
- if (is_snan(c_cls)) {
270
- return 2;
271
- } else if (is_snan(b_cls)) {
272
- return 1;
273
- } else if (is_snan(a_cls)) {
274
- return 0;
275
- } else if (is_qnan(c_cls)) {
276
- return 2;
277
- } else if (is_qnan(b_cls)) {
278
- return 1;
279
- } else {
280
- return 0;
281
- }
282
+ rule = float_3nan_prop_s_cba;
283
#elif defined(TARGET_XTENSA)
284
- /*
285
- * For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
286
- * an input NaN if we have one (ie c).
287
- */
288
- if (status->use_first_nan) {
289
- if (is_nan(a_cls)) {
290
- return 0;
291
- } else if (is_nan(b_cls)) {
292
- return 1;
293
+ if (status->use_first_nan) {
294
+ rule = float_3nan_prop_abc;
295
} else {
296
- return 2;
297
+ rule = float_3nan_prop_cba;
298
}
299
- } else {
300
- if (is_nan(c_cls)) {
301
- return 2;
302
- } else if (is_nan(b_cls)) {
303
- return 1;
304
- } else {
305
- return 0;
306
- }
307
- }
308
#else
309
- /* A default implementation: prefer a to b to c.
310
- * This is unlikely to actually match any real implementation.
311
- */
312
- if (is_nan(a_cls)) {
313
- return 0;
314
- } else if (is_nan(b_cls)) {
315
- return 1;
316
- } else {
317
- return 2;
318
- }
319
+ rule = float_3nan_prop_abc;
320
#endif
33
+ }
321
+ }
34
+
322
+
35
+ return CP_ACCESS_OK;
323
+ assert(rule != float_3nan_prop_none);
36
+}
324
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
37
+
325
+ /* We have at least one SNaN input and should prefer it */
38
static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
326
+ do {
39
{
327
+ which = rule & R_3NAN_1ST_MASK;
40
ARMCPU *cpu = env_archcpu(env);
328
+ rule >>= R_3NAN_1ST_LENGTH;
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
329
+ } while (!is_snan(cls[which]));
42
.writefn = pmintenclr_write },
330
+ } else {
43
{ .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
331
+ do {
44
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
332
+ which = rule & R_3NAN_1ST_MASK;
45
- .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
333
+ rule >>= R_3NAN_1ST_LENGTH;
46
+ .access = PL1_R,
334
+ } while (!is_nan(cls[which]));
47
+ .accessfn = access_aa64_tid2,
48
+ .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
49
{ .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
50
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
51
- .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
52
+ .access = PL1_RW,
53
+ .accessfn = access_aa64_tid2,
54
+ .writefn = csselr_write, .resetvalue = 0,
55
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
56
offsetof(CPUARMState, cp15.csselr_ns) } },
57
/* Auxiliary ID register: this actually has an IMPDEF value but for now
58
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
59
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCT)) {
60
return CP_ACCESS_TRAP;
61
}
62
+
63
+ if (arm_current_el(env) < 2 && arm_hcr_el2_eff(env) & HCR_TID2) {
64
+ return CP_ACCESS_TRAP_EL2;
65
+ }
335
+ }
66
+
336
+ return which;
67
return CP_ACCESS_OK;
68
}
337
}
69
338
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
339
/*----------------------------------------------------------------------------
71
ARMCPRegInfo clidr = {
72
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
73
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
74
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr
75
+ .access = PL1_R, .type = ARM_CP_CONST,
76
+ .accessfn = access_aa64_tid2,
77
+ .resetvalue = cpu->clidr
78
};
79
define_one_arm_cp_reg(cpu, &clidr);
80
define_arm_cp_regs(cpu, v7_cp_reginfo);
81
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
82
/* These are common to v8 and pre-v8 */
83
{ .name = "CTR",
84
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
85
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
86
+ .access = PL1_R, .accessfn = ctr_el0_access,
87
+ .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
88
{ .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
89
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
90
.access = PL0_R, .accessfn = ctr_el0_access,
91
--
340
--
92
2.20.1
341
2.34.1
93
94
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for propagating NaNs in
2
the muladd case. In meson.build we put -DTARGET_ARM in fpcflags, and
3
so we should select here the Arm rule of float_3nan_prop_s_cab.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-17-peter.maydell@linaro.org
8
---
9
tests/fp/fp-bench.c | 1 +
10
tests/fp/fp-test.c | 1 +
11
2 files changed, 2 insertions(+)
12
13
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/fp/fp-bench.c
16
+++ b/tests/fp/fp-bench.c
17
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
18
* doesn't specify match those used by the Arm architecture.
19
*/
20
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
22
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
23
24
f = bench_funcs[operation][precision];
25
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/fp/fp-test.c
28
+++ b/tests/fp/fp-test.c
29
@@ -XXX,XX +XXX,XX @@ void run_test(void)
30
* doesn't specify match those used by the Arm architecture.
31
*/
32
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
33
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
34
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
35
36
genCases_setLevel(test_level);
37
--
38
2.34.1
diff view generated by jsdifflib
1
From: Christophe Lyon <christophe.lyon@linaro.org>
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
ifdef from pickNaNMulAdd().
2
3
3
This is derived from cortex-m4 description, adding DP support and FPv5
4
instructions with the corresponding flags in isar and mvfr2.
5
6
Checked that it could successfully execute
7
vrinta.f32 s15, s15
8
while cortex-m4 emulation rejects it with "illegal instruction".
9
10
Signed-off-by: Christophe Lyon <christophe.lyon@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20191025090841.10299-1-christophe.lyon@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-18-peter.maydell@linaro.org
15
---
7
---
16
target/arm/cpu.c | 33 +++++++++++++++++++++++++++++++++
8
target/arm/cpu.c | 5 +++++
17
1 file changed, 33 insertions(+)
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 6 insertions(+), 7 deletions(-)
18
11
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
14
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
24
cpu->isar.id_isar6 = 0x00000000;
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);
25
}
33
}
26
34
27
+static void cortex_m7_initfn(Object *obj)
35
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
+{
36
index XXXXXXX..XXXXXXX 100644
29
+ ARMCPU *cpu = ARM_CPU(obj);
37
--- a/fpu/softfloat-specialize.c.inc
30
+
38
+++ b/fpu/softfloat-specialize.c.inc
31
+ set_feature(&cpu->env, ARM_FEATURE_V7);
39
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
32
+ set_feature(&cpu->env, ARM_FEATURE_M);
40
}
33
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
41
34
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
42
if (rule == float_3nan_prop_none) {
35
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
43
-#if defined(TARGET_ARM)
36
+ cpu->midr = 0x411fc272; /* r1p2 */
44
- /*
37
+ cpu->pmsav7_dregion = 8;
45
- * This looks different from the ARM ARM pseudocode, because the ARM ARM
38
+ cpu->isar.mvfr0 = 0x10110221;
46
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
39
+ cpu->isar.mvfr1 = 0x12000011;
47
- */
40
+ cpu->isar.mvfr2 = 0x00000040;
48
- rule = float_3nan_prop_s_cab;
41
+ cpu->id_pfr0 = 0x00000030;
49
-#elif defined(TARGET_MIPS)
42
+ cpu->id_pfr1 = 0x00000200;
50
+#if defined(TARGET_MIPS)
43
+ cpu->id_dfr0 = 0x00100000;
51
if (snan_bit_is_one(status)) {
44
+ cpu->id_afr0 = 0x00000000;
52
rule = float_3nan_prop_s_abc;
45
+ cpu->id_mmfr0 = 0x00100030;
53
} else {
46
+ cpu->id_mmfr1 = 0x00000000;
47
+ cpu->id_mmfr2 = 0x01000000;
48
+ cpu->id_mmfr3 = 0x00000000;
49
+ cpu->isar.id_isar0 = 0x01101110;
50
+ cpu->isar.id_isar1 = 0x02112000;
51
+ cpu->isar.id_isar2 = 0x20232231;
52
+ cpu->isar.id_isar3 = 0x01111131;
53
+ cpu->isar.id_isar4 = 0x01310132;
54
+ cpu->isar.id_isar5 = 0x00000000;
55
+ cpu->isar.id_isar6 = 0x00000000;
56
+}
57
+
58
static void cortex_m33_initfn(Object *obj)
59
{
60
ARMCPU *cpu = ARM_CPU(obj);
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
62
.class_init = arm_v7m_class_init },
63
{ .name = "cortex-m4", .initfn = cortex_m4_initfn,
64
.class_init = arm_v7m_class_init },
65
+ { .name = "cortex-m7", .initfn = cortex_m7_initfn,
66
+ .class_init = arm_v7m_class_init },
67
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
68
.class_init = arm_v7m_class_init },
69
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
70
--
54
--
71
2.20.1
55
2.34.1
72
73
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
1
From: Cédric Le Goater <clg@kaod.org>
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
ifdef from pickNaNMulAdd().
2
3
3
The segments can be disabled on the AST2600 (zero register value).
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
CS0 is open by default but not the other CS. This is closing the
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
access to the flash device in user mode and forbids scanning.
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(-)
6
12
7
In the model, check the segment size and disable the associated region
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
8
when the value is zero.
9
10
Fixes: bcaa8ddd081c ("aspeed/smc: Add AST2600 support")
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-12-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/ssi/aspeed_smc.c | 16 +++++++++++-----
18
1 file changed, 11 insertions(+), 5 deletions(-)
19
20
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/ssi/aspeed_smc.c
15
--- a/target/mips/fpu_helper.h
23
+++ b/hw/ssi/aspeed_smc.c
16
+++ b/target/mips/fpu_helper.h
24
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
25
uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
18
{
26
uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
19
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
27
20
FloatInfZeroNaNRule izn_rule;
28
- seg->addr = s->ctrl->flash_window_base + start_offset;
21
+ Float3NaNPropRule nan3_rule;
29
- seg->size = end_offset + MiB - start_offset;
22
30
+ if (reg) {
23
/*
31
+ seg->addr = s->ctrl->flash_window_base + start_offset;
24
* With nan2008, SNaNs are silenced in the usual way.
32
+ seg->size = end_offset + MiB - start_offset;
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
33
+ } else {
26
*/
34
+ seg->addr = s->ctrl->flash_window_base;
27
izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
35
+ seg->size = 0;
28
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
36
+ }
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
+
37
}
32
}
38
33
39
static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
34
static inline void restore_fp_status(CPUMIPSState *env)
40
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
35
diff --git a/target/mips/msa.c b/target/mips/msa.c
41
memory_region_transaction_begin();
36
index XXXXXXX..XXXXXXX 100644
42
memory_region_set_size(&fl->mmio, seg.size);
37
--- a/target/mips/msa.c
43
memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
38
+++ b/target/mips/msa.c
44
- memory_region_set_enabled(&fl->mmio, true);
39
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
45
+ memory_region_set_enabled(&fl->mmio, !!seg.size);
40
set_float_2nan_prop_rule(float_2nan_prop_s_ab,
46
memory_region_transaction_commit();
41
&env->active_tc.msa_fp_status);
47
42
48
s->regs[R_SEG_ADDR0 + cs] = regval;
43
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab,
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
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,
50
}
54
}
51
55
52
/* Keep the segment in the overall flash window */
56
if (rule == float_3nan_prop_none) {
53
- if (seg.addr + seg.size <= s->ctrl->flash_window_base ||
57
-#if defined(TARGET_MIPS)
54
- seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size) {
58
- if (snan_bit_is_one(status)) {
55
+ if (seg.size &&
59
- rule = float_3nan_prop_s_abc;
56
+ (seg.addr + seg.size <= s->ctrl->flash_window_base ||
60
- } else {
57
+ seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size)) {
61
- rule = float_3nan_prop_s_cab;
58
qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : "
62
- }
59
"[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
63
-#elif defined(TARGET_XTENSA)
60
s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
64
+#if defined(TARGET_XTENSA)
65
if (status->use_first_nan) {
66
rule = float_3nan_prop_abc;
67
} else {
61
--
68
--
62
2.20.1
69
2.34.1
63
64
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Set the Float3NaNPropRule explicitly for xtensa, and remove the
2
ifdef from pickNaNMulAdd().
2
3
3
The current model only restores the Segment Register values but leaves
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
the previous CS mapping behind. Introduce a helper setting the
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
register value and mapping the region at the requested address. Use
6
Message-id: 20241202131347.498124-24-peter.maydell@linaro.org
6
this helper when a Segment register is set and at reset.
7
---
8
target/xtensa/fpu_helper.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 8 --------
10
2 files changed, 2 insertions(+), 8 deletions(-)
7
11
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-11-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/ssi/aspeed_smc.c | 32 +++++++++++++++++++++-----------
15
1 file changed, 21 insertions(+), 11 deletions(-)
16
17
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/ssi/aspeed_smc.c
14
--- a/target/xtensa/fpu_helper.c
20
+++ b/hw/ssi/aspeed_smc.c
15
+++ b/target/xtensa/fpu_helper.c
21
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
16
@@ -XXX,XX +XXX,XX @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
22
return false;
17
set_use_first_nan(use_first, &env->fp_status);
18
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
19
&env->fp_status);
20
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
21
+ &env->fp_status);
23
}
22
}
24
23
25
+static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
24
void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
26
+ uint64_t regval)
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
27
+{
26
index XXXXXXX..XXXXXXX 100644
28
+ AspeedSMCFlash *fl = &s->flashes[cs];
27
--- a/fpu/softfloat-specialize.c.inc
29
+ AspeedSegments seg;
28
+++ b/fpu/softfloat-specialize.c.inc
30
+
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
31
+ s->ctrl->reg_to_segment(s, regval, &seg);
32
+
33
+ memory_region_transaction_begin();
34
+ memory_region_set_size(&fl->mmio, seg.size);
35
+ memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
36
+ memory_region_set_enabled(&fl->mmio, true);
37
+ memory_region_transaction_commit();
38
+
39
+ s->regs[R_SEG_ADDR0 + cs] = regval;
40
+}
41
+
42
static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
43
uint64_t new)
44
{
45
- AspeedSMCFlash *fl = &s->flashes[cs];
46
AspeedSegments seg;
47
48
s->ctrl->reg_to_segment(s, new, &seg);
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
50
aspeed_smc_flash_overlap(s, &seg, cs);
51
52
/* All should be fine now to move the region */
53
- memory_region_transaction_begin();
54
- memory_region_set_size(&fl->mmio, seg.size);
55
- memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
56
- memory_region_set_enabled(&fl->mmio, true);
57
- memory_region_transaction_commit();
58
-
59
- s->regs[R_SEG_ADDR0 + cs] = new;
60
+ aspeed_smc_flash_set_segment_region(s, cs, new);
61
}
62
63
static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
64
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
65
qemu_set_irq(s->cs_lines[i], true);
66
}
30
}
67
31
68
- /* setup default segment register values for all */
32
if (rule == float_3nan_prop_none) {
69
+ /* setup the default segment register values and regions for all */
33
-#if defined(TARGET_XTENSA)
70
for (i = 0; i < s->ctrl->max_slaves; ++i) {
34
- if (status->use_first_nan) {
71
- s->regs[R_SEG_ADDR0 + i] =
35
- rule = float_3nan_prop_abc;
72
- s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]);
36
- } else {
73
+ aspeed_smc_flash_set_segment_region(s, i,
37
- rule = float_3nan_prop_cba;
74
+ s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]));
38
- }
39
-#else
40
rule = float_3nan_prop_abc;
41
-#endif
75
}
42
}
76
43
77
/* HW strapping flash type for the AST2600 controllers */
44
assert(rule != float_3nan_prop_none);
78
--
45
--
79
2.20.1
46
2.34.1
80
81
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for i386. We had no
2
i386-specific behaviour in the old ifdef ladder, so we were using the
3
default "prefer a then b then c" fallback; this is actually the
4
correct per-the-spec handling for i386.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-25-peter.maydell@linaro.org
9
---
10
target/i386/tcg/fpu_helper.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/i386/tcg/fpu_helper.c
16
+++ b/target/i386/tcg/fpu_helper.c
17
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
18
* there are multiple input NaNs they are selected in the order a, b, c.
19
*/
20
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
22
}
23
24
static inline uint8_t save_exception_flags(CPUX86State *env)
25
--
26
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for HPPA, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
HPPA is the only target that was using the default branch of the
5
ifdef ladder (other targets either do not use muladd or set
6
default_nan_mode), so we can remove the ifdef fallback entirely now
7
(allowing the "rule not set" case to fall into the default of the
8
switch statement and assert).
9
10
We add a TODO note that the HPPA rule is probably wrong; this is
11
not a behavioural change for this refactoring.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-26-peter.maydell@linaro.org
16
---
17
target/hppa/fpu_helper.c | 8 ++++++++
18
fpu/softfloat-specialize.c.inc | 4 ----
19
2 files changed, 8 insertions(+), 4 deletions(-)
20
21
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/hppa/fpu_helper.c
24
+++ b/target/hppa/fpu_helper.c
25
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
26
* HPPA does note implement a CPU reset method at all...
27
*/
28
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
29
+ /*
30
+ * TODO: The HPPA architecture reference only documents its NaN
31
+ * propagation rule for 2-operand operations. Testing on real hardware
32
+ * might be necessary to confirm whether this order for muladd is correct.
33
+ * Not preferring the SNaN is almost certainly incorrect as it diverges
34
+ * from the documented rules for 2-operand operations.
35
+ */
36
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
37
/* For inf * 0 + NaN, return the input NaN */
38
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
39
}
40
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
41
index XXXXXXX..XXXXXXX 100644
42
--- a/fpu/softfloat-specialize.c.inc
43
+++ b/fpu/softfloat-specialize.c.inc
44
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
45
}
46
}
47
48
- if (rule == float_3nan_prop_none) {
49
- rule = float_3nan_prop_abc;
50
- }
51
-
52
assert(rule != float_3nan_prop_none);
53
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
54
/* We have at least one SNaN input and should prefer it */
55
--
56
2.34.1
diff view generated by jsdifflib
New patch
1
The use_first_nan field in float_status was an xtensa-specific way to
2
select at runtime from two different NaN propagation rules. Now that
3
xtensa is using the target-agnostic NaN propagation rule selection
4
that we've just added, we can remove use_first_nan, because there is
5
no longer any code that reads it.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20241202131347.498124-27-peter.maydell@linaro.org
10
---
11
include/fpu/softfloat-helpers.h | 5 -----
12
include/fpu/softfloat-types.h | 1 -
13
target/xtensa/fpu_helper.c | 1 -
14
3 files changed, 7 deletions(-)
15
16
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/fpu/softfloat-helpers.h
19
+++ b/include/fpu/softfloat-helpers.h
20
@@ -XXX,XX +XXX,XX @@ static inline void set_snan_bit_is_one(bool val, float_status *status)
21
status->snan_bit_is_one = val;
22
}
23
24
-static inline void set_use_first_nan(bool val, float_status *status)
25
-{
26
- status->use_first_nan = val;
27
-}
28
-
29
static inline void set_no_signaling_nans(bool val, float_status *status)
30
{
31
status->no_signaling_nans = val;
32
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/fpu/softfloat-types.h
35
+++ b/include/fpu/softfloat-types.h
36
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
37
* softfloat-specialize.inc.c)
38
*/
39
bool snan_bit_is_one;
40
- bool use_first_nan;
41
bool no_signaling_nans;
42
/* should overflowed results subtract re_bias to its exponent? */
43
bool rebias_overflow;
44
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/xtensa/fpu_helper.c
47
+++ b/target/xtensa/fpu_helper.c
48
@@ -XXX,XX +XXX,XX @@ static const struct {
49
50
void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
51
{
52
- set_use_first_nan(use_first, &env->fp_status);
53
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
54
&env->fp_status);
55
set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
56
--
57
2.34.1
diff view generated by jsdifflib
New patch
1
Currently m68k_cpu_reset_hold() calls floatx80_default_nan(NULL)
2
to get the NaN bit pattern to reset the FPU registers. This
3
works because it happens that our implementation of
4
floatx80_default_nan() doesn't actually look at the float_status
5
pointer except for TARGET_MIPS. However, this isn't guaranteed,
6
and to be able to remove the ifdef in floatx80_default_nan()
7
we're going to need a real float_status here.
1
8
9
Rearrange m68k_cpu_reset_hold() so that we initialize env->fp_status
10
earlier, and thus can pass it to floatx80_default_nan().
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20241202131347.498124-28-peter.maydell@linaro.org
15
---
16
target/m68k/cpu.c | 12 +++++++-----
17
1 file changed, 7 insertions(+), 5 deletions(-)
18
19
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/m68k/cpu.c
22
+++ b/target/m68k/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
24
CPUState *cs = CPU(obj);
25
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(obj);
26
CPUM68KState *env = cpu_env(cs);
27
- floatx80 nan = floatx80_default_nan(NULL);
28
+ floatx80 nan;
29
int i;
30
31
if (mcc->parent_phases.hold) {
32
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
33
#else
34
cpu_m68k_set_sr(env, SR_S | SR_I);
35
#endif
36
- for (i = 0; i < 8; i++) {
37
- env->fregs[i].d = nan;
38
- }
39
- cpu_m68k_set_fpcr(env, 0);
40
/*
41
* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
42
* 3.4 FLOATING-POINT INSTRUCTION DETAILS
43
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
44
* preceding paragraph for nonsignaling NaNs.
45
*/
46
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
47
+
48
+ nan = floatx80_default_nan(&env->fp_status);
49
+ for (i = 0; i < 8; i++) {
50
+ env->fregs[i].d = nan;
51
+ }
52
+ cpu_m68k_set_fpcr(env, 0);
53
env->fpsr = 0;
54
55
/* TODO: We should set PC from the interrupt vector. */
56
--
57
2.34.1
diff view generated by jsdifflib
New patch
1
We create our 128-bit default NaN by calling parts64_default_nan()
2
and then adjusting the result. We can do the same trick for creating
3
the floatx80 default NaN, which lets us drop a target ifdef.
1
4
5
floatx80 is used only by:
6
i386
7
m68k
8
arm nwfpe old floating-point emulation emulation support
9
(which is essentially dead, especially the parts involving floatx80)
10
PPC (only in the xsrqpxp instruction, which just rounds an input
11
value by converting to floatx80 and back, so will never generate
12
the default NaN)
13
14
The floatx80 default NaN as currently implemented is:
15
m68k: sign = 0, exp = 1...1, int = 1, frac = 1....1
16
i386: sign = 1, exp = 1...1, int = 1, frac = 10...0
17
18
These are the same as the parts64_default_nan for these architectures.
19
20
This is technically a possible behaviour change for arm linux-user
21
nwfpe emulation emulation, because the default NaN will now have the
22
sign bit clear. But we were already generating a different floatx80
23
default NaN from the real kernel emulation we are supposedly
24
following, which appears to use an all-bits-1 value:
25
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L267
26
27
This won't affect the only "real" use of the nwfpe emulation, which
28
is ancient binaries that used it as part of the old floating point
29
calling convention; that only uses loads and stores of 32 and 64 bit
30
floats, not any of the floatx80 behaviour the original hardware had.
31
We also get the nwfpe float64 default NaN value wrong:
32
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L166
33
so if we ever cared about this obscure corner the right fix would be
34
to correct that so nwfpe used its own default-NaN setting rather
35
than the Arm VFP one.
36
37
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
38
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
39
Message-id: 20241202131347.498124-29-peter.maydell@linaro.org
40
---
41
fpu/softfloat-specialize.c.inc | 20 ++++++++++----------
42
1 file changed, 10 insertions(+), 10 deletions(-)
43
44
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
45
index XXXXXXX..XXXXXXX 100644
46
--- a/fpu/softfloat-specialize.c.inc
47
+++ b/fpu/softfloat-specialize.c.inc
48
@@ -XXX,XX +XXX,XX @@ static void parts128_silence_nan(FloatParts128 *p, float_status *status)
49
floatx80 floatx80_default_nan(float_status *status)
50
{
51
floatx80 r;
52
+ /*
53
+ * Extrapolate from the choices made by parts64_default_nan to fill
54
+ * in the floatx80 format. We assume that floatx80's explicit
55
+ * integer bit is always set (this is true for i386 and m68k,
56
+ * which are the only real users of this format).
57
+ */
58
+ FloatParts64 p64;
59
+ parts64_default_nan(&p64, status);
60
61
- /* None of the targets that have snan_bit_is_one use floatx80. */
62
- assert(!snan_bit_is_one(status));
63
-#if defined(TARGET_M68K)
64
- r.low = UINT64_C(0xFFFFFFFFFFFFFFFF);
65
- r.high = 0x7FFF;
66
-#else
67
- /* X86 */
68
- r.low = UINT64_C(0xC000000000000000);
69
- r.high = 0xFFFF;
70
-#endif
71
+ r.high = 0x7FFF | (p64.sign << 15);
72
+ r.low = (1ULL << DECOMPOSED_BINARY_POINT) | p64.frac;
73
return r;
74
}
75
76
--
77
2.34.1
diff view generated by jsdifflib
New patch
1
In target/loongarch's helper_fclass_s() and helper_fclass_d() we pass
2
a zero-initialized float_status struct to float32_is_quiet_nan() and
3
float64_is_quiet_nan(), with the cryptic comment "for
4
snan_bit_is_one".
1
5
6
This pattern appears to have been copied from target/riscv, where it
7
is used because the functions there do not have ready access to the
8
CPU state struct. The comment presumably refers to the fact that the
9
main reason the is_quiet_nan() functions want the float_state is
10
because they want to know about the snan_bit_is_one config.
11
12
In the loongarch helpers, though, we have the CPU state struct
13
to hand. Use the usual env->fp_status here. This avoids our needing
14
to track that we need to update the initializer of the local
15
float_status structs when the core softfloat code adds new
16
options for targets to configure their behaviour.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20241202131347.498124-30-peter.maydell@linaro.org
21
---
22
target/loongarch/tcg/fpu_helper.c | 6 ++----
23
1 file changed, 2 insertions(+), 4 deletions(-)
24
25
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/loongarch/tcg/fpu_helper.c
28
+++ b/target/loongarch/tcg/fpu_helper.c
29
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
30
} else if (float32_is_zero_or_denormal(f)) {
31
return sign ? 1 << 4 : 1 << 8;
32
} else if (float32_is_any_nan(f)) {
33
- float_status s = { }; /* for snan_bit_is_one */
34
- return float32_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
35
+ return float32_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
36
} else {
37
return sign ? 1 << 3 : 1 << 7;
38
}
39
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
40
} else if (float64_is_zero_or_denormal(f)) {
41
return sign ? 1 << 4 : 1 << 8;
42
} else if (float64_is_any_nan(f)) {
43
- float_status s = { }; /* for snan_bit_is_one */
44
- return float64_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
45
+ return float64_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
46
} else {
47
return sign ? 1 << 3 : 1 << 7;
48
}
49
--
50
2.34.1
diff view generated by jsdifflib
New patch
1
In the frem helper, we have a local float_status because we want to
2
execute the floatx80_div() with a custom rounding mode. Instead of
3
zero-initializing the local float_status and then having to set it up
4
with the m68k standard behaviour (including the NaN propagation rule
5
and copying the rounding precision from env->fp_status), initialize
6
it as a complete copy of env->fp_status. This will avoid our having
7
to add new code in this function for every new config knob we add
8
to fp_status.
1
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-31-peter.maydell@linaro.org
13
---
14
target/m68k/fpu_helper.c | 6 ++----
15
1 file changed, 2 insertions(+), 4 deletions(-)
16
17
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/m68k/fpu_helper.c
20
+++ b/target/m68k/fpu_helper.c
21
@@ -XXX,XX +XXX,XX @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
22
23
fp_rem = floatx80_rem(val1->d, val0->d, &env->fp_status);
24
if (!floatx80_is_any_nan(fp_rem)) {
25
- float_status fp_status = { };
26
+ /* Use local temporary fp_status to set different rounding mode */
27
+ float_status fp_status = env->fp_status;
28
uint32_t quotient;
29
int sign;
30
31
/* Calculate quotient directly using round to nearest mode */
32
- set_float_2nan_prop_rule(float_2nan_prop_ab, &fp_status);
33
set_float_rounding_mode(float_round_nearest_even, &fp_status);
34
- set_floatx80_rounding_precision(
35
- get_floatx80_rounding_precision(&env->fp_status), &fp_status);
36
fp_quot.d = floatx80_div(val1->d, val0->d, &fp_status);
37
38
sign = extractFloatx80Sign(fp_quot.d);
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
In cf_fpu_gdb_get_reg() and cf_fpu_gdb_set_reg() we do the conversion
2
from float64 to floatx80 using a scratch float_status, because we
3
don't want the conversion to affect the CPU's floating point exception
4
status. Currently we use a zero-initialized float_status. This will
5
get steadily more awkward as we add config knobs to float_status
6
that the target must initialize. Avoid having to add any of that
7
configuration here by instead initializing our local float_status
8
from the env->fp_status.
1
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-32-peter.maydell@linaro.org
13
---
14
target/m68k/helper.c | 6 ++++--
15
1 file changed, 4 insertions(+), 2 deletions(-)
16
17
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/m68k/helper.c
20
+++ b/target/m68k/helper.c
21
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
22
CPUM68KState *env = &cpu->env;
23
24
if (n < 8) {
25
- float_status s = {};
26
+ /* Use scratch float_status so any exceptions don't change CPU state */
27
+ float_status s = env->fp_status;
28
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
29
}
30
switch (n) {
31
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
32
CPUM68KState *env = &cpu->env;
33
34
if (n < 8) {
35
- float_status s = {};
36
+ /* Use scratch float_status so any exceptions don't change CPU state */
37
+ float_status s = env->fp_status;
38
env->fregs[n].d = float64_to_floatx80(ldq_be_p(mem_buf), &s);
39
return 8;
40
}
41
--
42
2.34.1
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
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
The Aspeed I2C controller can operate in different transfer modes :
8
To do this we need to pass the CPU env pointer in to the helper.
4
9
5
- Byte Buffer mode, using a dedicated register to transfer a
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
byte. This is what the model supports today.
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-33-peter.maydell@linaro.org
13
---
14
target/sparc/helper.h | 4 ++--
15
target/sparc/fop_helper.c | 8 ++++----
16
target/sparc/translate.c | 4 ++--
17
3 files changed, 8 insertions(+), 8 deletions(-)
7
18
8
- Pool Buffer mode, using an internal SRAM to transfer multiple
19
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
9
bytes in the same command sequence.
10
11
Each SoC has different SRAM characteristics. On the AST2400, 2048
12
bytes of SRAM are available at offset 0x800 of the controller AHB
13
window. The pool buffer can be configured from 1 to 256 bytes per bus.
14
15
On the AST2500, the SRAM is at offset 0x200 and the pool buffer is of
16
16 bytes per bus.
17
18
On the AST2600, the SRAM is at offset 0xC00 and the pool buffer is of
19
32 bytes per bus. It can be splitted in two for TX and RX but the
20
current model does not add support for it as it it unused by known
21
drivers.
22
23
Signed-off-by: Cédric Le Goater <clg@kaod.org>
24
Reviewed-by: Joel Stanley <joel@jms.id.au>
25
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
26
Signed-off-by: Cédric Le Goater <clg@kaod.org>
27
Message-id: 20191119141211.25716-2-clg@kaod.org
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
30
include/hw/i2c/aspeed_i2c.h | 8 ++
31
hw/i2c/aspeed_i2c.c | 197 ++++++++++++++++++++++++++++++++----
32
2 files changed, 186 insertions(+), 19 deletions(-)
33
34
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
35
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/i2c/aspeed_i2c.h
21
--- a/target/sparc/helper.h
37
+++ b/include/hw/i2c/aspeed_i2c.h
22
+++ b/target/sparc/helper.h
38
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
39
OBJECT_CHECK(AspeedI2CState, (obj), TYPE_ASPEED_I2C)
24
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
40
25
DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
41
#define ASPEED_I2C_NR_BUSSES 16
26
DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
42
+#define ASPEED_I2C_MAX_POOL_SIZE 0x800
27
-DEF_HELPER_FLAGS_2(flcmps, TCG_CALL_NO_RWG_SE, i32, f32, f32)
43
28
-DEF_HELPER_FLAGS_2(flcmpd, TCG_CALL_NO_RWG_SE, i32, f64, f64)
44
struct AspeedI2CState;
29
+DEF_HELPER_FLAGS_3(flcmps, TCG_CALL_NO_RWG_SE, i32, env, f32, f32)
45
30
+DEF_HELPER_FLAGS_3(flcmpd, TCG_CALL_NO_RWG_SE, i32, env, f64, f64)
46
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
31
DEF_HELPER_2(raise_exception, noreturn, env, int)
47
uint32_t intr_status;
32
48
uint32_t cmd;
33
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
49
uint32_t buf;
34
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
50
+ uint32_t pool_ctrl;
51
} AspeedI2CBus;
52
53
typedef struct AspeedI2CState {
54
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
55
qemu_irq irq;
56
57
uint32_t intr_status;
58
+ MemoryRegion pool_iomem;
59
+ uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
60
61
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
62
} AspeedI2CState;
63
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
64
uint8_t reg_size;
65
uint8_t gap;
66
qemu_irq (*bus_get_irq)(AspeedI2CBus *);
67
+
68
+ uint64_t pool_size;
69
+ hwaddr pool_base;
70
+ uint8_t *(*bus_pool_base)(AspeedI2CBus *);
71
} AspeedI2CClass;
72
73
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
74
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
75
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
76
--- a/hw/i2c/aspeed_i2c.c
36
--- a/target/sparc/fop_helper.c
77
+++ b/hw/i2c/aspeed_i2c.c
37
+++ b/target/sparc/fop_helper.c
78
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@ uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
79
/* I2C Device (Bus) Register */
39
return finish_fcmp(env, r, GETPC());
80
81
#define I2CD_FUN_CTRL_REG 0x00 /* I2CD Function Control */
82
-#define I2CD_BUFF_SEL_MASK (0x7 << 20)
83
-#define I2CD_BUFF_SEL(x) (x << 20)
84
+#define I2CD_POOL_PAGE_SEL(x) (((x) >> 20) & 0x7) /* AST2400 */
85
#define I2CD_M_SDA_LOCK_EN (0x1 << 16)
86
#define I2CD_MULTI_MASTER_DIS (0x1 << 15)
87
#define I2CD_M_SCL_DRIVE_EN (0x1 << 14)
88
@@ -XXX,XX +XXX,XX @@
89
#define I2CD_SCL_O_OUT_DIR (0x1 << 12)
90
#define I2CD_BUS_RECOVER_CMD_EN (0x1 << 11)
91
#define I2CD_S_ALT_EN (0x1 << 10)
92
-#define I2CD_RX_DMA_ENABLE (0x1 << 9)
93
-#define I2CD_TX_DMA_ENABLE (0x1 << 8)
94
95
/* Command Bit */
96
+#define I2CD_RX_DMA_ENABLE (0x1 << 9)
97
+#define I2CD_TX_DMA_ENABLE (0x1 << 8)
98
+#define I2CD_RX_BUFF_ENABLE (0x1 << 7)
99
+#define I2CD_TX_BUFF_ENABLE (0x1 << 6)
100
#define I2CD_M_STOP_CMD (0x1 << 5)
101
#define I2CD_M_S_RX_CMD_LAST (0x1 << 4)
102
#define I2CD_M_RX_CMD (0x1 << 3)
103
@@ -XXX,XX +XXX,XX @@
104
#define I2CD_M_START_CMD (0x1)
105
106
#define I2CD_DEV_ADDR_REG 0x18 /* Slave Device Address */
107
-#define I2CD_BUF_CTRL_REG 0x1c /* Pool Buffer Control */
108
+#define I2CD_POOL_CTRL_REG 0x1c /* Pool Buffer Control */
109
+#define I2CD_POOL_RX_COUNT(x) (((x) >> 24) & 0xff)
110
+#define I2CD_POOL_RX_SIZE(x) ((((x) >> 16) & 0xff) + 1)
111
+#define I2CD_POOL_TX_COUNT(x) ((((x) >> 8) & 0xff) + 1)
112
+#define I2CD_POOL_OFFSET(x) (((x) & 0x3f) << 2) /* AST2400 */
113
#define I2CD_BYTE_BUF_REG 0x20 /* Transmit/Receive Byte Buffer */
114
#define I2CD_BYTE_BUF_TX_SHIFT 0
115
#define I2CD_BYTE_BUF_TX_MASK 0xff
116
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
117
return bus->intr_ctrl;
118
case I2CD_INTR_STS_REG:
119
return bus->intr_status;
120
+ case I2CD_POOL_CTRL_REG:
121
+ return bus->pool_ctrl;
122
case I2CD_BYTE_BUF_REG:
123
return bus->buf;
124
case I2CD_CMD_REG:
125
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
126
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
127
}
40
}
128
41
129
+static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
42
-uint32_t helper_flcmps(float32 src1, float32 src2)
130
+{
43
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
131
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
132
+ int ret = -1;
133
+ int i;
134
+
135
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
136
+ for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
137
+ uint8_t *pool_base = aic->bus_pool_base(bus);
138
+
139
+ ret = i2c_send(bus->bus, pool_base[i]);
140
+ if (ret) {
141
+ break;
142
+ }
143
+ }
144
+ bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
145
+ } else {
146
+ ret = i2c_send(bus->bus, bus->buf);
147
+ }
148
+
149
+ return ret;
150
+}
151
+
152
+static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
153
+{
154
+ AspeedI2CState *s = bus->controller;
155
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
156
+ uint8_t data;
157
+ int i;
158
+
159
+ if (bus->cmd & I2CD_RX_BUFF_ENABLE) {
160
+ uint8_t *pool_base = aic->bus_pool_base(bus);
161
+
162
+ for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
163
+ pool_base[i] = i2c_recv(bus->bus);
164
+ }
165
+
166
+ /* Update RX count */
167
+ bus->pool_ctrl &= ~(0xff << 24);
168
+ bus->pool_ctrl |= (i & 0xff) << 24;
169
+ bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
170
+ } else {
171
+ data = i2c_recv(bus->bus);
172
+ bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
173
+ }
174
+}
175
+
176
static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
177
{
44
{
178
- uint8_t ret;
45
/*
179
-
46
* FLCMP never raises an exception nor modifies any FSR fields.
180
aspeed_i2c_set_state(bus, I2CD_MRXD);
47
* Perform the comparison with a dummy fp environment.
181
- ret = i2c_recv(bus->bus);
48
*/
182
+ aspeed_i2c_bus_recv(bus);
49
- float_status discard = { };
183
bus->intr_status |= I2CD_INTR_RX_DONE;
50
+ float_status discard = env->fp_status;
184
- bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
51
FloatRelation r;
185
if (bus->cmd & I2CD_M_S_RX_CMD_LAST) {
52
186
i2c_nack(bus->bus);
53
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
187
}
54
@@ -XXX,XX +XXX,XX @@ uint32_t helper_flcmps(float32 src1, float32 src2)
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
55
g_assert_not_reached();
189
aspeed_i2c_set_state(bus, I2CD_MACTIVE);
190
}
56
}
191
57
192
+static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
58
-uint32_t helper_flcmpd(float64 src1, float64 src2)
193
+{
59
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
194
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
195
+
196
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
197
+ uint8_t *pool_base = aic->bus_pool_base(bus);
198
+
199
+ return pool_base[0];
200
+ } else {
201
+ return bus->buf;
202
+ }
203
+}
204
+
205
/*
206
* The state machine needs some refinement. It is only used to track
207
* invalid STOP commands for the moment.
208
*/
209
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
210
{
60
{
211
+ uint8_t pool_start = 0;
61
- float_status discard = { };
212
+
62
+ float_status discard = env->fp_status;
213
bus->cmd &= ~0xFFFF;
63
FloatRelation r;
214
bus->cmd |= value & 0xFFFF;
64
215
65
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
216
if (bus->cmd & I2CD_M_START_CMD) {
66
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
217
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
67
index XXXXXXX..XXXXXXX 100644
218
I2CD_MSTARTR : I2CD_MSTART;
68
--- a/target/sparc/translate.c
219
+ uint8_t addr;
69
+++ b/target/sparc/translate.c
220
70
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPs(DisasContext *dc, arg_FLCMPs *a)
221
aspeed_i2c_set_state(bus, state);
71
222
72
src1 = gen_load_fpr_F(dc, a->rs1);
223
- if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7),
73
src2 = gen_load_fpr_F(dc, a->rs2);
224
- extract32(bus->buf, 0, 1))) {
74
- gen_helper_flcmps(cpu_fcc[a->cc], src1, src2);
225
+ addr = aspeed_i2c_get_addr(bus);
75
+ gen_helper_flcmps(cpu_fcc[a->cc], tcg_env, src1, src2);
226
+
76
return advance_pc(dc);
227
+ if (i2c_start_transfer(bus->bus, extract32(addr, 1, 7),
228
+ extract32(addr, 0, 1))) {
229
bus->intr_status |= I2CD_INTR_TX_NAK;
230
} else {
231
bus->intr_status |= I2CD_INTR_TX_ACK;
232
}
233
234
- /* START command is also a TX command, as the slave address is
235
- * sent on the bus */
236
- bus->cmd &= ~(I2CD_M_START_CMD | I2CD_M_TX_CMD);
237
+ bus->cmd &= ~I2CD_M_START_CMD;
238
+
239
+ /*
240
+ * The START command is also a TX command, as the slave
241
+ * address is sent on the bus. Drop the TX flag if nothing
242
+ * else needs to be sent in this sequence.
243
+ */
244
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
245
+ if (I2CD_POOL_TX_COUNT(bus->pool_ctrl) == 1) {
246
+ bus->cmd &= ~I2CD_M_TX_CMD;
247
+ } else {
248
+ /*
249
+ * Increase the start index in the TX pool buffer to
250
+ * skip the address byte.
251
+ */
252
+ pool_start++;
253
+ }
254
+ } else {
255
+ bus->cmd &= ~I2CD_M_TX_CMD;
256
+ }
257
258
/* No slave found */
259
if (!i2c_bus_busy(bus->bus)) {
260
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
261
262
if (bus->cmd & I2CD_M_TX_CMD) {
263
aspeed_i2c_set_state(bus, I2CD_MTXD);
264
- if (i2c_send(bus->bus, bus->buf)) {
265
+ if (aspeed_i2c_bus_send(bus, pool_start)) {
266
bus->intr_status |= (I2CD_INTR_TX_NAK);
267
i2c_end_transfer(bus->bus);
268
} else {
269
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
270
qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
271
__func__);
272
break;
273
+ case I2CD_POOL_CTRL_REG:
274
+ bus->pool_ctrl &= ~0xffffff;
275
+ bus->pool_ctrl |= (value & 0xffffff);
276
+ break;
277
+
278
case I2CD_BYTE_BUF_REG:
279
bus->buf = (value & I2CD_BYTE_BUF_TX_MASK) << I2CD_BYTE_BUF_TX_SHIFT;
280
break;
281
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_ctrl_ops = {
282
.endianness = DEVICE_LITTLE_ENDIAN,
283
};
284
285
+static uint64_t aspeed_i2c_pool_read(void *opaque, hwaddr offset,
286
+ unsigned size)
287
+{
288
+ AspeedI2CState *s = opaque;
289
+ uint64_t ret = 0;
290
+ int i;
291
+
292
+ for (i = 0; i < size; i++) {
293
+ ret |= (uint64_t) s->pool[offset + i] << (8 * i);
294
+ }
295
+
296
+ return ret;
297
+}
298
+
299
+static void aspeed_i2c_pool_write(void *opaque, hwaddr offset,
300
+ uint64_t value, unsigned size)
301
+{
302
+ AspeedI2CState *s = opaque;
303
+ int i;
304
+
305
+ for (i = 0; i < size; i++) {
306
+ s->pool[offset + i] = (value >> (8 * i)) & 0xFF;
307
+ }
308
+}
309
+
310
+static const MemoryRegionOps aspeed_i2c_pool_ops = {
311
+ .read = aspeed_i2c_pool_read,
312
+ .write = aspeed_i2c_pool_write,
313
+ .endianness = DEVICE_LITTLE_ENDIAN,
314
+ .valid = {
315
+ .min_access_size = 1,
316
+ .max_access_size = 4,
317
+ },
318
+};
319
+
320
static const VMStateDescription aspeed_i2c_bus_vmstate = {
321
.name = TYPE_ASPEED_I2C,
322
- .version_id = 1,
323
- .minimum_version_id = 1,
324
+ .version_id = 2,
325
+ .minimum_version_id = 2,
326
.fields = (VMStateField[]) {
327
VMSTATE_UINT8(id, AspeedI2CBus),
328
VMSTATE_UINT32(ctrl, AspeedI2CBus),
329
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
330
VMSTATE_UINT32(intr_status, AspeedI2CBus),
331
VMSTATE_UINT32(cmd, AspeedI2CBus),
332
VMSTATE_UINT32(buf, AspeedI2CBus),
333
+ VMSTATE_UINT32(pool_ctrl, AspeedI2CBus),
334
VMSTATE_END_OF_LIST()
335
}
336
};
337
338
static const VMStateDescription aspeed_i2c_vmstate = {
339
.name = TYPE_ASPEED_I2C,
340
- .version_id = 1,
341
- .minimum_version_id = 1,
342
+ .version_id = 2,
343
+ .minimum_version_id = 2,
344
.fields = (VMStateField[]) {
345
VMSTATE_UINT32(intr_status, AspeedI2CState),
346
VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState,
347
ASPEED_I2C_NR_BUSSES, 1, aspeed_i2c_bus_vmstate,
348
AspeedI2CBus),
349
+ VMSTATE_UINT8_ARRAY(pool, AspeedI2CState, ASPEED_I2C_MAX_POOL_SIZE),
350
VMSTATE_END_OF_LIST()
351
}
352
};
353
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
354
memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset),
355
&s->busses[i].mr);
356
}
357
+
358
+ memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
359
+ "aspeed.i2c-pool", aic->pool_size);
360
+ memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
361
}
77
}
362
78
363
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
79
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPd(DisasContext *dc, arg_FLCMPd *a)
364
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CBus *bus)
80
365
return bus->controller->irq;
81
src1 = gen_load_fpr_D(dc, a->rs1);
82
src2 = gen_load_fpr_D(dc, a->rs2);
83
- gen_helper_flcmpd(cpu_fcc[a->cc], src1, src2);
84
+ gen_helper_flcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
85
return advance_pc(dc);
366
}
86
}
367
87
368
+static uint8_t *aspeed_2400_i2c_bus_pool_base(AspeedI2CBus *bus)
369
+{
370
+ uint8_t *pool_page =
371
+ &bus->controller->pool[I2CD_POOL_PAGE_SEL(bus->ctrl) * 0x100];
372
+
373
+ return &pool_page[I2CD_POOL_OFFSET(bus->pool_ctrl)];
374
+}
375
+
376
static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
377
{
378
DeviceClass *dc = DEVICE_CLASS(klass);
379
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
380
aic->reg_size = 0x40;
381
aic->gap = 7;
382
aic->bus_get_irq = aspeed_2400_i2c_bus_get_irq;
383
+ aic->pool_size = 0x800;
384
+ aic->pool_base = 0x800;
385
+ aic->bus_pool_base = aspeed_2400_i2c_bus_pool_base;
386
}
387
388
static const TypeInfo aspeed_2400_i2c_info = {
389
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2500_i2c_bus_get_irq(AspeedI2CBus *bus)
390
return bus->controller->irq;
391
}
392
393
+static uint8_t *aspeed_2500_i2c_bus_pool_base(AspeedI2CBus *bus)
394
+{
395
+ return &bus->controller->pool[bus->id * 0x10];
396
+}
397
+
398
static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
399
{
400
DeviceClass *dc = DEVICE_CLASS(klass);
401
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
402
aic->reg_size = 0x40;
403
aic->gap = 7;
404
aic->bus_get_irq = aspeed_2500_i2c_bus_get_irq;
405
+ aic->pool_size = 0x100;
406
+ aic->pool_base = 0x200;
407
+ aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
408
}
409
410
static const TypeInfo aspeed_2500_i2c_info = {
411
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus)
412
return bus->irq;
413
}
414
415
+static uint8_t *aspeed_2600_i2c_bus_pool_base(AspeedI2CBus *bus)
416
+{
417
+ return &bus->controller->pool[bus->id * 0x20];
418
+}
419
+
420
static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
421
{
422
DeviceClass *dc = DEVICE_CLASS(klass);
423
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
424
aic->reg_size = 0x80;
425
aic->gap = -1; /* no gap */
426
aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
427
+ aic->pool_size = 0x200;
428
+ aic->pool_base = 0xC00;
429
+ aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
430
}
431
432
static const TypeInfo aspeed_2600_i2c_info = {
433
--
88
--
434
2.20.1
89
2.34.1
435
436
diff view generated by jsdifflib
New patch
1
In the helper_compute_fprf functions, we pass a dummy float_status
2
in to the is_signaling_nan() function. This is unnecessary, because
3
we have convenient access to the CPU env pointer here and that
4
is already set up with the correct values for the snan_bit_is_one
5
and no_signaling_nans config settings. is_signaling_nan() doesn't
6
ever update the fp_status with any exception flags, so there is
7
no reason not to use env->fp_status here.
1
8
9
Use env->fp_status instead of the dummy fp_status.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20241202131347.498124-34-peter.maydell@linaro.org
14
---
15
target/ppc/fpu_helper.c | 3 +--
16
1 file changed, 1 insertion(+), 2 deletions(-)
17
18
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/ppc/fpu_helper.c
21
+++ b/target/ppc/fpu_helper.c
22
@@ -XXX,XX +XXX,XX @@ void helper_compute_fprf_##tp(CPUPPCState *env, tp arg) \
23
} else if (tp##_is_infinity(arg)) { \
24
fprf = neg ? 0x09 << FPSCR_FPRF : 0x05 << FPSCR_FPRF; \
25
} else { \
26
- float_status dummy = { }; /* snan_bit_is_one = 0 */ \
27
- if (tp##_is_signaling_nan(arg, &dummy)) { \
28
+ if (tp##_is_signaling_nan(arg, &env->fp_status)) { \
29
fprf = 0x00 << FPSCR_FPRF; \
30
} else { \
31
fprf = 0x11 << FPSCR_FPRF; \
32
--
33
2.34.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
Now that float_status has a bunch of fp parameters,
4
an array of qemu_irq and passing it around, directly call
4
it is easier to copy an existing structure than create
5
qdev_get_gpio_in() on the gic field.
5
one from scratch. Begin by copying the structure that
6
corresponds to the FPSR and make only the adjustments
7
required for BFloat16 semantics.
6
8
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20191206162303.30338-1-philmd@redhat.com
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20241203203949.483774-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
hw/arm/sbsa-ref.c | 86 +++++++++++++++++++++++------------------------
15
target/arm/tcg/vec_helper.c | 20 +++++++-------------
13
1 file changed, 42 insertions(+), 44 deletions(-)
16
1 file changed, 7 insertions(+), 13 deletions(-)
14
17
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
18
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
20
--- a/target/arm/tcg/vec_helper.c
18
+++ b/hw/arm/sbsa-ref.c
21
+++ b/target/arm/tcg/vec_helper.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct {
22
@@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
20
void *fdt;
23
* no effect on AArch32 instructions.
21
int fdt_size;
22
int psci_conduit;
23
+ DeviceState *gic;
24
PFlashCFI01 *flash[2];
25
} SBSAMachineState;
26
27
@@ -XXX,XX +XXX,XX @@ static void create_secure_ram(SBSAMachineState *sms,
28
memory_region_add_subregion(secure_sysmem, base, secram);
29
}
30
31
-static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
32
+static void create_gic(SBSAMachineState *sms)
33
{
34
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
35
- DeviceState *gicdev;
36
SysBusDevice *gicbusdev;
37
const char *gictype;
38
uint32_t redist0_capacity, redist0_count;
39
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
40
41
gictype = gicv3_class_name();
42
43
- gicdev = qdev_create(NULL, gictype);
44
- qdev_prop_set_uint32(gicdev, "revision", 3);
45
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
46
+ sms->gic = qdev_create(NULL, gictype);
47
+ qdev_prop_set_uint32(sms->gic, "revision", 3);
48
+ qdev_prop_set_uint32(sms->gic, "num-cpu", smp_cpus);
49
/*
50
* Note that the num-irq property counts both internal and external
51
* interrupts; there are always 32 of the former (mandated by GIC spec).
52
*/
24
*/
53
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
25
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
54
- qdev_prop_set_bit(gicdev, "has-security-extensions", true);
26
- *statusp = (float_status){
55
+ qdev_prop_set_uint32(sms->gic, "num-irq", NUM_IRQS + 32);
27
- .tininess_before_rounding = float_tininess_before_rounding,
56
+ qdev_prop_set_bit(sms->gic, "has-security-extensions", true);
28
- .float_rounding_mode = float_round_to_odd_inf,
57
29
- .flush_to_zero = true,
58
redist0_capacity =
30
- .flush_inputs_to_zero = true,
59
sbsa_ref_memmap[SBSA_GIC_REDIST].size / GICV3_REDIST_SIZE;
31
- .default_nan_mode = true,
60
redist0_count = MIN(smp_cpus, redist0_capacity);
32
- };
61
33
+
62
- qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
34
+ *statusp = env->vfp.fp_status;
63
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
35
+ set_default_nan_mode(true, statusp);
64
+ qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1);
36
65
+ qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count);
37
if (ebf) {
66
38
- float_status *fpst = &env->vfp.fp_status;
67
- qdev_init_nofail(gicdev);
39
- set_flush_to_zero(get_flush_to_zero(fpst), statusp);
68
- gicbusdev = SYS_BUS_DEVICE(gicdev);
40
- set_flush_inputs_to_zero(get_flush_inputs_to_zero(fpst), statusp);
69
+ qdev_init_nofail(sms->gic);
41
- set_float_rounding_mode(get_float_rounding_mode(fpst), statusp);
70
+ gicbusdev = SYS_BUS_DEVICE(sms->gic);
42
-
71
sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base);
43
/* EBF=1 needs to do a step with round-to-odd semantics */
72
sysbus_mmio_map(gicbusdev, 1, sbsa_ref_memmap[SBSA_GIC_REDIST].base);
44
*oddstatusp = *statusp;
73
45
set_float_rounding_mode(float_round_to_odd, oddstatusp);
74
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
46
+ } else {
75
47
+ set_flush_to_zero(true, statusp);
76
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
48
+ set_flush_inputs_to_zero(true, statusp);
77
qdev_connect_gpio_out(cpudev, irq,
49
+ set_float_rounding_mode(float_round_to_odd_inf, statusp);
78
- qdev_get_gpio_in(gicdev,
79
+ qdev_get_gpio_in(sms->gic,
80
ppibase + timer_irq[irq]));
81
}
82
83
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
84
- qdev_get_gpio_in(gicdev, ppibase
85
+ qdev_get_gpio_in(sms->gic, ppibase
86
+ ARCH_GIC_MAINT_IRQ));
87
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
88
- qdev_get_gpio_in(gicdev, ppibase
89
+ qdev_get_gpio_in(sms->gic, ppibase
90
+ VIRTUAL_PMU_IRQ));
91
92
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
93
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
94
sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
95
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
96
}
50
}
97
-
51
-
98
- for (i = 0; i < NUM_IRQS; i++) {
52
return ebf;
99
- pic[i] = qdev_get_gpio_in(gicdev, i);
100
- }
101
}
53
}
102
54
103
-static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
104
+static void create_uart(const SBSAMachineState *sms, int uart,
105
MemoryRegion *mem, Chardev *chr)
106
{
107
hwaddr base = sbsa_ref_memmap[uart].base;
108
@@ -XXX,XX +XXX,XX @@ static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
109
qdev_init_nofail(dev);
110
memory_region_add_subregion(mem, base,
111
sysbus_mmio_get_region(s, 0));
112
- sysbus_connect_irq(s, 0, pic[irq]);
113
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(sms->gic, irq));
114
}
115
116
-static void create_rtc(const SBSAMachineState *sms, qemu_irq *pic)
117
+static void create_rtc(const SBSAMachineState *sms)
118
{
119
hwaddr base = sbsa_ref_memmap[SBSA_RTC].base;
120
int irq = sbsa_ref_irqmap[SBSA_RTC];
121
122
- sysbus_create_simple("pl031", base, pic[irq]);
123
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(sms->gic, irq));
124
}
125
126
static DeviceState *gpio_key_dev;
127
@@ -XXX,XX +XXX,XX @@ static Notifier sbsa_ref_powerdown_notifier = {
128
.notify = sbsa_ref_powerdown_req
129
};
130
131
-static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
132
+static void create_gpio(const SBSAMachineState *sms)
133
{
134
DeviceState *pl061_dev;
135
hwaddr base = sbsa_ref_memmap[SBSA_GPIO].base;
136
int irq = sbsa_ref_irqmap[SBSA_GPIO];
137
138
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
139
+ pl061_dev = sysbus_create_simple("pl061", base,
140
+ qdev_get_gpio_in(sms->gic, irq));
141
142
gpio_key_dev = sysbus_create_simple("gpio-key", -1,
143
qdev_get_gpio_in(pl061_dev, 3));
144
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
145
qemu_register_powerdown_notifier(&sbsa_ref_powerdown_notifier);
146
}
147
148
-static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
149
+static void create_ahci(const SBSAMachineState *sms)
150
{
151
hwaddr base = sbsa_ref_memmap[SBSA_AHCI].base;
152
int irq = sbsa_ref_irqmap[SBSA_AHCI];
153
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
154
qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS);
155
qdev_init_nofail(dev);
156
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
157
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
158
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
159
160
sysahci = SYSBUS_AHCI(dev);
161
ahci = &sysahci->ahci;
162
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
163
}
164
}
165
166
-static void create_ehci(const SBSAMachineState *sms, qemu_irq *pic)
167
+static void create_ehci(const SBSAMachineState *sms)
168
{
169
hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
170
int irq = sbsa_ref_irqmap[SBSA_EHCI];
171
172
- sysbus_create_simple("platform-ehci-usb", base, pic[irq]);
173
+ sysbus_create_simple("platform-ehci-usb", base,
174
+ qdev_get_gpio_in(sms->gic, irq));
175
}
176
177
-static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
178
- PCIBus *bus)
179
+static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
180
{
181
hwaddr base = sbsa_ref_memmap[SBSA_SMMU].base;
182
int irq = sbsa_ref_irqmap[SBSA_SMMU];
183
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
184
qdev_init_nofail(dev);
185
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
186
for (i = 0; i < NUM_SMMU_IRQS; i++) {
187
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
188
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
189
+ qdev_get_gpio_in(sms->gic, irq + 1));
190
}
191
}
192
193
-static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
194
+static void create_pcie(SBSAMachineState *sms)
195
{
196
hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base;
197
hwaddr size_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].size;
198
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
199
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
200
201
for (i = 0; i < GPEX_NUM_IRQS; i++) {
202
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
203
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
204
+ qdev_get_gpio_in(sms->gic, irq + 1));
205
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
206
}
207
208
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
209
210
pci_create_simple(pci->bus, -1, "VGA");
211
212
- create_smmu(sms, pic, pci->bus);
213
+ create_smmu(sms, pci->bus);
214
}
215
216
static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
217
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
218
bool firmware_loaded;
219
const CPUArchIdList *possible_cpus;
220
int n, sbsa_max_cpus;
221
- qemu_irq pic[NUM_IRQS];
222
223
if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) {
224
error_report("sbsa-ref: CPU type other than the built-in "
225
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
226
227
create_secure_ram(sms, secure_sysmem);
228
229
- create_gic(sms, pic);
230
+ create_gic(sms);
231
232
- create_uart(sms, pic, SBSA_UART, sysmem, serial_hd(0));
233
- create_uart(sms, pic, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
234
+ create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
235
+ create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
236
/* Second secure UART for RAS and MM from EL0 */
237
- create_uart(sms, pic, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
238
+ create_uart(sms, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
239
240
- create_rtc(sms, pic);
241
+ create_rtc(sms);
242
243
- create_gpio(sms, pic);
244
+ create_gpio(sms);
245
246
- create_ahci(sms, pic);
247
+ create_ahci(sms);
248
249
- create_ehci(sms, pic);
250
+ create_ehci(sms);
251
252
- create_pcie(sms, pic);
253
+ create_pcie(sms);
254
255
sms->bootinfo.ram_size = machine->ram_size;
256
sms->bootinfo.nb_cpus = smp_cpus;
257
--
55
--
258
2.20.1
56
2.34.1
259
57
260
58
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
Currently we hardcode the default NaN value in parts64_default_nan()
2
using a compile-time ifdef ladder. This is awkward for two cases:
3
* for single-QEMU-binary we can't hard-code target-specifics like this
4
* for Arm FEAT_AFP the default NaN value depends on FPCR.AH
5
(specifically the sign bit is different)
2
6
3
HCR_EL2.TID1 mandates that access from EL1 to REVIDR_EL1, AIDR_EL1
7
Add a field to float_status to specify the default NaN value; fall
4
(and their 32bit equivalents) as well as TCMTR, TLBTR are trapped
8
back to the old ifdef behaviour if these are not set.
5
to EL2. QEMU ignores it, making it harder for a hypervisor to
6
virtualize the HW (though to be fair, no known hypervisor actually
7
cares).
8
9
9
Do the right thing by trapping to EL2 if HCR_EL2.TID1 is set.
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.
10
14
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-3-maz@kernel.org
17
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
18
---
17
target/arm/helper.c | 36 ++++++++++++++++++++++++++++++++----
19
include/fpu/softfloat-helpers.h | 11 +++++++
18
1 file changed, 32 insertions(+), 4 deletions(-)
20
include/fpu/softfloat-types.h | 10 ++++++
21
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
22
3 files changed, 54 insertions(+), 22 deletions(-)
19
23
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
21
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
26
--- a/include/fpu/softfloat-helpers.h
23
+++ b/target/arm/helper.c
27
+++ b/include/fpu/softfloat-helpers.h
24
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
28
@@ -XXX,XX +XXX,XX @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
25
return ret;
29
status->float_infzeronan_rule = rule;
26
}
30
}
27
31
28
+static CPAccessResult access_aa64_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
32
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
29
+ bool isread)
33
+ float_status *status)
30
+{
34
+{
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID1)) {
35
+ status->default_nan_pattern = dnan_pattern;
32
+ return CP_ACCESS_TRAP_EL2;
33
+ }
34
+
35
+ return CP_ACCESS_OK;
36
+}
36
+}
37
+
37
+
38
+static CPAccessResult access_aa32_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
38
static inline void set_flush_to_zero(bool val, float_status *status)
39
+ bool isread)
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)
40
+{
46
+{
41
+ if (arm_feature(env, ARM_FEATURE_V8)) {
47
+ return status->default_nan_pattern;
42
+ return access_aa64_tid1(env, ri, isread);
43
+ }
44
+
45
+ return CP_ACCESS_OK;
46
+}
48
+}
47
+
49
+
48
static const ARMCPRegInfo v7_cp_reginfo[] = {
50
static inline bool get_flush_to_zero(float_status *status)
49
/* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */
51
{
50
{ .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
52
return status->flush_to_zero;
51
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
53
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
52
*/
54
index XXXXXXX..XXXXXXX 100644
53
{ .name = "AIDR", .state = ARM_CP_STATE_BOTH,
55
--- a/include/fpu/softfloat-types.h
54
.opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7,
56
+++ b/include/fpu/softfloat-types.h
55
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
57
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
56
+ .access = PL1_R, .type = ARM_CP_CONST,
58
/* should denormalised inputs go to zero and set the input_denormal flag? */
57
+ .accessfn = access_aa64_tid1,
59
bool flush_inputs_to_zero;
58
+ .resetvalue = 0 },
60
bool default_nan_mode;
59
/* Auxiliary fault status registers: these also are IMPDEF, and we
61
+ /*
60
* choose to RAZ/WI for all cores.
62
+ * The pattern to use for the default NaN. Here the high bit specifies
61
*/
63
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
62
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
64
+ * fractional part. The low bits of the fractional part are copies of bit 0.
63
.access = PL1_R, .resetvalue = cpu->midr },
65
+ * The exponent of the default NaN is (as for any NaN) always all 1s.
64
{ .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,
66
+ * Note that a value of 0 here is not a valid NaN. The target must set
65
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
67
+ * this to the correct non-zero value, or we will assert when trying to
66
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
68
+ * create a default NaN.
67
+ .access = PL1_R,
69
+ */
68
+ .accessfn = access_aa64_tid1,
70
+ uint8_t default_nan_pattern;
69
+ .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
71
/*
70
REGINFO_SENTINEL
72
* The flags below are not used on all specializations and may
71
};
73
* constant fold away (see snan_bit_is_one()/no_signalling_nans() in
72
ARMCPRegInfo id_cp_reginfo[] = {
74
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
75
index XXXXXXX..XXXXXXX 100644
74
/* TCMTR and TLBTR exist in v8 but have no 64-bit versions */
76
--- a/fpu/softfloat-specialize.c.inc
75
{ .name = "TCMTR",
77
+++ b/fpu/softfloat-specialize.c.inc
76
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2,
78
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
77
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
79
{
78
+ .access = PL1_R,
80
bool sign = 0;
79
+ .accessfn = access_aa32_tid1,
81
uint64_t frac;
80
+ .type = ARM_CP_CONST, .resetvalue = 0 },
82
+ uint8_t dnan_pattern = status->default_nan_pattern;
81
REGINFO_SENTINEL
83
82
};
84
+ if (dnan_pattern == 0) {
83
/* TLBTR is specific to VMSA */
85
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
84
ARMCPRegInfo id_tlbtr_reginfo = {
86
- /* !snan_bit_is_one, set all bits */
85
.name = "TLBTR",
87
- frac = (1ULL << DECOMPOSED_BINARY_POINT) - 1;
86
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3,
88
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
87
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0,
89
+ /* Sign bit clear, all frac bits set */
88
+ .access = PL1_R,
90
+ dnan_pattern = 0b01111111;
89
+ .accessfn = access_aa32_tid1,
91
+#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
90
+ .type = ARM_CP_CONST, .resetvalue = 0,
92
|| defined(TARGET_MICROBLAZE)
91
};
93
- /* !snan_bit_is_one, set sign and msb */
92
/* MPUIR is specific to PMSA V6+ */
94
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
93
ARMCPRegInfo id_mpuir_reginfo = {
95
- sign = 1;
96
+ /* Sign bit set, most significant frac bit set */
97
+ dnan_pattern = 0b11000000;
98
#elif defined(TARGET_HPPA)
99
- /* snan_bit_is_one, set msb-1. */
100
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 2);
101
+ /* Sign bit clear, msb-1 frac bit set */
102
+ dnan_pattern = 0b00100000;
103
#elif defined(TARGET_HEXAGON)
104
- sign = 1;
105
- frac = ~0ULL;
106
+ /* Sign bit set, all frac bits set. */
107
+ dnan_pattern = 0b11111111;
108
#else
109
- /*
110
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
111
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
112
- * do not have floating-point.
113
- */
114
- if (snan_bit_is_one(status)) {
115
- /* set all bits other than msb */
116
- frac = (1ULL << (DECOMPOSED_BINARY_POINT - 1)) - 1;
117
- } else {
118
- /* set msb */
119
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
120
- }
121
+ /*
122
+ * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
123
+ * S390, SH4, TriCore, and Xtensa. Our other supported targets
124
+ * do not have floating-point.
125
+ */
126
+ if (snan_bit_is_one(status)) {
127
+ /* sign bit clear, set all frac bits other than msb */
128
+ dnan_pattern = 0b00111111;
129
+ } else {
130
+ /* sign bit clear, set frac msb */
131
+ dnan_pattern = 0b01000000;
132
+ }
133
#endif
134
+ }
135
+ assert(dnan_pattern != 0);
136
+
137
+ sign = dnan_pattern >> 7;
138
+ /*
139
+ * Place default_nan_pattern [6:0] into bits [62:56],
140
+ * and replecate bit [0] down into [55:0]
141
+ */
142
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
143
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
144
145
*p = (FloatParts64) {
146
.cls = float_class_qnan,
94
--
147
--
95
2.20.1
148
2.34.1
96
97
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the tests/fp code.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-36-peter.maydell@linaro.org
6
---
7
tests/fp/fp-bench.c | 1 +
8
tests/fp/fp-test-log2.c | 1 +
9
tests/fp/fp-test.c | 1 +
10
3 files changed, 3 insertions(+)
11
12
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/fp/fp-bench.c
15
+++ b/tests/fp/fp-bench.c
16
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
17
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
18
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
19
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
20
+ set_float_default_nan_pattern(0b01000000, &soft_status);
21
22
f = bench_funcs[operation][precision];
23
g_assert(f);
24
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/tests/fp/fp-test-log2.c
27
+++ b/tests/fp/fp-test-log2.c
28
@@ -XXX,XX +XXX,XX @@ int main(int ac, char **av)
29
int i;
30
31
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
32
+ set_float_default_nan_pattern(0b01000000, &qsf);
33
set_float_rounding_mode(float_round_nearest_even, &qsf);
34
35
test.d = 0.0;
36
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/fp/fp-test.c
39
+++ b/tests/fp/fp-test.c
40
@@ -XXX,XX +XXX,XX @@ void run_test(void)
41
*/
42
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
43
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
44
+ set_float_default_nan_pattern(0b01000000, &qsf);
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
46
47
genCases_setLevel(test_level);
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-37-peter.maydell@linaro.org
7
---
8
target/microblaze/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/microblaze/cpu.c
15
+++ b/target/microblaze/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_reset_hold(Object *obj, ResetType type)
17
* this architecture.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
23
#if defined(CONFIG_USER_ONLY)
24
/* start in user mode with interrupts enabled. */
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
34
- || defined(TARGET_MICROBLAZE)
35
+#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
/* Sign bit set, most significant frac bit set */
37
dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-38-peter.maydell@linaro.org
7
---
8
target/i386/tcg/fpu_helper.c | 4 ++++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 4 insertions(+), 3 deletions(-)
11
12
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/i386/tcg/fpu_helper.c
15
+++ b/target/i386/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
17
*/
18
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
19
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
+ set_float_default_nan_pattern(0b11000000, &env->mmx_status);
23
+ set_float_default_nan_pattern(0b11000000, &env->sse_status);
24
}
25
26
static inline uint8_t save_exception_flags(CPUX86State *env)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
index XXXXXXX..XXXXXXX 100644
29
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
32
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
/* Sign bit clear, all frac bits set */
34
dnan_pattern = 0b01111111;
35
-#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
- /* Sign bit set, most significant frac bit set */
37
- dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
/* Sign bit clear, msb-1 frac bit set */
40
dnan_pattern = 0b00100000;
41
--
42
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-39-peter.maydell@linaro.org
7
---
8
target/hppa/fpu_helper.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 2 insertions(+), 3 deletions(-)
11
12
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/hppa/fpu_helper.c
15
+++ b/target/hppa/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
17
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
18
/* For inf * 0 + NaN, return the input NaN */
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ /* Default NaN: sign bit clear, msb-1 frac bit set */
21
+ set_float_default_nan_pattern(0b00100000, &env->fp_status);
22
}
23
24
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_HPPA)
34
- /* Sign bit clear, msb-1 frac bit set */
35
- dnan_pattern = 0b00100000;
36
#elif defined(TARGET_HEXAGON)
37
/* Sign bit set, all frac bits set. */
38
dnan_pattern = 0b11111111;
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the alpha target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-40-peter.maydell@linaro.org
6
---
7
target/alpha/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/alpha/cpu.c
13
+++ b/target/alpha/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_initfn(Object *obj)
15
* operand in Fa. That is float_2nan_prop_ba.
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
18
+ /* Default NaN: sign bit clear, msb frac bit set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
#if defined(CONFIG_USER_ONLY)
21
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
22
cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the arm target.
2
This includes setting it for the old linux-user nwfpe emulation.
3
For nwfpe, our default doesn't match the real kernel, but we
4
avoid making a behaviour change in this commit.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-41-peter.maydell@linaro.org
9
---
10
linux-user/arm/nwfpe/fpa11.c | 5 +++++
11
target/arm/cpu.c | 2 ++
12
2 files changed, 7 insertions(+)
13
14
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/arm/nwfpe/fpa11.c
17
+++ b/linux-user/arm/nwfpe/fpa11.c
18
@@ -XXX,XX +XXX,XX @@ void resetFPA11(void)
19
* this late date.
20
*/
21
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
22
+ /*
23
+ * Use the same default NaN value as Arm VFP. This doesn't match
24
+ * the Linux kernel's nwfpe emulation, which uses an all-1s value.
25
+ */
26
+ set_float_default_nan_pattern(0b01000000, &fpa11->fp_status);
27
}
28
29
void SetRoundingMode(const unsigned int opcode)
30
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu.c
33
+++ b/target/arm/cpu.c
34
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
35
* the pseudocode function the arguments are in the order c, a, b.
36
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
37
* and the input NaN if it is signalling
38
+ * * Default NaN has sign bit clear, msb frac bit set
39
*/
40
static void arm_set_default_fp_behaviours(float_status *s)
41
{
42
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
44
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
46
+ set_float_default_nan_pattern(0b01000000, s);
47
}
48
49
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
50
--
51
2.34.1
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Set the default NaN pattern explicitly for loongarch.
2
2
3
A write to the SCR can change the effective EL by droppping the system
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
from secure to non-secure mode. However if we use a cached current_el
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
from before the change we'll rebuild the flags incorrectly. To fix
5
Message-id: 20241202131347.498124-42-peter.maydell@linaro.org
6
this we introduce the ARM_CP_NEWEL CP flag to indicate the new EL
6
---
7
should be used when recomputing the flags.
7
target/loongarch/tcg/fpu_helper.c | 2 ++
8
1 file changed, 2 insertions(+)
8
9
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
10
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20191212114734.6962-1-alex.bennee@linaro.org
13
Cc: Richard Henderson <richard.henderson@linaro.org>
14
Message-Id: <20191209143723.6368-1-alex.bennee@linaro.org>
15
Cc: qemu-stable@nongnu.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/cpu.h | 8 ++++++--
19
target/arm/helper.h | 1 +
20
target/arm/helper.c | 14 +++++++++++++-
21
target/arm/translate.c | 6 +++++-
22
4 files changed, 25 insertions(+), 4 deletions(-)
23
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu.h
12
--- a/target/loongarch/tcg/fpu_helper.c
27
+++ b/target/arm/cpu.h
13
+++ b/target/loongarch/tcg/fpu_helper.c
28
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
14
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
29
* RAISES_EXC is for when the read or write hook might raise an exception;
15
*/
30
* the generated code will synchronize the CPU state before calling the hook
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
31
* so that it is safe for the hook to call raise_exception().
17
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
32
+ * NEWEL is for writes to registers that might change the exception
18
+ /* Default NaN: sign bit clear, msb frac bit set */
33
+ * level - typically on older ARM chips. For those cases we need to
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
34
+ * re-read the new el when recomputing the translation flags.
35
*/
36
#define ARM_CP_SPECIAL 0x0001
37
#define ARM_CP_CONST 0x0002
38
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
39
#define ARM_CP_SVE 0x2000
40
#define ARM_CP_NO_GDB 0x4000
41
#define ARM_CP_RAISES_EXC 0x8000
42
+#define ARM_CP_NEWEL 0x10000
43
/* Used only as a terminator for ARMCPRegInfo lists */
44
-#define ARM_CP_SENTINEL 0xffff
45
+#define ARM_CP_SENTINEL 0xfffff
46
/* Mask of only the flag bits in a type field */
47
-#define ARM_CP_FLAG_MASK 0xf0ff
48
+#define ARM_CP_FLAG_MASK 0x1f0ff
49
50
/* Valid values for ARMCPRegInfo state field, indicating which of
51
* the AArch32 and AArch64 execution states this register is visible in.
52
diff --git a/target/arm/helper.h b/target/arm/helper.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/helper.h
55
+++ b/target/arm/helper.h
56
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_user_reg, i32, env, i32)
57
DEF_HELPER_3(set_user_reg, void, env, i32, i32)
58
59
DEF_HELPER_FLAGS_2(rebuild_hflags_m32, TCG_CALL_NO_RWG, void, env, int)
60
+DEF_HELPER_FLAGS_1(rebuild_hflags_a32_newel, TCG_CALL_NO_RWG, void, env)
61
DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, int)
62
DEF_HELPER_FLAGS_2(rebuild_hflags_a64, TCG_CALL_NO_RWG, void, env, int)
63
64
diff --git a/target/arm/helper.c b/target/arm/helper.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/helper.c
67
+++ b/target/arm/helper.c
68
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
69
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
70
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
71
.resetvalue = 0, .writefn = scr_write },
72
- { .name = "SCR", .type = ARM_CP_ALIAS,
73
+ { .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
74
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
75
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
76
.fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
77
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
78
env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
79
}
20
}
80
21
81
+/*
22
int ieee_ex_to_loongarch(int xcpt)
82
+ * If we have triggered a EL state change we can't rely on the
83
+ * translator having passed it too us, we need to recompute.
84
+ */
85
+void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
86
+{
87
+ int el = arm_current_el(env);
88
+ int fp_el = fp_exception_el(env, el);
89
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
90
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
91
+}
92
+
93
void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
94
{
95
int fp_el = fp_exception_el(env, el);
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
101
if (arm_dc_feature(s, ARM_FEATURE_M)) {
102
gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
103
} else {
104
- gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
105
+ if (ri->type & ARM_CP_NEWEL) {
106
+ gen_helper_rebuild_hflags_a32_newel(cpu_env);
107
+ } else {
108
+ gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
109
+ }
110
}
111
tcg_temp_free_i32(tcg_el);
112
/*
113
--
23
--
114
2.20.1
24
2.34.1
115
116
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for m68k.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-43-peter.maydell@linaro.org
6
---
7
target/m68k/cpu.c | 2 ++
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 3 insertions(+), 1 deletion(-)
10
11
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/m68k/cpu.c
14
+++ b/target/m68k/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
16
* preceding paragraph for nonsignaling NaNs.
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
+ /* Default NaN: sign bit clear, all frac bits set */
20
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
21
22
nan = floatx80_default_nan(&env->fp_status);
23
for (i = 0; i < 8; i++) {
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
29
uint8_t dnan_pattern = status->default_nan_pattern;
30
31
if (dnan_pattern == 0) {
32
-#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
+#if defined(TARGET_SPARC)
34
/* Sign bit clear, all frac bits set */
35
dnan_pattern = 0b01111111;
36
#elif defined(TARGET_HEXAGON)
37
--
38
2.34.1
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
Set the default NaN pattern explicitly for MIPS. Note that this
2
is our only target which currently changes the default NaN
3
at runtime (which it was previously doing indirectly when it
4
changed the snan_bit_is_one setting).
2
5
3
Add probe_read alongside the write probing equivalent.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-44-peter.maydell@linaro.org
9
---
10
target/mips/fpu_helper.h | 7 +++++++
11
target/mips/msa.c | 3 +++
12
2 files changed, 10 insertions(+)
4
13
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
14
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20191121000843.24844-2-beata.michalska@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/exec/exec-all.h | 6 ++++++
12
1 file changed, 6 insertions(+)
13
14
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/exec-all.h
16
--- a/target/mips/fpu_helper.h
17
+++ b/include/exec/exec-all.h
17
+++ b/target/mips/fpu_helper.h
18
@@ -XXX,XX +XXX,XX @@ static inline void *probe_write(CPUArchState *env, target_ulong addr, int size,
18
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
19
return probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
19
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
20
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
21
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
22
+ /*
23
+ * With nan2008, the default NaN value has the sign bit clear and the
24
+ * frac msb set; with the older mode, the sign bit is clear, and all
25
+ * frac bits except the msb are set.
26
+ */
27
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
28
+ &env->active_fpu.fp_status);
29
20
}
30
}
21
31
22
+static inline void *probe_read(CPUArchState *env, target_ulong addr, int size,
32
diff --git a/target/mips/msa.c b/target/mips/msa.c
23
+ int mmu_idx, uintptr_t retaddr)
33
index XXXXXXX..XXXXXXX 100644
24
+{
34
--- a/target/mips/msa.c
25
+ return probe_access(env, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
35
+++ b/target/mips/msa.c
26
+}
36
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
27
+
37
/* Inf * 0 + NaN returns the input NaN */
28
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
38
set_float_infzeronan_rule(float_infzeronan_dnan_never,
29
39
&env->active_tc.msa_fp_status);
30
/* Estimated block size for TB allocation. */
40
+ /* Default NaN: sign bit clear, frac msb set */
41
+ set_float_default_nan_pattern(0b01000000,
42
+ &env->active_tc.msa_fp_status);
43
}
31
--
44
--
32
2.20.1
45
2.34.1
33
34
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for openrisc.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-45-peter.maydell@linaro.org
6
---
7
target/openrisc/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/openrisc/cpu.c
13
+++ b/target/openrisc/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
15
*/
16
set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
17
18
+ /* Default NaN: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
20
21
#ifndef CONFIG_USER_ONLY
22
cpu->env.picmr = 0x00000000;
23
--
24
2.34.1
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Set the default NaN pattern explicitly for ppc.
2
2
3
Currently, we link the DRAM memory region to the FMC model (for DMAs)
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
through a property alias at the SoC level. The I2C model will need a
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
similar region for DMA support, add a DRAM region property at the SoC
5
Message-id: 20241202131347.498124-46-peter.maydell@linaro.org
6
level for both model to use.
6
---
7
target/ppc/cpu_init.c | 4 ++++
8
1 file changed, 4 insertions(+)
7
9
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-id: 20191119141211.25716-4-clg@kaod.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/hw/arm/aspeed_soc.h | 1 +
16
hw/arm/aspeed_ast2600.c | 7 +++++--
17
hw/arm/aspeed_soc.c | 9 +++++++--
18
3 files changed, 13 insertions(+), 4 deletions(-)
19
20
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
21
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/aspeed_soc.h
12
--- a/target/ppc/cpu_init.c
23
+++ b/include/hw/arm/aspeed_soc.h
13
+++ b/target/ppc/cpu_init.c
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
14
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
25
ARMCPU cpu[ASPEED_CPUS_NUM];
15
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
uint32_t num_cpus;
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
27
A15MPPrivState a7mpcore;
17
28
+ MemoryRegion *dram_mr;
18
+ /* Default NaN: sign bit clear, set frac msb */
29
MemoryRegion sram;
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
30
AspeedVICState vic;
20
+ set_float_default_nan_pattern(0b01000000, &env->vec_status);
31
AspeedRtcState rtc;
21
+
32
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
22
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
33
index XXXXXXX..XXXXXXX 100644
23
ppc_spr_t *spr = &env->spr_cb[i];
34
--- a/hw/arm/aspeed_ast2600.c
35
+++ b/hw/arm/aspeed_ast2600.c
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
37
typename);
38
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
39
&error_abort);
40
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
41
- &error_abort);
42
43
for (i = 0; i < sc->spis_num; i++) {
44
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
46
}
47
48
/* FMC, The number of CS is set at the board level */
49
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
50
+ if (err) {
51
+ error_propagate(errp, err);
52
+ return;
53
+ }
54
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
55
"sdram-base", &err);
56
if (err) {
57
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/aspeed_soc.c
60
+++ b/hw/arm/aspeed_soc.c
61
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
62
typename);
63
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
64
&error_abort);
65
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
66
- &error_abort);
67
68
for (i = 0; i < sc->spis_num; i++) {
69
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
70
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
71
aspeed_soc_get_irq(s, ASPEED_I2C));
72
73
/* FMC, The number of CS is set at the board level */
74
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
75
+ if (err) {
76
+ error_propagate(errp, err);
77
+ return;
78
+ }
79
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
80
"sdram-base", &err);
81
if (err) {
82
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
83
}
84
static Property aspeed_soc_properties[] = {
85
DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
86
+ DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
87
+ MemoryRegion *),
88
DEFINE_PROP_END_OF_LIST(),
89
};
90
24
91
--
25
--
92
2.20.1
26
2.34.1
93
94
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
Set the default NaN pattern explicitly for sh4. Note that sh4
2
is one of the only three targets (the others being HPPA and
3
sometimes MIPS) that has snan_bit_is_one set.
2
4
3
QEMU lacks the minimum Jazelle implementation that is required
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
by the architecture (everything is RAZ or RAZ/WI). Add it
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
together with the HCR_EL2.TID0 trapping that goes with it.
7
Message-id: 20241202131347.498124-47-peter.maydell@linaro.org
8
---
9
target/sh4/cpu.c | 2 ++
10
1 file changed, 2 insertions(+)
6
11
7
Signed-off-by: Marc Zyngier <maz@kernel.org>
12
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20191201122018.25808-6-maz@kernel.org
11
[PMM: moved ARMCPRegInfo array to file scope, marked it
12
'static global', moved new condition down in
13
register_cp_regs_for_features() to go with other feature
14
things rather than up with the v6/v7/v8 stuff]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/helper.c | 27 +++++++++++++++++++++++++++
18
1 file changed, 27 insertions(+)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
14
--- a/target/sh4/cpu.c
23
+++ b/target/arm/helper.c
15
+++ b/target/sh4/cpu.c
24
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
16
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_reset_hold(Object *obj, ResetType type)
25
return CP_ACCESS_OK;
17
set_flush_to_zero(1, &env->fp_status);
18
#endif
19
set_default_nan_mode(1, &env->fp_status);
20
+ /* sign bit clear, set all frac bits other than msb */
21
+ set_float_default_nan_pattern(0b00111111, &env->fp_status);
26
}
22
}
27
23
28
+static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
24
static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
29
+ bool isread)
30
+{
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID0)) {
32
+ return CP_ACCESS_TRAP_EL2;
33
+ }
34
+
35
+ return CP_ACCESS_OK;
36
+}
37
+
38
+static const ARMCPRegInfo jazelle_regs[] = {
39
+ { .name = "JIDR",
40
+ .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
41
+ .access = PL1_R, .accessfn = access_jazelle,
42
+ .type = ARM_CP_CONST, .resetvalue = 0 },
43
+ { .name = "JOSCR",
44
+ .cp = 14, .crn = 1, .crm = 0, .opc1 = 7, .opc2 = 0,
45
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
46
+ { .name = "JMCR",
47
+ .cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
48
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
49
+ REGINFO_SENTINEL
50
+};
51
+
52
void register_cp_regs_for_features(ARMCPU *cpu)
53
{
54
/* Register all the coprocessor registers based on feature bits */
55
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
56
if (arm_feature(env, ARM_FEATURE_LPAE)) {
57
define_arm_cp_regs(cpu, lpae_cp_reginfo);
58
}
59
+ if (cpu_isar_feature(jazelle, cpu)) {
60
+ define_arm_cp_regs(cpu, jazelle_regs);
61
+ }
62
/* Slightly awkwardly, the OMAP and StrongARM cores need all of
63
* cp15 crn=0 to be writes-ignored, whereas for other cores they should
64
* be read-only (ie write causes UNDEF exception).
65
--
25
--
66
2.20.1
26
2.34.1
67
68
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Set the default NaN pattern explicitly for rx.
2
2
3
The Tacoma BMC board is replacement board for the BMC of the OpenPOWER
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Witherspoon system. It uses a AST2600 SoC instead of a AST2500 and the
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
I2C layout is the same as it controls the same main board. Used for HW
5
Message-id: 20241202131347.498124-48-peter.maydell@linaro.org
6
bringup.
6
---
7
target/rx/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
7
9
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-15-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/aspeed.c | 28 ++++++++++++++++++++++++++++
15
1 file changed, 28 insertions(+)
16
17
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/aspeed.c
12
--- a/target/rx/cpu.c
20
+++ b/hw/arm/aspeed.c
13
+++ b/target/rx/cpu.c
21
@@ -XXX,XX +XXX,XX @@ struct AspeedBoardState {
14
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_reset_hold(Object *obj, ResetType type)
22
#define AST2600_EVB_HW_STRAP1 0x000000C0
15
* then prefer dest over source", which is float_2nan_prop_s_ab.
23
#define AST2600_EVB_HW_STRAP2 0x00000003
16
*/
24
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
25
+/* Tacoma hardware value */
18
+ /* Default NaN value: sign bit clear, set frac msb */
26
+#define TACOMA_BMC_HW_STRAP1 0x00000000
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
27
+#define TACOMA_BMC_HW_STRAP2 0x00000000
28
+
29
/*
30
* The max ram region is for firmwares that scan the address space
31
* with load/store to guess how much RAM the SoC has.
32
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
33
AspeedSoCState *soc = &bmc->soc;
34
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
35
36
+ /* Bus 3: TODO bmp280@77 */
37
+ /* Bus 3: TODO max31785@52 */
38
+ /* Bus 3: TODO dps310@76 */
39
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
40
0x60);
41
42
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
43
eeprom_buf);
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
45
0x60);
46
+ /* Bus 11: TODO ucd90160@64 */
47
}
20
}
48
21
49
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
22
static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
50
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
51
mc->default_ram_size = 1 * GiB;
52
};
53
54
+static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
55
+{
56
+ MachineClass *mc = MACHINE_CLASS(oc);
57
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
58
+
59
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
60
+ amc->soc_name = "ast2600-a0";
61
+ amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
62
+ amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
63
+ amc->fmc_model = "mx66l1g45g";
64
+ amc->spi_model = "mx66l1g45g";
65
+ amc->num_cs = 2;
66
+ amc->i2c_init = witherspoon_bmc_i2c_init; /* Same board layout */
67
+ mc->default_ram_size = 1 * GiB;
68
+};
69
+
70
static const TypeInfo aspeed_machine_types[] = {
71
{
72
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
73
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
74
.name = MACHINE_TYPE_NAME("ast2600-evb"),
75
.parent = TYPE_ASPEED_MACHINE,
76
.class_init = aspeed_machine_ast2600_evb_class_init,
77
+ }, {
78
+ .name = MACHINE_TYPE_NAME("tacoma-bmc"),
79
+ .parent = TYPE_ASPEED_MACHINE,
80
+ .class_init = aspeed_machine_tacoma_class_init,
81
}, {
82
.name = TYPE_ASPEED_MACHINE,
83
.parent = TYPE_MACHINE,
84
--
23
--
85
2.20.1
24
2.34.1
86
87
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for s390x.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-49-peter.maydell@linaro.org
6
---
7
target/s390x/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/s390x/cpu.c
13
+++ b/target/s390x/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
15
set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
16
set_float_infzeronan_rule(float_infzeronan_dnan_always,
17
&env->fpu_status);
18
+ /* Default NaN value: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fpu_status);
20
/* fall through */
21
case RESET_TYPE_S390_CPU_NORMAL:
22
env->psw.mask &= ~PSW_MASK_RI;
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for SPARC, and remove
2
the ifdef from parts64_default_nan.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-50-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 5 +----
10
2 files changed, 3 insertions(+), 4 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
18
/* For inf * 0 + NaN, return the input NaN */
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ /* Default NaN value: sign bit clear, all frac bits set */
21
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
22
23
cpu_exec_realizefn(cs, &local_err);
24
if (local_err != NULL) {
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
uint8_t dnan_pattern = status->default_nan_pattern;
31
32
if (dnan_pattern == 0) {
33
-#if defined(TARGET_SPARC)
34
- /* Sign bit clear, all frac bits set */
35
- dnan_pattern = 0b01111111;
36
-#elif defined(TARGET_HEXAGON)
37
+#if defined(TARGET_HEXAGON)
38
/* Sign bit set, all frac bits set. */
39
dnan_pattern = 0b11111111;
40
#else
41
--
42
2.34.1
diff view generated by jsdifflib
1
From: PanNengyuan <pannengyuan@huawei.com>
1
Set the default NaN pattern explicitly for xtensa.
2
2
3
Address Sanitizer shows memory leak in hw/gpio/aspeed_gpio.c:875
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
6
---
7
target/xtensa/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
4
9
5
Reported-by: Euler Robot <euler.robot@huawei.com>
10
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
6
Signed-off-by: PanNengyuan <pannengyuan@huawei.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-16-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/gpio/aspeed_gpio.c | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/gpio/aspeed_gpio.c
12
--- a/target/xtensa/cpu.c
18
+++ b/hw/gpio/aspeed_gpio.c
13
+++ b/target/xtensa/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_init(Object *obj)
14
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
20
pin_idx % GPIOS_PER_GROUP);
15
/* For inf * 0 + NaN, return the input NaN */
21
object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
aspeed_gpio_set_pin, NULL, NULL, NULL);
17
set_no_signaling_nans(!dfpu, &env->fp_status);
23
+ g_free(name);
18
+ /* Default NaN value: sign bit clear, set frac msb */
24
}
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
xtensa_use_first_nan(env, !dfpu);
25
}
21
}
26
22
27
--
23
--
28
2.20.1
24
2.34.1
29
30
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
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
This models the clock write one to clear registers, and fixes up some
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
incorrect behavior in all of the write to clear registers.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-52-peter.maydell@linaro.org
8
---
9
target/hexagon/cpu.c | 2 ++
10
fpu/softfloat-specialize.c.inc | 5 -----
11
2 files changed, 2 insertions(+), 5 deletions(-)
5
12
6
There was also a typo in one of the register definitions.
13
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
7
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Joel Stanley <joel@jms.id.au>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-id: 20191119141211.25716-8-clg@kaod.org
13
[clg: checkpatch.pl fixes ]
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/misc/aspeed_scu.c | 19 ++++++++++++++-----
18
1 file changed, 14 insertions(+), 5 deletions(-)
19
20
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/aspeed_scu.c
15
--- a/target/hexagon/cpu.c
23
+++ b/hw/misc/aspeed_scu.c
16
+++ b/target/hexagon/cpu.c
24
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
25
#define AST2600_CLK_STOP_CTRL TO_REG(0x80)
18
26
#define AST2600_CLK_STOP_CTRL_CLR TO_REG(0x84)
19
set_default_nan_mode(1, &env->fp_status);
27
#define AST2600_CLK_STOP_CTRL2 TO_REG(0x90)
20
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
28
-#define AST2600_CLK_STOP_CTR2L_CLR TO_REG(0x94)
21
+ /* Default NaN value: sign bit set, all frac bits set */
29
+#define AST2600_CLK_STOP_CTRL2_CLR TO_REG(0x94)
22
+ set_float_default_nan_pattern(0b11111111, &env->fp_status);
30
#define AST2600_SDRAM_HANDSHAKE TO_REG(0x100)
31
#define AST2600_HPLL_PARAM TO_REG(0x200)
32
#define AST2600_HPLL_EXT TO_REG(0x204)
33
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_ast2600_scu_read(void *opaque, hwaddr offset,
34
return s->regs[reg];
35
}
23
}
36
24
37
-static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
25
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
38
- unsigned size)
26
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
39
+static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
27
index XXXXXXX..XXXXXXX 100644
40
+ uint64_t data64, unsigned size)
28
--- a/fpu/softfloat-specialize.c.inc
41
{
29
+++ b/fpu/softfloat-specialize.c.inc
42
AspeedSCUState *s = ASPEED_SCU(opaque);
30
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
43
int reg = TO_REG(offset);
31
uint8_t dnan_pattern = status->default_nan_pattern;
44
+ /* Truncate here so bitwise operations below behave as expected */
32
45
+ uint32_t data = data64;
33
if (dnan_pattern == 0) {
46
34
-#if defined(TARGET_HEXAGON)
47
if (reg >= ASPEED_AST2600_SCU_NR_REGS) {
35
- /* Sign bit set, all frac bits set. */
48
qemu_log_mask(LOG_GUEST_ERROR,
36
- dnan_pattern = 0b11111111;
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
37
-#else
50
/* fall through */
38
/*
51
case AST2600_SYS_RST_CTRL:
39
* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
52
case AST2600_SYS_RST_CTRL2:
40
* S390, SH4, TriCore, and Xtensa. Our other supported targets
53
+ case AST2600_CLK_STOP_CTRL:
41
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
54
+ case AST2600_CLK_STOP_CTRL2:
42
/* sign bit clear, set frac msb */
55
/* W1S (Write 1 to set) registers */
43
dnan_pattern = 0b01000000;
56
s->regs[reg] |= data;
44
}
57
return;
45
-#endif
58
case AST2600_SYS_RST_CTRL_CLR:
46
}
59
case AST2600_SYS_RST_CTRL2_CLR:
47
assert(dnan_pattern != 0);
60
+ case AST2600_CLK_STOP_CTRL_CLR:
48
61
+ case AST2600_CLK_STOP_CTRL2_CLR:
62
case AST2600_HW_STRAP1_CLR:
63
case AST2600_HW_STRAP2_CLR:
64
- /* W1C (Write 1 to clear) registers */
65
- s->regs[reg] &= ~data;
66
+ /*
67
+ * W1C (Write 1 to clear) registers are offset by one address from
68
+ * the data register
69
+ */
70
+ s->regs[reg - 1] &= ~data;
71
return;
72
73
case AST2600_RNG_DATA:
74
--
49
--
75
2.20.1
50
2.34.1
76
77
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for riscv.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-53-peter.maydell@linaro.org
6
---
7
target/riscv/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/riscv/cpu.c
13
+++ b/target/riscv/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
15
cs->exception_index = RISCV_EXCP_NONE;
16
env->load_res = -1;
17
set_default_nan_mode(1, &env->fp_status);
18
+ /* Default NaN value: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
env->vill = true;
21
22
#ifndef CONFIG_USER_ONLY
23
--
24
2.34.1
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Set the default NaN pattern explicitly for tricore.
2
2
3
Signed-off-by: Cédric Le Goater <clg@kaod.org>
4
Reviewed-by: Joel Stanley <joel@jms.id.au>
5
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20191119141211.25716-6-clg@kaod.org
9
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-54-peter.maydell@linaro.org
10
---
6
---
11
hw/i2c/aspeed_i2c.c | 93 ++++++++++++++++++++++++++++++++++++++-------
7
target/tricore/helper.c | 2 ++
12
hw/i2c/trace-events | 9 +++++
8
1 file changed, 2 insertions(+)
13
2 files changed, 89 insertions(+), 13 deletions(-)
14
9
15
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
10
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/i2c/aspeed_i2c.c
12
--- a/target/tricore/helper.c
18
+++ b/hw/i2c/aspeed_i2c.c
13
+++ b/target/tricore/helper.c
19
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ void fpu_set_state(CPUTriCoreState *env)
20
#include "hw/i2c/aspeed_i2c.h"
15
set_flush_to_zero(1, &env->fp_status);
21
#include "hw/irq.h"
16
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
22
#include "hw/qdev-properties.h"
17
set_default_nan_mode(1, &env->fp_status);
23
+#include "trace.h"
18
+ /* Default NaN pattern: sign bit clear, frac msb set */
24
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
25
/* I2C Global Register */
26
27
@@ -XXX,XX +XXX,XX @@ static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
28
{
29
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
30
31
+ trace_aspeed_i2c_bus_raise_interrupt(bus->intr_status,
32
+ bus->intr_status & I2CD_INTR_TX_NAK ? "nak|" : "",
33
+ bus->intr_status & I2CD_INTR_TX_ACK ? "ack|" : "",
34
+ bus->intr_status & I2CD_INTR_RX_DONE ? "done|" : "",
35
+ bus->intr_status & I2CD_INTR_NORMAL_STOP ? "normal|" : "",
36
+ bus->intr_status & I2CD_INTR_ABNORMAL ? "abnormal" : "");
37
+
38
bus->intr_status &= bus->intr_ctrl;
39
if (bus->intr_status) {
40
bus->controller->intr_status |= 1 << bus->id;
41
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
42
{
43
AspeedI2CBus *bus = opaque;
44
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
45
+ uint64_t value = -1;
46
47
switch (offset) {
48
case I2CD_FUN_CTRL_REG:
49
- return bus->ctrl;
50
+ value = bus->ctrl;
51
+ break;
52
case I2CD_AC_TIMING_REG1:
53
- return bus->timing[0];
54
+ value = bus->timing[0];
55
+ break;
56
case I2CD_AC_TIMING_REG2:
57
- return bus->timing[1];
58
+ value = bus->timing[1];
59
+ break;
60
case I2CD_INTR_CTRL_REG:
61
- return bus->intr_ctrl;
62
+ value = bus->intr_ctrl;
63
+ break;
64
case I2CD_INTR_STS_REG:
65
- return bus->intr_status;
66
+ value = bus->intr_status;
67
+ break;
68
case I2CD_POOL_CTRL_REG:
69
- return bus->pool_ctrl;
70
+ value = bus->pool_ctrl;
71
+ break;
72
case I2CD_BYTE_BUF_REG:
73
- return bus->buf;
74
+ value = bus->buf;
75
+ break;
76
case I2CD_CMD_REG:
77
- return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
78
+ value = bus->cmd | (i2c_bus_busy(bus->bus) << 16);
79
+ break;
80
case I2CD_DMA_ADDR:
81
if (!aic->has_dma) {
82
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
83
- return -1;
84
+ break;
85
}
86
- return bus->dma_addr;
87
+ value = bus->dma_addr;
88
+ break;
89
case I2CD_DMA_LEN:
90
if (!aic->has_dma) {
91
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
92
- return -1;
93
+ break;
94
}
95
- return bus->dma_len;
96
+ value = bus->dma_len;
97
+ break;
98
+
99
default:
100
qemu_log_mask(LOG_GUEST_ERROR,
101
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
102
- return -1;
103
+ value = -1;
104
+ break;
105
}
106
+
107
+ trace_aspeed_i2c_bus_read(bus->id, offset, size, value);
108
+ return value;
109
}
20
}
110
21
111
static void aspeed_i2c_set_state(AspeedI2CBus *bus, uint8_t state)
22
uint32_t psw_read(CPUTriCoreState *env)
112
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
113
for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
114
uint8_t *pool_base = aic->bus_pool_base(bus);
115
116
+ trace_aspeed_i2c_bus_send("BUF", i + 1,
117
+ I2CD_POOL_TX_COUNT(bus->pool_ctrl),
118
+ pool_base[i]);
119
ret = i2c_send(bus->bus, pool_base[i]);
120
if (ret) {
121
break;
122
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
123
while (bus->dma_len) {
124
uint8_t data;
125
aspeed_i2c_dma_read(bus, &data);
126
+ trace_aspeed_i2c_bus_send("DMA", bus->dma_len, bus->dma_len, data);
127
ret = i2c_send(bus->bus, data);
128
if (ret) {
129
break;
130
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
131
}
132
bus->cmd &= ~I2CD_TX_DMA_ENABLE;
133
} else {
134
+ trace_aspeed_i2c_bus_send("BYTE", pool_start, 1, bus->buf);
135
ret = i2c_send(bus->bus, bus->buf);
136
}
137
138
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
139
140
for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
141
pool_base[i] = i2c_recv(bus->bus);
142
+ trace_aspeed_i2c_bus_recv("BUF", i + 1,
143
+ I2CD_POOL_RX_SIZE(bus->pool_ctrl),
144
+ pool_base[i]);
145
}
146
147
/* Update RX count */
148
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
149
MemTxResult result;
150
151
data = i2c_recv(bus->bus);
152
+ trace_aspeed_i2c_bus_recv("DMA", bus->dma_len, bus->dma_len, data);
153
result = address_space_write(&s->dram_as, bus->dma_addr,
154
MEMTXATTRS_UNSPECIFIED, &data, 1);
155
if (result != MEMTX_OK) {
156
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
157
bus->cmd &= ~I2CD_RX_DMA_ENABLE;
158
} else {
159
data = i2c_recv(bus->bus);
160
+ trace_aspeed_i2c_bus_recv("BYTE", 1, 1, bus->buf);
161
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
162
}
163
}
164
@@ -XXX,XX +XXX,XX @@ static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
165
return true;
166
}
167
168
+static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
169
+{
170
+ g_autofree char *cmd_flags;
171
+ uint32_t count;
172
+
173
+ if (bus->cmd & (I2CD_RX_BUFF_ENABLE | I2CD_RX_BUFF_ENABLE)) {
174
+ count = I2CD_POOL_TX_COUNT(bus->pool_ctrl);
175
+ } else if (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_RX_DMA_ENABLE)) {
176
+ count = bus->dma_len;
177
+ } else { /* BYTE mode */
178
+ count = 1;
179
+ }
180
+
181
+ cmd_flags = g_strdup_printf("%s%s%s%s%s%s%s%s%s",
182
+ bus->cmd & I2CD_M_START_CMD ? "start|" : "",
183
+ bus->cmd & I2CD_RX_DMA_ENABLE ? "rxdma|" : "",
184
+ bus->cmd & I2CD_TX_DMA_ENABLE ? "txdma|" : "",
185
+ bus->cmd & I2CD_RX_BUFF_ENABLE ? "rxbuf|" : "",
186
+ bus->cmd & I2CD_TX_BUFF_ENABLE ? "txbuf|" : "",
187
+ bus->cmd & I2CD_M_TX_CMD ? "tx|" : "",
188
+ bus->cmd & I2CD_M_RX_CMD ? "rx|" : "",
189
+ bus->cmd & I2CD_M_S_RX_CMD_LAST ? "last|" : "",
190
+ bus->cmd & I2CD_M_STOP_CMD ? "stop" : "");
191
+
192
+ trace_aspeed_i2c_bus_cmd(bus->cmd, cmd_flags, count, bus->intr_status);
193
+}
194
+
195
/*
196
* The state machine needs some refinement. It is only used to track
197
* invalid STOP commands for the moment.
198
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
199
return;
200
}
201
202
+ if (trace_event_get_state_backends(TRACE_ASPEED_I2C_BUS_CMD)) {
203
+ aspeed_i2c_bus_cmd_dump(bus);
204
+ }
205
+
206
if (bus->cmd & I2CD_M_START_CMD) {
207
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
208
I2CD_MSTARTR : I2CD_MSTART;
209
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
210
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
211
bool handle_rx;
212
213
+ trace_aspeed_i2c_bus_write(bus->id, offset, size, value);
214
+
215
switch (offset) {
216
case I2CD_FUN_CTRL_REG:
217
if (value & I2CD_SLAVE_EN) {
218
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/i2c/trace-events
221
+++ b/hw/i2c/trace-events
222
@@ -XXX,XX +XXX,XX @@
223
i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)"
224
i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x"
225
i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
226
+
227
+# aspeed_i2c.c
228
+
229
+aspeed_i2c_bus_cmd(uint32_t cmd, const char *cmd_flags, uint32_t count, uint32_t intr_status) "handling cmd=0x%x %s count=%d intr=0x%x"
230
+aspeed_i2c_bus_raise_interrupt(uint32_t intr_status, const char *str1, const char *str2, const char *str3, const char *str4, const char *str5) "handled intr=0x%x %s%s%s%s%s"
231
+aspeed_i2c_bus_read(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
232
+aspeed_i2c_bus_write(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
233
+aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s send %d/%d 0x%02x"
234
+aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s recv %d/%d 0x%02x"
235
--
23
--
236
2.20.1
24
2.34.1
237
238
diff view generated by jsdifflib
New patch
1
Now that all our targets have bene converted to explicitly specify
2
their pattern for the default NaN value we can remove the remaining
3
fallback code in parts64_default_nan().
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-55-peter.maydell@linaro.org
8
---
9
fpu/softfloat-specialize.c.inc | 14 --------------
10
1 file changed, 14 deletions(-)
11
12
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
13
index XXXXXXX..XXXXXXX 100644
14
--- a/fpu/softfloat-specialize.c.inc
15
+++ b/fpu/softfloat-specialize.c.inc
16
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
17
uint64_t frac;
18
uint8_t dnan_pattern = status->default_nan_pattern;
19
20
- if (dnan_pattern == 0) {
21
- /*
22
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
23
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
24
- * do not have floating-point.
25
- */
26
- if (snan_bit_is_one(status)) {
27
- /* sign bit clear, set all frac bits other than msb */
28
- dnan_pattern = 0b00111111;
29
- } else {
30
- /* sign bit clear, set frac msb */
31
- dnan_pattern = 0b01000000;
32
- }
33
- }
34
assert(dnan_pattern != 0);
35
36
sign = dnan_pattern >> 7;
37
--
38
2.34.1
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
AspeedBoardConfig is a redundant way to define class attributes and it
3
Inline pickNaNMulAdd into its only caller. This makes
4
complexifies the machine definition and initialization.
4
one assert redundant with the immediately preceding IF.
5
5
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20241203203949.483774-3-richard.henderson@linaro.org
9
Message-id: 20191119141211.25716-14-clg@kaod.org
9
[PMM: keep comment from old code in new location]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
include/hw/arm/aspeed.h | 24 ++--
12
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
13
hw/arm/aspeed.c | 243 ++++++++++++++++++++++------------------
13
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
14
2 files changed, 143 insertions(+), 124 deletions(-)
14
2 files changed, 40 insertions(+), 55 deletions(-)
15
15
16
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/aspeed.h
18
--- a/fpu/softfloat-parts.c.inc
19
+++ b/include/hw/arm/aspeed.h
19
+++ b/fpu/softfloat-parts.c.inc
20
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
21
21
}
22
typedef struct AspeedBoardState AspeedBoardState;
22
23
23
if (s->default_nan_mode) {
24
-typedef struct AspeedBoardConfig {
24
+ /*
25
- const char *name;
25
+ * We guarantee not to require the target to tell us how to
26
- const char *desc;
26
+ * pick a NaN if we're always returning the default NaN.
27
- const char *soc_name;
27
+ * But if we're not in default-NaN mode then the target must
28
- uint32_t hw_strap1;
28
+ * specify.
29
- uint32_t hw_strap2;
29
+ */
30
- const char *fmc_model;
30
which = 3;
31
- const char *spi_model;
31
+ } else if (infzero) {
32
- uint32_t num_cs;
32
+ /*
33
- void (*i2c_init)(AspeedBoardState *bmc);
33
+ * Inf * 0 + NaN -- some implementations return the
34
- uint32_t ram;
34
+ * default NaN here, and some return the input NaN.
35
-} AspeedBoardConfig;
35
+ */
36
-
36
+ switch (s->float_infzeronan_rule) {
37
#define TYPE_ASPEED_MACHINE MACHINE_TYPE_NAME("aspeed")
37
+ case float_infzeronan_dnan_never:
38
#define ASPEED_MACHINE(obj) \
38
+ which = 2;
39
OBJECT_CHECK(AspeedMachine, (obj), TYPE_ASPEED_MACHINE)
39
+ break;
40
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedMachine {
40
+ case float_infzeronan_dnan_always:
41
41
+ which = 3;
42
typedef struct AspeedMachineClass {
42
+ break;
43
MachineClass parent_obj;
43
+ case float_infzeronan_dnan_if_qnan:
44
- const AspeedBoardConfig *board;
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;
45
+
53
+
46
+ const char *name;
54
+ assert(rule != float_3nan_prop_none);
47
+ const char *desc;
55
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
48
+ const char *soc_name;
56
+ /* We have at least one SNaN input and should prefer it */
49
+ uint32_t hw_strap1;
57
+ do {
50
+ uint32_t hw_strap2;
58
+ which = rule & R_3NAN_1ST_MASK;
51
+ const char *fmc_model;
59
+ rule >>= R_3NAN_1ST_LENGTH;
52
+ const char *spi_model;
60
+ } while (!is_snan(cls[which]));
53
+ uint32_t num_cs;
61
+ } else {
54
+ void (*i2c_init)(AspeedBoardState *bmc);
62
+ do {
55
} AspeedMachineClass;
63
+ which = rule & R_3NAN_1ST_MASK;
56
64
+ rule >>= R_3NAN_1ST_LENGTH;
57
65
+ } while (!is_nan(cls[which]));
58
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
66
+ }
67
}
68
69
if (which == 3) {
70
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
59
index XXXXXXX..XXXXXXX 100644
71
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/arm/aspeed.c
72
--- a/fpu/softfloat-specialize.c.inc
61
+++ b/hw/arm/aspeed.c
73
+++ b/fpu/softfloat-specialize.c.inc
62
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
74
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
63
}
75
}
64
}
76
}
65
77
66
-static void aspeed_board_init(MachineState *machine,
78
-/*----------------------------------------------------------------------------
67
- const AspeedBoardConfig *cfg)
79
-| Select which NaN to propagate for a three-input operation.
68
+static void aspeed_machine_init(MachineState *machine)
80
-| For the moment we assume that no CPU needs the 'larger significand'
69
{
81
-| information.
70
AspeedBoardState *bmc;
82
-| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
71
+ AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
83
-*----------------------------------------------------------------------------*/
72
AspeedSoCClass *sc;
84
-static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
73
DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
85
- bool infzero, bool have_snan, float_status *status)
74
ram_addr_t max_ram_size;
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
76
UINT32_MAX);
77
78
object_initialize_child(OBJECT(machine), "soc", &bmc->soc,
79
- (sizeof(bmc->soc)), cfg->soc_name, &error_abort,
80
+ (sizeof(bmc->soc)), amc->soc_name, &error_abort,
81
NULL);
82
83
sc = ASPEED_SOC_GET_CLASS(&bmc->soc);
84
85
object_property_set_uint(OBJECT(&bmc->soc), ram_size, "ram-size",
86
&error_abort);
87
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1",
88
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap1, "hw-strap1",
89
&error_abort);
90
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap2, "hw-strap2",
91
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap2, "hw-strap2",
92
&error_abort);
93
- object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs",
94
+ object_property_set_int(OBJECT(&bmc->soc), amc->num_cs, "num-cs",
95
&error_abort);
96
object_property_set_int(OBJECT(&bmc->soc), machine->smp.cpus, "num-cpus",
97
&error_abort);
98
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
99
"max_ram", max_ram_size - ram_size);
100
memory_region_add_subregion(&bmc->ram_container, ram_size, &bmc->max_ram);
101
102
- aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort);
103
- aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort);
104
+ aspeed_board_init_flashes(&bmc->soc.fmc, amc->fmc_model, &error_abort);
105
+ aspeed_board_init_flashes(&bmc->soc.spi[0], amc->spi_model, &error_abort);
106
107
/* Install first FMC flash content as a boot rom. */
108
if (drive0) {
109
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
110
aspeed_board_binfo.loader_start = sc->memmap[ASPEED_SDRAM];
111
aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus;
112
113
- if (cfg->i2c_init) {
114
- cfg->i2c_init(bmc);
115
+ if (amc->i2c_init) {
116
+ amc->i2c_init(bmc);
117
}
118
119
for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
120
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
121
0x60);
122
}
123
124
-static void aspeed_machine_init(MachineState *machine)
125
-{
86
-{
126
- AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
87
- FloatClass cls[3] = { a_cls, b_cls, c_cls };
88
- Float3NaNPropRule rule = status->float_3nan_prop_rule;
89
- int which;
127
-
90
-
128
- aspeed_board_init(machine, amc->board);
91
- /*
92
- * We guarantee not to require the target to tell us how to
93
- * pick a NaN if we're always returning the default NaN.
94
- * But if we're not in default-NaN mode then the target must
95
- * specify.
96
- */
97
- assert(!status->default_nan_mode);
98
-
99
- if (infzero) {
100
- /*
101
- * Inf * 0 + NaN -- some implementations return the default NaN here,
102
- * and some return the input NaN.
103
- */
104
- switch (status->float_infzeronan_rule) {
105
- case float_infzeronan_dnan_never:
106
- return 2;
107
- case float_infzeronan_dnan_always:
108
- return 3;
109
- case float_infzeronan_dnan_if_qnan:
110
- return is_qnan(c_cls) ? 3 : 2;
111
- default:
112
- g_assert_not_reached();
113
- }
114
- }
115
-
116
- assert(rule != float_3nan_prop_none);
117
- if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
118
- /* We have at least one SNaN input and should prefer it */
119
- do {
120
- which = rule & R_3NAN_1ST_MASK;
121
- rule >>= R_3NAN_1ST_LENGTH;
122
- } while (!is_snan(cls[which]));
123
- } else {
124
- do {
125
- which = rule & R_3NAN_1ST_MASK;
126
- rule >>= R_3NAN_1ST_LENGTH;
127
- } while (!is_nan(cls[which]));
128
- }
129
- return which;
129
-}
130
-}
130
-
131
-
131
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
132
/*----------------------------------------------------------------------------
132
{
133
| Returns 1 if the double-precision floating-point value `a' is a quiet
133
MachineClass *mc = MACHINE_CLASS(oc);
134
| NaN; otherwise returns 0.
134
- AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
135
- const AspeedBoardConfig *board = data;
136
137
- mc->desc = board->desc;
138
mc->init = aspeed_machine_init;
139
mc->max_cpus = ASPEED_CPUS_NUM;
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->no_parallel = 1;
143
- if (board->ram) {
144
- mc->default_ram_size = board->ram;
145
- }
146
- amc->board = board;
147
}
148
149
-static const TypeInfo aspeed_machine_type = {
150
- .name = TYPE_ASPEED_MACHINE,
151
- .parent = TYPE_MACHINE,
152
- .instance_size = sizeof(AspeedMachine),
153
- .class_size = sizeof(AspeedMachineClass),
154
- .abstract = true,
155
-};
156
-
157
-static const AspeedBoardConfig aspeed_boards[] = {
158
- {
159
- .name = MACHINE_TYPE_NAME("palmetto-bmc"),
160
- .desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)",
161
- .soc_name = "ast2400-a1",
162
- .hw_strap1 = PALMETTO_BMC_HW_STRAP1,
163
- .fmc_model = "n25q256a",
164
- .spi_model = "mx25l25635e",
165
- .num_cs = 1,
166
- .i2c_init = palmetto_bmc_i2c_init,
167
- .ram = 256 * MiB,
168
- }, {
169
- .name = MACHINE_TYPE_NAME("ast2500-evb"),
170
- .desc = "Aspeed AST2500 EVB (ARM1176)",
171
- .soc_name = "ast2500-a1",
172
- .hw_strap1 = AST2500_EVB_HW_STRAP1,
173
- .fmc_model = "w25q256",
174
- .spi_model = "mx25l25635e",
175
- .num_cs = 1,
176
- .i2c_init = ast2500_evb_i2c_init,
177
- .ram = 512 * MiB,
178
- }, {
179
- .name = MACHINE_TYPE_NAME("romulus-bmc"),
180
- .desc = "OpenPOWER Romulus BMC (ARM1176)",
181
- .soc_name = "ast2500-a1",
182
- .hw_strap1 = ROMULUS_BMC_HW_STRAP1,
183
- .fmc_model = "n25q256a",
184
- .spi_model = "mx66l1g45g",
185
- .num_cs = 2,
186
- .i2c_init = romulus_bmc_i2c_init,
187
- .ram = 512 * MiB,
188
- }, {
189
- .name = MACHINE_TYPE_NAME("swift-bmc"),
190
- .desc = "OpenPOWER Swift BMC (ARM1176)",
191
- .soc_name = "ast2500-a1",
192
- .hw_strap1 = SWIFT_BMC_HW_STRAP1,
193
- .fmc_model = "mx66l1g45g",
194
- .spi_model = "mx66l1g45g",
195
- .num_cs = 2,
196
- .i2c_init = swift_bmc_i2c_init,
197
- .ram = 512 * MiB,
198
- }, {
199
- .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
200
- .desc = "OpenPOWER Witherspoon BMC (ARM1176)",
201
- .soc_name = "ast2500-a1",
202
- .hw_strap1 = WITHERSPOON_BMC_HW_STRAP1,
203
- .fmc_model = "mx25l25635e",
204
- .spi_model = "mx66l1g45g",
205
- .num_cs = 2,
206
- .i2c_init = witherspoon_bmc_i2c_init,
207
- .ram = 512 * MiB,
208
- }, {
209
- .name = MACHINE_TYPE_NAME("ast2600-evb"),
210
- .desc = "Aspeed AST2600 EVB (Cortex A7)",
211
- .soc_name = "ast2600-a0",
212
- .hw_strap1 = AST2600_EVB_HW_STRAP1,
213
- .hw_strap2 = AST2600_EVB_HW_STRAP2,
214
- .fmc_model = "w25q512jv",
215
- .spi_model = "mx66u51235f",
216
- .num_cs = 1,
217
- .i2c_init = ast2600_evb_i2c_init,
218
- .ram = 1 * GiB,
219
- },
220
-};
221
-
222
-static void aspeed_machine_types(void)
223
+static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data)
224
{
225
- int i;
226
+ MachineClass *mc = MACHINE_CLASS(oc);
227
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
228
229
- type_register_static(&aspeed_machine_type);
230
- for (i = 0; i < ARRAY_SIZE(aspeed_boards); ++i) {
231
- TypeInfo ti = {
232
- .name = aspeed_boards[i].name,
233
- .parent = TYPE_ASPEED_MACHINE,
234
- .class_init = aspeed_machine_class_init,
235
- .class_data = (void *)&aspeed_boards[i],
236
- };
237
- type_register(&ti);
238
+ mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)";
239
+ amc->soc_name = "ast2400-a1";
240
+ amc->hw_strap1 = PALMETTO_BMC_HW_STRAP1;
241
+ amc->fmc_model = "n25q256a";
242
+ amc->spi_model = "mx25l25635e";
243
+ amc->num_cs = 1;
244
+ amc->i2c_init = palmetto_bmc_i2c_init;
245
+ mc->default_ram_size = 256 * MiB;
246
+};
247
+
248
+static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data)
249
+{
250
+ MachineClass *mc = MACHINE_CLASS(oc);
251
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
252
+
253
+ mc->desc = "Aspeed AST2500 EVB (ARM1176)";
254
+ amc->soc_name = "ast2500-a1";
255
+ amc->hw_strap1 = AST2500_EVB_HW_STRAP1;
256
+ amc->fmc_model = "w25q256";
257
+ amc->spi_model = "mx25l25635e";
258
+ amc->num_cs = 1;
259
+ amc->i2c_init = ast2500_evb_i2c_init;
260
+ mc->default_ram_size = 512 * MiB;
261
+};
262
+
263
+static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data)
264
+{
265
+ MachineClass *mc = MACHINE_CLASS(oc);
266
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
267
+
268
+ mc->desc = "OpenPOWER Romulus BMC (ARM1176)";
269
+ amc->soc_name = "ast2500-a1";
270
+ amc->hw_strap1 = ROMULUS_BMC_HW_STRAP1;
271
+ amc->fmc_model = "n25q256a";
272
+ amc->spi_model = "mx66l1g45g";
273
+ amc->num_cs = 2;
274
+ amc->i2c_init = romulus_bmc_i2c_init;
275
+ mc->default_ram_size = 512 * MiB;
276
+};
277
+
278
+static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data)
279
+{
280
+ MachineClass *mc = MACHINE_CLASS(oc);
281
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
282
+
283
+ mc->desc = "OpenPOWER Swift BMC (ARM1176)";
284
+ amc->soc_name = "ast2500-a1";
285
+ amc->hw_strap1 = SWIFT_BMC_HW_STRAP1;
286
+ amc->fmc_model = "mx66l1g45g";
287
+ amc->spi_model = "mx66l1g45g";
288
+ amc->num_cs = 2;
289
+ amc->i2c_init = swift_bmc_i2c_init;
290
+ mc->default_ram_size = 512 * MiB;
291
+};
292
+
293
+static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data)
294
+{
295
+ MachineClass *mc = MACHINE_CLASS(oc);
296
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
297
+
298
+ mc->desc = "OpenPOWER Witherspoon BMC (ARM1176)";
299
+ amc->soc_name = "ast2500-a1";
300
+ amc->hw_strap1 = WITHERSPOON_BMC_HW_STRAP1;
301
+ amc->fmc_model = "mx25l25635e";
302
+ amc->spi_model = "mx66l1g45g";
303
+ amc->num_cs = 2;
304
+ amc->i2c_init = witherspoon_bmc_i2c_init;
305
+ mc->default_ram_size = 512 * MiB;
306
+};
307
+
308
+static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
309
+{
310
+ MachineClass *mc = MACHINE_CLASS(oc);
311
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
312
+
313
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
314
+ amc->soc_name = "ast2600-a0";
315
+ amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
316
+ amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
317
+ amc->fmc_model = "w25q512jv";
318
+ amc->spi_model = "mx66u51235f";
319
+ amc->num_cs = 1;
320
+ amc->i2c_init = ast2600_evb_i2c_init;
321
+ mc->default_ram_size = 1 * GiB;
322
+};
323
+
324
+static const TypeInfo aspeed_machine_types[] = {
325
+ {
326
+ .name = MACHINE_TYPE_NAME("palmetto-bmc"),
327
+ .parent = TYPE_ASPEED_MACHINE,
328
+ .class_init = aspeed_machine_palmetto_class_init,
329
+ }, {
330
+ .name = MACHINE_TYPE_NAME("ast2500-evb"),
331
+ .parent = TYPE_ASPEED_MACHINE,
332
+ .class_init = aspeed_machine_ast2500_evb_class_init,
333
+ }, {
334
+ .name = MACHINE_TYPE_NAME("romulus-bmc"),
335
+ .parent = TYPE_ASPEED_MACHINE,
336
+ .class_init = aspeed_machine_romulus_class_init,
337
+ }, {
338
+ .name = MACHINE_TYPE_NAME("swift-bmc"),
339
+ .parent = TYPE_ASPEED_MACHINE,
340
+ .class_init = aspeed_machine_swift_class_init,
341
+ }, {
342
+ .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
343
+ .parent = TYPE_ASPEED_MACHINE,
344
+ .class_init = aspeed_machine_witherspoon_class_init,
345
+ }, {
346
+ .name = MACHINE_TYPE_NAME("ast2600-evb"),
347
+ .parent = TYPE_ASPEED_MACHINE,
348
+ .class_init = aspeed_machine_ast2600_evb_class_init,
349
+ }, {
350
+ .name = TYPE_ASPEED_MACHINE,
351
+ .parent = TYPE_MACHINE,
352
+ .instance_size = sizeof(AspeedMachine),
353
+ .class_size = sizeof(AspeedMachineClass),
354
+ .class_init = aspeed_machine_class_init,
355
+ .abstract = true,
356
}
357
-}
358
+};
359
360
-type_init(aspeed_machine_types)
361
+DEFINE_TYPES(aspeed_machine_types)
362
--
135
--
363
2.20.1
136
2.34.1
364
137
365
138
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
Remove "3" as a special case for which and simply
4
an array of qemu_irq and passing it around, directly call
4
branch to return the desired value.
5
qdev_get_gpio_in() on the gic field.
6
5
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20191209090306.20433-1-philmd@redhat.com
8
Message-id: 20241203203949.483774-4-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
include/hw/arm/virt.h | 1 +
11
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
14
hw/arm/virt.c | 109 +++++++++++++++++++++---------------------
12
1 file changed, 10 insertions(+), 10 deletions(-)
15
2 files changed, 55 insertions(+), 55 deletions(-)
16
13
17
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/virt.h
16
--- a/fpu/softfloat-parts.c.inc
20
+++ b/include/hw/arm/virt.h
17
+++ b/fpu/softfloat-parts.c.inc
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
22
uint32_t iommu_phandle;
19
* But if we're not in default-NaN mode then the target must
23
int psci_conduit;
20
* specify.
24
hwaddr highest_gpa;
21
*/
25
+ DeviceState *gic;
22
- which = 3;
26
DeviceState *acpi_dev;
23
+ goto default_nan;
27
Notifier powerdown_notifier;
24
} else if (infzero) {
28
} VirtMachineState;
25
/*
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
26
* Inf * 0 + NaN -- some implementations return the
30
index XXXXXXX..XXXXXXX 100644
27
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
31
--- a/hw/arm/virt.c
28
*/
32
+++ b/hw/arm/virt.c
29
switch (s->float_infzeronan_rule) {
33
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
30
case float_infzeronan_dnan_never:
34
}
31
- which = 2;
35
}
32
break;
36
33
case float_infzeronan_dnan_always:
37
-static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
34
- which = 3;
38
+static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
35
- break;
39
{
36
+ goto default_nan;
40
DeviceState *dev;
37
case float_infzeronan_dnan_if_qnan:
41
MachineState *ms = MACHINE(vms);
38
- which = is_qnan(c->cls) ? 3 : 2;
42
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
39
+ if (is_qnan(c->cls)) {
43
40
+ goto default_nan;
44
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
41
+ }
45
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
42
break;
46
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
43
default:
47
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
44
g_assert_not_reached();
48
49
qdev_init_nofail(dev);
50
51
return dev;
52
}
53
54
-static void create_its(VirtMachineState *vms, DeviceState *gicdev)
55
+static void create_its(VirtMachineState *vms)
56
{
57
const char *itsclass = its_class_name();
58
DeviceState *dev;
59
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
60
61
dev = qdev_create(NULL, itsclass);
62
63
- object_property_set_link(OBJECT(dev), OBJECT(gicdev), "parent-gicv3",
64
+ object_property_set_link(OBJECT(dev), OBJECT(vms->gic), "parent-gicv3",
65
&error_abort);
66
qdev_init_nofail(dev);
67
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_ITS].base);
68
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
69
fdt_add_its_gic_node(vms);
70
}
71
72
-static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
73
+static void create_v2m(VirtMachineState *vms)
74
{
75
int i;
76
int irq = vms->irqmap[VIRT_GIC_V2M];
77
@@ -XXX,XX +XXX,XX @@ static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
78
qdev_init_nofail(dev);
79
80
for (i = 0; i < NUM_GICV2M_SPIS; i++) {
81
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
82
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
83
+ qdev_get_gpio_in(vms->gic, irq + i));
84
}
85
86
fdt_add_v2m_gic_node(vms);
87
}
88
89
-static void create_gic(VirtMachineState *vms, qemu_irq *pic)
90
+static void create_gic(VirtMachineState *vms)
91
{
92
MachineState *ms = MACHINE(vms);
93
/* We create a standalone GIC */
94
- DeviceState *gicdev;
95
SysBusDevice *gicbusdev;
96
const char *gictype;
97
int type = vms->gic_version, i;
98
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
99
100
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
101
102
- gicdev = qdev_create(NULL, gictype);
103
- qdev_prop_set_uint32(gicdev, "revision", type);
104
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
105
+ vms->gic = qdev_create(NULL, gictype);
106
+ qdev_prop_set_uint32(vms->gic, "revision", type);
107
+ qdev_prop_set_uint32(vms->gic, "num-cpu", smp_cpus);
108
/* Note that the num-irq property counts both internal and external
109
* interrupts; there are always 32 of the former (mandated by GIC spec).
110
*/
111
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
112
+ qdev_prop_set_uint32(vms->gic, "num-irq", NUM_IRQS + 32);
113
if (!kvm_irqchip_in_kernel()) {
114
- qdev_prop_set_bit(gicdev, "has-security-extensions", vms->secure);
115
+ qdev_prop_set_bit(vms->gic, "has-security-extensions", vms->secure);
116
}
117
118
if (type == 3) {
119
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
120
121
nb_redist_regions = virt_gicv3_redist_region_count(vms);
122
123
- qdev_prop_set_uint32(gicdev, "len-redist-region-count",
124
+ qdev_prop_set_uint32(vms->gic, "len-redist-region-count",
125
nb_redist_regions);
126
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
127
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[0]", redist0_count);
128
129
if (nb_redist_regions == 2) {
130
uint32_t redist1_capacity =
131
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
132
133
- qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
134
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[1]",
135
MIN(smp_cpus - redist0_count, redist1_capacity));
136
}
45
}
46
+ which = 2;
137
} else {
47
} else {
138
if (!kvm_irqchip_in_kernel()) {
48
FloatClass cls[3] = { a->cls, b->cls, c->cls };
139
- qdev_prop_set_bit(gicdev, "has-virtualization-extensions",
49
Float3NaNPropRule rule = s->float_3nan_prop_rule;
140
+ qdev_prop_set_bit(vms->gic, "has-virtualization-extensions",
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
141
vms->virt);
142
}
51
}
143
}
52
}
144
- qdev_init_nofail(gicdev);
53
145
- gicbusdev = SYS_BUS_DEVICE(gicdev);
54
- if (which == 3) {
146
+ qdev_init_nofail(vms->gic);
55
- parts_default_nan(a, s);
147
+ gicbusdev = SYS_BUS_DEVICE(vms->gic);
56
- return a;
148
sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base);
149
if (type == 3) {
150
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
151
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
152
153
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
154
qdev_connect_gpio_out(cpudev, irq,
155
- qdev_get_gpio_in(gicdev,
156
+ qdev_get_gpio_in(vms->gic,
157
ppibase + timer_irq[irq]));
158
}
159
160
if (type == 3) {
161
- qemu_irq irq = qdev_get_gpio_in(gicdev,
162
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
163
ppibase + ARCH_GIC_MAINT_IRQ);
164
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
165
0, irq);
166
} else if (vms->virt) {
167
- qemu_irq irq = qdev_get_gpio_in(gicdev,
168
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
169
ppibase + ARCH_GIC_MAINT_IRQ);
170
sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
171
}
172
173
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
174
- qdev_get_gpio_in(gicdev, ppibase
175
+ qdev_get_gpio_in(vms->gic, ppibase
176
+ VIRTUAL_PMU_IRQ));
177
178
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
180
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
181
}
182
183
- for (i = 0; i < NUM_IRQS; i++) {
184
- pic[i] = qdev_get_gpio_in(gicdev, i);
185
- }
57
- }
186
-
58
-
187
fdt_add_gic_node(vms);
59
switch (which) {
188
60
case 0:
189
if (type == 3 && vms->its) {
61
break;
190
- create_its(vms, gicdev);
62
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
191
+ create_its(vms);
63
parts_silence_nan(a, s);
192
} else if (type == 2) {
193
- create_v2m(vms, pic);
194
+ create_v2m(vms);
195
}
64
}
65
return a;
66
+
67
+ default_nan:
68
+ parts_default_nan(a, s);
69
+ return a;
196
}
70
}
197
71
198
-static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
72
/*
199
+static void create_uart(const VirtMachineState *vms, int uart,
200
MemoryRegion *mem, Chardev *chr)
201
{
202
char *nodename;
203
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
204
qdev_init_nofail(dev);
205
memory_region_add_subregion(mem, base,
206
sysbus_mmio_get_region(s, 0));
207
- sysbus_connect_irq(s, 0, pic[irq]);
208
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
209
210
nodename = g_strdup_printf("/pl011@%" PRIx64, base);
211
qemu_fdt_add_subnode(vms->fdt, nodename);
212
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
213
g_free(nodename);
214
}
215
216
-static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
217
+static void create_rtc(const VirtMachineState *vms)
218
{
219
char *nodename;
220
hwaddr base = vms->memmap[VIRT_RTC].base;
221
@@ -XXX,XX +XXX,XX @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
222
int irq = vms->irqmap[VIRT_RTC];
223
const char compat[] = "arm,pl031\0arm,primecell";
224
225
- sysbus_create_simple("pl031", base, pic[irq]);
226
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(vms->gic, irq));
227
228
nodename = g_strdup_printf("/pl031@%" PRIx64, base);
229
qemu_fdt_add_subnode(vms->fdt, nodename);
230
@@ -XXX,XX +XXX,XX @@ static void virt_powerdown_req(Notifier *n, void *opaque)
231
}
232
}
233
234
-static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
235
+static void create_gpio(const VirtMachineState *vms)
236
{
237
char *nodename;
238
DeviceState *pl061_dev;
239
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
240
int irq = vms->irqmap[VIRT_GPIO];
241
const char compat[] = "arm,pl061\0arm,primecell";
242
243
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
244
+ pl061_dev = sysbus_create_simple("pl061", base,
245
+ qdev_get_gpio_in(vms->gic, irq));
246
247
uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
248
nodename = g_strdup_printf("/pl061@%" PRIx64, base);
249
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
250
g_free(nodename);
251
}
252
253
-static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
254
+static void create_virtio_devices(const VirtMachineState *vms)
255
{
256
int i;
257
hwaddr size = vms->memmap[VIRT_MMIO].size;
258
@@ -XXX,XX +XXX,XX @@ static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
259
int irq = vms->irqmap[VIRT_MMIO] + i;
260
hwaddr base = vms->memmap[VIRT_MMIO].base + i * size;
261
262
- sysbus_create_simple("virtio-mmio", base, pic[irq]);
263
+ sysbus_create_simple("virtio-mmio", base,
264
+ qdev_get_gpio_in(vms->gic, irq));
265
}
266
267
/* We add dtb nodes in reverse order so that they appear in the finished
268
@@ -XXX,XX +XXX,XX @@ static void create_pcie_irq_map(const VirtMachineState *vms,
269
0x7 /* PCI irq */);
270
}
271
272
-static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
273
+static void create_smmu(const VirtMachineState *vms,
274
PCIBus *bus)
275
{
276
char *node;
277
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
278
qdev_init_nofail(dev);
279
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
280
for (i = 0; i < NUM_SMMU_IRQS; i++) {
281
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
282
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
283
+ qdev_get_gpio_in(vms->gic, irq + i));
284
}
285
286
node = g_strdup_printf("/smmuv3@%" PRIx64, base);
287
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
288
g_free(node);
289
}
290
291
-static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
292
+static void create_pcie(VirtMachineState *vms)
293
{
294
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
295
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
296
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
297
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
298
299
for (i = 0; i < GPEX_NUM_IRQS; i++) {
300
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
301
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
302
+ qdev_get_gpio_in(vms->gic, irq + i));
303
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
304
}
305
306
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
307
if (vms->iommu) {
308
vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt);
309
310
- create_smmu(vms, pic, pci->bus);
311
+ create_smmu(vms, pci->bus);
312
313
qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map",
314
0x0, vms->iommu_phandle, 0x0, 0x10000);
315
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
316
g_free(nodename);
317
}
318
319
-static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
320
+static void create_platform_bus(VirtMachineState *vms)
321
{
322
DeviceState *dev;
323
SysBusDevice *s;
324
@@ -XXX,XX +XXX,XX @@ static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
325
326
s = SYS_BUS_DEVICE(dev);
327
for (i = 0; i < PLATFORM_BUS_NUM_IRQS; i++) {
328
- int irqn = vms->irqmap[VIRT_PLATFORM_BUS] + i;
329
- sysbus_connect_irq(s, i, pic[irqn]);
330
+ int irq = vms->irqmap[VIRT_PLATFORM_BUS] + i;
331
+ sysbus_connect_irq(s, i, qdev_get_gpio_in(vms->gic, irq));
332
}
333
334
memory_region_add_subregion(sysmem,
335
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
336
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
337
MachineClass *mc = MACHINE_GET_CLASS(machine);
338
const CPUArchIdList *possible_cpus;
339
- qemu_irq pic[NUM_IRQS];
340
MemoryRegion *sysmem = get_system_memory();
341
MemoryRegion *secure_sysmem = NULL;
342
int n, virt_max_cpus;
343
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
344
345
virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
346
347
- create_gic(vms, pic);
348
+ create_gic(vms);
349
350
fdt_add_pmu_nodes(vms);
351
352
- create_uart(vms, pic, VIRT_UART, sysmem, serial_hd(0));
353
+ create_uart(vms, VIRT_UART, sysmem, serial_hd(0));
354
355
if (vms->secure) {
356
create_secure_ram(vms, secure_sysmem);
357
- create_uart(vms, pic, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
358
+ create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
359
}
360
361
vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
362
363
- create_rtc(vms, pic);
364
+ create_rtc(vms);
365
366
- create_pcie(vms, pic);
367
+ create_pcie(vms);
368
369
if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
370
- vms->acpi_dev = create_acpi_ged(vms, pic);
371
+ vms->acpi_dev = create_acpi_ged(vms);
372
} else {
373
- create_gpio(vms, pic);
374
+ create_gpio(vms);
375
}
376
377
/* connect powerdown request */
378
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
379
* (which will be automatically plugged in to the transports). If
380
* no backend is created the transport will just sit harmlessly idle.
381
*/
382
- create_virtio_devices(vms, pic);
383
+ create_virtio_devices(vms);
384
385
vms->fw_cfg = create_fw_cfg(vms, &address_space_memory);
386
rom_set_fw(vms->fw_cfg);
387
388
- create_platform_bus(vms, pic);
389
+ create_platform_bus(vms);
390
391
vms->bootinfo.ram_size = machine->ram_size;
392
vms->bootinfo.nb_cpus = smp_cpus;
393
--
73
--
394
2.20.1
74
2.34.1
395
75
396
76
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Switch to ram block writeback for pmem migration.
3
Assign the pointer return value to 'a' directly,
4
rather than going through an intermediary index.
4
5
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
8
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
9
Message-id: 20191121000843.24844-4-beata.michalska@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
migration/ram.c | 5 +----
11
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
13
1 file changed, 1 insertion(+), 4 deletions(-)
12
1 file changed, 10 insertions(+), 22 deletions(-)
14
13
15
diff --git a/migration/ram.c b/migration/ram.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/migration/ram.c
16
--- a/fpu/softfloat-parts.c.inc
18
+++ b/migration/ram.c
17
+++ b/fpu/softfloat-parts.c.inc
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
20
#include "qemu/bitops.h"
19
FloatPartsN *c, float_status *s,
21
#include "qemu/bitmap.h"
20
int ab_mask, int abc_mask)
22
#include "qemu/main-loop.h"
21
{
23
-#include "qemu/pmem.h"
22
- int which;
24
#include "xbzrle.h"
23
bool infzero = (ab_mask == float_cmask_infzero);
25
#include "ram.h"
24
bool have_snan = (abc_mask & float_cmask_snan);
26
#include "migration.h"
25
+ FloatPartsN *ret;
27
@@ -XXX,XX +XXX,XX @@ static int ram_load_cleanup(void *opaque)
26
28
RAMBlock *rb;
27
if (unlikely(have_snan)) {
29
28
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
30
RAMBLOCK_FOREACH_NOT_IGNORED(rb) {
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
31
- if (ramblock_is_pmem(rb)) {
30
default:
32
- pmem_persist(rb->host, rb->used_length);
31
g_assert_not_reached();
33
- }
32
}
34
+ qemu_ram_block_writeback(rb);
33
- which = 2;
34
+ ret = c;
35
} else {
36
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
37
+ FloatPartsN *val[3] = { a, b, c };
38
Float3NaNPropRule rule = s->float_3nan_prop_rule;
39
40
assert(rule != float_3nan_prop_none);
41
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
42
/* We have at least one SNaN input and should prefer it */
43
do {
44
- which = rule & R_3NAN_1ST_MASK;
45
+ ret = val[rule & R_3NAN_1ST_MASK];
46
rule >>= R_3NAN_1ST_LENGTH;
47
- } while (!is_snan(cls[which]));
48
+ } while (!is_snan(ret->cls));
49
} else {
50
do {
51
- which = rule & R_3NAN_1ST_MASK;
52
+ ret = val[rule & R_3NAN_1ST_MASK];
53
rule >>= R_3NAN_1ST_LENGTH;
54
- } while (!is_nan(cls[which]));
55
+ } while (!is_nan(ret->cls));
56
}
35
}
57
}
36
58
37
xbzrle_load_cleanup();
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);
38
--
81
--
39
2.20.1
82
2.34.1
40
83
41
84
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This change ensures that the FPU can be accessed in Non-Secure mode
3
While all indices into val[] should be in [0-2], the mask
4
when the CPU core is reset using the arm_set_cpu_on() function call.
4
applied is two bits. To help static analysis see there is
5
The NSACR.{CP11,CP10} bits define the exception level required to
5
no possibility of read beyond the end of the array, pad the
6
access the FPU in Non-Secure mode. Without these bits set, the CPU
6
array to 4 entries, with the final being (implicitly) NULL.
7
will give an undefined exception trap on the first FPU access for the
8
secondary cores under Linux.
9
7
10
This is necessary because in this power-control codepath QEMU
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
is effectively emulating a bit of EL3 firmware, and has to set
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
the CPU up as the EL3 firmware would.
10
Message-id: 20241203203949.483774-6-richard.henderson@linaro.org
13
14
Fixes: fc1120a7f5
15
Cc: qemu-stable@nongnu.org
16
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
17
[PMM: added clarifying para to commit message]
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
12
---
21
target/arm/arm-powerctl.c | 3 +++
13
fpu/softfloat-parts.c.inc | 2 +-
22
1 file changed, 3 insertions(+)
14
1 file changed, 1 insertion(+), 1 deletion(-)
23
15
24
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/arm-powerctl.c
18
--- a/fpu/softfloat-parts.c.inc
27
+++ b/target/arm/arm-powerctl.c
19
+++ b/fpu/softfloat-parts.c.inc
28
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
29
/* Processor is not in secure mode */
21
}
30
target_cpu->env.cp15.scr_el3 |= SCR_NS;
22
ret = c;
31
23
} else {
32
+ /* Set NSACR.{CP11,CP10} so NS can access the FPU */
24
- FloatPartsN *val[3] = { a, b, c };
33
+ target_cpu->env.cp15.nsacr |= 3 << 10;
25
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
34
+
26
Float3NaNPropRule rule = s->float_3nan_prop_rule;
35
/*
27
36
* If QEMU is providing the equivalent of EL3 firmware, then we need
28
assert(rule != float_3nan_prop_none);
37
* to make sure a CPU targeting EL2 comes out of reset with a
38
--
29
--
39
2.20.1
30
2.34.1
40
31
41
32
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The SRAM must be enabled before using the Buffer Pool mode or the DMA
3
This function is part of the public interface and
4
mode. This is not required on other SoCs.
4
is not "specialized" to any target in any way.
5
5
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
8
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 20191119141211.25716-3-clg@kaod.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
include/hw/i2c/aspeed_i2c.h | 3 +++
11
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
14
hw/i2c/aspeed_i2c.c | 37 +++++++++++++++++++++++++++++++++++++
12
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
15
2 files changed, 40 insertions(+)
13
2 files changed, 52 insertions(+), 52 deletions(-)
16
14
17
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/i2c/aspeed_i2c.h
17
--- a/fpu/softfloat.c
20
+++ b/include/hw/i2c/aspeed_i2c.h
18
+++ b/fpu/softfloat.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
22
qemu_irq irq;
20
*zExpPtr = 1 - shiftCount;
23
21
}
24
uint32_t intr_status;
22
25
+ uint32_t ctrl_global;
23
+/*----------------------------------------------------------------------------
26
MemoryRegion pool_iomem;
24
+| Takes two extended double-precision floating-point values `a' and `b', one
27
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
25
+| of which is a NaN, and returns the appropriate NaN result. If either `a' or
28
26
+| `b' is a signaling NaN, the invalid exception is raised.
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
27
+*----------------------------------------------------------------------------*/
30
uint64_t pool_size;
31
hwaddr pool_base;
32
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
33
+ bool check_sram;
34
+
28
+
35
} AspeedI2CClass;
29
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
36
37
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
38
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/i2c/aspeed_i2c.c
41
+++ b/hw/i2c/aspeed_i2c.c
42
@@ -XXX,XX +XXX,XX @@
43
#define I2C_CTRL_STATUS 0x00 /* Device Interrupt Status */
44
#define I2C_CTRL_ASSIGN 0x08 /* Device Interrupt Target
45
Assignment */
46
+#define I2C_CTRL_GLOBAL 0x0C /* Global Control Register */
47
+#define I2C_CTRL_SRAM_EN BIT(0)
48
49
/* I2C Device (Bus) Register */
50
51
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
52
}
53
}
54
55
+static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
56
+{
30
+{
57
+ AspeedI2CState *s = bus->controller;
31
+ bool aIsLargerSignificand;
58
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
32
+ FloatClass a_cls, b_cls;
59
+
33
+
60
+ if (!aic->check_sram) {
34
+ /* This is not complete, but is good enough for pickNaN. */
61
+ return true;
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);
62
+ }
48
+ }
63
+
49
+
64
+ /*
50
+ if (status->default_nan_mode) {
65
+ * AST2500: SRAM must be enabled before using the Buffer Pool or
51
+ return floatx80_default_nan(status);
66
+ * DMA mode.
67
+ */
68
+ if (!(s->ctrl_global & I2C_CTRL_SRAM_EN) &&
69
+ (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE |
70
+ I2CD_RX_BUFF_ENABLE | I2CD_TX_BUFF_ENABLE))) {
71
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: SRAM is not enabled\n", __func__);
72
+ return false;
73
+ }
52
+ }
74
+
53
+
75
+ return true;
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
+ }
76
+}
73
+}
77
+
74
+
78
/*
75
/*----------------------------------------------------------------------------
79
* The state machine needs some refinement. It is only used to track
76
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
80
* invalid STOP commands for the moment.
77
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
78
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
82
bus->cmd &= ~0xFFFF;
79
index XXXXXXX..XXXXXXX 100644
83
bus->cmd |= value & 0xFFFF;
80
--- a/fpu/softfloat-specialize.c.inc
84
81
+++ b/fpu/softfloat-specialize.c.inc
85
+ if (!aspeed_i2c_check_sram(bus)) {
82
@@ -XXX,XX +XXX,XX @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
86
+ return;
83
return a;
87
+ }
88
+
89
if (bus->cmd & I2CD_M_START_CMD) {
90
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
91
I2CD_MSTARTR : I2CD_MSTART;
92
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
93
switch (offset) {
94
case I2C_CTRL_STATUS:
95
return s->intr_status;
96
+ case I2C_CTRL_GLOBAL:
97
+ return s->ctrl_global;
98
default:
99
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
100
__func__, offset);
101
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
102
static void aspeed_i2c_ctrl_write(void *opaque, hwaddr offset,
103
uint64_t value, unsigned size)
104
{
105
+ AspeedI2CState *s = opaque;
106
+
107
switch (offset) {
108
+ case I2C_CTRL_GLOBAL:
109
+ s->ctrl_global = value;
110
+ break;
111
case I2C_CTRL_STATUS:
112
default:
113
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
114
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
115
aic->pool_size = 0x100;
116
aic->pool_base = 0x200;
117
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
118
+ aic->check_sram = true;
119
}
84
}
120
85
121
static const TypeInfo aspeed_2500_i2c_info = {
86
-/*----------------------------------------------------------------------------
87
-| Takes two extended double-precision floating-point values `a' and `b', one
88
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
89
-| `b' is a signaling NaN, the invalid exception is raised.
90
-*----------------------------------------------------------------------------*/
91
-
92
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
93
-{
94
- bool aIsLargerSignificand;
95
- FloatClass a_cls, b_cls;
96
-
97
- /* This is not complete, but is good enough for pickNaN. */
98
- a_cls = (!floatx80_is_any_nan(a)
99
- ? float_class_normal
100
- : floatx80_is_signaling_nan(a, status)
101
- ? float_class_snan
102
- : float_class_qnan);
103
- b_cls = (!floatx80_is_any_nan(b)
104
- ? float_class_normal
105
- : floatx80_is_signaling_nan(b, status)
106
- ? float_class_snan
107
- : float_class_qnan);
108
-
109
- if (is_snan(a_cls) || is_snan(b_cls)) {
110
- float_raise(float_flag_invalid, status);
111
- }
112
-
113
- if (status->default_nan_mode) {
114
- return floatx80_default_nan(status);
115
- }
116
-
117
- if (a.low < b.low) {
118
- aIsLargerSignificand = 0;
119
- } else if (b.low < a.low) {
120
- aIsLargerSignificand = 1;
121
- } else {
122
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
123
- }
124
-
125
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
126
- if (is_snan(b_cls)) {
127
- return floatx80_silence_nan(b, status);
128
- }
129
- return b;
130
- } else {
131
- if (is_snan(a_cls)) {
132
- return floatx80_silence_nan(a, status);
133
- }
134
- return a;
135
- }
136
-}
137
-
138
/*----------------------------------------------------------------------------
139
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
140
| NaN; otherwise returns 0.
122
--
141
--
123
2.20.1
142
2.34.1
124
125
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Most boards have this much.
3
Unpacking and repacking the parts may be slightly more work
4
than we did before, but we get to reuse more code. For a
5
code path handling exceptional values, this is an improvement.
4
6
5
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20241203203949.483774-8-richard.henderson@linaro.org
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-7-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/misc/aspeed_sdmc.c | 6 +++---
12
fpu/softfloat.c | 43 +++++--------------------------------------
13
1 file changed, 3 insertions(+), 3 deletions(-)
13
1 file changed, 5 insertions(+), 38 deletions(-)
14
14
15
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/aspeed_sdmc.c
17
--- a/fpu/softfloat.c
18
+++ b/hw/misc/aspeed_sdmc.c
18
+++ b/fpu/softfloat.c
19
@@ -XXX,XX +XXX,XX @@ static int ast2600_rambits(AspeedSDMCState *s)
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
20
21
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
22
{
23
- bool aIsLargerSignificand;
24
- FloatClass a_cls, b_cls;
25
+ FloatParts128 pa, pb, *pr;
26
27
- /* This is not complete, but is good enough for pickNaN. */
28
- a_cls = (!floatx80_is_any_nan(a)
29
- ? float_class_normal
30
- : floatx80_is_signaling_nan(a, status)
31
- ? float_class_snan
32
- : float_class_qnan);
33
- b_cls = (!floatx80_is_any_nan(b)
34
- ? float_class_normal
35
- : floatx80_is_signaling_nan(b, status)
36
- ? float_class_snan
37
- : float_class_qnan);
38
-
39
- if (is_snan(a_cls) || is_snan(b_cls)) {
40
- float_raise(float_flag_invalid, status);
41
- }
42
-
43
- if (status->default_nan_mode) {
44
+ if (!floatx80_unpack_canonical(&pa, a, status) ||
45
+ !floatx80_unpack_canonical(&pb, b, status)) {
46
return floatx80_default_nan(status);
20
}
47
}
21
48
22
/* use a common default */
49
- if (a.low < b.low) {
23
- warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M",
50
- aIsLargerSignificand = 0;
24
+ warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 1024M",
51
- } else if (b.low < a.low) {
25
s->ram_size);
52
- aIsLargerSignificand = 1;
26
- s->ram_size = 512 << 20;
53
- } else {
27
- return ASPEED_SDMC_AST2600_512MB;
54
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
28
+ s->ram_size = 1024 << 20;
55
- }
29
+ return ASPEED_SDMC_AST2600_1024MB;
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
static void aspeed_sdmc_reset(DeviceState *dev)
72
/*----------------------------------------------------------------------------
33
--
73
--
34
2.20.1
74
2.34.1
35
36
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
HCR_EL2.TID3 requires that AArch32 reads of MVFR[012] are trapped to
3
Inline pickNaN into its only caller. This makes one assert
4
EL2, and HCR_EL2.TID0 does the same for reads of FPSID.
4
redundant with the immediately preceding IF.
5
In order to handle this, introduce a new TCG helper function that
5
6
checks for these control bits before executing the VMRC instruction.
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Tested with a hacked-up version of KVM/arm64 that sets the control
8
Message-id: 20241203203949.483774-9-richard.henderson@linaro.org
9
bits for 32bit guests.
10
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-4-maz@kernel.org
15
[PMM: move helper declaration to helper.h; make it
16
TCG_CALL_NO_WG]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
10
---
19
target/arm/helper.h | 2 ++
11
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
20
target/arm/translate-vfp.inc.c | 20 ++++++++++++++++----
12
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
21
target/arm/vfp_helper.c | 29 +++++++++++++++++++++++++++++
13
2 files changed, 73 insertions(+), 105 deletions(-)
22
3 files changed, 47 insertions(+), 4 deletions(-)
14
23
15
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
17
--- a/fpu/softfloat-parts.c.inc
27
+++ b/target/arm/helper.h
18
+++ b/fpu/softfloat-parts.c.inc
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG, f64, f64, ptr)
19
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
29
DEF_HELPER_FLAGS_2(vjcvt, TCG_CALL_NO_RWG, i32, f64, env)
20
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
30
DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
21
float_status *s)
31
22
{
32
+DEF_HELPER_FLAGS_3(check_hcr_el2_trap, TCG_CALL_NO_WG, void, env, i32, i32)
23
+ int cmp, which;
33
+
24
+
34
/* neon_helper.c */
25
if (is_snan(a->cls) || is_snan(b->cls)) {
35
DEF_HELPER_FLAGS_3(neon_qadd_u8, TCG_CALL_NO_RWG, i32, env, i32, i32)
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
36
DEF_HELPER_FLAGS_3(neon_qadd_s8, TCG_CALL_NO_RWG, i32, env, i32, i32)
27
}
37
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
28
38
index XXXXXXX..XXXXXXX 100644
29
if (s->default_nan_mode) {
39
--- a/target/arm/translate-vfp.inc.c
30
parts_default_nan(a, s);
40
+++ b/target/arm/translate-vfp.inc.c
31
- } else {
41
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
32
- int cmp = frac_cmp(a, b);
42
if (a->l) {
33
- if (cmp == 0) {
43
/* VMRS, move VFP special register to gp register */
34
- cmp = a->sign < b->sign;
44
switch (a->reg) {
35
- }
45
- case ARM_VFP_FPSID:
36
+ return a;
46
- case ARM_VFP_FPEXC:
37
+ }
47
- case ARM_VFP_FPINST:
38
48
- case ARM_VFP_FPINST2:
39
- if (pickNaN(a->cls, b->cls, cmp > 0, s)) {
49
case ARM_VFP_MVFR0:
40
- a = b;
50
case ARM_VFP_MVFR1:
41
- }
51
case ARM_VFP_MVFR2:
42
+ cmp = frac_cmp(a, b);
52
+ case ARM_VFP_FPSID:
43
+ if (cmp == 0) {
53
+ if (s->current_el == 1) {
44
+ cmp = a->sign < b->sign;
54
+ TCGv_i32 tcg_reg, tcg_rt;
45
+ }
55
+
46
+
56
+ gen_set_condexec(s);
47
+ switch (s->float_2nan_prop_rule) {
57
+ gen_set_pc_im(s, s->pc_curr);
48
+ case float_2nan_prop_s_ab:
58
+ tcg_reg = tcg_const_i32(a->reg);
49
if (is_snan(a->cls)) {
59
+ tcg_rt = tcg_const_i32(a->rt);
50
- parts_silence_nan(a, s);
60
+ gen_helper_check_hcr_el2_trap(cpu_env, tcg_rt, tcg_reg);
51
+ which = 0;
61
+ tcg_temp_free_i32(tcg_reg);
52
+ } else if (is_snan(b->cls)) {
62
+ tcg_temp_free_i32(tcg_rt);
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;
63
+ }
94
+ }
64
+ /* fall through */
95
+ } else if (is_qnan(a->cls)) {
65
+ case ARM_VFP_FPEXC:
96
+ if (is_snan(b->cls) || !is_qnan(b->cls)) {
66
+ case ARM_VFP_FPINST:
97
+ which = 0;
67
+ case ARM_VFP_FPINST2:
98
+ } else {
68
tmp = load_cpu_field(vfp.xregs[a->reg]);
99
+ which = cmp > 0 ? 0 : 1;
69
break;
100
+ }
70
case ARM_VFP_FPSCR:
101
+ } else {
71
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
102
+ which = 1;
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/vfp_helper.c
74
+++ b/target/arm/vfp_helper.c
75
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frint64_d)(float64 f, void *fpst)
76
return frint_d(f, fpst, 64);
77
}
78
79
+void HELPER(check_hcr_el2_trap)(CPUARMState *env, uint32_t rt, uint32_t reg)
80
+{
81
+ uint32_t syndrome;
82
+
83
+ switch (reg) {
84
+ case ARM_VFP_MVFR0:
85
+ case ARM_VFP_MVFR1:
86
+ case ARM_VFP_MVFR2:
87
+ if (!(arm_hcr_el2_eff(env) & HCR_TID3)) {
88
+ return;
89
+ }
90
+ break;
91
+ case ARM_VFP_FPSID:
92
+ if (!(arm_hcr_el2_eff(env) & HCR_TID0)) {
93
+ return;
94
+ }
103
+ }
95
+ break;
104
+ break;
96
+ default:
105
+ default:
97
+ g_assert_not_reached();
106
+ g_assert_not_reached();
98
+ }
107
+ }
99
+
108
+
100
+ syndrome = ((EC_FPIDTRAP << ARM_EL_EC_SHIFT)
109
+ if (which) {
101
+ | ARM_EL_IL
110
+ a = b;
102
+ | (1 << 24) | (0xe << 20) | (7 << 14)
111
+ }
103
+ | (reg << 10) | (rt << 5) | 1);
112
+ if (is_snan(a->cls)) {
104
+
113
+ parts_silence_nan(a, s);
105
+ raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
114
}
106
+}
115
return a;
107
+
116
}
108
#endif
117
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
118
index XXXXXXX..XXXXXXX 100644
119
--- a/fpu/softfloat-specialize.c.inc
120
+++ b/fpu/softfloat-specialize.c.inc
121
@@ -XXX,XX +XXX,XX @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
122
}
123
}
124
125
-/*----------------------------------------------------------------------------
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)
144
-{
145
- /*
146
- * We guarantee not to require the target to tell us how to
147
- * pick a NaN if we're always returning the default NaN.
148
- * But if we're not in default-NaN mode then the target must
149
- * specify via set_float_2nan_prop_rule().
150
- */
151
- assert(!status->default_nan_mode);
152
-
153
- switch (status->float_2nan_prop_rule) {
154
- case float_2nan_prop_s_ab:
155
- if (is_snan(a_cls)) {
156
- return 0;
157
- } else if (is_snan(b_cls)) {
158
- return 1;
159
- } else if (is_qnan(a_cls)) {
160
- return 0;
161
- } else {
162
- return 1;
163
- }
164
- break;
165
- case float_2nan_prop_s_ba:
166
- if (is_snan(b_cls)) {
167
- return 1;
168
- } else if (is_snan(a_cls)) {
169
- return 0;
170
- } else if (is_qnan(b_cls)) {
171
- return 1;
172
- } else {
173
- return 0;
174
- }
175
- break;
176
- case float_2nan_prop_ab:
177
- if (is_nan(a_cls)) {
178
- return 0;
179
- } else {
180
- return 1;
181
- }
182
- break;
183
- case float_2nan_prop_ba:
184
- if (is_nan(b_cls)) {
185
- return 1;
186
- } else {
187
- return 0;
188
- }
189
- break;
190
- case float_2nan_prop_x87:
191
- /*
192
- * This implements x87 NaN propagation rules:
193
- * SNaN + QNaN => return the QNaN
194
- * two SNaNs => return the one with the larger significand, silenced
195
- * two QNaNs => return the one with the larger significand
196
- * SNaN and a non-NaN => return the SNaN, silenced
197
- * QNaN and a non-NaN => return the QNaN
198
- *
199
- * If we get down to comparing significands and they are the same,
200
- * return the NaN with the positive sign bit (if any).
201
- */
202
- if (is_snan(a_cls)) {
203
- if (is_snan(b_cls)) {
204
- return aIsLargerSignificand ? 0 : 1;
205
- }
206
- return is_qnan(b_cls) ? 1 : 0;
207
- } else if (is_qnan(a_cls)) {
208
- if (is_snan(b_cls) || !is_qnan(b_cls)) {
209
- return 0;
210
- } else {
211
- return aIsLargerSignificand ? 0 : 1;
212
- }
213
- } else {
214
- return 1;
215
- }
216
- default:
217
- g_assert_not_reached();
218
- }
219
-}
220
-
221
/*----------------------------------------------------------------------------
222
| Returns 1 if the double-precision floating-point value `a' is a quiet
223
| NaN; otherwise returns 0.
109
--
224
--
110
2.20.1
225
2.34.1
111
226
112
227
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Users benefit from knowing which watchdog timer has expired. The address
3
Remember if there was an SNaN, and use that to simplify
4
of the watchdog's registers unambiguously indicates which has expired,
4
float_2nan_prop_s_{ab,ba} to only the snan component.
5
so log that.
5
Then, fall through to the corresponding
6
float_2nan_prop_{ab,ba} case to handle any remaining
7
nans, which must be quiet.
6
8
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
11
Message-id: 20241203203949.483774-10-richard.henderson@linaro.org
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-9-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
hw/watchdog/wdt_aspeed.c | 3 ++-
14
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
15
1 file changed, 2 insertions(+), 1 deletion(-)
15
1 file changed, 12 insertions(+), 20 deletions(-)
16
16
17
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/watchdog/wdt_aspeed.c
19
--- a/fpu/softfloat-parts.c.inc
20
+++ b/hw/watchdog/wdt_aspeed.c
20
+++ b/fpu/softfloat-parts.c.inc
21
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_timer_expired(void *dev)
21
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
22
return;
22
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
23
float_status *s)
24
{
25
+ bool have_snan = false;
26
int cmp, which;
27
28
if (is_snan(a->cls) || is_snan(b->cls)) {
29
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
30
+ have_snan = true;
23
}
31
}
24
32
25
- qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
33
if (s->default_nan_mode) {
26
+ qemu_log_mask(CPU_LOG_RESET, "Watchdog timer %" HWADDR_PRIx " expired.\n",
34
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
27
+ s->iomem.addr);
35
28
watchdog_perform_action();
36
switch (s->float_2nan_prop_rule) {
29
timer_del(s->timer);
37
case float_2nan_prop_s_ab:
30
}
38
- if (is_snan(a->cls)) {
39
- which = 0;
40
- } else if (is_snan(b->cls)) {
41
- which = 1;
42
- } else if (is_qnan(a->cls)) {
43
- which = 0;
44
- } else {
45
- which = 1;
46
+ if (have_snan) {
47
+ which = is_snan(a->cls) ? 0 : 1;
48
+ break;
49
}
50
- break;
51
- case float_2nan_prop_s_ba:
52
- if (is_snan(b->cls)) {
53
- which = 1;
54
- } else if (is_snan(a->cls)) {
55
- which = 0;
56
- } else if (is_qnan(b->cls)) {
57
- which = 1;
58
- } else {
59
- which = 0;
60
- }
61
- break;
62
+ /* fall through */
63
case float_2nan_prop_ab:
64
which = is_nan(a->cls) ? 0 : 1;
65
break;
66
+ case float_2nan_prop_s_ba:
67
+ if (have_snan) {
68
+ which = is_snan(b->cls) ? 1 : 0;
69
+ break;
70
+ }
71
+ /* fall through */
72
case float_2nan_prop_ba:
73
which = is_nan(b->cls) ? 1 : 0;
74
break;
31
--
75
--
32
2.20.1
76
2.34.1
33
34
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The Aspeed MII model has a link pointing to its associated FTGMAC100
3
Move the fractional comparison to the end of the
4
NIC in the machine.
4
float_2nan_prop_x87 case. This is not required for
5
any other 2nan propagation rule. Reorganize the
6
x87 case itself to break out of the switch when the
7
fractional comparison is not required.
5
8
6
Change the "nic" property definition so that it explicitly sets the
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
pointer. The property isn't optional : not being able to set the link
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
is a bug and QEMU should rather abort than exit in this case.
11
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Greg Kurz <groug@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-18-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
13
---
17
hw/arm/aspeed_ast2600.c | 5 ++---
14
fpu/softfloat-parts.c.inc | 19 +++++++++----------
18
hw/net/ftgmac100.c | 19 +++++++++----------
15
1 file changed, 9 insertions(+), 10 deletions(-)
19
2 files changed, 11 insertions(+), 13 deletions(-)
20
16
21
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/aspeed_ast2600.c
19
--- a/fpu/softfloat-parts.c.inc
24
+++ b/hw/arm/aspeed_ast2600.c
20
+++ b/fpu/softfloat-parts.c.inc
25
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
26
22
return a;
27
sysbus_init_child_obj(obj, "mii[*]", &s->mii[i], sizeof(s->mii[i]),
28
TYPE_ASPEED_MII);
29
- object_property_add_const_link(OBJECT(&s->mii[i]), "nic",
30
- OBJECT(&s->ftgmac100[i]),
31
- &error_abort);
32
}
23
}
33
24
34
sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
25
- cmp = frac_cmp(a, b);
35
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
26
- if (cmp == 0) {
36
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
27
- cmp = a->sign < b->sign;
37
aspeed_soc_get_irq(s, ASPEED_ETH1 + i));
38
39
+ object_property_set_link(OBJECT(&s->mii[i]), OBJECT(&s->ftgmac100[i]),
40
+ "nic", &error_abort);
41
object_property_set_bool(OBJECT(&s->mii[i]), true, "realized",
42
&err);
43
if (err) {
44
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/net/ftgmac100.c
47
+++ b/hw/net/ftgmac100.c
48
@@ -XXX,XX +XXX,XX @@ static void aspeed_mii_realize(DeviceState *dev, Error **errp)
49
{
50
AspeedMiiState *s = ASPEED_MII(dev);
51
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
52
- Object *obj;
53
- Error *local_err = NULL;
54
55
- obj = object_property_get_link(OBJECT(dev), "nic", &local_err);
56
- if (!obj) {
57
- error_propagate(errp, local_err);
58
- error_prepend(errp, "required link 'nic' not found: ");
59
- return;
60
- }
28
- }
61
-
29
-
62
- s->nic = FTGMAC100(obj);
30
switch (s->float_2nan_prop_rule) {
63
+ assert(s->nic);
31
case float_2nan_prop_s_ab:
64
32
if (have_snan) {
65
memory_region_init_io(&s->iomem, OBJECT(dev), &aspeed_mii_ops, s,
33
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
66
TYPE_ASPEED_MII, 0x8);
34
* return the NaN with the positive sign bit (if any).
67
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_mii = {
35
*/
68
VMSTATE_END_OF_LIST()
36
if (is_snan(a->cls)) {
69
}
37
- if (is_snan(b->cls)) {
70
};
38
- which = cmp > 0 ? 0 : 1;
71
+
39
- } else {
72
+static Property aspeed_mii_properties[] = {
40
+ if (!is_snan(b->cls)) {
73
+ DEFINE_PROP_LINK("nic", AspeedMiiState, nic, TYPE_FTGMAC100,
41
which = is_qnan(b->cls) ? 1 : 0;
74
+ FTGMAC100State *),
42
+ break;
75
+ DEFINE_PROP_END_OF_LIST(),
43
}
76
+};
44
} else if (is_qnan(a->cls)) {
77
+
45
if (is_snan(b->cls) || !is_qnan(b->cls)) {
78
static void aspeed_mii_class_init(ObjectClass *klass, void *data)
46
which = 0;
79
{
47
- } else {
80
DeviceClass *dc = DEVICE_CLASS(klass);
48
- which = cmp > 0 ? 0 : 1;
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_mii_class_init(ObjectClass *klass, void *data)
49
+ break;
82
dc->reset = aspeed_mii_reset;
50
}
83
dc->realize = aspeed_mii_realize;
51
} else {
84
dc->desc = "Aspeed MII controller";
52
which = 1;
85
+ dc->props = aspeed_mii_properties;
53
+ break;
86
}
54
}
87
55
+ cmp = frac_cmp(a, b);
88
static const TypeInfo aspeed_mii_info = {
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();
89
--
63
--
90
2.20.1
64
2.34.1
91
92
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
HSTR_EL2 offers a way to trap ranges of CP15 system register
3
Replace the "index" selecting between A and B with a result variable
4
accesses to EL2, and it looks like this register is completely
4
of the proper type. This improves clarity within the function.
5
ignored by QEMU.
6
5
7
To avoid adding extra .accessfn filters all over the place (which
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
would have a direct performance impact), let's add a new TB flag
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
that gets set whenever HSTR_EL2 is non-zero and that QEMU translates
8
Message-id: 20241203203949.483774-12-richard.henderson@linaro.org
10
a context where this trap has a chance to apply, and only generate
11
the extra access check if the hypervisor is actively using this feature.
12
13
Tested with a hand-crafted KVM guest accessing CBAR.
14
15
Signed-off-by: Marc Zyngier <maz@kernel.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20191201122018.25808-5-maz@kernel.org
18
[PMM: use is_a64(); fix comment syntax]
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
10
---
21
target/arm/cpu.h | 2 ++
11
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
22
target/arm/translate.h | 2 ++
12
1 file changed, 13 insertions(+), 15 deletions(-)
23
target/arm/helper.c | 6 ++++++
24
target/arm/op_helper.c | 22 ++++++++++++++++++++++
25
target/arm/translate.c | 3 ++-
26
5 files changed, 34 insertions(+), 1 deletion(-)
27
13
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
29
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
16
--- a/fpu/softfloat-parts.c.inc
31
+++ b/target/arm/cpu.h
17
+++ b/fpu/softfloat-parts.c.inc
32
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
33
FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Partially cached, minus FPEXC. */
19
float_status *s)
34
FIELD(TBFLAG_A32, CONDEXEC, 8, 8) /* Not cached. */
20
{
35
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
21
bool have_snan = false;
36
+FIELD(TBFLAG_A32, HSTR_ACTIVE, 17, 1)
22
- int cmp, which;
37
+
23
+ FloatPartsN *ret;
38
/* For M profile only, set if FPCCR.LSPACT is set */
24
+ int cmp;
39
FIELD(TBFLAG_A32, LSPACT, 18, 1) /* Not cached. */
25
40
/* For M profile only, set if we must create a new FP context */
26
if (is_snan(a->cls) || is_snan(b->cls)) {
41
diff --git a/target/arm/translate.h b/target/arm/translate.h
27
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
42
index XXXXXXX..XXXXXXX 100644
28
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
43
--- a/target/arm/translate.h
29
switch (s->float_2nan_prop_rule) {
44
+++ b/target/arm/translate.h
30
case float_2nan_prop_s_ab:
45
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
31
if (have_snan) {
46
bool pauth_active;
32
- which = is_snan(a->cls) ? 0 : 1;
47
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
33
+ ret = is_snan(a->cls) ? a : b;
48
bool bt;
34
break;
49
+ /* True if any CP15 access is trapped by HSTR_EL2 */
35
}
50
+ bool hstr_active;
36
/* fall through */
51
/*
37
case float_2nan_prop_ab:
52
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
38
- which = is_nan(a->cls) ? 0 : 1;
53
* < 0, set by the current instruction.
39
+ ret = is_nan(a->cls) ? a : b;
54
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
break;
55
index XXXXXXX..XXXXXXX 100644
41
case float_2nan_prop_s_ba:
56
--- a/target/arm/helper.c
42
if (have_snan) {
57
+++ b/target/arm/helper.c
43
- which = is_snan(b->cls) ? 1 : 0;
58
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
44
+ ret = is_snan(b->cls) ? b : a;
59
if (arm_el_is_aa64(env, 1)) {
45
break;
60
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
46
}
61
}
47
/* fall through */
62
+
48
case float_2nan_prop_ba:
63
+ if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
49
- which = is_nan(b->cls) ? 1 : 0;
64
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
50
+ ret = is_nan(b->cls) ? b : a;
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
51
break;
66
+ }
52
case float_2nan_prop_x87:
67
+
53
/*
68
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
54
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
69
}
55
*/
70
56
if (is_snan(a->cls)) {
71
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
57
if (!is_snan(b->cls)) {
72
index XXXXXXX..XXXXXXX 100644
58
- which = is_qnan(b->cls) ? 1 : 0;
73
--- a/target/arm/op_helper.c
59
+ ret = is_qnan(b->cls) ? b : a;
74
+++ b/target/arm/op_helper.c
60
break;
75
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
61
}
76
raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
62
} else if (is_qnan(a->cls)) {
77
}
63
if (is_snan(b->cls) || !is_qnan(b->cls)) {
78
64
- which = 0;
79
+ /*
65
+ ret = a;
80
+ * Check for an EL2 trap due to HSTR_EL2. We expect EL0 accesses
66
break;
81
+ * to sysregs non accessible at EL0 to have UNDEF-ed already.
67
}
82
+ */
68
} else {
83
+ if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
69
- which = 1;
84
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
70
+ ret = b;
85
+ uint32_t mask = 1 << ri->crn;
71
break;
86
+
72
}
87
+ if (ri->type & ARM_CP_64BIT) {
73
cmp = frac_cmp(a, b);
88
+ mask = 1 << ri->crm;
74
if (cmp == 0) {
89
+ }
75
cmp = a->sign < b->sign;
90
+
76
}
91
+ /* T4 and T14 are RES0 */
77
- which = cmp > 0 ? 0 : 1;
92
+ mask &= ~((1 << 4) | (1 << 14));
78
+ ret = cmp > 0 ? a : b;
93
+
79
break;
94
+ if (env->cp15.hstr_el2 & mask) {
80
default:
95
+ target_el = 2;
96
+ goto exept;
97
+ }
98
+ }
99
+
100
if (!ri->accessfn) {
101
return;
102
}
103
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
104
g_assert_not_reached();
81
g_assert_not_reached();
105
}
82
}
106
83
107
+exept:
84
- if (which) {
108
raise_exception(env, EXCP_UDEF, syndrome, target_el);
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;
109
}
94
}
110
95
111
diff --git a/target/arm/translate.c b/target/arm/translate.c
96
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/translate.c
114
+++ b/target/arm/translate.c
115
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
116
return 1;
117
}
118
119
- if (ri->accessfn ||
120
+ if (s->hstr_active || ri->accessfn ||
121
(arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
122
/* Emit code to perform further access permissions checks at
123
* runtime; this may result in an exception.
124
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
125
!arm_el_is_aa64(env, 3);
126
dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
127
dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
128
+ dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
129
dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
130
condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
131
dc->condexec_mask = (condexec & 0xf) << 1;
132
--
97
--
133
2.20.1
98
2.34.1
134
99
135
100
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
Each CS has its own Read Timing Compensation Register on newer SoCs.
3
I'm migrating to Qualcomm's new open source email infrastructure, so
4
update my email address, and update the mailmap to match.
4
5
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
6
Reviewed-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
8
Message-id: 20191119141211.25716-13-clg@kaod.org
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
include/hw/ssi/aspeed_smc.h | 1 +
14
MAINTAINERS | 2 +-
12
hw/ssi/aspeed_smc.c | 17 ++++++++++++++---
15
.mailmap | 5 +++--
13
2 files changed, 15 insertions(+), 3 deletions(-)
16
2 files changed, 4 insertions(+), 3 deletions(-)
14
17
15
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
18
diff --git a/MAINTAINERS b/MAINTAINERS
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/aspeed_smc.h
20
--- a/MAINTAINERS
18
+++ b/include/hw/ssi/aspeed_smc.h
21
+++ b/MAINTAINERS
19
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCController {
22
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
20
uint8_t r_ce_ctrl;
23
SBSA-REF
21
uint8_t r_ctrl0;
24
M: Radoslaw Biernacki <rad@semihalf.com>
22
uint8_t r_timings;
25
M: Peter Maydell <peter.maydell@linaro.org>
23
+ uint8_t nregs_timings;
26
-R: Leif Lindholm <quic_llindhol@quicinc.com>
24
uint8_t conf_enable_w0;
27
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
25
uint8_t max_slaves;
28
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
26
const AspeedSegments *segments;
29
L: qemu-arm@nongnu.org
27
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
30
S: Maintained
31
diff --git a/.mailmap b/.mailmap
28
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/ssi/aspeed_smc.c
33
--- a/.mailmap
30
+++ b/hw/ssi/aspeed_smc.c
34
+++ b/.mailmap
31
@@ -XXX,XX +XXX,XX @@
35
@@ -XXX,XX +XXX,XX @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
32
/* Checksum Calculation Result */
36
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
33
#define R_DMA_CHECKSUM (0x90 / 4)
37
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
34
38
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
35
-/* Misc Control Register #2 */
39
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
36
+/* Read Timing Compensation Register */
40
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
37
#define R_TIMINGS (0x94 / 4)
41
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
38
42
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
39
/* SPI controller registers and bits (AST2400) */
43
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
40
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
44
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
41
.r_ce_ctrl = R_CE_CTRL,
45
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
42
.r_ctrl0 = R_CTRL0,
46
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
43
.r_timings = R_TIMINGS,
44
+ .nregs_timings = 1,
45
.conf_enable_w0 = CONF_ENABLE_W0,
46
.max_slaves = 5,
47
.segments = aspeed_segments_legacy,
48
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
49
.r_ce_ctrl = R_CE_CTRL,
50
.r_ctrl0 = R_CTRL0,
51
.r_timings = R_TIMINGS,
52
+ .nregs_timings = 1,
53
.conf_enable_w0 = CONF_ENABLE_W0,
54
.max_slaves = 5,
55
.segments = aspeed_segments_fmc,
56
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
57
.r_ce_ctrl = 0xff,
58
.r_ctrl0 = R_SPI_CTRL0,
59
.r_timings = R_SPI_TIMINGS,
60
+ .nregs_timings = 1,
61
.conf_enable_w0 = SPI_CONF_ENABLE_W0,
62
.max_slaves = 1,
63
.segments = aspeed_segments_spi,
64
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
65
.r_ce_ctrl = R_CE_CTRL,
66
.r_ctrl0 = R_CTRL0,
67
.r_timings = R_TIMINGS,
68
+ .nregs_timings = 1,
69
.conf_enable_w0 = CONF_ENABLE_W0,
70
.max_slaves = 3,
71
.segments = aspeed_segments_ast2500_fmc,
72
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
73
.r_ce_ctrl = R_CE_CTRL,
74
.r_ctrl0 = R_CTRL0,
75
.r_timings = R_TIMINGS,
76
+ .nregs_timings = 1,
77
.conf_enable_w0 = CONF_ENABLE_W0,
78
.max_slaves = 2,
79
.segments = aspeed_segments_ast2500_spi1,
80
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
81
.r_ce_ctrl = R_CE_CTRL,
82
.r_ctrl0 = R_CTRL0,
83
.r_timings = R_TIMINGS,
84
+ .nregs_timings = 1,
85
.conf_enable_w0 = CONF_ENABLE_W0,
86
.max_slaves = 2,
87
.segments = aspeed_segments_ast2500_spi2,
88
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
89
.r_ce_ctrl = R_CE_CTRL,
90
.r_ctrl0 = R_CTRL0,
91
.r_timings = R_TIMINGS,
92
+ .nregs_timings = 1,
93
.conf_enable_w0 = CONF_ENABLE_W0,
94
.max_slaves = 3,
95
.segments = aspeed_segments_ast2600_fmc,
96
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
97
.r_ce_ctrl = R_CE_CTRL,
98
.r_ctrl0 = R_CTRL0,
99
.r_timings = R_TIMINGS,
100
+ .nregs_timings = 2,
101
.conf_enable_w0 = CONF_ENABLE_W0,
102
.max_slaves = 2,
103
.segments = aspeed_segments_ast2600_spi1,
104
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
105
.r_ce_ctrl = R_CE_CTRL,
106
.r_ctrl0 = R_CTRL0,
107
.r_timings = R_TIMINGS,
108
+ .nregs_timings = 3,
109
.conf_enable_w0 = CONF_ENABLE_W0,
110
.max_slaves = 3,
111
.segments = aspeed_segments_ast2600_spi2,
112
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
113
addr >>= 2;
114
115
if (addr == s->r_conf ||
116
- addr == s->r_timings ||
117
+ (addr >= s->r_timings &&
118
+ addr < s->r_timings + s->ctrl->nregs_timings) ||
119
addr == s->r_ce_ctrl ||
120
addr == R_INTR_CTRL ||
121
addr == R_DUMMY_DATA ||
122
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
123
addr >>= 2;
124
125
if (addr == s->r_conf ||
126
- addr == s->r_timings ||
127
+ (addr >= s->r_timings &&
128
+ addr < s->r_timings + s->ctrl->nregs_timings) ||
129
addr == s->r_ce_ctrl) {
130
s->regs[addr] = value;
131
} else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
132
--
47
--
133
2.20.1
48
2.34.1
134
49
135
50
diff view generated by jsdifflib
1
From: David Gibson <david@gibson.dropbear.id.au>
1
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
2
2
3
exynos4210_gic_realize() prints the number of cpus into some temporary
3
Previously, maintainer role was paused due to inactive email id. Commit id:
4
buffers, but it only allows 3 bytes space for it. That's plenty:
4
c009d715721861984c4987bcc78b7ee183e86d75.
5
existing machines will only ever set this value to EXYNOS4210_NCPUS
6
(2). But the compiler can't always figure that out, so some[*] gcc9
7
versions emit -Wformat-truncation warnings.
8
5
9
We can fix that by hinting the constraint to the compiler with a
6
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
10
suitably placed assert().
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
11
8
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
12
[*] The bizarre thing here, is that I've long gotten these warnings
13
compiling in a 32-bit x86 container as host - Fedora 30 with
14
gcc-9.2.1-1.fc30.i686 - but it compiles just fine on my normal
15
x86_64 host - Fedora 30 with and gcc-9.2.1-1.fc30.x86_64.
16
17
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
[PMM: deleted stray blank line]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
10
---
23
hw/intc/exynos4210_gic.c | 9 ++++++++-
11
MAINTAINERS | 2 ++
24
1 file changed, 8 insertions(+), 1 deletion(-)
12
1 file changed, 2 insertions(+)
25
13
26
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
14
diff --git a/MAINTAINERS b/MAINTAINERS
27
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/exynos4210_gic.c
16
--- a/MAINTAINERS
29
+++ b/hw/intc/exynos4210_gic.c
17
+++ b/MAINTAINERS
30
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-sb16-test.c
31
char cpu_alias_name[sizeof(cpu_prefix) + 3];
19
32
char dist_alias_name[sizeof(cpu_prefix) + 3];
20
Xilinx CAN
33
SysBusDevice *gicbusdev;
21
M: Francisco Iglesias <francisco.iglesias@amd.com>
34
+ uint32_t n = s->num_cpu;
22
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
35
uint32_t i;
23
S: Maintained
36
24
F: hw/net/can/xlnx-*
37
s->gic = qdev_create(NULL, "arm_gic");
25
F: include/hw/net/xlnx-*
38
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
26
@@ -XXX,XX +XXX,XX @@ F: include/hw/rx/
39
memory_region_init(&s->dist_container, obj, "exynos4210-dist-container",
27
CAN bus subsystem and hardware
40
EXYNOS4210_EXT_GIC_DIST_REGION_SIZE);
28
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
41
29
M: Francisco Iglesias <francisco.iglesias@amd.com>
42
- for (i = 0; i < s->num_cpu; i++) {
30
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
43
+ /*
31
S: Maintained
44
+ * This clues in gcc that our on-stack buffers do, in fact have
32
W: https://canbus.pages.fel.cvut.cz/
45
+ * enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
33
F: net/can/*
46
+ * doesn't figure this out, otherwise and gives spurious warnings.
47
+ */
48
+ assert(n <= EXYNOS4210_NCPUS);
49
+ for (i = 0; i < n; i++) {
50
/* Map CPU interface per SMP Core */
51
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
52
memory_region_init_alias(&s->cpu_alias[i], obj,
53
--
34
--
54
2.20.1
35
2.34.1
55
56
diff view generated by jsdifflib