1
The following changes since commit dccbaf0cc0f1744ffd7562a3dc60e4fc99fd9d44:
1
First arm pullreq of the cycle; this is mostly my softfloat NaN
2
handling series. (Lots more in my to-review queue, but I don't
3
like pullreqs growing too close to a hundred patches at a time :-))
2
4
3
Merge tag 'hw-misc-20240227' of https://github.com/philmd/qemu into staging (2024-02-27 10:11:07 +0000)
5
thanks
6
-- PMM
7
8
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
9
10
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240227
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
8
15
9
for you to fetch changes up to 48f471ab5450ef8981298e39583118729f6b2aa2:
16
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
10
17
11
docs/system/arm: Add RPi4B to raspi.rst (2024-02-27 13:01:43 +0000)
18
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
target-arm queue:
21
target-arm queue:
15
* Handle atomic updates of page tables entries in MMIO during PTW
22
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
16
* Advertise Cortex-A53 erratum #843419 fix via REVIDR
23
* fpu: Make muladd NaN handling runtime-selected, not compile-time
17
* MAINTAINERS: Cover hw/ide/ahci-allwinner.c with AllWinner A10 machine
24
* fpu: Make default NaN pattern runtime-selected, not compile-time
18
* misc: m48t59: replace qemu_system_reset_request() call with watchdog_perform_action()
25
* fpu: Minor NaN-related cleanups
19
* misc: pxa2xx_timer: replace qemu_system_reset_request() call with watchdog_perform_action()
26
* MAINTAINERS: email address updates
20
* xlnx-versal-ospi: disable reentrancy detection for iomem_dac
21
* sbsa-ref: Simplify init since PCIe is always enabled
22
* stm32l4x5: Use TYPE_OR_IRQ when connecting STM32L4x5 EXTI fan-in IRQs
23
* pl031: Update last RTCLR value on write in case it's read back
24
* block: m25p80: Add support of mt35xu02gbba
25
* xlnx-versal-virt: Add machine property ospi-flash
26
* reset: refactor system reset to be three-phase aware
27
* new board model raspi4b
28
27
29
----------------------------------------------------------------
28
----------------------------------------------------------------
30
Abhiram Tilak (2):
29
Bernhard Beschow (5):
31
misc: m48t59: replace qemu_system_reset_request() call with watchdog_perform_action()
30
hw/net/lan9118: Extract lan9118_phy
32
misc: pxa2xx_timer: replace qemu_system_reset_request() call with watchdog_perform_action()
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
Ard Biesheuvel (1):
36
Leif Lindholm (1):
35
target/arm: Advertise Cortex-A53 erratum #843419 fix via REVIDR
37
MAINTAINERS: update email address for Leif Lindholm
36
38
37
Inès Varhol (2):
39
Peter Maydell (54):
38
hw/arm: Use TYPE_OR_IRQ when connecting STM32L4x5 EXTI fan-in IRQs
40
fpu: handle raising Invalid for infzero in pick_nan_muladd
39
tests/qtest: Check that EXTI fan-in irqs are correctly connected
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
40
94
41
Jessica Clarke (1):
95
Richard Henderson (11):
42
pl031: Update last RTCLR value on write in case it's read back
96
target/arm: Copy entire float_status in is_ebf
97
softfloat: Inline pickNaNMulAdd
98
softfloat: Use goto for default nan case in pick_nan_muladd
99
softfloat: Remove which from parts_pick_nan_muladd
100
softfloat: Pad array size in pick_nan_muladd
101
softfloat: Move propagateFloatx80NaN to softfloat.c
102
softfloat: Use parts_pick_nan in propagateFloatx80NaN
103
softfloat: Inline pickNaN
104
softfloat: Share code between parts_pick_nan cases
105
softfloat: Sink frac_cmp in parts_pick_nan until needed
106
softfloat: Replace WHICH with RET in parts_pick_nan
43
107
44
Jonathan Cameron (1):
108
Vikram Garhwal (1):
45
arm/ptw: Handle atomic updates of page tables entries in MMIO during PTW.
109
MAINTAINERS: Add correct email address for Vikram Garhwal
46
110
47
Marcin Juszkiewicz (1):
111
MAINTAINERS | 4 +-
48
hw/arm/sbsa-ref: Simplify init since PCIe is always enabled
112
include/fpu/softfloat-helpers.h | 38 +++-
49
113
include/fpu/softfloat-types.h | 89 +++++++-
50
Peter Maydell (9):
114
include/hw/net/imx_fec.h | 9 +-
51
system/bootdevice: Don't unregister reset handler in restore_boot_order()
115
include/hw/net/lan9118_phy.h | 37 ++++
52
include/qom/object.h: New OBJECT_DEFINE_SIMPLE_TYPE{, _WITH_INTERFACES} macros
116
include/hw/net/mii.h | 6 +
53
hw/core: Add documentation and license comments to reset.h
117
target/mips/fpu_helper.h | 20 ++
54
hw/core: Add ResetContainer which holds objects implementing Resettable
118
target/sparc/helper.h | 4 +-
55
hw/core/reset: Add qemu_{register, unregister}_resettable()
119
fpu/softfloat.c | 19 ++
56
hw/core/reset: Implement qemu_register_reset via qemu_register_resettable
120
hw/net/imx_fec.c | 146 ++------------
57
hw/core/machine: Use qemu_register_resettable for sysbus reset
121
hw/net/lan9118.c | 137 ++-----------
58
docs/devel/reset: Update to discuss system reset
122
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
59
tests/avocado/boot_linux_console.py: Add Rpi4b boot tests
123
linux-user/arm/nwfpe/fpa11.c | 5 +
60
124
target/alpha/cpu.c | 2 +
61
Philippe Mathieu-Daudé (1):
125
target/arm/cpu.c | 10 +
62
MAINTAINERS: Cover hw/ide/ahci-allwinner.c with AllWinner A10 machine
126
target/arm/tcg/vec_helper.c | 20 +-
63
127
target/hexagon/cpu.c | 2 +
64
Sai Pavan Boddu (3):
128
target/hppa/fpu_helper.c | 12 ++
65
xlnx-versal-ospi: disable reentrancy detection for iomem_dac
129
target/i386/tcg/fpu_helper.c | 12 ++
66
block: m25p80: Add support of mt35xu02gbba
130
target/loongarch/tcg/fpu_helper.c | 14 +-
67
arm: xlnx-versal-virt: Add machine property ospi-flash
131
target/m68k/cpu.c | 14 +-
68
132
target/m68k/fpu_helper.c | 6 +-
69
Sergey Kambalin (24):
133
target/m68k/helper.c | 6 +-
70
hw/arm/bcm2836: Split out common part of BCM283X classes
134
target/microblaze/cpu.c | 2 +
71
hw/arm/bcm2853_peripherals: Split out common part of peripherals
135
target/mips/msa.c | 10 +
72
hw/arm/raspi: Split out raspi machine common part
136
target/openrisc/cpu.c | 2 +
73
hw/arm: Introduce BCM2838 SoC
137
target/ppc/cpu_init.c | 19 ++
74
hw/arm/bcm2838: Add GIC-400 to BCM2838 SoC
138
target/ppc/fpu_helper.c | 3 +-
75
hw/gpio: Add BCM2838 GPIO stub
139
target/riscv/cpu.c | 2 +
76
hw/gpio: Implement BCM2838 GPIO functionality
140
target/rx/cpu.c | 2 +
77
hw/gpio: Connect SD controller to BCM2838 GPIO
141
target/s390x/cpu.c | 5 +
78
hw/arm: Add GPIO and SD to BCM2838 periph
142
target/sh4/cpu.c | 2 +
79
hw/arm: Introduce Raspberry PI 4 machine
143
target/sparc/cpu.c | 6 +
80
hw/arm/raspi4b: Temporarily disable unimplemented rpi4b devices
144
target/sparc/fop_helper.c | 8 +-
81
hw/arm: Add memory region for BCM2837 RPiVid ASB
145
target/sparc/translate.c | 4 +-
82
hw/arm/bcm2838_peripherals: Add clock_isp stub
146
target/tricore/helper.c | 2 +
83
tests/qtest: Add bcm2838 mailbox test stub
147
target/xtensa/cpu.c | 4 +
84
tests/qtest/bcm2828-mailbox: Add mailbox test constants
148
target/xtensa/fpu_helper.c | 3 +-
85
tests/qtest/bcm2828-mailbox: Add mailbox tests tags. Part 1
149
tests/fp/fp-bench.c | 7 +
86
tests/qtest/bcm2828-mailbox: Add mailbox tests tags. Part 2
150
tests/fp/fp-test-log2.c | 1 +
87
tests/qtest/bcm2828-mailbox: Add mailbox tests tags. Part 3
151
tests/fp/fp-test.c | 7 +
88
tests/qtest/bcm2828-mailbox: Add mailbox property tests. Part 1
152
fpu/softfloat-parts.c.inc | 152 +++++++++++---
89
tests/qtest/bcm2828-mailbox: Add mailbox property tests. Part 2
153
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
90
tests/qtest/bcm2828-mailbox: Add mailbox property tests. Part 3
154
.mailmap | 5 +-
91
hw/misc/bcm2835_property: Add missed BCM2835 properties
155
hw/net/Kconfig | 5 +
92
tests/qtest/bcm2828-mailbox: Append added properties to mailbox test
156
hw/net/meson.build | 1 +
93
docs/system/arm: Add RPi4B to raspi.rst
157
hw/net/trace-events | 10 +-
94
158
47 files changed, 778 insertions(+), 730 deletions(-)
95
MAINTAINERS | 11 +
159
create mode 100644 include/hw/net/lan9118_phy.h
96
docs/devel/qom.rst | 34 +-
160
create mode 100644 hw/net/lan9118_phy.c
97
docs/devel/reset.rst | 44 ++-
98
docs/system/arm/raspi.rst | 12 +-
99
hw/block/m25p80_sfdp.h | 1 +
100
include/hw/arm/bcm2835_peripherals.h | 29 +-
101
include/hw/arm/bcm2836.h | 27 +-
102
include/hw/arm/bcm2838.h | 31 ++
103
include/hw/arm/bcm2838_peripherals.h | 84 ++++
104
include/hw/arm/raspberrypi-fw-defs.h | 11 +
105
include/hw/arm/raspi_platform.h | 38 +-
106
include/hw/arm/stm32l4x5_soc.h | 4 +
107
include/hw/core/resetcontainer.h | 48 +++
108
include/hw/display/bcm2835_fb.h | 2 +
109
include/hw/gpio/bcm2838_gpio.h | 45 +++
110
include/qom/object.h | 114 ++++--
111
include/sysemu/reset.h | 113 ++++++
112
tests/qtest/bcm2838-mailbox.h | 532 ++++++++++++++++++++++++++
113
hw/arm/bcm2835_peripherals.c | 215 ++++++-----
114
hw/arm/bcm2836.c | 117 +++---
115
hw/arm/bcm2838.c | 263 +++++++++++++
116
hw/arm/bcm2838_peripherals.c | 224 +++++++++++
117
hw/arm/raspi.c | 130 ++++---
118
hw/arm/raspi4b.c | 132 +++++++
119
hw/arm/sbsa-ref.c | 5 +-
120
hw/arm/stm32l4x5_soc.c | 80 +++-
121
hw/arm/xlnx-versal-virt.c | 44 ++-
122
hw/block/m25p80.c | 3 +
123
hw/block/m25p80_sfdp.c | 36 ++
124
hw/core/machine.c | 7 +-
125
hw/core/reset.c | 166 ++++++--
126
hw/core/resetcontainer.c | 77 ++++
127
hw/gpio/bcm2838_gpio.c | 390 +++++++++++++++++++
128
hw/misc/bcm2835_property.c | 21 +
129
hw/rtc/m48t59.c | 4 +-
130
hw/rtc/pl031.c | 1 +
131
hw/ssi/xlnx-versal-ospi.c | 6 +
132
hw/timer/pxa2xx_timer.c | 3 +-
133
system/bootdevice.c | 25 +-
134
target/arm/cpu64.c | 2 +-
135
target/arm/ptw.c | 64 +++-
136
tests/qtest/bcm2838-mailbox.c | 60 +++
137
tests/qtest/bcm2838-mbox-property-test.c | 631 +++++++++++++++++++++++++++++++
138
tests/qtest/stm32l4x5_exti-test.c | 37 ++
139
hw/arm/meson.build | 2 +
140
hw/arm/trace-events | 3 +
141
hw/core/meson.build | 1 +
142
hw/gpio/meson.build | 5 +-
143
tests/avocado/boot_linux_console.py | 97 +++++
144
tests/qtest/meson.build | 3 +-
145
50 files changed, 3728 insertions(+), 306 deletions(-)
146
create mode 100644 include/hw/arm/bcm2838.h
147
create mode 100644 include/hw/arm/bcm2838_peripherals.h
148
create mode 100644 include/hw/core/resetcontainer.h
149
create mode 100644 include/hw/gpio/bcm2838_gpio.h
150
create mode 100644 tests/qtest/bcm2838-mailbox.h
151
create mode 100644 hw/arm/bcm2838.c
152
create mode 100644 hw/arm/bcm2838_peripherals.c
153
create mode 100644 hw/arm/raspi4b.c
154
create mode 100644 hw/core/resetcontainer.c
155
create mode 100644 hw/gpio/bcm2838_gpio.c
156
create mode 100644 tests/qtest/bcm2838-mailbox.c
157
create mode 100644 tests/qtest/bcm2838-mbox-property-test.c
158
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
3
A very similar implementation of the same device exists in imx_fec. Prepare for
4
a common implementation by extracting a device model into its own files.
5
6
Some migration state has been moved into the new device model which breaks
7
migration compatibility for the following machines:
8
* smdkc210
9
* realview-*
10
* vexpress-*
11
* kzm
12
* mps2-*
13
14
While breaking migration ABI, fix the size of the MII registers to be 16 bit,
15
as defined by IEEE 802.3u.
16
17
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
18
Tested-by: Guenter Roeck <linux@roeck-us.net>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240226000259.2752893-7-sergey.kambalin@auriga.com
20
Message-id: 20241102125724.532843-2-shentey@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
22
---
8
include/hw/gpio/bcm2838_gpio.h | 40 +++++++++
23
include/hw/net/lan9118_phy.h | 37 ++++++++
9
hw/gpio/bcm2838_gpio.c | 153 +++++++++++++++++++++++++++++++++
24
hw/net/lan9118.c | 137 +++++-----------------------
10
hw/gpio/meson.build | 5 +-
25
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
11
3 files changed, 197 insertions(+), 1 deletion(-)
26
hw/net/Kconfig | 4 +
12
create mode 100644 include/hw/gpio/bcm2838_gpio.h
27
hw/net/meson.build | 1 +
13
create mode 100644 hw/gpio/bcm2838_gpio.c
28
5 files changed, 233 insertions(+), 115 deletions(-)
29
create mode 100644 include/hw/net/lan9118_phy.h
30
create mode 100644 hw/net/lan9118_phy.c
14
31
15
diff --git a/include/hw/gpio/bcm2838_gpio.h b/include/hw/gpio/bcm2838_gpio.h
32
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
16
new file mode 100644
33
new file mode 100644
17
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
18
--- /dev/null
35
--- /dev/null
19
+++ b/include/hw/gpio/bcm2838_gpio.h
36
+++ b/include/hw/net/lan9118_phy.h
20
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
21
+/*
38
+/*
22
+ * Raspberry Pi (BCM2838) GPIO Controller
39
+ * SMSC LAN9118 PHY emulation
23
+ * This implementation is based on bcm2835_gpio (hw/gpio/bcm2835_gpio.c)
24
+ *
40
+ *
25
+ * Copyright (c) 2022 Auriga LLC
41
+ * Copyright (c) 2009 CodeSourcery, LLC.
26
+ *
42
+ * Written by Paul Brook
27
+ * Authors:
28
+ * Lotosh, Aleksey <aleksey.lotosh@auriga.com>
29
+ *
43
+ *
30
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
31
+ * See the COPYING file in the top-level directory.
45
+ * See the COPYING file in the top-level directory.
32
+ */
46
+ */
33
+
47
+
34
+#ifndef BCM2838_GPIO_H
48
+#ifndef HW_NET_LAN9118_PHY_H
35
+#define BCM2838_GPIO_H
49
+#define HW_NET_LAN9118_PHY_H
36
+
50
+
51
+#include "qom/object.h"
37
+#include "hw/sysbus.h"
52
+#include "hw/sysbus.h"
38
+#include "qom/object.h"
53
+
39
+
54
+#define TYPE_LAN9118_PHY "lan9118-phy"
40
+#define TYPE_BCM2838_GPIO "bcm2838-gpio"
55
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
41
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2838GpioState, BCM2838_GPIO)
56
+
42
+
57
+typedef struct Lan9118PhyState {
43
+#define BCM2838_GPIO_REGS_SIZE 0x1000
44
+#define BCM2838_GPIO_NUM 58
45
+#define GPIO_PUP_PDN_CNTRL_NUM 4
46
+
47
+struct BCM2838GpioState {
48
+ SysBusDevice parent_obj;
58
+ SysBusDevice parent_obj;
49
+
59
+
50
+ MemoryRegion iomem;
60
+ uint16_t status;
51
+
61
+ uint16_t control;
52
+
62
+ uint16_t advertise;
53
+ uint8_t fsel[BCM2838_GPIO_NUM];
63
+ uint16_t ints;
54
+ uint32_t lev0, lev1;
64
+ uint16_t int_mask;
55
+ uint8_t sd_fsel;
65
+ qemu_irq irq;
56
+ qemu_irq out[BCM2838_GPIO_NUM];
66
+ bool link_down;
57
+ uint32_t pup_cntrl_reg[GPIO_PUP_PDN_CNTRL_NUM];
67
+} Lan9118PhyState;
58
+};
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);
59
+
73
+
60
+#endif
74
+#endif
61
diff --git a/hw/gpio/bcm2838_gpio.c b/hw/gpio/bcm2838_gpio.c
75
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/net/lan9118.c
78
+++ b/hw/net/lan9118.c
79
@@ -XXX,XX +XXX,XX @@
80
#include "net/net.h"
81
#include "net/eth.h"
82
#include "hw/irq.h"
83
+#include "hw/net/lan9118_phy.h"
84
#include "hw/net/lan9118.h"
85
#include "hw/ptimer.h"
86
#include "hw/qdev-properties.h"
87
@@ -XXX,XX +XXX,XX @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
88
#define MAC_CR_RXEN 0x00000004
89
#define MAC_CR_RESERVED 0x7f404213
90
91
-#define PHY_INT_ENERGYON 0x80
92
-#define PHY_INT_AUTONEG_COMPLETE 0x40
93
-#define PHY_INT_FAULT 0x20
94
-#define PHY_INT_DOWN 0x10
95
-#define PHY_INT_AUTONEG_LP 0x08
96
-#define PHY_INT_PARFAULT 0x04
97
-#define PHY_INT_AUTONEG_PAGE 0x02
98
-
99
#define GPT_TIMER_EN 0x20000000
100
101
/*
102
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
103
uint32_t mac_mii_data;
104
uint32_t mac_flow;
105
106
- uint32_t phy_status;
107
- uint32_t phy_control;
108
- uint32_t phy_advertise;
109
- uint32_t phy_int;
110
- uint32_t phy_int_mask;
111
+ Lan9118PhyState mii;
112
+ IRQState mii_irq;
113
114
int32_t eeprom_writable;
115
uint8_t eeprom[128];
116
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
117
118
static const VMStateDescription vmstate_lan9118 = {
119
.name = "lan9118",
120
- .version_id = 2,
121
- .minimum_version_id = 1,
122
+ .version_id = 3,
123
+ .minimum_version_id = 3,
124
.fields = (const VMStateField[]) {
125
VMSTATE_PTIMER(timer, lan9118_state),
126
VMSTATE_UINT32(irq_cfg, lan9118_state),
127
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118 = {
128
VMSTATE_UINT32(mac_mii_acc, lan9118_state),
129
VMSTATE_UINT32(mac_mii_data, lan9118_state),
130
VMSTATE_UINT32(mac_flow, lan9118_state),
131
- VMSTATE_UINT32(phy_status, lan9118_state),
132
- VMSTATE_UINT32(phy_control, lan9118_state),
133
- VMSTATE_UINT32(phy_advertise, lan9118_state),
134
- VMSTATE_UINT32(phy_int, lan9118_state),
135
- VMSTATE_UINT32(phy_int_mask, lan9118_state),
136
VMSTATE_INT32(eeprom_writable, lan9118_state),
137
VMSTATE_UINT8_ARRAY(eeprom, lan9118_state, 128),
138
VMSTATE_INT32(tx_fifo_size, lan9118_state),
139
@@ -XXX,XX +XXX,XX @@ static void lan9118_reload_eeprom(lan9118_state *s)
140
lan9118_mac_changed(s);
141
}
142
143
-static void phy_update_irq(lan9118_state *s)
144
+static void lan9118_update_irq(void *opaque, int n, int level)
145
{
146
- if (s->phy_int & s->phy_int_mask) {
147
+ lan9118_state *s = opaque;
148
+
149
+ if (level) {
150
s->int_sts |= PHY_INT;
151
} else {
152
s->int_sts &= ~PHY_INT;
153
@@ -XXX,XX +XXX,XX @@ static void phy_update_irq(lan9118_state *s)
154
lan9118_update(s);
155
}
156
157
-static void phy_update_link(lan9118_state *s)
158
-{
159
- /* Autonegotiation status mirrors link status. */
160
- if (qemu_get_queue(s->nic)->link_down) {
161
- s->phy_status &= ~0x0024;
162
- s->phy_int |= PHY_INT_DOWN;
163
- } else {
164
- s->phy_status |= 0x0024;
165
- s->phy_int |= PHY_INT_ENERGYON;
166
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
167
- }
168
- phy_update_irq(s);
169
-}
170
-
171
static void lan9118_set_link(NetClientState *nc)
172
{
173
- phy_update_link(qemu_get_nic_opaque(nc));
174
-}
175
-
176
-static void phy_reset(lan9118_state *s)
177
-{
178
- s->phy_status = 0x7809;
179
- s->phy_control = 0x3000;
180
- s->phy_advertise = 0x01e1;
181
- s->phy_int_mask = 0;
182
- s->phy_int = 0;
183
- phy_update_link(s);
184
+ lan9118_phy_update_link(&LAN9118(qemu_get_nic_opaque(nc))->mii,
185
+ nc->link_down);
186
}
187
188
static void lan9118_reset(DeviceState *d)
189
@@ -XXX,XX +XXX,XX @@ static void lan9118_reset(DeviceState *d)
190
s->read_word_n = 0;
191
s->write_word_n = 0;
192
193
- phy_reset(s);
194
-
195
s->eeprom_writable = 0;
196
lan9118_reload_eeprom(s);
197
}
198
@@ -XXX,XX +XXX,XX @@ static void do_tx_packet(lan9118_state *s)
199
uint32_t status;
200
201
/* FIXME: Honor TX disable, and allow queueing of packets. */
202
- if (s->phy_control & 0x4000) {
203
+ if (s->mii.control & 0x4000) {
204
/* This assumes the receive routine doesn't touch the VLANClient. */
205
qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
206
} else {
207
@@ -XXX,XX +XXX,XX @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
208
}
209
}
210
211
-static uint32_t do_phy_read(lan9118_state *s, int reg)
212
-{
213
- uint32_t val;
214
-
215
- switch (reg) {
216
- case 0: /* Basic Control */
217
- return s->phy_control;
218
- case 1: /* Basic Status */
219
- return s->phy_status;
220
- case 2: /* ID1 */
221
- return 0x0007;
222
- case 3: /* ID2 */
223
- return 0xc0d1;
224
- case 4: /* Auto-neg advertisement */
225
- return s->phy_advertise;
226
- case 5: /* Auto-neg Link Partner Ability */
227
- return 0x0f71;
228
- case 6: /* Auto-neg Expansion */
229
- return 1;
230
- /* TODO 17, 18, 27, 29, 30, 31 */
231
- case 29: /* Interrupt source. */
232
- val = s->phy_int;
233
- s->phy_int = 0;
234
- phy_update_irq(s);
235
- return val;
236
- case 30: /* Interrupt mask */
237
- return s->phy_int_mask;
238
- default:
239
- qemu_log_mask(LOG_GUEST_ERROR,
240
- "do_phy_read: PHY read reg %d\n", reg);
241
- return 0;
242
- }
243
-}
244
-
245
-static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
246
-{
247
- switch (reg) {
248
- case 0: /* Basic Control */
249
- if (val & 0x8000) {
250
- phy_reset(s);
251
- break;
252
- }
253
- s->phy_control = val & 0x7980;
254
- /* Complete autonegotiation immediately. */
255
- if (val & 0x1000) {
256
- s->phy_status |= 0x0020;
257
- }
258
- break;
259
- case 4: /* Auto-neg advertisement */
260
- s->phy_advertise = (val & 0x2d7f) | 0x80;
261
- break;
262
- /* TODO 17, 18, 27, 31 */
263
- case 30: /* Interrupt mask */
264
- s->phy_int_mask = val & 0xff;
265
- phy_update_irq(s);
266
- break;
267
- default:
268
- qemu_log_mask(LOG_GUEST_ERROR,
269
- "do_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
270
- }
271
-}
272
-
273
static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
274
{
275
switch (reg) {
276
@@ -XXX,XX +XXX,XX @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
277
if (val & 2) {
278
DPRINTF("PHY write %d = 0x%04x\n",
279
(val >> 6) & 0x1f, s->mac_mii_data);
280
- do_phy_write(s, (val >> 6) & 0x1f, s->mac_mii_data);
281
+ lan9118_phy_write(&s->mii, (val >> 6) & 0x1f, s->mac_mii_data);
282
} else {
283
- s->mac_mii_data = do_phy_read(s, (val >> 6) & 0x1f);
284
+ s->mac_mii_data = lan9118_phy_read(&s->mii, (val >> 6) & 0x1f);
285
DPRINTF("PHY read %d = 0x%04x\n",
286
(val >> 6) & 0x1f, s->mac_mii_data);
287
}
288
@@ -XXX,XX +XXX,XX @@ static void lan9118_writel(void *opaque, hwaddr offset,
289
break;
290
case CSR_PMT_CTRL:
291
if (val & 0x400) {
292
- phy_reset(s);
293
+ lan9118_phy_reset(&s->mii);
294
}
295
s->pmt_ctrl &= ~0x34e;
296
s->pmt_ctrl |= (val & 0x34e);
297
@@ -XXX,XX +XXX,XX @@ static void lan9118_realize(DeviceState *dev, Error **errp)
298
const MemoryRegionOps *mem_ops =
299
s->mode_16bit ? &lan9118_16bit_mem_ops : &lan9118_mem_ops;
300
301
+ qemu_init_irq(&s->mii_irq, lan9118_update_irq, s, 0);
302
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
303
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
304
+ return;
305
+ }
306
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
307
+
308
memory_region_init_io(&s->mmio, OBJECT(dev), mem_ops, s,
309
"lan9118-mmio", 0x100);
310
sysbus_init_mmio(sbd, &s->mmio);
311
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
62
new file mode 100644
312
new file mode 100644
63
index XXXXXXX..XXXXXXX
313
index XXXXXXX..XXXXXXX
64
--- /dev/null
314
--- /dev/null
65
+++ b/hw/gpio/bcm2838_gpio.c
315
+++ b/hw/net/lan9118_phy.c
66
@@ -XXX,XX +XXX,XX @@
316
@@ -XXX,XX +XXX,XX @@
67
+/*
317
+/*
68
+ * Raspberry Pi (BCM2838) GPIO Controller
318
+ * SMSC LAN9118 PHY emulation
69
+ * This implementation is based on bcm2835_gpio (hw/gpio/bcm2835_gpio.c)
70
+ *
319
+ *
71
+ * Copyright (c) 2022 Auriga LLC
320
+ * Copyright (c) 2009 CodeSourcery, LLC.
321
+ * Written by Paul Brook
72
+ *
322
+ *
73
+ * Authors:
323
+ * This code is licensed under the GNU GPL v2
74
+ * Lotosh, Aleksey <aleksey.lotosh@auriga.com>
75
+ *
324
+ *
76
+ * SPDX-License-Identifier: GPL-2.0-or-later
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.
77
+ */
327
+ */
78
+
328
+
79
+#include "qemu/osdep.h"
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"
80
+#include "qemu/log.h"
334
+#include "qemu/log.h"
81
+#include "qemu/module.h"
335
+
82
+#include "qemu/timer.h"
336
+#define PHY_INT_ENERGYON (1 << 7)
83
+#include "qapi/error.h"
337
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
84
+#include "hw/sysbus.h"
338
+#define PHY_INT_FAULT (1 << 5)
85
+#include "migration/vmstate.h"
339
+#define PHY_INT_DOWN (1 << 4)
86
+#include "hw/gpio/bcm2838_gpio.h"
340
+#define PHY_INT_AUTONEG_LP (1 << 3)
87
+
341
+#define PHY_INT_PARFAULT (1 << 2)
88
+#define GPFSEL0 0x00
342
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
89
+#define GPFSEL1 0x04
343
+
90
+#define GPFSEL2 0x08
344
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
91
+#define GPFSEL3 0x0C
345
+{
92
+#define GPFSEL4 0x10
346
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
93
+#define GPFSEL5 0x14
347
+}
94
+#define GPSET0 0x1C
348
+
95
+#define GPSET1 0x20
349
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
96
+#define GPCLR0 0x28
350
+{
97
+#define GPCLR1 0x2C
351
+ uint16_t val;
98
+#define GPLEV0 0x34
352
+
99
+#define GPLEV1 0x38
353
+ switch (reg) {
100
+#define GPEDS0 0x40
354
+ case 0: /* Basic Control */
101
+#define GPEDS1 0x44
355
+ return s->control;
102
+#define GPREN0 0x4C
356
+ case 1: /* Basic Status */
103
+#define GPREN1 0x50
357
+ return s->status;
104
+#define GPFEN0 0x58
358
+ case 2: /* ID1 */
105
+#define GPFEN1 0x5C
359
+ return 0x0007;
106
+#define GPHEN0 0x64
360
+ case 3: /* ID2 */
107
+#define GPHEN1 0x68
361
+ return 0xc0d1;
108
+#define GPLEN0 0x70
362
+ case 4: /* Auto-neg advertisement */
109
+#define GPLEN1 0x74
363
+ return s->advertise;
110
+#define GPAREN0 0x7C
364
+ case 5: /* Auto-neg Link Partner Ability */
111
+#define GPAREN1 0x80
365
+ return 0x0f71;
112
+#define GPAFEN0 0x88
366
+ case 6: /* Auto-neg Expansion */
113
+#define GPAFEN1 0x8C
367
+ return 1;
114
+
368
+ /* TODO 17, 18, 27, 29, 30, 31 */
115
+#define GPIO_PUP_PDN_CNTRL_REG0 0xE4
369
+ case 29: /* Interrupt source. */
116
+#define GPIO_PUP_PDN_CNTRL_REG1 0xE8
370
+ val = s->ints;
117
+#define GPIO_PUP_PDN_CNTRL_REG2 0xEC
371
+ s->ints = 0;
118
+#define GPIO_PUP_PDN_CNTRL_REG3 0xF0
372
+ lan9118_phy_update_irq(s);
119
+
373
+ return val;
120
+#define RESET_VAL_CNTRL_REG0 0xAAA95555
374
+ case 30: /* Interrupt mask */
121
+#define RESET_VAL_CNTRL_REG1 0xA0AAAAAA
375
+ return s->int_mask;
122
+#define RESET_VAL_CNTRL_REG2 0x50AAA95A
376
+ default:
123
+#define RESET_VAL_CNTRL_REG3 0x00055555
377
+ qemu_log_mask(LOG_GUEST_ERROR,
124
+
378
+ "lan9118_phy_read: PHY read reg %d\n", reg);
125
+#define BYTES_IN_WORD 4
379
+ return 0;
126
+
380
+ }
127
+static uint64_t bcm2838_gpio_read(void *opaque, hwaddr offset, unsigned size)
381
+}
128
+{
382
+
129
+ uint64_t value = 0;
383
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
130
+
384
+{
131
+ qemu_log_mask(LOG_UNIMP, "%s: %s: not implemented for %"HWADDR_PRIx"\n",
385
+ switch (reg) {
132
+ TYPE_BCM2838_GPIO, __func__, offset);
386
+ case 0: /* Basic Control */
133
+
387
+ if (val & 0x8000) {
134
+ return value;
388
+ lan9118_phy_reset(s);
135
+}
389
+ break;
136
+
390
+ }
137
+static void bcm2838_gpio_write(void *opaque, hwaddr offset, uint64_t value,
391
+ s->control = val & 0x7980;
138
+ unsigned size)
392
+ /* Complete autonegotiation immediately. */
139
+{
393
+ if (val & 0x1000) {
140
+ qemu_log_mask(LOG_UNIMP, "%s: %s: not implemented for %"HWADDR_PRIx"\n",
394
+ s->status |= 0x0020;
141
+ TYPE_BCM2838_GPIO, __func__, offset);
395
+ }
142
+}
396
+ break;
143
+
397
+ case 4: /* Auto-neg advertisement */
144
+static void bcm2838_gpio_reset(DeviceState *dev)
398
+ s->advertise = (val & 0x2d7f) | 0x80;
145
+{
399
+ break;
146
+ BCM2838GpioState *s = BCM2838_GPIO(dev);
400
+ /* TODO 17, 18, 27, 31 */
147
+
401
+ case 30: /* Interrupt mask */
148
+ s->lev0 = 0;
402
+ s->int_mask = val & 0xff;
149
+ s->lev1 = 0;
403
+ lan9118_phy_update_irq(s);
150
+
404
+ break;
151
+ memset(s->fsel, 0, sizeof(s->fsel));
405
+ default:
152
+
406
+ qemu_log_mask(LOG_GUEST_ERROR,
153
+ s->pup_cntrl_reg[0] = RESET_VAL_CNTRL_REG0;
407
+ "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
154
+ s->pup_cntrl_reg[1] = RESET_VAL_CNTRL_REG1;
408
+ }
155
+ s->pup_cntrl_reg[2] = RESET_VAL_CNTRL_REG2;
409
+}
156
+ s->pup_cntrl_reg[3] = RESET_VAL_CNTRL_REG3;
410
+
157
+}
411
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
158
+
412
+{
159
+static const MemoryRegionOps bcm2838_gpio_ops = {
413
+ s->link_down = link_down;
160
+ .read = bcm2838_gpio_read,
414
+
161
+ .write = bcm2838_gpio_write,
415
+ /* Autonegotiation status mirrors link status. */
162
+ .endianness = DEVICE_NATIVE_ENDIAN,
416
+ if (link_down) {
163
+};
417
+ s->status &= ~0x0024;
164
+
418
+ s->ints |= PHY_INT_DOWN;
165
+static const VMStateDescription vmstate_bcm2838_gpio = {
419
+ } else {
166
+ .name = "bcm2838_gpio",
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",
167
+ .version_id = 1,
453
+ .version_id = 1,
168
+ .minimum_version_id = 1,
454
+ .minimum_version_id = 1,
169
+ .fields = (VMStateField[]) {
455
+ .fields = (const VMStateField[]) {
170
+ VMSTATE_UINT8_ARRAY(fsel, BCM2838GpioState, BCM2838_GPIO_NUM),
456
+ VMSTATE_UINT16(control, Lan9118PhyState),
171
+ VMSTATE_UINT32(lev0, BCM2838GpioState),
457
+ VMSTATE_UINT16(status, Lan9118PhyState),
172
+ VMSTATE_UINT32(lev1, BCM2838GpioState),
458
+ VMSTATE_UINT16(advertise, Lan9118PhyState),
173
+ VMSTATE_UINT8(sd_fsel, BCM2838GpioState),
459
+ VMSTATE_UINT16(ints, Lan9118PhyState),
174
+ VMSTATE_UINT32_ARRAY(pup_cntrl_reg, BCM2838GpioState,
460
+ VMSTATE_UINT16(int_mask, Lan9118PhyState),
175
+ GPIO_PUP_PDN_CNTRL_NUM),
461
+ VMSTATE_BOOL(link_down, Lan9118PhyState),
176
+ VMSTATE_END_OF_LIST()
462
+ VMSTATE_END_OF_LIST()
177
+ }
463
+ }
178
+};
464
+};
179
+
465
+
180
+static void bcm2838_gpio_init(Object *obj)
466
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
181
+{
467
+{
182
+ BCM2838GpioState *s = BCM2838_GPIO(obj);
468
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
183
+ DeviceState *dev = DEVICE(obj);
184
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
185
+
186
+ memory_region_init_io(&s->iomem, obj, &bcm2838_gpio_ops, s,
187
+ "bcm2838_gpio", BCM2838_GPIO_REGS_SIZE);
188
+ sysbus_init_mmio(sbd, &s->iomem);
189
+ qdev_init_gpio_out(dev, s->out, BCM2838_GPIO_NUM);
190
+}
191
+
192
+static void bcm2838_gpio_realize(DeviceState *dev, Error **errp)
193
+{
194
+ /* Temporary stub. Do nothing */
195
+}
196
+
197
+static void bcm2838_gpio_class_init(ObjectClass *klass, void *data)
198
+{
199
+ DeviceClass *dc = DEVICE_CLASS(klass);
469
+ DeviceClass *dc = DEVICE_CLASS(klass);
200
+
470
+
201
+ dc->vmsd = &vmstate_bcm2838_gpio;
471
+ rc->phases.hold = lan9118_phy_reset_hold;
202
+ dc->realize = &bcm2838_gpio_realize;
472
+ dc->vmsd = &vmstate_lan9118_phy;
203
+ dc->reset = &bcm2838_gpio_reset;
473
+}
204
+}
474
+
205
+
475
+static const TypeInfo types[] = {
206
+static const TypeInfo bcm2838_gpio_info = {
476
+ {
207
+ .name = TYPE_BCM2838_GPIO,
477
+ .name = TYPE_LAN9118_PHY,
208
+ .parent = TYPE_SYS_BUS_DEVICE,
478
+ .parent = TYPE_SYS_BUS_DEVICE,
209
+ .instance_size = sizeof(BCM2838GpioState),
479
+ .instance_size = sizeof(Lan9118PhyState),
210
+ .instance_init = bcm2838_gpio_init,
480
+ .instance_init = lan9118_phy_init,
211
+ .class_init = bcm2838_gpio_class_init,
481
+ .class_init = lan9118_phy_class_init,
482
+ }
212
+};
483
+};
213
+
484
+
214
+static void bcm2838_gpio_register_types(void)
485
+DEFINE_TYPES(types)
215
+{
486
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
216
+ type_register_static(&bcm2838_gpio_info);
217
+}
218
+
219
+type_init(bcm2838_gpio_register_types)
220
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
221
index XXXXXXX..XXXXXXX 100644
487
index XXXXXXX..XXXXXXX 100644
222
--- a/hw/gpio/meson.build
488
--- a/hw/net/Kconfig
223
+++ b/hw/gpio/meson.build
489
+++ b/hw/net/Kconfig
224
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_IMX', if_true: files('imx_gpio.c'))
490
@@ -XXX,XX +XXX,XX @@ config VMXNET3_PCI
225
system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_gpio.c'))
491
config SMC91C111
226
system_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_gpio.c'))
492
bool
227
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_gpio.c'))
493
228
-system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_gpio.c'))
494
+config LAN9118_PHY
229
+system_ss.add(when: 'CONFIG_RASPI', if_true: files(
495
+ bool
230
+ 'bcm2835_gpio.c',
496
+
231
+ 'bcm2838_gpio.c'
497
config LAN9118
232
+))
498
bool
233
system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c'))
499
+ select LAN9118_PHY
234
system_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c'))
500
select PTIMER
501
502
config NE2000_ISA
503
diff --git a/hw/net/meson.build b/hw/net/meson.build
504
index XXXXXXX..XXXXXXX 100644
505
--- a/hw/net/meson.build
506
+++ b/hw/net/meson.build
507
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('vmxnet3.c'))
508
509
system_ss.add(when: 'CONFIG_SMC91C111', if_true: files('smc91c111.c'))
510
system_ss.add(when: 'CONFIG_LAN9118', if_true: files('lan9118.c'))
511
+system_ss.add(when: 'CONFIG_LAN9118_PHY', if_true: files('lan9118_phy.c'))
512
system_ss.add(when: 'CONFIG_NE2000_ISA', if_true: files('ne2000-isa.c'))
513
system_ss.add(when: 'CONFIG_OPENCORES_ETH', if_true: files('opencores_eth.c'))
514
system_ss.add(when: 'CONFIG_XGMAC', if_true: files('xgmac.c'))
235
--
515
--
236
2.34.1
516
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
3
imx_fec models the same PHY as lan9118_phy. The code is almost the same with
4
imx_fec having more logging and tracing. Merge these improvements into
5
lan9118_phy and reuse in imx_fec to fix the code duplication.
6
7
Some migration state how resides in the new device model which breaks migration
8
compatibility for the following machines:
9
* imx25-pdk
10
* sabrelite
11
* mcimx7d-sabre
12
* mcimx6ul-evk
13
14
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
15
Tested-by: Guenter Roeck <linux@roeck-us.net>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240226000259.2752893-6-sergey.kambalin@auriga.com
17
Message-id: 20241102125724.532843-3-shentey@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
19
---
8
include/hw/arm/bcm2838.h | 2 +
20
include/hw/net/imx_fec.h | 9 ++-
9
include/hw/arm/bcm2838_peripherals.h | 37 ++++++
21
hw/net/imx_fec.c | 146 ++++-----------------------------------
10
hw/arm/bcm2838.c | 167 ++++++++++++++++++++++++++-
22
hw/net/lan9118_phy.c | 82 ++++++++++++++++------
11
hw/arm/trace-events | 3 +
23
hw/net/Kconfig | 1 +
12
4 files changed, 207 insertions(+), 2 deletions(-)
24
hw/net/trace-events | 10 +--
25
5 files changed, 85 insertions(+), 163 deletions(-)
13
26
14
diff --git a/include/hw/arm/bcm2838.h b/include/hw/arm/bcm2838.h
27
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
15
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/bcm2838.h
29
--- a/include/hw/net/imx_fec.h
17
+++ b/include/hw/arm/bcm2838.h
30
+++ b/include/hw/net/imx_fec.h
18
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
19
#define BCM2838_H
32
#define TYPE_IMX_ENET "imx.enet"
20
33
21
#include "hw/arm/bcm2836.h"
34
#include "hw/sysbus.h"
22
+#include "hw/intc/arm_gic.h"
35
+#include "hw/net/lan9118_phy.h"
23
#include "hw/arm/bcm2838_peripherals.h"
36
+#include "hw/irq.h"
24
37
#include "net/net.h"
25
#define BCM2838_PERI_LOW_BASE 0xfc000000
38
26
@@ -XXX,XX +XXX,XX @@ struct BCM2838State {
39
#define ENET_EIR 1
27
BCM283XBaseState parent_obj;
40
@@ -XXX,XX +XXX,XX @@ struct IMXFECState {
28
/*< public >*/
41
uint32_t tx_descriptor[ENET_TX_RING_NUM];
29
BCM2838PeripheralState peripherals;
42
uint32_t tx_ring_num;
30
+ GICState gic;
43
44
- uint32_t phy_status;
45
- uint32_t phy_control;
46
- uint32_t phy_advertise;
47
- uint32_t phy_int;
48
- uint32_t phy_int_mask;
49
+ Lan9118PhyState mii;
50
+ IRQState mii_irq;
51
uint32_t phy_num;
52
bool phy_connected;
53
struct IMXFECState *phy_consumer;
54
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/net/imx_fec.c
57
+++ b/hw/net/imx_fec.c
58
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth_txdescs = {
59
60
static const VMStateDescription vmstate_imx_eth = {
61
.name = TYPE_IMX_FEC,
62
- .version_id = 2,
63
- .minimum_version_id = 2,
64
+ .version_id = 3,
65
+ .minimum_version_id = 3,
66
.fields = (const VMStateField[]) {
67
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
68
VMSTATE_UINT32(rx_descriptor, IMXFECState),
69
VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
70
- VMSTATE_UINT32(phy_status, IMXFECState),
71
- VMSTATE_UINT32(phy_control, IMXFECState),
72
- VMSTATE_UINT32(phy_advertise, IMXFECState),
73
- VMSTATE_UINT32(phy_int, IMXFECState),
74
- VMSTATE_UINT32(phy_int_mask, IMXFECState),
75
VMSTATE_END_OF_LIST()
76
},
77
.subsections = (const VMStateDescription * const []) {
78
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth = {
79
},
31
};
80
};
32
81
33
#endif /* BCM2838_H */
82
-#define PHY_INT_ENERGYON (1 << 7)
34
diff --git a/include/hw/arm/bcm2838_peripherals.h b/include/hw/arm/bcm2838_peripherals.h
83
-#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
35
index XXXXXXX..XXXXXXX 100644
84
-#define PHY_INT_FAULT (1 << 5)
36
--- a/include/hw/arm/bcm2838_peripherals.h
85
-#define PHY_INT_DOWN (1 << 4)
37
+++ b/include/hw/arm/bcm2838_peripherals.h
86
-#define PHY_INT_AUTONEG_LP (1 << 3)
38
@@ -XXX,XX +XXX,XX @@
87
-#define PHY_INT_PARFAULT (1 << 2)
39
88
-#define PHY_INT_AUTONEG_PAGE (1 << 1)
40
#include "hw/arm/bcm2835_peripherals.h"
89
-
41
90
static void imx_eth_update(IMXFECState *s);
42
+/* SPI */
91
43
+#define GIC_SPI_INTERRUPT_MBOX 33
92
/*
44
+#define GIC_SPI_INTERRUPT_MPHI 40
93
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s);
45
+#define GIC_SPI_INTERRUPT_DWC2 73
94
* For now we don't handle any GPIO/interrupt line, so the OS will
46
+#define GIC_SPI_INTERRUPT_DMA_0 80
95
* have to poll for the PHY status.
47
+#define GIC_SPI_INTERRUPT_DMA_6 86
96
*/
48
+#define GIC_SPI_INTERRUPT_DMA_7_8 87
97
-static void imx_phy_update_irq(IMXFECState *s)
49
+#define GIC_SPI_INTERRUPT_DMA_9_10 88
98
+static void imx_phy_update_irq(void *opaque, int n, int level)
50
+#define GIC_SPI_INTERRUPT_AUX_UART1 93
51
+#define GIC_SPI_INTERRUPT_SDHOST 120
52
+#define GIC_SPI_INTERRUPT_UART0 121
53
+#define GIC_SPI_INTERRUPT_RNG200 125
54
+#define GIC_SPI_INTERRUPT_EMMC_EMMC2 126
55
+#define GIC_SPI_INTERRUPT_PCI_INT_A 143
56
+#define GIC_SPI_INTERRUPT_GENET_A 157
57
+#define GIC_SPI_INTERRUPT_GENET_B 158
58
+
59
+
60
+/* GPU (legacy) DMA interrupts */
61
+#define GPU_INTERRUPT_DMA0 16
62
+#define GPU_INTERRUPT_DMA1 17
63
+#define GPU_INTERRUPT_DMA2 18
64
+#define GPU_INTERRUPT_DMA3 19
65
+#define GPU_INTERRUPT_DMA4 20
66
+#define GPU_INTERRUPT_DMA5 21
67
+#define GPU_INTERRUPT_DMA6 22
68
+#define GPU_INTERRUPT_DMA7_8 23
69
+#define GPU_INTERRUPT_DMA9_10 24
70
+#define GPU_INTERRUPT_DMA11 25
71
+#define GPU_INTERRUPT_DMA12 26
72
+#define GPU_INTERRUPT_DMA13 27
73
+#define GPU_INTERRUPT_DMA14 28
74
+#define GPU_INTERRUPT_DMA15 31
75
76
#define TYPE_BCM2838_PERIPHERALS "bcm2838-peripherals"
77
OBJECT_DECLARE_TYPE(BCM2838PeripheralState, BCM2838PeripheralClass,
78
@@ -XXX,XX +XXX,XX @@ struct BCM2838PeripheralState {
79
MemoryRegion peri_low_mr;
80
MemoryRegion peri_low_mr_alias;
81
MemoryRegion mphi_mr_alias;
82
+
83
+ OrIRQState mmc_irq_orgate;
84
+ OrIRQState dma_7_8_irq_orgate;
85
+ OrIRQState dma_9_10_irq_orgate;
86
};
87
88
struct BCM2838PeripheralClass {
89
diff --git a/hw/arm/bcm2838.c b/hw/arm/bcm2838.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/hw/arm/bcm2838.c
92
+++ b/hw/arm/bcm2838.c
93
@@ -XXX,XX +XXX,XX @@
94
#include "hw/arm/bcm2838.h"
95
#include "trace.h"
96
97
+#define GIC400_MAINTENANCE_IRQ 9
98
+#define GIC400_TIMER_NS_EL2_IRQ 10
99
+#define GIC400_TIMER_VIRT_IRQ 11
100
+#define GIC400_LEGACY_FIQ 12
101
+#define GIC400_TIMER_S_EL1_IRQ 13
102
+#define GIC400_TIMER_NS_EL1_IRQ 14
103
+#define GIC400_LEGACY_IRQ 15
104
+
105
+/* Number of external interrupt lines to configure the GIC with */
106
+#define GIC_NUM_IRQS 192
107
+
108
+#define PPI(cpu, irq) (GIC_NUM_IRQS + (cpu) * GIC_INTERNAL + GIC_NR_SGIS + irq)
109
+
110
+#define GIC_BASE_OFS 0x0000
111
+#define GIC_DIST_OFS 0x1000
112
+#define GIC_CPU_OFS 0x2000
113
+#define GIC_VIFACE_THIS_OFS 0x4000
114
+#define GIC_VIFACE_OTHER_OFS(cpu) (0x5000 + (cpu) * 0x200)
115
+#define GIC_VCPU_OFS 0x6000
116
+
117
#define VIRTUAL_PMU_IRQ 7
118
119
+static void bcm2838_gic_set_irq(void *opaque, int irq, int level)
120
+{
121
+ BCM2838State *s = (BCM2838State *)opaque;
122
+
123
+ trace_bcm2838_gic_set_irq(irq, level);
124
+ qemu_set_irq(qdev_get_gpio_in(DEVICE(&s->gic), irq), level);
125
+}
126
+
127
static void bcm2838_init(Object *obj)
128
{
99
{
129
BCM2838State *s = BCM2838(obj);
100
- imx_eth_update(s);
130
@@ -XXX,XX +XXX,XX @@ static void bcm2838_init(Object *obj)
101
-}
131
"vcram-size");
102
-
132
object_property_add_alias(obj, "command-line", OBJECT(&s->peripherals),
103
-static void imx_phy_update_link(IMXFECState *s)
133
"command-line");
104
-{
134
+
105
- /* Autonegotiation status mirrors link status. */
135
+ object_initialize_child(obj, "gic", &s->gic, TYPE_ARM_GIC);
106
- if (qemu_get_queue(s->nic)->link_down) {
136
}
107
- trace_imx_phy_update_link("down");
137
108
- s->phy_status &= ~0x0024;
138
static void bcm2838_realize(DeviceState *dev, Error **errp)
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)
139
{
121
{
140
- int n;
122
- imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
141
BCM2838State *s = BCM2838(dev);
123
-}
142
BCM283XBaseState *s_base = BCM283X_BASE(dev);
124
-
143
BCM283XBaseClass *bc_base = BCM283X_BASE_GET_CLASS(dev);
125
-static void imx_phy_reset(IMXFECState *s)
144
@@ -XXX,XX +XXX,XX @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
126
-{
145
BCMSocPeripheralBaseState *ps_base =
127
- trace_imx_phy_reset();
146
BCM_SOC_PERIPHERALS_BASE(&s->peripherals);
128
-
147
129
- s->phy_status = 0x7809;
148
+ DeviceState *gicdev = NULL;
130
- s->phy_control = 0x3000;
149
+
131
- s->phy_advertise = 0x01e1;
150
if (!bcm283x_common_realize(dev, ps_base, errp)) {
132
- s->phy_int_mask = 0;
151
return;
133
- s->phy_int = 0;
152
}
134
- imx_phy_update_link(s);
153
@@ -XXX,XX +XXX,XX @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
135
+ lan9118_phy_update_link(&IMX_FEC(qemu_get_nic_opaque(nc))->mii,
154
sysbus_mmio_map(SYS_BUS_DEVICE(&s_base->control), 0, bc_base->ctrl_base);
136
+ nc->link_down);
155
137
}
156
/* Create cores */
138
157
- for (n = 0; n < bc_base->core_count; n++) {
139
static uint32_t imx_phy_read(IMXFECState *s, int reg)
158
+ for (int n = 0; n < bc_base->core_count; n++) {
140
{
159
141
- uint32_t val;
160
object_property_set_int(OBJECT(&s_base->cpu[n].core), "mp-affinity",
142
uint32_t phy = reg / 32;
161
(bc_base->clusterid << 8) | n, &error_abort);
143
162
144
if (!s->phy_connected) {
163
+ /* set periphbase/CBAR value for CPU-local registers */
145
@@ -XXX,XX +XXX,XX @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
164
+ object_property_set_int(OBJECT(&s_base->cpu[n].core), "reset-cbar",
146
165
+ bc_base->peri_base, &error_abort);
147
reg %= 32;
166
+
148
167
/* start powered off if not enabled */
149
- switch (reg) {
168
object_property_set_bool(OBJECT(&s_base->cpu[n].core),
150
- case 0: /* Basic Control */
169
"start-powered-off",
151
- val = s->phy_control;
170
@@ -XXX,XX +XXX,XX @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
152
- break;
171
return;
153
- case 1: /* Basic Status */
172
}
154
- val = s->phy_status;
173
}
155
- break;
174
+
156
- case 2: /* ID1 */
175
+ if (!object_property_set_uint(OBJECT(&s->gic), "revision", 2, errp)) {
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)) {
176
+ return;
259
+ return;
177
+ }
260
+ }
178
+
261
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
179
+ if (!object_property_set_uint(OBJECT(&s->gic), "num-cpu", BCM283X_NCPUS,
262
+
180
+ errp)) {
263
qemu_macaddr_default_if_unset(&s->conf.macaddr);
181
+ return;
264
182
+ }
265
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
183
+
266
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
184
+ if (!object_property_set_uint(OBJECT(&s->gic), "num-irq",
185
+ GIC_NUM_IRQS + GIC_INTERNAL, errp)) {
186
+ return;
187
+ }
188
+
189
+ if (!object_property_set_bool(OBJECT(&s->gic),
190
+ "has-virtualization-extensions", true,
191
+ errp)) {
192
+ return;
193
+ }
194
+
195
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gic), errp)) {
196
+ return;
197
+ }
198
+
199
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 0,
200
+ bc_base->ctrl_base + BCM2838_GIC_BASE + GIC_DIST_OFS);
201
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 1,
202
+ bc_base->ctrl_base + BCM2838_GIC_BASE + GIC_CPU_OFS);
203
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 2,
204
+ bc_base->ctrl_base + BCM2838_GIC_BASE + GIC_VIFACE_THIS_OFS);
205
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 3,
206
+ bc_base->ctrl_base + BCM2838_GIC_BASE + GIC_VCPU_OFS);
207
+
208
+ for (int n = 0; n < BCM283X_NCPUS; n++) {
209
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 4 + n,
210
+ bc_base->ctrl_base + BCM2838_GIC_BASE
211
+ + GIC_VIFACE_OTHER_OFS(n));
212
+ }
213
+
214
+ gicdev = DEVICE(&s->gic);
215
+
216
+ for (int n = 0; n < BCM283X_NCPUS; n++) {
217
+ DeviceState *cpudev = DEVICE(&s_base->cpu[n]);
218
+
219
+ /* Connect the GICv2 outputs to the CPU */
220
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), n,
221
+ qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
222
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), n + BCM283X_NCPUS,
223
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
224
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), n + 2 * BCM283X_NCPUS,
225
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
226
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), n + 3 * BCM283X_NCPUS,
227
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
228
+
229
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), n + 4 * BCM283X_NCPUS,
230
+ qdev_get_gpio_in(gicdev,
231
+ PPI(n, GIC400_MAINTENANCE_IRQ)));
232
+
233
+ /* Connect timers from the CPU to the interrupt controller */
234
+ qdev_connect_gpio_out(cpudev, GTIMER_PHYS,
235
+ qdev_get_gpio_in(gicdev, PPI(n, GIC400_TIMER_NS_EL1_IRQ)));
236
+ qdev_connect_gpio_out(cpudev, GTIMER_VIRT,
237
+ qdev_get_gpio_in(gicdev, PPI(n, GIC400_TIMER_VIRT_IRQ)));
238
+ qdev_connect_gpio_out(cpudev, GTIMER_HYP,
239
+ qdev_get_gpio_in(gicdev, PPI(n, GIC400_TIMER_NS_EL2_IRQ)));
240
+ qdev_connect_gpio_out(cpudev, GTIMER_SEC,
241
+ qdev_get_gpio_in(gicdev, PPI(n, GIC400_TIMER_S_EL1_IRQ)));
242
+ /* PMU interrupt */
243
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
244
+ qdev_get_gpio_in(gicdev, PPI(n, VIRTUAL_PMU_IRQ)));
245
+ }
246
+
247
+ /* Connect UART0 to the interrupt controller */
248
+ sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->uart0), 0,
249
+ qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_UART0));
250
+
251
+ /* Connect AUX / UART1 to the interrupt controller */
252
+ sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->aux), 0,
253
+ qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_AUX_UART1));
254
+
255
+ /* Connect VC mailbox to the interrupt controller */
256
+ sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->mboxes), 0,
257
+ qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_MBOX));
258
+
259
+ /* Connect SD host to the interrupt controller */
260
+ sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->sdhost), 0,
261
+ qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_SDHOST));
262
+
263
+ /* According to DTS, EMMC and EMMC2 share one irq */
264
+ DeviceState *mmc_irq_orgate = DEVICE(&ps->mmc_irq_orgate);
265
+
266
+ /* Connect EMMC and EMMC2 to the interrupt controller */
267
+ qdev_connect_gpio_out(mmc_irq_orgate, 0,
268
+ qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_EMMC_EMMC2));
269
+
270
+ /* Connect USB OTG and MPHI to the interrupt controller */
271
+ sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->mphi), 0,
272
+ qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_MPHI));
273
+ sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->dwc2), 0,
274
+ qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_DWC2));
275
+
276
+ /* Connect DMA 0-6 to the interrupt controller */
277
+ for (int n = GIC_SPI_INTERRUPT_DMA_0; n <= GIC_SPI_INTERRUPT_DMA_6; n++) {
278
+ sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->dma),
279
+ n - GIC_SPI_INTERRUPT_DMA_0,
280
+ qdev_get_gpio_in(gicdev, n));
281
+ }
282
+
283
+ /* According to DTS, DMA 7 and 8 share one irq */
284
+ DeviceState *dma_7_8_irq_orgate = DEVICE(&ps->dma_7_8_irq_orgate);
285
+
286
+ /* Connect DMA 7-8 to the interrupt controller */
287
+ qdev_connect_gpio_out(dma_7_8_irq_orgate, 0,
288
+ qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_DMA_7_8));
289
+
290
+ /* According to DTS, DMA 9 and 10 share one irq */
291
+ DeviceState *dma_9_10_irq_orgate = DEVICE(&ps->dma_9_10_irq_orgate);
292
+
293
+ /* Connect DMA 9-10 to the interrupt controller */
294
+ qdev_connect_gpio_out(dma_9_10_irq_orgate, 0,
295
+ qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_DMA_9_10));
296
+
297
+ /* Pass through inbound GPIO lines to the GIC */
298
+ qdev_init_gpio_in(dev, bcm2838_gic_set_irq, GIC_NUM_IRQS);
299
+
300
+ /* Pass through outbound IRQ lines from the GIC */
301
+ qdev_pass_gpios(DEVICE(&s->gic), DEVICE(&s->peripherals), NULL);
302
}
303
304
static void bcm2838_class_init(ObjectClass *oc, void *data)
305
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
306
index XXXXXXX..XXXXXXX 100644
267
index XXXXXXX..XXXXXXX 100644
307
--- a/hw/arm/trace-events
268
--- a/hw/net/lan9118_phy.c
308
+++ b/hw/arm/trace-events
269
+++ b/hw/net/lan9118_phy.c
309
@@ -XXX,XX +XXX,XX @@ z2_aer915_event(int8_t event, int8_t len) "i2c event =0x%x len=%d bytes"
270
@@ -XXX,XX +XXX,XX @@
310
xen_create_virtio_mmio_devices(int i, int irq, uint64_t base) "Created virtio-mmio device %d: irq %d base 0x%"PRIx64
271
* Copyright (c) 2009 CodeSourcery, LLC.
311
xen_init_ram(uint64_t machine_ram_size) "Initialized xen ram with size 0x%"PRIx64
272
* Written by Paul Brook
312
xen_enable_tpm(uint64_t addr) "Connected tpmdev at address 0x%"PRIx64
273
*
313
+
274
+ * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
314
+# bcm2838.c
275
+ *
315
+bcm2838_gic_set_irq(int irq, int level) "gic irq:%d lvl:%d"
276
* This code is licensed under the GNU GPL v2
277
*
278
* Contributions after 2012-01-13 are licensed under the terms of the
279
@@ -XXX,XX +XXX,XX @@
280
#include "hw/resettable.h"
281
#include "migration/vmstate.h"
282
#include "qemu/log.h"
283
+#include "trace.h"
284
285
#define PHY_INT_ENERGYON (1 << 7)
286
#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
287
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
288
289
switch (reg) {
290
case 0: /* Basic Control */
291
- return s->control;
292
+ val = s->control;
293
+ break;
294
case 1: /* Basic Status */
295
- return s->status;
296
+ val = s->status;
297
+ break;
298
case 2: /* ID1 */
299
- return 0x0007;
300
+ val = 0x0007;
301
+ break;
302
case 3: /* ID2 */
303
- return 0xc0d1;
304
+ val = 0xc0d1;
305
+ break;
306
case 4: /* Auto-neg advertisement */
307
- return s->advertise;
308
+ val = s->advertise;
309
+ break;
310
case 5: /* Auto-neg Link Partner Ability */
311
- return 0x0f71;
312
+ val = 0x0f71;
313
+ break;
314
case 6: /* Auto-neg Expansion */
315
- return 1;
316
- /* TODO 17, 18, 27, 29, 30, 31 */
317
+ val = 1;
318
+ break;
319
case 29: /* Interrupt source. */
320
val = s->ints;
321
s->ints = 0;
322
lan9118_phy_update_irq(s);
323
- return val;
324
+ break;
325
case 30: /* Interrupt mask */
326
- return s->int_mask;
327
+ val = s->int_mask;
328
+ break;
329
+ case 17:
330
+ case 18:
331
+ case 27:
332
+ case 31:
333
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
334
+ __func__, reg);
335
+ val = 0;
336
+ break;
337
default:
338
- qemu_log_mask(LOG_GUEST_ERROR,
339
- "lan9118_phy_read: PHY read reg %d\n", reg);
340
- return 0;
341
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
342
+ __func__, reg);
343
+ val = 0;
344
+ break;
345
}
346
+
347
+ trace_lan9118_phy_read(val, reg);
348
+
349
+ return val;
350
}
351
352
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
353
{
354
+ trace_lan9118_phy_write(val, reg);
355
+
356
switch (reg) {
357
case 0: /* Basic Control */
358
if (val & 0x8000) {
359
lan9118_phy_reset(s);
360
- break;
361
- }
362
- s->control = val & 0x7980;
363
- /* Complete autonegotiation immediately. */
364
- if (val & 0x1000) {
365
- s->status |= 0x0020;
366
+ } else {
367
+ s->control = val & 0x7980;
368
+ /* Complete autonegotiation immediately. */
369
+ if (val & 0x1000) {
370
+ s->status |= 0x0020;
371
+ }
372
}
373
break;
374
case 4: /* Auto-neg advertisement */
375
s->advertise = (val & 0x2d7f) | 0x80;
376
break;
377
- /* TODO 17, 18, 27, 31 */
378
case 30: /* Interrupt mask */
379
s->int_mask = val & 0xff;
380
lan9118_phy_update_irq(s);
381
break;
382
+ case 17:
383
+ case 18:
384
+ case 27:
385
+ case 31:
386
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
387
+ __func__, reg);
388
+ break;
389
default:
390
- qemu_log_mask(LOG_GUEST_ERROR,
391
- "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
392
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
393
+ __func__, reg);
394
+ break;
395
}
396
}
397
398
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
399
400
/* Autonegotiation status mirrors link status. */
401
if (link_down) {
402
+ trace_lan9118_phy_update_link("down");
403
s->status &= ~0x0024;
404
s->ints |= PHY_INT_DOWN;
405
} else {
406
+ trace_lan9118_phy_update_link("up");
407
s->status |= 0x0024;
408
s->ints |= PHY_INT_ENERGYON;
409
s->ints |= PHY_INT_AUTONEG_COMPLETE;
410
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
411
412
void lan9118_phy_reset(Lan9118PhyState *s)
413
{
414
+ trace_lan9118_phy_reset();
415
+
416
s->control = 0x3000;
417
s->status = 0x7809;
418
s->advertise = 0x01e1;
419
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_phy = {
420
.version_id = 1,
421
.minimum_version_id = 1,
422
.fields = (const VMStateField[]) {
423
- VMSTATE_UINT16(control, Lan9118PhyState),
424
VMSTATE_UINT16(status, Lan9118PhyState),
425
+ VMSTATE_UINT16(control, Lan9118PhyState),
426
VMSTATE_UINT16(advertise, Lan9118PhyState),
427
VMSTATE_UINT16(ints, Lan9118PhyState),
428
VMSTATE_UINT16(int_mask, Lan9118PhyState),
429
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
430
index XXXXXXX..XXXXXXX 100644
431
--- a/hw/net/Kconfig
432
+++ b/hw/net/Kconfig
433
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_SUN8I_EMAC
434
435
config IMX_FEC
436
bool
437
+ select LAN9118_PHY
438
439
config CADENCE
440
bool
441
diff --git a/hw/net/trace-events b/hw/net/trace-events
442
index XXXXXXX..XXXXXXX 100644
443
--- a/hw/net/trace-events
444
+++ b/hw/net/trace-events
445
@@ -XXX,XX +XXX,XX @@ allwinner_sun8i_emac_set_link(bool active) "Set link: active=%u"
446
allwinner_sun8i_emac_read(uint64_t offset, uint64_t val) "MMIO read: offset=0x%" PRIx64 " value=0x%" PRIx64
447
allwinner_sun8i_emac_write(uint64_t offset, uint64_t val) "MMIO write: offset=0x%" PRIx64 " value=0x%" PRIx64
448
449
+# lan9118_phy.c
450
+lan9118_phy_read(uint16_t val, int reg) "[0x%02x] -> 0x%04" PRIx16
451
+lan9118_phy_write(uint16_t val, int reg) "[0x%02x] <- 0x%04" PRIx16
452
+lan9118_phy_update_link(const char *s) "%s"
453
+lan9118_phy_reset(void) ""
454
+
455
# lance.c
456
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x"
457
lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x"
458
@@ -XXX,XX +XXX,XX @@ i82596_set_multicast(uint16_t count) "Added %d multicast entries"
459
i82596_channel_attention(void *s) "%p: Received CHANNEL ATTENTION"
460
461
# imx_fec.c
462
-imx_phy_read(uint32_t val, int phy, int reg) "0x%04"PRIx32" <= phy[%d].reg[%d]"
463
imx_phy_read_num(int phy, int configured) "read request from unconfigured phy %d (configured %d)"
464
-imx_phy_write(uint32_t val, int phy, int reg) "0x%04"PRIx32" => phy[%d].reg[%d]"
465
imx_phy_write_num(int phy, int configured) "write request to unconfigured phy %d (configured %d)"
466
-imx_phy_update_link(const char *s) "%s"
467
-imx_phy_reset(void) ""
468
imx_fec_read_bd(uint64_t addr, int flags, int len, int data) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x"
469
imx_enet_read_bd(uint64_t addr, int flags, int len, int data, int options, int status) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x option 0x%04x status 0x%04x"
470
imx_eth_tx_bd_busy(void) "tx_bd ran out of descriptors to transmit"
316
--
471
--
317
2.34.1
472
2.34.1
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ardb@kernel.org>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
The Cortex-A53 r0p4 revision that QEMU emulates is affected by a CatA
3
Turns 0x70 into 0xe0 (== 0x70 << 1) which adds the missing MII_ANLPAR_TX and
4
erratum #843419 (i.e., the most severe), which requires workarounds in
4
fixes the MSB of selector field to be zero, as specified in the datasheet.
5
the toolchain as well as the OS.
6
5
7
Since the emulation is obviously not affected in the same way, we can
6
Fixes: 2a424990170b "LAN9118 emulation"
8
indicate this via REVIDR bit #8, which on r0p4 has the meaning that no
7
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
9
workarounds for erratum #843419 are needed.
8
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
10
Message-id: 20241102125724.532843-4-shentey@gmail.com
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20240215160202.2803452-1-ardb+git@google.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
12
---
16
target/arm/cpu64.c | 2 +-
13
hw/net/lan9118_phy.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
18
15
19
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu64.c
18
--- a/hw/net/lan9118_phy.c
22
+++ b/target/arm/cpu64.c
19
+++ b/hw/net/lan9118_phy.c
23
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
24
set_feature(&cpu->env, ARM_FEATURE_PMU);
21
val = s->advertise;
25
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A53;
22
break;
26
cpu->midr = 0x410fd034;
23
case 5: /* Auto-neg Link Partner Ability */
27
- cpu->revidr = 0x00000000;
24
- val = 0x0f71;
28
+ cpu->revidr = 0x00000100;
25
+ val = 0x0fe1;
29
cpu->reset_fpsid = 0x41034070;
26
break;
30
cpu->isar.mvfr0 = 0x10110222;
27
case 6: /* Auto-neg Expansion */
31
cpu->isar.mvfr1 = 0x12111111;
28
val = 1;
32
--
29
--
33
2.34.1
30
2.34.1
diff view generated by jsdifflib
1
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
Message-id: 20240226000259.2752893-31-sergey.kambalin@auriga.com
2
3
Prefer named constants over magic values for better readability.
4
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
[PMM: Comment out use of USB, which depends on PCI]
6
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
7
Tested-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20241102125724.532843-5-shentey@gmail.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
10
---
7
tests/avocado/boot_linux_console.py | 97 +++++++++++++++++++++++++++++
11
include/hw/net/mii.h | 6 +++++
8
1 file changed, 97 insertions(+)
12
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
13
2 files changed, 46 insertions(+), 23 deletions(-)
9
14
10
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
15
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
11
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
12
--- a/tests/avocado/boot_linux_console.py
17
--- a/include/hw/net/mii.h
13
+++ b/tests/avocado/boot_linux_console.py
18
+++ b/include/hw/net/mii.h
14
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_initrd(self):
19
@@ -XXX,XX +XXX,XX @@
15
# Wait for VM to shut down gracefully
20
#define MII_BMSR_JABBER (1 << 1) /* Jabber detected */
16
self.vm.wait()
21
#define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */
17
22
18
+ def test_arm_raspi4(self):
23
+#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */
19
+ """
24
#define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */
20
+ :avocado: tags=arch:aarch64
25
#define MII_ANAR_PAUSE (1 << 10) /* Try for pause */
21
+ :avocado: tags=machine:raspi4b
26
#define MII_ANAR_TXFD (1 << 8)
22
+ :avocado: tags=device:pl011
27
@@ -XXX,XX +XXX,XX @@
23
+ :avocado: tags=accel:tcg
28
#define MII_ANAR_10FD (1 << 6)
24
+ :avocado: tags=rpi4b
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
25
+
42
+
26
+ The kernel can be rebuilt using the kernel source referenced
43
/* RealTek 8211E */
27
+ and following the instructions on the on:
44
#define RTL8211E_PHYID1 0x001c
28
+ https://www.raspberrypi.org/documentation/linux/kernel/building.md
45
#define RTL8211E_PHYID2 0xc915
29
+ """
46
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
30
+
47
index XXXXXXX..XXXXXXX 100644
31
+ deb_url = ('http://archive.raspberrypi.org/debian/'
48
--- a/hw/net/lan9118_phy.c
32
+ 'pool/main/r/raspberrypi-firmware/'
49
+++ b/hw/net/lan9118_phy.c
33
+ 'raspberrypi-kernel_1.20230106-1_arm64.deb')
50
@@ -XXX,XX +XXX,XX @@
34
+ deb_hash = '08dc55696535b18a6d4fe6fa10d4c0d905cbb2ed'
51
35
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
52
#include "qemu/osdep.h"
36
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel8.img')
53
#include "hw/net/lan9118_phy.h"
37
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2711-rpi-4-b.dtb')
54
+#include "hw/net/mii.h"
38
+
55
#include "hw/irq.h"
39
+ self.vm.set_console()
56
#include "hw/resettable.h"
40
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
57
#include "migration/vmstate.h"
41
+ 'earlycon=pl011,mmio32,0xfe201000 ' +
58
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
42
+ 'console=ttyAMA0,115200 ' +
59
uint16_t val;
43
+ 'root=/dev/mmcblk1p2 rootwait ' +
60
44
+ 'dwc_otg.fiq_fsm_enable=0')
61
switch (reg) {
45
+ self.vm.add_args('-kernel', kernel_path,
62
- case 0: /* Basic Control */
46
+ '-dtb', dtb_path,
63
+ case MII_BMCR:
47
+ '-append', kernel_command_line)
64
val = s->control;
48
+ # When PCI is supported we can add a USB controller:
65
break;
49
+ # '-device', 'qemu-xhci,bus=pcie.1,id=xhci',
66
- case 1: /* Basic Status */
50
+ # '-device', 'usb-kbd,bus=xhci.0',
67
+ case MII_BMSR:
51
+ self.vm.launch()
68
val = s->status;
52
+ console_pattern = 'Kernel command line: %s' % kernel_command_line
69
break;
53
+ self.wait_for_console_pattern(console_pattern)
70
- case 2: /* ID1 */
54
+ # When USB is enabled we can look for this
71
- val = 0x0007;
55
+ # console_pattern = 'Product: QEMU USB Keyboard'
72
+ case MII_PHYID1:
56
+ # self.wait_for_console_pattern(console_pattern)
73
+ val = SMSCLAN9118_PHYID1;
57
+ console_pattern = 'Waiting for root device'
74
break;
58
+ self.wait_for_console_pattern(console_pattern)
75
- case 3: /* ID2 */
59
+
76
- val = 0xc0d1;
60
+
77
+ case MII_PHYID2:
61
+ def test_arm_raspi4_initrd(self):
78
+ val = SMSCLAN9118_PHYID2;
62
+ """
79
break;
63
+ :avocado: tags=arch:aarch64
80
- case 4: /* Auto-neg advertisement */
64
+ :avocado: tags=machine:raspi4b
81
+ case MII_ANAR:
65
+ :avocado: tags=device:pl011
82
val = s->advertise;
66
+ :avocado: tags=accel:tcg
83
break;
67
+ :avocado: tags=rpi4b
84
- case 5: /* Auto-neg Link Partner Ability */
68
+
85
- val = 0x0fe1;
69
+ The kernel can be rebuilt using the kernel source referenced
86
+ case MII_ANLPAR:
70
+ and following the instructions on the on:
87
+ val = MII_ANLPAR_PAUSEASY | MII_ANLPAR_PAUSE | MII_ANLPAR_T4 |
71
+ https://www.raspberrypi.org/documentation/linux/kernel/building.md
88
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
72
+ """
89
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
73
+ deb_url = ('http://archive.raspberrypi.org/debian/'
90
break;
74
+ 'pool/main/r/raspberrypi-firmware/'
91
- case 6: /* Auto-neg Expansion */
75
+ 'raspberrypi-kernel_1.20230106-1_arm64.deb')
92
- val = 1;
76
+ deb_hash = '08dc55696535b18a6d4fe6fa10d4c0d905cbb2ed'
93
+ case MII_ANER:
77
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
94
+ val = MII_ANER_NWAY;
78
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel8.img')
95
break;
79
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2711-rpi-4-b.dtb')
96
case 29: /* Interrupt source. */
80
+
97
val = s->ints;
81
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
98
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
82
+ '86b2be1384d41c8c388e63078a847f1e1c4cb1de/rootfs/'
99
trace_lan9118_phy_write(val, reg);
83
+ 'arm64/rootfs.cpio.gz')
100
84
+ initrd_hash = 'f3d4f9fa92a49aa542f1b44d34be77bbf8ca5b9d'
101
switch (reg) {
85
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
102
- case 0: /* Basic Control */
86
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
103
- if (val & 0x8000) {
87
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
104
+ case MII_BMCR:
88
+
105
+ if (val & MII_BMCR_RESET) {
89
+ self.vm.set_console()
106
lan9118_phy_reset(s);
90
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
107
} else {
91
+ 'earlycon=pl011,mmio32,0xfe201000 ' +
108
- s->control = val & 0x7980;
92
+ 'console=ttyAMA0,115200 ' +
109
+ s->control = val & (MII_BMCR_LOOPBACK | MII_BMCR_SPEED100 |
93
+ 'panic=-1 noreboot ' +
110
+ MII_BMCR_AUTOEN | MII_BMCR_PDOWN | MII_BMCR_FD |
94
+ 'dwc_otg.fiq_fsm_enable=0')
111
+ MII_BMCR_CTST);
95
+ self.vm.add_args('-kernel', kernel_path,
112
/* Complete autonegotiation immediately. */
96
+ '-dtb', dtb_path,
113
- if (val & 0x1000) {
97
+ '-initrd', initrd_path,
114
- s->status |= 0x0020;
98
+ '-append', kernel_command_line,
115
+ if (val & MII_BMCR_AUTOEN) {
99
+ '-no-reboot')
116
+ s->status |= MII_BMSR_AN_COMP;
100
+ # When PCI is supported we can add a USB controller:
117
}
101
+ # '-device', 'qemu-xhci,bus=pcie.1,id=xhci',
118
}
102
+ # '-device', 'usb-kbd,bus=xhci.0',
119
break;
103
+ self.vm.launch()
120
- case 4: /* Auto-neg advertisement */
104
+ self.wait_for_console_pattern('Boot successful.')
121
- s->advertise = (val & 0x2d7f) | 0x80;
105
+
122
+ case MII_ANAR:
106
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
123
+ s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
107
+ 'BCM2835')
124
+ MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
108
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
125
+ MII_ANAR_SELECT))
109
+ 'cprman@7e101000')
126
+ | MII_ANAR_TX;
110
+ exec_command_and_wait_for_pattern(self, 'halt', 'reboot: System halted')
127
break;
111
+ # TODO: Raspberry Pi4 doesn't shut down properly with recent kernels
128
case 30: /* Interrupt mask */
112
+ # Wait for VM to shut down gracefully
129
s->int_mask = val & 0xff;
113
+ #self.vm.wait()
130
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
114
+
131
/* Autonegotiation status mirrors link status. */
115
def test_arm_exynos4210_initrd(self):
132
if (link_down) {
116
"""
133
trace_lan9118_phy_update_link("down");
117
:avocado: tags=arch:arm
134
- s->status &= ~0x0024;
135
+ s->status &= ~(MII_BMSR_AN_COMP | MII_BMSR_LINK_ST);
136
s->ints |= PHY_INT_DOWN;
137
} else {
138
trace_lan9118_phy_update_link("up");
139
- s->status |= 0x0024;
140
+ s->status |= MII_BMSR_AN_COMP | MII_BMSR_LINK_ST;
141
s->ints |= PHY_INT_ENERGYON;
142
s->ints |= PHY_INT_AUTONEG_COMPLETE;
143
}
144
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_reset(Lan9118PhyState *s)
145
{
146
trace_lan9118_phy_reset();
147
148
- s->control = 0x3000;
149
- s->status = 0x7809;
150
- s->advertise = 0x01e1;
151
+ s->control = MII_BMCR_AUTOEN | MII_BMCR_SPEED100;
152
+ s->status = MII_BMSR_100TX_FD
153
+ | MII_BMSR_100TX_HD
154
+ | MII_BMSR_10T_FD
155
+ | MII_BMSR_10T_HD
156
+ | MII_BMSR_AUTONEG
157
+ | MII_BMSR_EXTCAP;
158
+ s->advertise = MII_ANAR_TXFD
159
+ | MII_ANAR_TX
160
+ | MII_ANAR_10FD
161
+ | MII_ANAR_10
162
+ | MII_ANAR_CSMACD;
163
s->int_mask = 0;
164
s->ints = 0;
165
lan9118_phy_update_link(s, s->link_down);
118
--
166
--
119
2.34.1
167
2.34.1
diff view generated by jsdifflib
1
From: Abhiram Tilak <atp.exp@gmail.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
A few watchdog devices use qemu_system_reset_request(). This is not ideal since
3
The real device advertises this mode and the device model already advertises
4
behaviour of watchdog-expiry can't be changed by QMP using `watchdog_action`.
4
100 mbps half duplex and 10 mbps full+half duplex. So advertise this mode to
5
As stated in BiteSizedTasks wiki page, instead of using qemu_system_reset_request()
5
make the model more realistic.
6
to reset when a watchdog timer expires, let watchdog_perform_action() decide
7
what to do.
8
6
9
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2124
10
Signed-off-by: Abhiram Tilak <atp.exp@gmail.com>
11
Message-id: 20240216192612.30838-4-atp.exp@gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
9
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
Message-id: 20241102125724.532843-6-shentey@gmail.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
12
---
15
hw/rtc/m48t59.c | 4 ++--
13
hw/net/lan9118_phy.c | 4 ++--
16
1 file changed, 2 insertions(+), 2 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
17
15
18
diff --git a/hw/rtc/m48t59.c b/hw/rtc/m48t59.c
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/rtc/m48t59.c
18
--- a/hw/net/lan9118_phy.c
21
+++ b/hw/rtc/m48t59.c
19
+++ b/hw/net/lan9118_phy.c
22
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
23
#include "qemu/bcd.h"
21
break;
24
#include "qemu/module.h"
22
case MII_ANAR:
25
#include "trace.h"
23
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
26
+#include "sysemu/watchdog.h"
24
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
27
25
- MII_ANAR_SELECT))
28
#include "m48t59-internal.h"
26
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
29
#include "migration/vmstate.h"
27
+ MII_ANAR_10 | MII_ANAR_SELECT))
30
@@ -XXX,XX +XXX,XX @@ static void watchdog_cb (void *opaque)
28
| MII_ANAR_TX;
31
if (NVRAM->buffer[0x1FF7] & 0x80) {
29
break;
32
NVRAM->buffer[0x1FF7] = 0x00;
30
case 30: /* Interrupt mask */
33
NVRAM->buffer[0x1FFC] &= ~0x40;
34
- /* May it be a hw CPU Reset instead ? */
35
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
36
+ watchdog_perform_action();
37
} else {
38
qemu_set_irq(NVRAM->IRQ, 1);
39
qemu_set_irq(NVRAM->IRQ, 0);
40
--
31
--
41
2.34.1
32
2.34.1
diff view generated by jsdifflib
New patch
1
For IEEE fused multiply-add, the (0 * inf) + NaN case should raise
2
Invalid for the multiplication of 0 by infinity. Currently we handle
3
this in the per-architecture ifdef ladder in pickNaNMulAdd().
4
However, since this isn't really architecture specific we can hoist
5
it up to the generic code.
1
6
7
For the cases where the infzero test in pickNaNMulAdd was
8
returning 2, we can delete the check entirely and allow the
9
code to fall into the normal pick-a-NaN handling, because this
10
will return 2 anyway (input 'c' being the only NaN in this case).
11
For the cases where infzero was returning 3 to indicate "return
12
the default NaN", we must retain that "return 3".
13
14
For Arm, this looks like it might be a behaviour change because we
15
used to set float_flag_invalid | float_flag_invalid_imz only if C is
16
a quiet NaN. However, it is not, because Arm target code never looks
17
at float_flag_invalid_imz, and for the (0 * inf) + SNaN case we
18
already raised float_flag_invalid via the "abc_mask &
19
float_cmask_snan" check in pick_nan_muladd.
20
21
For any target architecture using the "default implementation" at the
22
bottom of the ifdef, this is a behaviour change but will be fixing a
23
bug (where we failed to raise the Invalid exception for (0 * inf +
24
QNaN). The architectures using the default case are:
25
* hppa
26
* i386
27
* sh4
28
* tricore
29
30
The x86, Tricore and SH4 CPU architecture manuals are clear that this
31
should have raised Invalid; HPPA is a bit vaguer but still seems
32
clear enough.
33
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
36
Message-id: 20241202131347.498124-2-peter.maydell@linaro.org
37
---
38
fpu/softfloat-parts.c.inc | 13 +++++++------
39
fpu/softfloat-specialize.c.inc | 29 +----------------------------
40
2 files changed, 8 insertions(+), 34 deletions(-)
41
42
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
43
index XXXXXXX..XXXXXXX 100644
44
--- a/fpu/softfloat-parts.c.inc
45
+++ b/fpu/softfloat-parts.c.inc
46
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
47
int ab_mask, int abc_mask)
48
{
49
int which;
50
+ bool infzero = (ab_mask == float_cmask_infzero);
51
52
if (unlikely(abc_mask & float_cmask_snan)) {
53
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
54
}
55
56
- which = pickNaNMulAdd(a->cls, b->cls, c->cls,
57
- ab_mask == float_cmask_infzero, s);
58
+ if (infzero) {
59
+ /* This is (0 * inf) + NaN or (inf * 0) + NaN */
60
+ float_raise(float_flag_invalid | float_flag_invalid_imz, s);
61
+ }
62
+
63
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
64
65
if (s->default_nan_mode || which == 3) {
66
- /*
67
- * Note that this check is after pickNaNMulAdd so that function
68
- * has an opportunity to set the Invalid flag for infzero.
69
- */
70
parts_default_nan(a, s);
71
return a;
72
}
73
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
74
index XXXXXXX..XXXXXXX 100644
75
--- a/fpu/softfloat-specialize.c.inc
76
+++ b/fpu/softfloat-specialize.c.inc
77
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
78
* the default NaN
79
*/
80
if (infzero && is_qnan(c_cls)) {
81
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
82
return 3;
83
}
84
85
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
86
* case sets InvalidOp and returns the default NaN
87
*/
88
if (infzero) {
89
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
90
return 3;
91
}
92
/* Prefer sNaN over qNaN, in the a, b, c order. */
93
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
94
* For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
95
* case sets InvalidOp and returns the input value 'c'
96
*/
97
- if (infzero) {
98
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
99
- return 2;
100
- }
101
/* Prefer sNaN over qNaN, in the c, a, b order. */
102
if (is_snan(c_cls)) {
103
return 2;
104
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
105
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
106
* case sets InvalidOp and returns the input value 'c'
107
*/
108
- if (infzero) {
109
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
110
- return 2;
111
- }
112
+
113
/* Prefer sNaN over qNaN, in the c, a, b order. */
114
if (is_snan(c_cls)) {
115
return 2;
116
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
117
* to return an input NaN if we have one (ie c) rather than generating
118
* a default NaN
119
*/
120
- if (infzero) {
121
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
122
- return 2;
123
- }
124
125
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
126
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
127
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
128
return 1;
129
}
130
#elif defined(TARGET_RISCV)
131
- /* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */
132
- if (infzero) {
133
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
134
- }
135
return 3; /* default NaN */
136
#elif defined(TARGET_S390X)
137
if (infzero) {
138
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
139
return 3;
140
}
141
142
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
143
return 2;
144
}
145
#elif defined(TARGET_SPARC)
146
- /* For (inf,0,nan) return c. */
147
- if (infzero) {
148
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
149
- return 2;
150
- }
151
/* Prefer SNaN over QNaN, order C, B, A. */
152
if (is_snan(c_cls)) {
153
return 2;
154
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
155
* For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
156
* an input NaN if we have one (ie c).
157
*/
158
- if (infzero) {
159
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
160
- return 2;
161
- }
162
if (status->use_first_nan) {
163
if (is_nan(a_cls)) {
164
return 0;
165
--
166
2.34.1
diff view generated by jsdifflib
New patch
1
If the target sets default_nan_mode then we're always going to return
2
the default NaN, and pickNaNMulAdd() no longer has any side effects.
3
For consistency with pickNaN(), check for default_nan_mode before
4
calling pickNaNMulAdd().
1
5
6
When we convert pickNaNMulAdd() to allow runtime selection of the NaN
7
propagation rule, this means we won't have to make the targets which
8
use default_nan_mode also set a propagation rule.
9
10
Since RiscV always uses default_nan_mode, this allows us to remove
11
its ifdef case from pickNaNMulAdd().
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-3-peter.maydell@linaro.org
16
---
17
fpu/softfloat-parts.c.inc | 8 ++++++--
18
fpu/softfloat-specialize.c.inc | 9 +++++++--
19
2 files changed, 13 insertions(+), 4 deletions(-)
20
21
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
index XXXXXXX..XXXXXXX 100644
23
--- a/fpu/softfloat-parts.c.inc
24
+++ b/fpu/softfloat-parts.c.inc
25
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
26
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
27
}
28
29
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
30
+ if (s->default_nan_mode) {
31
+ which = 3;
32
+ } else {
33
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ }
35
36
- if (s->default_nan_mode || which == 3) {
37
+ if (which == 3) {
38
parts_default_nan(a, s);
39
return a;
40
}
41
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
42
index XXXXXXX..XXXXXXX 100644
43
--- a/fpu/softfloat-specialize.c.inc
44
+++ b/fpu/softfloat-specialize.c.inc
45
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
46
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
47
bool infzero, float_status *status)
48
{
49
+ /*
50
+ * We guarantee not to require the target to tell us how to
51
+ * pick a NaN if we're always returning the default NaN.
52
+ * But if we're not in default-NaN mode then the target must
53
+ * specify.
54
+ */
55
+ assert(!status->default_nan_mode);
56
#if defined(TARGET_ARM)
57
/* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
58
* the default NaN
59
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
60
} else {
61
return 1;
62
}
63
-#elif defined(TARGET_RISCV)
64
- return 3; /* default NaN */
65
#elif defined(TARGET_S390X)
66
if (infzero) {
67
return 3;
68
--
69
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
IEEE 758 does not define a fixed rule for what NaN to return in
2
2
the case of a fused multiply-add of inf * 0 + NaN. Different
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
3
architectures thus do different things:
4
Message-id: 20240226000259.2752893-41-sergey.kambalin@auriga.com
4
* some return the default NaN
5
* some return the input NaN
6
* Arm returns the default NaN if the input NaN is quiet,
7
and the input NaN if it is signalling
8
9
We want to make this logic be runtime selected rather than
10
hardcoded into the binary, because:
11
* this will let us have multiple targets in one QEMU binary
12
* the Arm FEAT_AFP architectural feature includes letting
13
the guest select a NaN propagation rule at runtime
14
15
In this commit we add an enum for the propagation rule, the field in
16
float_status, and the corresponding getters and setters. We change
17
pickNaNMulAdd to honour this, but because all targets still leave
18
this field at its default 0 value, the fallback logic will pick the
19
rule type with the old ifdef ladder.
20
21
Note that four architectures both use the muladd softfloat functions
22
and did not have a branch of the ifdef ladder to specify their
23
behaviour (and so were ending up with the "default" case, probably
24
wrongly): i386, HPPA, SH4 and Tricore. SH4 and Tricore both set
25
default_nan_mode, and so will never get into pickNaNMulAdd(). For
26
HPPA and i386 we retain the same behaviour as the old default-case,
27
which is to not ever return the default NaN. This might not be
28
correct but it is not a behaviour change.
29
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
7
---
33
---
8
tests/qtest/bcm2838-mbox-property-test.c | 19 +++++++++++++++++++
34
include/fpu/softfloat-helpers.h | 11 ++++
9
1 file changed, 19 insertions(+)
35
include/fpu/softfloat-types.h | 23 +++++++++
10
36
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
11
diff --git a/tests/qtest/bcm2838-mbox-property-test.c b/tests/qtest/bcm2838-mbox-property-test.c
37
3 files changed, 95 insertions(+), 30 deletions(-)
38
39
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
12
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qtest/bcm2838-mbox-property-test.c
41
--- a/include/fpu/softfloat-helpers.h
14
+++ b/tests/qtest/bcm2838-mbox-property-test.c
42
+++ b/include/fpu/softfloat-helpers.h
15
@@ -XXX,XX +XXX,XX @@ DECLARE_TEST_CASE_SETUP(GET_MIN_CLOCK_RATE, ANY) {
43
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
16
tag->request.value.clock_id = CLOCK_ID_UNDEFINED;
44
status->float_2nan_prop_rule = rule;
17
}
45
}
18
46
19
+/*----------------------------------------------------------------------------*/
47
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
20
+DECLARE_TEST_CASE(GET_CLOCKS) {
48
+ float_status *status)
21
+ g_assert_cmphex(tag->response.value.root_clock, ==, CLOCK_ID_ROOT);
49
+{
22
+ g_assert_cmphex(tag->response.value.arm_clock, ==, CLOCK_ID_ARM);
50
+ status->float_infzeronan_rule = rule;
23
+}
51
+}
24
+
52
+
25
/*----------------------------------------------------------------------------*/
53
static inline void set_flush_to_zero(bool val, float_status *status)
26
DECLARE_TEST_CASE(GET_TEMPERATURE) {
54
{
27
g_assert_cmphex(tag->response.value.temperature_id, ==, TEMPERATURE_ID_SOC);
55
status->flush_to_zero = val;
28
@@ -XXX,XX +XXX,XX @@ DECLARE_TEST_CASE(GET_COMMAND_LINE) {
56
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
29
/* No special checks are needed for this test case */
57
return status->float_2nan_prop_rule;
30
}
58
}
31
59
32
+/*----------------------------------------------------------------------------*/
60
+static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
33
+DECLARE_TEST_CASE(GET_THROTTLED) {
61
+{
34
+ g_assert_cmpint(tag->response.value.throttled, ==, 0);
62
+ return status->float_infzeronan_rule;
35
+}
63
+}
36
+
64
+
37
/*----------------------------------------------------------------------------*/
65
static inline bool get_flush_to_zero(float_status *status)
38
DECLARE_TEST_CASE(FRAMEBUFFER_GET_NUM_DISPLAYS) {
39
g_assert_cmpint(tag->response.value.num_displays, ==, 1);
40
@@ -XXX,XX +XXX,XX @@ DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_PITCH) {
41
tag->request.value.pitch = DUMMY_VALUE;
42
}
43
44
+/*----------------------------------------------------------------------------*/
45
+DECLARE_TEST_CASE(VCHIQ_INIT) {
46
+ g_assert_cmpint(tag->response.value.zero, ==, 0);
47
+}
48
+
49
/*----------------------------------------------------------------------------*/
50
int main(int argc, char **argv)
51
{
66
{
52
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
67
return status->flush_to_zero;
53
QTEST_ADD_TEST_CASE(GET_CLOCK_RATE, ANY);
68
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
54
QTEST_ADD_TEST_CASE(GET_MAX_CLOCK_RATE, ANY);
69
index XXXXXXX..XXXXXXX 100644
55
QTEST_ADD_TEST_CASE(GET_MIN_CLOCK_RATE, ANY);
70
--- a/include/fpu/softfloat-types.h
56
+ QTEST_ADD_TEST_CASE(GET_CLOCKS);
71
+++ b/include/fpu/softfloat-types.h
57
QTEST_ADD_TEST_CASE(GET_TEMPERATURE);
72
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
58
QTEST_ADD_TEST_CASE(GET_MAX_TEMPERATURE);
73
float_2nan_prop_x87,
59
QTEST_ADD_TEST_CASE(FRAMEBUFFER_ALLOCATE);
74
} Float2NaNPropRule;
60
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
75
61
QTEST_ADD_TEST_CASE(GET_COMMAND_LINE);
76
+/*
62
QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_NUM_DISPLAYS);
77
+ * Rule for result of fused multiply-add 0 * Inf + NaN.
63
QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_PITCH);
78
+ * This must be a NaN, but implementations differ on whether this
64
+ QTEST_ADD_TEST_CASE(GET_THROTTLED);
79
+ * is the input NaN or the default NaN.
65
+ QTEST_ADD_TEST_CASE(VCHIQ_INIT);
80
+ *
66
81
+ * You don't need to set this if default_nan_mode is enabled.
67
return g_test_run();
82
+ * When not in default-NaN mode, it is an error for the target
68
}
83
+ * not to set the rule in float_status if it uses muladd, and we
84
+ * will assert if we need to handle an input NaN and no rule was
85
+ * selected.
86
+ */
87
+typedef enum __attribute__((__packed__)) {
88
+ /* No propagation rule specified */
89
+ float_infzeronan_none = 0,
90
+ /* Result is never the default NaN (so always the input NaN) */
91
+ float_infzeronan_dnan_never,
92
+ /* Result is always the default NaN */
93
+ float_infzeronan_dnan_always,
94
+ /* Result is the default NaN if the input NaN is quiet */
95
+ float_infzeronan_dnan_if_qnan,
96
+} FloatInfZeroNaNRule;
97
+
98
/*
99
* Floating Point Status. Individual architectures may maintain
100
* several versions of float_status for different functions. The
101
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
102
FloatRoundMode float_rounding_mode;
103
FloatX80RoundPrec floatx80_rounding_precision;
104
Float2NaNPropRule float_2nan_prop_rule;
105
+ FloatInfZeroNaNRule float_infzeronan_rule;
106
bool tininess_before_rounding;
107
/* should denormalised results go to zero and set the inexact flag? */
108
bool flush_to_zero;
109
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
110
index XXXXXXX..XXXXXXX 100644
111
--- a/fpu/softfloat-specialize.c.inc
112
+++ b/fpu/softfloat-specialize.c.inc
113
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
114
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
115
bool infzero, float_status *status)
116
{
117
+ FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
118
+
119
/*
120
* We guarantee not to require the target to tell us how to
121
* pick a NaN if we're always returning the default NaN.
122
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
123
* specify.
124
*/
125
assert(!status->default_nan_mode);
126
+
127
+ if (rule == float_infzeronan_none) {
128
+ /*
129
+ * Temporarily fall back to ifdef ladder
130
+ */
131
#if defined(TARGET_ARM)
132
- /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
133
- * the default NaN
134
- */
135
- if (infzero && is_qnan(c_cls)) {
136
- return 3;
137
+ /*
138
+ * For ARM, the (inf,zero,qnan) case returns the default NaN,
139
+ * but (inf,zero,snan) returns the input NaN.
140
+ */
141
+ rule = float_infzeronan_dnan_if_qnan;
142
+#elif defined(TARGET_MIPS)
143
+ if (snan_bit_is_one(status)) {
144
+ /*
145
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
146
+ * case sets InvalidOp and returns the default NaN
147
+ */
148
+ rule = float_infzeronan_dnan_always;
149
+ } else {
150
+ /*
151
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
152
+ * case sets InvalidOp and returns the input value 'c'
153
+ */
154
+ rule = float_infzeronan_dnan_never;
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();
188
+ }
189
+ }
190
+
191
+#if defined(TARGET_ARM)
192
+
193
/* This looks different from the ARM ARM pseudocode, because the ARM ARM
194
* puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
195
*/
196
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
197
}
198
#elif defined(TARGET_MIPS)
199
if (snan_bit_is_one(status)) {
200
- /*
201
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
202
- * case sets InvalidOp and returns the default NaN
203
- */
204
- if (infzero) {
205
- return 3;
206
- }
207
/* Prefer sNaN over qNaN, in the a, b, c order. */
208
if (is_snan(a_cls)) {
209
return 0;
210
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
211
return 2;
212
}
213
} else {
214
- /*
215
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
216
- * case sets InvalidOp and returns the input value 'c'
217
- */
218
/* Prefer sNaN over qNaN, in the c, a, b order. */
219
if (is_snan(c_cls)) {
220
return 2;
221
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
222
}
223
}
224
#elif defined(TARGET_LOONGARCH64)
225
- /*
226
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
227
- * case sets InvalidOp and returns the input value 'c'
228
- */
229
-
230
/* Prefer sNaN over qNaN, in the c, a, b order. */
231
if (is_snan(c_cls)) {
232
return 2;
233
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
234
return 1;
235
}
236
#elif defined(TARGET_PPC)
237
- /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
238
- * to return an input NaN if we have one (ie c) rather than generating
239
- * a default NaN
240
- */
241
-
242
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
243
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
244
*/
245
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
246
return 1;
247
}
248
#elif defined(TARGET_S390X)
249
- if (infzero) {
250
- return 3;
251
- }
252
-
253
if (is_snan(a_cls)) {
254
return 0;
255
} else if (is_snan(b_cls)) {
69
--
256
--
70
2.34.1
257
2.34.1
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for the inf-zero-nan
2
muladd special case. In meson.build we put -DTARGET_ARM in fpcflags,
3
and so we should select here the Arm rule of
4
float_infzeronan_dnan_if_qnan.
1
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241202131347.498124-5-peter.maydell@linaro.org
9
---
10
tests/fp/fp-bench.c | 5 +++++
11
tests/fp/fp-test.c | 5 +++++
12
2 files changed, 10 insertions(+)
13
14
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/fp/fp-bench.c
17
+++ b/tests/fp/fp-bench.c
18
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
19
{
20
bench_func_t f;
21
22
+ /*
23
+ * These implementation-defined choices for various things IEEE
24
+ * doesn't specify match those used by the Arm architecture.
25
+ */
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
28
29
f = bench_funcs[operation][precision];
30
g_assert(f);
31
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/tests/fp/fp-test.c
34
+++ b/tests/fp/fp-test.c
35
@@ -XXX,XX +XXX,XX @@ void run_test(void)
36
{
37
unsigned int i;
38
39
+ /*
40
+ * These implementation-defined choices for various things IEEE
41
+ * doesn't specify match those used by the Arm architecture.
42
+ */
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
44
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
45
46
genCases_setLevel(test_level);
47
verCases_maxErrorCount = n_max_errors;
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the Arm target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-6-peter.maydell@linaro.org
7
---
8
target/arm/cpu.c | 3 +++
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 4 insertions(+), 7 deletions(-)
11
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
17
* * tininess-before-rounding
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
20
+ * * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
21
+ * and the input NaN if it is signalling
22
*/
23
static void arm_set_default_fp_behaviours(float_status *s)
24
{
25
set_float_detect_tininess(float_tininess_before_rounding, s);
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
28
}
29
30
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
/*
37
* Temporarily fall back to ifdef ladder
38
*/
39
-#if defined(TARGET_ARM)
40
- /*
41
- * For ARM, the (inf,zero,qnan) case returns the default NaN,
42
- * but (inf,zero,snan) returns the input NaN.
43
- */
44
- rule = float_infzeronan_dnan_if_qnan;
45
-#elif defined(TARGET_MIPS)
46
+#if defined(TARGET_MIPS)
47
if (snan_bit_is_one(status)) {
48
/*
49
* For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
50
--
51
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for s390, so we
2
can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-7-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_infzeronan_rule(float_infzeronan_dnan_always,
21
+ &env->fpu_status);
22
/* fall through */
23
case RESET_TYPE_S390_CPU_NORMAL:
24
env->psw.mask &= ~PSW_MASK_RI;
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
* a default NaN
31
*/
32
rule = float_infzeronan_dnan_never;
33
-#elif defined(TARGET_S390X)
34
- rule = float_infzeronan_dnan_always;
35
#endif
36
}
37
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the PPC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-8-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 7 +++++++
9
fpu/softfloat-specialize.c.inc | 7 +------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
22
+ * to return an input NaN if we have one (ie c) rather than generating
23
+ * a default NaN
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
27
28
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
29
ppc_spr_t *spr = &env->spr_cb[i];
30
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
31
index XXXXXXX..XXXXXXX 100644
32
--- a/fpu/softfloat-specialize.c.inc
33
+++ b/fpu/softfloat-specialize.c.inc
34
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
*/
36
rule = float_infzeronan_dnan_never;
37
}
38
-#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
39
+#elif defined(TARGET_SPARC) || \
40
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
41
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
42
/*
43
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
44
* case sets InvalidOp and returns the input value 'c'
45
*/
46
- /*
47
- * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
48
- * to return an input NaN if we have one (ie c) rather than generating
49
- * a default NaN
50
- */
51
rule = float_infzeronan_dnan_never;
52
#endif
53
}
54
--
55
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the MIPS target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-9-peter.maydell@linaro.org
7
---
8
target/mips/fpu_helper.h | 9 +++++++++
9
target/mips/msa.c | 4 ++++
10
fpu/softfloat-specialize.c.inc | 16 +---------------
11
3 files changed, 14 insertions(+), 15 deletions(-)
12
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/mips/fpu_helper.h
16
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_flush_mode(CPUMIPSState *env)
18
static inline void restore_snan_bit_mode(CPUMIPSState *env)
19
{
20
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
21
+ FloatInfZeroNaNRule izn_rule;
22
23
/*
24
* With nan2008, SNaNs are silenced in the usual way.
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
26
*/
27
set_snan_bit_is_one(!nan2008, &env->active_fpu.fp_status);
28
set_default_nan_mode(!nan2008, &env->active_fpu.fp_status);
29
+ /*
30
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
31
+ * case sets InvalidOp and returns the default NaN.
32
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
33
+ * case sets InvalidOp and returns the input value 'c'.
34
+ */
35
+ izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
36
+ set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
37
}
38
39
static inline void restore_fp_status(CPUMIPSState *env)
40
diff --git a/target/mips/msa.c b/target/mips/msa.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/mips/msa.c
43
+++ b/target/mips/msa.c
44
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
45
46
/* set proper signanling bit meaning ("1" means "quiet") */
47
set_snan_bit_is_one(0, &env->active_tc.msa_fp_status);
48
+
49
+ /* Inf * 0 + NaN returns the input NaN */
50
+ set_float_infzeronan_rule(float_infzeronan_dnan_never,
51
+ &env->active_tc.msa_fp_status);
52
}
53
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
54
index XXXXXXX..XXXXXXX 100644
55
--- a/fpu/softfloat-specialize.c.inc
56
+++ b/fpu/softfloat-specialize.c.inc
57
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
58
/*
59
* Temporarily fall back to ifdef ladder
60
*/
61
-#if defined(TARGET_MIPS)
62
- if (snan_bit_is_one(status)) {
63
- /*
64
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
65
- * case sets InvalidOp and returns the default NaN
66
- */
67
- rule = float_infzeronan_dnan_always;
68
- } else {
69
- /*
70
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
71
- * case sets InvalidOp and returns the input value 'c'
72
- */
73
- rule = float_infzeronan_dnan_never;
74
- }
75
-#elif defined(TARGET_SPARC) || \
76
+#if defined(TARGET_SPARC) || \
77
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
78
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
79
/*
80
--
81
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the SPARC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-10-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
23
cpu_exec_realizefn(cs, &local_err);
24
if (local_err != NULL) {
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_SPARC) || \
34
- defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
35
+#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
36
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
37
/*
38
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the xtensa target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-11-peter.maydell@linaro.org
7
---
8
target/xtensa/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 +-
10
2 files changed, 3 insertions(+), 1 deletion(-)
11
12
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/xtensa/cpu.c
15
+++ b/target/xtensa/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
17
reset_mmu(env);
18
cs->halted = env->runstall;
19
#endif
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
set_no_signaling_nans(!dfpu, &env->fp_status);
23
xtensa_use_first_nan(env, !dfpu);
24
}
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
34
+#if defined(TARGET_HPPA) || \
35
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
36
/*
37
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the x86 target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-12-peter.maydell@linaro.org
6
---
7
target/i386/tcg/fpu_helper.c | 7 +++++++
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 8 insertions(+), 1 deletion(-)
10
11
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/i386/tcg/fpu_helper.c
14
+++ b/target/i386/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->mmx_status);
18
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->sse_status);
19
+ /*
20
+ * Only SSE has multiply-add instructions. In the SDM Section 14.5.2
21
+ * "Fused-Multiply-ADD (FMA) Numeric Behavior" the NaN handling is
22
+ * specified -- for 0 * inf + NaN the input NaN is selected, and if
23
+ * there are multiple input NaNs they are selected in the order a, b, c.
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
26
}
27
28
static inline uint8_t save_exception_flags(CPUX86State *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
34
* Temporarily fall back to ifdef ladder
35
*/
36
#if defined(TARGET_HPPA) || \
37
- defined(TARGET_I386) || defined(TARGET_LOONGARCH)
38
+ defined(TARGET_LOONGARCH)
39
/*
40
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
41
* case sets InvalidOp and returns the input value 'c'
42
--
43
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the loongarch target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-13-peter.maydell@linaro.org
6
---
7
target/loongarch/tcg/fpu_helper.c | 5 +++++
8
fpu/softfloat-specialize.c.inc | 7 +------
9
2 files changed, 6 insertions(+), 6 deletions(-)
10
11
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/tcg/fpu_helper.c
14
+++ b/target/loongarch/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
16
&env->fp_status);
17
set_flush_to_zero(0, &env->fp_status);
18
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
19
+ /*
20
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
21
+ * case sets InvalidOp and returns the input value 'c'
22
+ */
23
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
}
25
26
int ieee_ex_to_loongarch(int xcpt)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
index XXXXXXX..XXXXXXX 100644
29
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
32
/*
33
* Temporarily fall back to ifdef ladder
34
*/
35
-#if defined(TARGET_HPPA) || \
36
- defined(TARGET_LOONGARCH)
37
- /*
38
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
- * case sets InvalidOp and returns the input value 'c'
40
- */
41
+#if defined(TARGET_HPPA)
42
rule = float_infzeronan_dnan_never;
43
#endif
44
}
45
--
46
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the HPPA target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
As this is the last target to be converted to explicitly setting
5
the rule, we can remove the fallback code in pickNaNMulAdd()
6
entirely.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20241202131347.498124-14-peter.maydell@linaro.org
11
---
12
target/hppa/fpu_helper.c | 2 ++
13
fpu/softfloat-specialize.c.inc | 13 +------------
14
2 files changed, 3 insertions(+), 12 deletions(-)
15
16
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/hppa/fpu_helper.c
19
+++ b/target/hppa/fpu_helper.c
20
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
21
* HPPA does note implement a CPU reset method at all...
22
*/
23
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
24
+ /* For inf * 0 + NaN, return the input NaN */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
}
27
28
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
34
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
bool infzero, float_status *status)
36
{
37
- FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
38
-
39
/*
40
* We guarantee not to require the target to tell us how to
41
* pick a NaN if we're always returning the default NaN.
42
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
43
*/
44
assert(!status->default_nan_mode);
45
46
- if (rule == float_infzeronan_none) {
47
- /*
48
- * Temporarily fall back to ifdef ladder
49
- */
50
-#if defined(TARGET_HPPA)
51
- rule = float_infzeronan_dnan_never;
52
-#endif
53
- }
54
-
55
if (infzero) {
56
/*
57
* Inf * 0 + NaN -- some implementations return the default NaN here,
58
* and some return the input NaN.
59
*/
60
- switch (rule) {
61
+ switch (status->float_infzeronan_rule) {
62
case float_infzeronan_dnan_never:
63
return 2;
64
case float_infzeronan_dnan_always:
65
--
66
2.34.1
diff view generated by jsdifflib
New patch
1
The new implementation of pickNaNMulAdd() will find it convenient
2
to know whether at least one of the three arguments to the muladd
3
was a signaling NaN. We already calculate that in the caller,
4
so pass it in as a new bool have_snan.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-15-peter.maydell@linaro.org
9
---
10
fpu/softfloat-parts.c.inc | 5 +++--
11
fpu/softfloat-specialize.c.inc | 2 +-
12
2 files changed, 4 insertions(+), 3 deletions(-)
13
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat-parts.c.inc
17
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
19
{
20
int which;
21
bool infzero = (ab_mask == float_cmask_infzero);
22
+ bool have_snan = (abc_mask & float_cmask_snan);
23
24
- if (unlikely(abc_mask & float_cmask_snan)) {
25
+ if (unlikely(have_snan)) {
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
27
}
28
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
if (s->default_nan_mode) {
31
which = 3;
32
} else {
33
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
35
}
36
37
if (which == 3) {
38
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
39
index XXXXXXX..XXXXXXX 100644
40
--- a/fpu/softfloat-specialize.c.inc
41
+++ b/fpu/softfloat-specialize.c.inc
42
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
43
| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
44
*----------------------------------------------------------------------------*/
45
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
46
- bool infzero, float_status *status)
47
+ bool infzero, bool have_snan, float_status *status)
48
{
49
/*
50
* We guarantee not to require the target to tell us how to
51
--
52
2.34.1
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
1
IEEE 758 does not define a fixed rule for which NaN to pick as the
2
2
result if both operands of a 3-operand fused multiply-add operation
3
This property allows users to change flash model on command line as
3
are NaNs. As a result different architectures have ended up with
4
below.
4
different rules for propagating NaNs.
5
5
6
ex: "-M xlnx-versal-virt,ospi-flash=mt35xu02gbba"
6
QEMU currently hardcodes the NaN propagation logic into the binary
7
7
because pickNaNMulAdd() has an ifdef ladder for different targets.
8
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
8
We want to make the propagation rule instead be selectable at
9
Message-id: 20240220091721.82954-3-sai.pavan.boddu@amd.com
9
runtime, because:
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
* this will let us have multiple targets in one QEMU binary
11
* 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
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20241202131347.498124-16-peter.maydell@linaro.org
12
---
27
---
13
hw/arm/xlnx-versal-virt.c | 44 ++++++++++++++++++++++++++++++++++++++-
28
include/fpu/softfloat-helpers.h | 11 +++
14
1 file changed, 43 insertions(+), 1 deletion(-)
29
include/fpu/softfloat-types.h | 55 +++++++++++
15
30
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
16
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.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
17
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/xlnx-versal-virt.c
35
--- a/include/fpu/softfloat-helpers.h
19
+++ b/hw/arm/xlnx-versal-virt.c
36
+++ b/include/fpu/softfloat-helpers.h
20
@@ -XXX,XX +XXX,XX @@ struct VersalVirt {
37
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
21
struct {
38
status->float_2nan_prop_rule = rule;
22
bool secure;
23
} cfg;
24
+ char *ospi_model;
25
};
26
27
static void fdt_create(VersalVirt *s)
28
@@ -XXX,XX +XXX,XX @@ static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
29
&error_fatal);
30
}
39
}
31
40
32
+static char *versal_get_ospi_model(Object *obj, Error **errp)
41
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
42
+ float_status *status)
33
+{
43
+{
34
+ VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
44
+ status->float_3nan_prop_rule = rule;
35
+
36
+ return g_strdup(s->ospi_model);
37
+}
45
+}
38
+
46
+
39
+static void versal_set_ospi_model(Object *obj, const char *value, Error **errp)
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)
40
+{
55
+{
41
+ VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
56
+ return status->float_3nan_prop_rule;
42
+
43
+ g_free(s->ospi_model);
44
+ s->ospi_model = g_strdup(value);
45
+}
57
+}
46
+
58
+
47
+
59
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
48
static void versal_virt_init(MachineState *machine)
49
{
60
{
50
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
61
return status->float_infzeronan_rule;
51
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
62
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
52
for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
63
index XXXXXXX..XXXXXXX 100644
53
BusState *spi_bus;
64
--- a/include/fpu/softfloat-types.h
54
DeviceState *flash_dev;
65
+++ b/include/fpu/softfloat-types.h
55
+ ObjectClass *flash_klass;
66
@@ -XXX,XX +XXX,XX @@ this code that are retained.
56
qemu_irq cs_line;
67
#ifndef SOFTFLOAT_TYPES_H
57
DriveInfo *dinfo = drive_get(IF_MTD, 0, i);
68
#define SOFTFLOAT_TYPES_H
58
69
59
spi_bus = qdev_get_child_bus(DEVICE(&s->soc.pmc.iou.ospi), "spi0");
70
+#include "hw/registerfields.h"
60
71
+
61
- flash_dev = qdev_new("mt35xu01g");
72
/*
62
+ if (s->ospi_model) {
73
* Software IEC/IEEE floating-point types.
63
+ flash_klass = object_class_by_name(s->ospi_model);
74
*/
64
+ if (!flash_klass ||
75
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
65
+ object_class_is_abstract(flash_klass) ||
76
float_2nan_prop_x87,
66
+ !object_class_dynamic_cast(flash_klass, "m25p80-generic")) {
77
} Float2NaNPropRule;
67
+ error_setg(&error_fatal, "'%s' is either abstract or"
78
68
+ " not a subtype of m25p80", s->ospi_model);
79
+/*
69
+ return;
80
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
70
+ }
81
+ * architectures have different rules for which input NaN is
71
+ }
82
+ * propagated to the output when there is more than one NaN on the
72
+
83
+ * input.
73
+ flash_dev = qdev_new(s->ospi_model ? s->ospi_model : "mt35xu01g");
84
+ *
74
+
85
+ * If default_nan_mode is enabled then it is valid not to set a NaN
75
if (dinfo) {
86
+ * propagation rule, because the softfloat code guarantees not to try
76
qdev_prop_set_drive_err(flash_dev, "drive",
87
+ * to pick a NaN to propagate in default NaN mode. When not in
77
blk_by_legacy_dinfo(dinfo), &error_fatal);
88
+ * default-NaN mode, it is an error for the target not to set the rule
78
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_instance_init(Object *obj)
89
+ * in float_status if it uses a muladd, and we will assert if we need
79
0);
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
321
+ }
322
+
323
+ assert(rule != float_3nan_prop_none);
324
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
325
+ /* We have at least one SNaN input and should prefer it */
326
+ do {
327
+ which = rule & R_3NAN_1ST_MASK;
328
+ rule >>= R_3NAN_1ST_LENGTH;
329
+ } while (!is_snan(cls[which]));
330
+ } else {
331
+ do {
332
+ which = rule & R_3NAN_1ST_MASK;
333
+ rule >>= R_3NAN_1ST_LENGTH;
334
+ } while (!is_nan(cls[which]));
335
+ }
336
+ return which;
80
}
337
}
81
338
82
+static void versal_virt_machine_finalize(Object *obj)
339
/*----------------------------------------------------------------------------
83
+{
84
+ VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
85
+
86
+ g_free(s->ospi_model);
87
+}
88
+
89
static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
90
{
91
MachineClass *mc = MACHINE_CLASS(oc);
92
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
93
mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
94
mc->no_cdrom = true;
95
mc->default_ram_id = "ddr";
96
+ object_class_property_add_str(oc, "ospi-flash", versal_get_ospi_model,
97
+ versal_set_ospi_model);
98
+ object_class_property_set_description(oc, "ospi-flash",
99
+ "Change the OSPI Flash model");
100
}
101
102
static const TypeInfo versal_virt_machine_init_typeinfo = {
103
@@ -XXX,XX +XXX,XX @@ static const TypeInfo versal_virt_machine_init_typeinfo = {
104
.class_init = versal_virt_machine_class_init,
105
.instance_init = versal_virt_machine_instance_init,
106
.instance_size = sizeof(VersalVirt),
107
+ .instance_finalize = versal_virt_machine_finalize,
108
};
109
110
static void versal_virt_machine_init_register_types(void)
111
--
340
--
112
2.34.1
341
2.34.1
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for propagating NaNs in
2
the muladd case. In meson.build we put -DTARGET_ARM in fpcflags, and
3
so we should select here the Arm rule of float_3nan_prop_s_cab.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-17-peter.maydell@linaro.org
8
---
9
tests/fp/fp-bench.c | 1 +
10
tests/fp/fp-test.c | 1 +
11
2 files changed, 2 insertions(+)
12
13
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/fp/fp-bench.c
16
+++ b/tests/fp/fp-bench.c
17
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
18
* doesn't specify match those used by the Arm architecture.
19
*/
20
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
22
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
23
24
f = bench_funcs[operation][precision];
25
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/fp/fp-test.c
28
+++ b/tests/fp/fp-test.c
29
@@ -XXX,XX +XXX,XX @@ void run_test(void)
30
* doesn't specify match those used by the Arm architecture.
31
*/
32
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
33
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
34
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
35
36
genCases_setLevel(test_level);
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-18-peter.maydell@linaro.org
7
---
8
target/arm/cpu.c | 5 +++++
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 6 insertions(+), 7 deletions(-)
11
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
17
* * tininess-before-rounding
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
20
+ * * 3-input NaN propagation prefers SNaN over QNaN, and then
21
+ * operand C over A over B (see FPProcessNaNs3() pseudocode,
22
+ * but note that for QEMU muladd is a * b + c, whereas for
23
+ * the pseudocode function the arguments are in the order c, a, b.
24
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
25
* and the input NaN if it is signalling
26
*/
27
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
28
{
29
set_float_detect_tininess(float_tininess_before_rounding, s);
30
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
31
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
32
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
33
}
34
35
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
36
index XXXXXXX..XXXXXXX 100644
37
--- a/fpu/softfloat-specialize.c.inc
38
+++ b/fpu/softfloat-specialize.c.inc
39
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
40
}
41
42
if (rule == float_3nan_prop_none) {
43
-#if defined(TARGET_ARM)
44
- /*
45
- * This looks different from the ARM ARM pseudocode, because the ARM ARM
46
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
47
- */
48
- rule = float_3nan_prop_s_cab;
49
-#elif defined(TARGET_MIPS)
50
+#if defined(TARGET_MIPS)
51
if (snan_bit_is_one(status)) {
52
rule = float_3nan_prop_s_abc;
53
} else {
54
--
55
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for loongarch, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-19-peter.maydell@linaro.org
7
---
8
target/loongarch/tcg/fpu_helper.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/loongarch/tcg/fpu_helper.c
15
+++ b/target/loongarch/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
17
* case sets InvalidOp and returns the input value 'c'
18
*/
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
21
}
22
23
int ieee_ex_to_loongarch(int xcpt)
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_LOONGARCH64)
33
- rule = float_3nan_prop_s_cab;
34
#elif defined(TARGET_PPC)
35
/*
36
* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for PPC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-20-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 8 ++++++++
9
fpu/softfloat-specialize.c.inc | 6 ------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * NaN propagation for fused multiply-add:
22
+ * if fRA is a NaN return it; otherwise if fRB is a NaN return it;
23
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
24
+ * whereas QEMU labels the operands as (a * b) + c.
25
+ */
26
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->fp_status);
27
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->vec_status);
28
/*
29
* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
30
* to return an input NaN if we have one (ie c) rather than generating
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
} else {
37
rule = float_3nan_prop_s_cab;
38
}
39
-#elif defined(TARGET_PPC)
40
- /*
41
- * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
42
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
43
- */
44
- rule = float_3nan_prop_acb;
45
#elif defined(TARGET_S390X)
46
rule = float_3nan_prop_s_abc;
47
#elif defined(TARGET_SPARC)
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for s390x, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-21-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
21
set_float_infzeronan_rule(float_infzeronan_dnan_always,
22
&env->fpu_status);
23
/* fall through */
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_S390X)
33
- rule = float_3nan_prop_s_abc;
34
#elif defined(TARGET_SPARC)
35
rule = float_3nan_prop_s_cba;
36
#elif defined(TARGET_XTENSA)
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for SPARC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-22-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For fused-multiply add, prefer SNaN over QNaN, then C->B->A */
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
22
/* For inf * 0 + NaN, return the input NaN */
23
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
} else {
31
rule = float_3nan_prop_s_cab;
32
}
33
-#elif defined(TARGET_SPARC)
34
- rule = float_3nan_prop_s_cba;
35
#elif defined(TARGET_XTENSA)
36
if (status->use_first_nan) {
37
rule = float_3nan_prop_abc;
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-23-peter.maydell@linaro.org
7
---
8
target/mips/fpu_helper.h | 4 ++++
9
target/mips/msa.c | 3 +++
10
fpu/softfloat-specialize.c.inc | 8 +-------
11
3 files changed, 8 insertions(+), 7 deletions(-)
12
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/mips/fpu_helper.h
16
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
18
{
19
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
20
FloatInfZeroNaNRule izn_rule;
21
+ Float3NaNPropRule nan3_rule;
22
23
/*
24
* With nan2008, SNaNs are silenced in the usual way.
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
26
*/
27
izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
28
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
29
+ nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
30
+ set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
31
+
32
}
33
34
static inline void restore_fp_status(CPUMIPSState *env)
35
diff --git a/target/mips/msa.c b/target/mips/msa.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/mips/msa.c
38
+++ b/target/mips/msa.c
39
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
40
set_float_2nan_prop_rule(float_2nan_prop_s_ab,
41
&env->active_tc.msa_fp_status);
42
43
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab,
44
+ &env->active_tc.msa_fp_status);
45
+
46
/* clear float_status exception flags */
47
set_float_exception_flags(0, &env->active_tc.msa_fp_status);
48
49
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
50
index XXXXXXX..XXXXXXX 100644
51
--- a/fpu/softfloat-specialize.c.inc
52
+++ b/fpu/softfloat-specialize.c.inc
53
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
54
}
55
56
if (rule == float_3nan_prop_none) {
57
-#if defined(TARGET_MIPS)
58
- if (snan_bit_is_one(status)) {
59
- rule = float_3nan_prop_s_abc;
60
- } else {
61
- rule = float_3nan_prop_s_cab;
62
- }
63
-#elif defined(TARGET_XTENSA)
64
+#if defined(TARGET_XTENSA)
65
if (status->use_first_nan) {
66
rule = float_3nan_prop_abc;
67
} else {
68
--
69
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the Float3NaNPropRule explicitly for xtensa, and remove the
2
ifdef from pickNaNMulAdd().
2
3
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240226000259.2752893-11-sergey.kambalin@auriga.com
6
[PMM: Change name to 'raspi4b', not 'raspi4b-2g']
7
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-24-peter.maydell@linaro.org
8
---
7
---
9
include/hw/arm/raspi_platform.h | 11 ++++++
8
target/xtensa/fpu_helper.c | 2 ++
10
include/hw/display/bcm2835_fb.h | 2 +
9
fpu/softfloat-specialize.c.inc | 8 --------
11
hw/arm/bcm2835_peripherals.c | 17 ++++++--
10
2 files changed, 2 insertions(+), 8 deletions(-)
12
hw/arm/bcm2836.c | 2 +
13
hw/arm/bcm2838.c | 2 +
14
hw/arm/raspi.c | 27 ++++++++-----
15
hw/arm/raspi4b.c | 70 +++++++++++++++++++++++++++++++++
16
hw/arm/meson.build | 2 +-
17
8 files changed, 119 insertions(+), 14 deletions(-)
18
create mode 100644 hw/arm/raspi4b.c
19
11
20
diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h
12
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/raspi_platform.h
14
--- a/target/xtensa/fpu_helper.c
23
+++ b/include/hw/arm/raspi_platform.h
15
+++ b/target/xtensa/fpu_helper.c
24
@@ -XXX,XX +XXX,XX @@ struct RaspiBaseMachineClass {
16
@@ -XXX,XX +XXX,XX @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
25
uint32_t board_rev;
17
set_use_first_nan(use_first, &env->fp_status);
26
};
18
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
27
19
&env->fp_status);
28
+/* Common functions for raspberry pi machines */
20
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
29
+const char *board_soc_type(uint32_t board_rev);
21
+ &env->fp_status);
30
+void raspi_machine_init(MachineState *machine);
22
}
31
+
23
32
+typedef struct BCM283XBaseState BCM283XBaseState;
24
void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
33
+void raspi_base_machine_init(MachineState *machine,
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
34
+ BCM283XBaseState *soc);
35
+
36
+void raspi_machine_class_common_init(MachineClass *mc,
37
+ uint32_t board_rev);
38
+
39
#define MSYNC_OFFSET 0x0000 /* Multicore Sync Block */
40
#define CCPT_OFFSET 0x1000 /* Compact Camera Port 2 TX */
41
#define INTE_OFFSET 0x2000 /* VC Interrupt controller */
42
diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h
43
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
44
--- a/include/hw/display/bcm2835_fb.h
27
--- a/fpu/softfloat-specialize.c.inc
45
+++ b/include/hw/display/bcm2835_fb.h
28
+++ b/fpu/softfloat-specialize.c.inc
46
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
47
#include "ui/console.h"
48
#include "qom/object.h"
49
50
+#define UPPER_RAM_BASE 0x40000000
51
+
52
#define TYPE_BCM2835_FB "bcm2835-fb"
53
OBJECT_DECLARE_SIMPLE_TYPE(BCM2835FBState, BCM2835_FB)
54
55
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/bcm2835_peripherals.c
58
+++ b/hw/arm/bcm2835_peripherals.c
59
@@ -XXX,XX +XXX,XX @@ static void raspi_peripherals_base_init(Object *obj)
60
/* Framebuffer */
61
object_initialize_child(obj, "fb", &s->fb, TYPE_BCM2835_FB);
62
object_property_add_alias(obj, "vcram-size", OBJECT(&s->fb), "vcram-size");
63
+ object_property_add_alias(obj, "vcram-base", OBJECT(&s->fb), "vcram-base");
64
65
object_property_add_const_link(OBJECT(&s->fb), "dma-mr",
66
OBJECT(&s->gpu_bus_mr));
67
@@ -XXX,XX +XXX,XX @@ void bcm_soc_peripherals_common_realize(DeviceState *dev, Error **errp)
68
Object *obj;
69
MemoryRegion *ram;
70
Error *err = NULL;
71
- uint64_t ram_size, vcram_size;
72
+ uint64_t ram_size, vcram_size, vcram_base;
73
int n;
74
75
obj = object_property_get_link(OBJECT(dev), "ram", &error_abort);
76
@@ -XXX,XX +XXX,XX @@ void bcm_soc_peripherals_common_realize(DeviceState *dev, Error **errp)
77
return;
78
}
30
}
79
31
80
- if (!object_property_set_uint(OBJECT(&s->fb), "vcram-base",
32
if (rule == float_3nan_prop_none) {
81
- ram_size - vcram_size, errp)) {
33
-#if defined(TARGET_XTENSA)
82
+ vcram_base = object_property_get_uint(OBJECT(s), "vcram-base", &err);
34
- if (status->use_first_nan) {
83
+ if (err) {
35
- rule = float_3nan_prop_abc;
84
+ error_propagate(errp, err);
36
- } else {
85
return;
37
- rule = float_3nan_prop_cba;
38
- }
39
-#else
40
rule = float_3nan_prop_abc;
41
-#endif
86
}
42
}
87
43
88
+ if (vcram_base == 0) {
44
assert(rule != float_3nan_prop_none);
89
+ vcram_base = ram_size - vcram_size;
90
+ }
91
+ vcram_base = MIN(vcram_base, UPPER_RAM_BASE - vcram_size);
92
+
93
+ if (!object_property_set_uint(OBJECT(&s->fb), "vcram-base", vcram_base,
94
+ errp)) {
95
+ return;
96
+ }
97
if (!sysbus_realize(SYS_BUS_DEVICE(&s->fb), errp)) {
98
return;
99
}
100
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/arm/bcm2836.c
103
+++ b/hw/arm/bcm2836.c
104
@@ -XXX,XX +XXX,XX @@ static void bcm283x_init(Object *obj)
105
"command-line");
106
object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
107
"vcram-size");
108
+ object_property_add_alias(obj, "vcram-base", OBJECT(&s->peripherals),
109
+ "vcram-base");
110
}
111
112
bool bcm283x_common_realize(DeviceState *dev, BCMSocPeripheralBaseState *ps,
113
diff --git a/hw/arm/bcm2838.c b/hw/arm/bcm2838.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/hw/arm/bcm2838.c
116
+++ b/hw/arm/bcm2838.c
117
@@ -XXX,XX +XXX,XX @@ static void bcm2838_init(Object *obj)
118
"board-rev");
119
object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
120
"vcram-size");
121
+ object_property_add_alias(obj, "vcram-base", OBJECT(&s->peripherals),
122
+ "vcram-base");
123
object_property_add_alias(obj, "command-line", OBJECT(&s->peripherals),
124
"command-line");
125
126
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/arm/raspi.c
129
+++ b/hw/arm/raspi.c
130
@@ -XXX,XX +XXX,XX @@
131
#include "qapi/error.h"
132
#include "hw/arm/boot.h"
133
#include "hw/arm/bcm2836.h"
134
+#include "hw/arm/bcm2838.h"
135
#include "hw/arm/raspi_platform.h"
136
#include "hw/registerfields.h"
137
#include "qemu/error-report.h"
138
@@ -XXX,XX +XXX,XX @@ typedef enum RaspiProcessorId {
139
PROCESSOR_ID_BCM2835 = 0,
140
PROCESSOR_ID_BCM2836 = 1,
141
PROCESSOR_ID_BCM2837 = 2,
142
+ PROCESSOR_ID_BCM2838 = 3,
143
} RaspiProcessorId;
144
145
static const struct {
146
@@ -XXX,XX +XXX,XX @@ static const struct {
147
[PROCESSOR_ID_BCM2835] = {TYPE_BCM2835, 1},
148
[PROCESSOR_ID_BCM2836] = {TYPE_BCM2836, BCM283X_NCPUS},
149
[PROCESSOR_ID_BCM2837] = {TYPE_BCM2837, BCM283X_NCPUS},
150
+ [PROCESSOR_ID_BCM2838] = {TYPE_BCM2838, BCM283X_NCPUS},
151
};
152
153
-static void raspi_base_machine_init(MachineState *machine,
154
- BCM283XBaseState *soc);
155
-static void raspi_machine_class_common_init(MachineClass *mc,
156
- uint32_t board_rev);
157
-
158
static uint64_t board_ram_size(uint32_t board_rev)
159
{
160
assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */
161
@@ -XXX,XX +XXX,XX @@ static RaspiProcessorId board_processor_id(uint32_t board_rev)
162
return proc_id;
163
}
164
165
-static const char *board_soc_type(uint32_t board_rev)
166
+const char *board_soc_type(uint32_t board_rev)
167
{
168
return soc_property[board_processor_id(board_rev)].type;
169
}
170
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, ARMCPU *cpu,
171
arm_load_kernel(cpu, machine, &s->binfo);
172
}
173
174
-static void raspi_base_machine_init(MachineState *machine,
175
+void raspi_base_machine_init(MachineState *machine,
176
BCM283XBaseState *soc)
177
{
178
RaspiBaseMachineClass *mc = RASPI_BASE_MACHINE_GET_CLASS(machine);
179
uint32_t board_rev = mc->board_rev;
180
uint64_t ram_size = board_ram_size(board_rev);
181
- uint32_t vcram_size;
182
+ uint32_t vcram_base, vcram_size;
183
+ size_t boot_ram_size;
184
DriveInfo *di;
185
BlockBackend *blk;
186
BusState *bus;
187
@@ -XXX,XX +XXX,XX @@ static void raspi_base_machine_init(MachineState *machine,
188
189
vcram_size = object_property_get_uint(OBJECT(soc), "vcram-size",
190
&error_abort);
191
+ vcram_base = object_property_get_uint(OBJECT(soc), "vcram-base",
192
+ &error_abort);
193
+
194
+ if (vcram_base == 0) {
195
+ vcram_base = ram_size - vcram_size;
196
+ }
197
+ boot_ram_size = MIN(vcram_base, UPPER_RAM_BASE - vcram_size);
198
+
199
setup_boot(machine, &soc->cpu[0].core, board_processor_id(board_rev),
200
- machine->ram_size - vcram_size);
201
+ boot_ram_size);
202
}
203
204
-static void raspi_machine_init(MachineState *machine)
205
+void raspi_machine_init(MachineState *machine)
206
{
207
RaspiMachineState *s = RASPI_MACHINE(machine);
208
RaspiBaseMachineState *s_base = RASPI_BASE_MACHINE(machine);
209
diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c
210
new file mode 100644
211
index XXXXXXX..XXXXXXX
212
--- /dev/null
213
+++ b/hw/arm/raspi4b.c
214
@@ -XXX,XX +XXX,XX @@
215
+/*
216
+ * Raspberry Pi 4B emulation
217
+ *
218
+ * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com>
219
+ *
220
+ * SPDX-License-Identifier: GPL-2.0-or-later
221
+ */
222
+
223
+#include "qemu/osdep.h"
224
+#include "qemu/units.h"
225
+#include "qemu/cutils.h"
226
+#include "qapi/error.h"
227
+#include "qapi/visitor.h"
228
+#include "hw/arm/raspi_platform.h"
229
+#include "hw/display/bcm2835_fb.h"
230
+#include "hw/registerfields.h"
231
+#include "qemu/error-report.h"
232
+#include "sysemu/device_tree.h"
233
+#include "hw/boards.h"
234
+#include "hw/loader.h"
235
+#include "hw/arm/boot.h"
236
+#include "qom/object.h"
237
+#include "hw/arm/bcm2838.h"
238
+
239
+#define TYPE_RASPI4B_MACHINE MACHINE_TYPE_NAME("raspi4b")
240
+OBJECT_DECLARE_SIMPLE_TYPE(Raspi4bMachineState, RASPI4B_MACHINE)
241
+
242
+struct Raspi4bMachineState {
243
+ RaspiBaseMachineState parent_obj;
244
+ BCM2838State soc;
245
+};
246
+
247
+static void raspi4b_machine_init(MachineState *machine)
248
+{
249
+ Raspi4bMachineState *s = RASPI4B_MACHINE(machine);
250
+ RaspiBaseMachineState *s_base = RASPI_BASE_MACHINE(machine);
251
+ RaspiBaseMachineClass *mc = RASPI_BASE_MACHINE_GET_CLASS(machine);
252
+ BCM2838State *soc = &s->soc;
253
+
254
+ s_base->binfo.board_id = mc->board_rev;
255
+
256
+ object_initialize_child(OBJECT(machine), "soc", soc,
257
+ board_soc_type(mc->board_rev));
258
+
259
+ raspi_base_machine_init(machine, &soc->parent_obj);
260
+}
261
+
262
+static void raspi4b_machine_class_init(ObjectClass *oc, void *data)
263
+{
264
+ MachineClass *mc = MACHINE_CLASS(oc);
265
+ RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc);
266
+
267
+ rmc->board_rev = 0xb03115; /* Revision 1.5, 2 Gb RAM */
268
+ raspi_machine_class_common_init(mc, rmc->board_rev);
269
+ mc->init = raspi4b_machine_init;
270
+}
271
+
272
+static const TypeInfo raspi4b_machine_type = {
273
+ .name = TYPE_RASPI4B_MACHINE,
274
+ .parent = TYPE_RASPI_BASE_MACHINE,
275
+ .instance_size = sizeof(Raspi4bMachineState),
276
+ .class_init = raspi4b_machine_class_init,
277
+};
278
+
279
+static void raspi4b_machine_register_type(void)
280
+{
281
+ type_register_static(&raspi4b_machine_type);
282
+}
283
+
284
+type_init(raspi4b_machine_register_type)
285
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
286
index XXXXXXX..XXXXXXX 100644
287
--- a/hw/arm/meson.build
288
+++ b/hw/arm/meson.build
289
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubi
290
arm_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 'orangepi.c'))
291
arm_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40.c', 'bananapi_m2u.c'))
292
arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
293
-arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files('bcm2838.c'))
294
+arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files('bcm2838.c', 'raspi4b.c'))
295
arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
296
arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
297
arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
298
--
45
--
299
2.34.1
46
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for i386. We had no
2
i386-specific behaviour in the old ifdef ladder, so we were using the
3
default "prefer a then b then c" fallback; this is actually the
4
correct per-the-spec handling for i386.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-25-peter.maydell@linaro.org
9
---
10
target/i386/tcg/fpu_helper.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/i386/tcg/fpu_helper.c
16
+++ b/target/i386/tcg/fpu_helper.c
17
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
18
* there are multiple input NaNs they are selected in the order a, b, c.
19
*/
20
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
22
}
23
24
static inline uint8_t save_exception_flags(CPUX86State *env)
25
--
26
2.34.1
diff view generated by jsdifflib
1
From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
1
Set the Float3NaNPropRule explicitly for HPPA, and remove the
2
ifdef from pickNaNMulAdd().
2
3
3
I'm far from confident this handling here is correct. Hence
4
HPPA is the only target that was using the default branch of the
4
RFC. In particular not sure on what locks I should hold for this
5
ifdef ladder (other targets either do not use muladd or set
5
to be even moderately safe.
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).
6
9
7
The function already appears to be inconsistent in what it returns
10
We add a TODO note that the HPPA rule is probably wrong; this is
8
as the CONFIG_ATOMIC64 block returns the endian converted 'eventual'
11
not a behavioural change for this refactoring.
9
value of the cmpxchg whereas the TCG_OVERSIZED_GUEST case returns
10
the previous value.
11
12
12
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
13
Message-id: 20240219161229.11776-1-Jonathan.Cameron@huawei.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-26-peter.maydell@linaro.org
16
---
16
---
17
target/arm/ptw.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++--
17
target/hppa/fpu_helper.c | 8 ++++++++
18
1 file changed, 62 insertions(+), 2 deletions(-)
18
fpu/softfloat-specialize.c.inc | 4 ----
19
2 files changed, 8 insertions(+), 4 deletions(-)
19
20
20
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
21
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/ptw.c
23
--- a/target/hppa/fpu_helper.c
23
+++ b/target/arm/ptw.c
24
+++ b/target/hppa/fpu_helper.c
24
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
25
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
25
void *host = ptw->out_host;
26
* HPPA does note implement a CPU reset method at all...
26
27
*/
27
if (unlikely(!host)) {
28
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
28
- fi->type = ARMFault_UnsuppAtomicUpdate;
29
+ /*
29
- return 0;
30
+ * TODO: The HPPA architecture reference only documents its NaN
30
+ /* Page table in MMIO Memory Region */
31
+ * propagation rule for 2-operand operations. Testing on real hardware
31
+ CPUState *cs = env_cpu(env);
32
+ * might be necessary to confirm whether this order for muladd is correct.
32
+ MemTxAttrs attrs = {
33
+ * Not preferring the SNaN is almost certainly incorrect as it diverges
33
+ .space = ptw->out_space,
34
+ * from the documented rules for 2-operand operations.
34
+ .secure = arm_space_is_secure(ptw->out_space),
35
+ */
35
+ };
36
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
36
+ AddressSpace *as = arm_addressspace(cs, attrs);
37
/* For inf * 0 + NaN, return the input NaN */
37
+ MemTxResult result = MEMTX_OK;
38
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
38
+ bool need_lock = !bql_locked();
39
}
39
+
40
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
40
+ if (need_lock) {
41
index XXXXXXX..XXXXXXX 100644
41
+ bql_lock();
42
--- a/fpu/softfloat-specialize.c.inc
42
+ }
43
+++ b/fpu/softfloat-specialize.c.inc
43
+ if (ptw->out_be) {
44
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
44
+ cur_val = address_space_ldq_be(as, ptw->out_phys, attrs, &result);
45
}
45
+ if (unlikely(result != MEMTX_OK)) {
46
+ fi->type = ARMFault_SyncExternalOnWalk;
47
+ fi->ea = arm_extabort_type(result);
48
+ if (need_lock) {
49
+ bql_unlock();
50
+ }
51
+ return old_val;
52
+ }
53
+ if (cur_val == old_val) {
54
+ address_space_stq_be(as, ptw->out_phys, new_val, attrs, &result);
55
+ if (unlikely(result != MEMTX_OK)) {
56
+ fi->type = ARMFault_SyncExternalOnWalk;
57
+ fi->ea = arm_extabort_type(result);
58
+ if (need_lock) {
59
+ bql_unlock();
60
+ }
61
+ return old_val;
62
+ }
63
+ cur_val = new_val;
64
+ }
65
+ } else {
66
+ cur_val = address_space_ldq_le(as, ptw->out_phys, attrs, &result);
67
+ if (unlikely(result != MEMTX_OK)) {
68
+ fi->type = ARMFault_SyncExternalOnWalk;
69
+ fi->ea = arm_extabort_type(result);
70
+ if (need_lock) {
71
+ bql_unlock();
72
+ }
73
+ return old_val;
74
+ }
75
+ if (cur_val == old_val) {
76
+ address_space_stq_le(as, ptw->out_phys, new_val, attrs, &result);
77
+ if (unlikely(result != MEMTX_OK)) {
78
+ fi->type = ARMFault_SyncExternalOnWalk;
79
+ fi->ea = arm_extabort_type(result);
80
+ if (need_lock) {
81
+ bql_unlock();
82
+ }
83
+ return old_val;
84
+ }
85
+ cur_val = new_val;
86
+ }
87
+ }
88
+ if (need_lock) {
89
+ bql_unlock();
90
+ }
91
+ return cur_val;
92
}
46
}
93
47
94
/*
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 */
95
--
55
--
96
2.34.1
56
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
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.
2
6
3
Pre-setup for BCM2838 introduction
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(-)
4
15
5
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
16
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20240226000259.2752893-3-sergey.kambalin@auriga.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
include/hw/arm/bcm2835_peripherals.h | 29 +++-
11
include/hw/arm/bcm2836.h | 3 +-
12
hw/arm/bcm2835_peripherals.c | 198 +++++++++++++++------------
13
hw/arm/bcm2836.c | 24 ++--
14
4 files changed, 154 insertions(+), 100 deletions(-)
15
16
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/bcm2835_peripherals.h
18
--- a/include/fpu/softfloat-helpers.h
19
+++ b/include/hw/arm/bcm2835_peripherals.h
19
+++ b/include/fpu/softfloat-helpers.h
20
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static inline void set_snan_bit_is_one(bool val, float_status *status)
21
#include "hw/misc/unimp.h"
21
status->snan_bit_is_one = val;
22
#include "qom/object.h"
23
24
+#define TYPE_BCM_SOC_PERIPHERALS_BASE "bcm-soc-peripherals-base"
25
+OBJECT_DECLARE_TYPE(BCMSocPeripheralBaseState, BCMSocPeripheralBaseClass,
26
+ BCM_SOC_PERIPHERALS_BASE)
27
#define TYPE_BCM2835_PERIPHERALS "bcm2835-peripherals"
28
OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PeripheralState, BCM2835_PERIPHERALS)
29
30
-struct BCM2835PeripheralState {
31
+struct BCMSocPeripheralBaseState {
32
/*< private >*/
33
SysBusDevice parent_obj;
34
/*< public >*/
35
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
36
OrIRQState orgated_dma_irq;
37
BCM2835ICState ic;
38
BCM2835PropertyState property;
39
- BCM2835RngState rng;
40
BCM2835MboxState mboxes;
41
SDHCIState sdhci;
42
BCM2835SDHostState sdhost;
43
- BCM2835GpioState gpio;
44
- Bcm2835ThermalState thermal;
45
UnimplementedDeviceState i2s;
46
BCM2835SPIState spi[1];
47
UnimplementedDeviceState i2c[3];
48
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
49
UnimplementedDeviceState sdramc;
50
};
51
52
+struct BCMSocPeripheralBaseClass {
53
+ /*< private >*/
54
+ SysBusDeviceClass parent_class;
55
+ /*< public >*/
56
+ uint64_t peri_size; /* Peripheral range size */
57
+};
58
+
59
+struct BCM2835PeripheralState {
60
+ /*< private >*/
61
+ BCMSocPeripheralBaseState parent_obj;
62
+ /*< public >*/
63
+ BCM2835RngState rng;
64
+ Bcm2835ThermalState thermal;
65
+ BCM2835GpioState gpio;
66
+};
67
+
68
+void create_unimp(BCMSocPeripheralBaseState *ps,
69
+ UnimplementedDeviceState *uds,
70
+ const char *name, hwaddr ofs, hwaddr size);
71
+void bcm_soc_peripherals_common_realize(DeviceState *dev, Error **errp);
72
+
73
#endif /* BCM2835_PERIPHERALS_H */
74
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
75
index XXXXXXX..XXXXXXX 100644
76
--- a/include/hw/arm/bcm2836.h
77
+++ b/include/hw/arm/bcm2836.h
78
@@ -XXX,XX +XXX,XX @@ struct BCM283XState {
79
BCM2835PeripheralState peripherals;
80
};
81
82
-bool bcm283x_common_realize(DeviceState *dev, Error **errp);
83
+bool bcm283x_common_realize(DeviceState *dev, BCMSocPeripheralBaseState *ps,
84
+ Error **errp);
85
86
#endif /* BCM2836_H */
87
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/arm/bcm2835_peripherals.c
90
+++ b/hw/arm/bcm2835_peripherals.c
91
@@ -XXX,XX +XXX,XX @@
92
#define SEPARATE_DMA_IRQ_MAX 10
93
#define ORGATED_DMA_IRQ_COUNT 4
94
95
-static void create_unimp(BCM2835PeripheralState *ps,
96
- UnimplementedDeviceState *uds,
97
- const char *name, hwaddr ofs, hwaddr size)
98
+void create_unimp(BCMSocPeripheralBaseState *ps,
99
+ UnimplementedDeviceState *uds,
100
+ const char *name, hwaddr ofs, hwaddr size)
101
{
102
object_initialize_child(OBJECT(ps), name, uds, TYPE_UNIMPLEMENTED_DEVICE);
103
qdev_prop_set_string(DEVICE(uds), "name", name);
104
@@ -XXX,XX +XXX,XX @@ static void create_unimp(BCM2835PeripheralState *ps,
105
static void bcm2835_peripherals_init(Object *obj)
106
{
107
BCM2835PeripheralState *s = BCM2835_PERIPHERALS(obj);
108
+ BCMSocPeripheralBaseState *s_base = BCM_SOC_PERIPHERALS_BASE(obj);
109
+
110
+ /* Random Number Generator */
111
+ object_initialize_child(obj, "rng", &s->rng, TYPE_BCM2835_RNG);
112
+
113
+ /* Thermal */
114
+ object_initialize_child(obj, "thermal", &s->thermal, TYPE_BCM2835_THERMAL);
115
+
116
+ /* GPIO */
117
+ object_initialize_child(obj, "gpio", &s->gpio, TYPE_BCM2835_GPIO);
118
+
119
+ object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhci",
120
+ OBJECT(&s_base->sdhci.sdbus));
121
+ object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhost",
122
+ OBJECT(&s_base->sdhost.sdbus));
123
+
124
+ /* Gated DMA interrupts */
125
+ object_initialize_child(obj, "orgated-dma-irq",
126
+ &s_base->orgated_dma_irq, TYPE_OR_IRQ);
127
+ object_property_set_int(OBJECT(&s_base->orgated_dma_irq), "num-lines",
128
+ ORGATED_DMA_IRQ_COUNT, &error_abort);
129
+}
130
+
131
+static void raspi_peripherals_base_init(Object *obj)
132
+{
133
+ BCMSocPeripheralBaseState *s = BCM_SOC_PERIPHERALS_BASE(obj);
134
+ BCMSocPeripheralBaseClass *bc = BCM_SOC_PERIPHERALS_BASE_GET_CLASS(obj);
135
136
/* Memory region for peripheral devices, which we export to our parent */
137
- memory_region_init(&s->peri_mr, obj,"bcm2835-peripherals", 0x1000000);
138
+ memory_region_init(&s->peri_mr, obj, "bcm2835-peripherals", bc->peri_size);
139
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->peri_mr);
140
141
/* Internal memory region for peripheral bus addresses (not exported) */
142
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
143
object_property_add_const_link(OBJECT(&s->property), "dma-mr",
144
OBJECT(&s->gpu_bus_mr));
145
146
- /* Random Number Generator */
147
- object_initialize_child(obj, "rng", &s->rng, TYPE_BCM2835_RNG);
148
-
149
/* Extended Mass Media Controller */
150
object_initialize_child(obj, "sdhci", &s->sdhci, TYPE_SYSBUS_SDHCI);
151
152
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
153
/* DMA Channels */
154
object_initialize_child(obj, "dma", &s->dma, TYPE_BCM2835_DMA);
155
156
- object_initialize_child(obj, "orgated-dma-irq",
157
- &s->orgated_dma_irq, TYPE_OR_IRQ);
158
- object_property_set_int(OBJECT(&s->orgated_dma_irq), "num-lines",
159
- ORGATED_DMA_IRQ_COUNT, &error_abort);
160
-
161
object_property_add_const_link(OBJECT(&s->dma), "dma-mr",
162
OBJECT(&s->gpu_bus_mr));
163
164
- /* Thermal */
165
- object_initialize_child(obj, "thermal", &s->thermal, TYPE_BCM2835_THERMAL);
166
-
167
- /* GPIO */
168
- object_initialize_child(obj, "gpio", &s->gpio, TYPE_BCM2835_GPIO);
169
-
170
- object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhci",
171
- OBJECT(&s->sdhci.sdbus));
172
- object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhost",
173
- OBJECT(&s->sdhost.sdbus));
174
-
175
/* Mphi */
176
object_initialize_child(obj, "mphi", &s->mphi, TYPE_BCM2835_MPHI);
177
178
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
179
180
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
181
{
182
+ MemoryRegion *mphi_mr;
183
BCM2835PeripheralState *s = BCM2835_PERIPHERALS(dev);
184
+ BCMSocPeripheralBaseState *s_base = BCM_SOC_PERIPHERALS_BASE(dev);
185
+ int n;
186
+
187
+ bcm_soc_peripherals_common_realize(dev, errp);
188
+
189
+ /* Extended Mass Media Controller */
190
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s_base->sdhci), 0,
191
+ qdev_get_gpio_in_named(DEVICE(&s_base->ic), BCM2835_IC_GPU_IRQ,
192
+ INTERRUPT_ARASANSDIO));
193
+
194
+ /* Connect DMA 0-12 to the interrupt controller */
195
+ for (n = 0; n <= SEPARATE_DMA_IRQ_MAX; n++) {
196
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s_base->dma), n,
197
+ qdev_get_gpio_in_named(DEVICE(&s_base->ic),
198
+ BCM2835_IC_GPU_IRQ,
199
+ INTERRUPT_DMA0 + n));
200
+ }
201
+
202
+ if (!qdev_realize(DEVICE(&s_base->orgated_dma_irq), NULL, errp)) {
203
+ return;
204
+ }
205
+ for (n = 0; n < ORGATED_DMA_IRQ_COUNT; n++) {
206
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s_base->dma),
207
+ SEPARATE_DMA_IRQ_MAX + 1 + n,
208
+ qdev_get_gpio_in(DEVICE(&s_base->orgated_dma_irq), n));
209
+ }
210
+ qdev_connect_gpio_out(DEVICE(&s_base->orgated_dma_irq), 0,
211
+ qdev_get_gpio_in_named(DEVICE(&s_base->ic),
212
+ BCM2835_IC_GPU_IRQ,
213
+ INTERRUPT_DMA0 + SEPARATE_DMA_IRQ_MAX + 1));
214
+
215
+ /* Random Number Generator */
216
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->rng), errp)) {
217
+ return;
218
+ }
219
+ memory_region_add_subregion(
220
+ &s_base->peri_mr, RNG_OFFSET,
221
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rng), 0));
222
+
223
+ /* THERMAL */
224
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->thermal), errp)) {
225
+ return;
226
+ }
227
+ memory_region_add_subregion(&s_base->peri_mr, THERMAL_OFFSET,
228
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->thermal), 0));
229
+
230
+ /* Map MPHI to the peripherals memory map */
231
+ mphi_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s_base->mphi), 0);
232
+ memory_region_add_subregion(&s_base->peri_mr, MPHI_OFFSET, mphi_mr);
233
+
234
+ /* GPIO */
235
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
236
+ return;
237
+ }
238
+ memory_region_add_subregion(
239
+ &s_base->peri_mr, GPIO_OFFSET,
240
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gpio), 0));
241
+
242
+ object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->gpio), "sd-bus");
243
+}
244
+
245
+void bcm_soc_peripherals_common_realize(DeviceState *dev, Error **errp)
246
+{
247
+ BCMSocPeripheralBaseState *s = BCM_SOC_PERIPHERALS_BASE(dev);
248
Object *obj;
249
MemoryRegion *ram;
250
Error *err = NULL;
251
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
252
sysbus_connect_irq(SYS_BUS_DEVICE(&s->property), 0,
253
qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_PROPERTY));
254
255
- /* Random Number Generator */
256
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->rng), errp)) {
257
- return;
258
- }
259
-
260
- memory_region_add_subregion(&s->peri_mr, RNG_OFFSET,
261
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rng), 0));
262
-
263
/* Extended Mass Media Controller
264
*
265
* Compatible with:
266
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
267
268
memory_region_add_subregion(&s->peri_mr, EMMC1_OFFSET,
269
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->sdhci), 0));
270
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
271
- qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
272
- INTERRUPT_ARASANSDIO));
273
274
/* SDHOST */
275
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhost), errp)) {
276
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
277
memory_region_add_subregion(&s->peri_mr, DMA15_OFFSET,
278
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dma), 1));
279
280
- for (n = 0; n <= SEPARATE_DMA_IRQ_MAX; n++) {
281
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), n,
282
- qdev_get_gpio_in_named(DEVICE(&s->ic),
283
- BCM2835_IC_GPU_IRQ,
284
- INTERRUPT_DMA0 + n));
285
- }
286
- if (!qdev_realize(DEVICE(&s->orgated_dma_irq), NULL, errp)) {
287
- return;
288
- }
289
- for (n = 0; n < ORGATED_DMA_IRQ_COUNT; n++) {
290
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma),
291
- SEPARATE_DMA_IRQ_MAX + 1 + n,
292
- qdev_get_gpio_in(DEVICE(&s->orgated_dma_irq), n));
293
- }
294
- qdev_connect_gpio_out(DEVICE(&s->orgated_dma_irq), 0,
295
- qdev_get_gpio_in_named(DEVICE(&s->ic),
296
- BCM2835_IC_GPU_IRQ,
297
- INTERRUPT_DMA0 + SEPARATE_DMA_IRQ_MAX + 1));
298
-
299
- /* THERMAL */
300
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->thermal), errp)) {
301
- return;
302
- }
303
- memory_region_add_subregion(&s->peri_mr, THERMAL_OFFSET,
304
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->thermal), 0));
305
-
306
- /* GPIO */
307
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
308
- return;
309
- }
310
-
311
- memory_region_add_subregion(&s->peri_mr, GPIO_OFFSET,
312
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gpio), 0));
313
-
314
- object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->gpio), "sd-bus");
315
-
316
/* Mphi */
317
if (!sysbus_realize(SYS_BUS_DEVICE(&s->mphi), errp)) {
318
return;
319
}
320
321
- memory_region_add_subregion(&s->peri_mr, MPHI_OFFSET,
322
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mphi), 0));
323
sysbus_connect_irq(SYS_BUS_DEVICE(&s->mphi), 0,
324
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
325
INTERRUPT_HOSTPORT));
326
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
327
static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data)
328
{
329
DeviceClass *dc = DEVICE_CLASS(oc);
330
+ BCMSocPeripheralBaseClass *bc = BCM_SOC_PERIPHERALS_BASE_CLASS(oc);
331
332
+ bc->peri_size = 0x1000000;
333
dc->realize = bcm2835_peripherals_realize;
334
}
22
}
335
23
336
-static const TypeInfo bcm2835_peripherals_type_info = {
24
-static inline void set_use_first_nan(bool val, float_status *status)
337
- .name = TYPE_BCM2835_PERIPHERALS,
338
- .parent = TYPE_SYS_BUS_DEVICE,
339
- .instance_size = sizeof(BCM2835PeripheralState),
340
- .instance_init = bcm2835_peripherals_init,
341
- .class_init = bcm2835_peripherals_class_init,
342
+static const TypeInfo bcm2835_peripherals_types[] = {
343
+ {
344
+ .name = TYPE_BCM2835_PERIPHERALS,
345
+ .parent = TYPE_BCM_SOC_PERIPHERALS_BASE,
346
+ .instance_size = sizeof(BCM2835PeripheralState),
347
+ .instance_init = bcm2835_peripherals_init,
348
+ .class_init = bcm2835_peripherals_class_init,
349
+ }, {
350
+ .name = TYPE_BCM_SOC_PERIPHERALS_BASE,
351
+ .parent = TYPE_SYS_BUS_DEVICE,
352
+ .instance_size = sizeof(BCMSocPeripheralBaseState),
353
+ .instance_init = raspi_peripherals_base_init,
354
+ .class_size = sizeof(BCMSocPeripheralBaseClass),
355
+ .abstract = true,
356
+ }
357
};
358
359
-static void bcm2835_peripherals_register_types(void)
360
-{
25
-{
361
- type_register_static(&bcm2835_peripherals_type_info);
26
- status->use_first_nan = val;
362
-}
27
-}
363
-
28
-
364
-type_init(bcm2835_peripherals_register_types)
29
static inline void set_no_signaling_nans(bool val, float_status *status)
365
+DEFINE_TYPES(bcm2835_peripherals_types)
30
{
366
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
31
status->no_signaling_nans = val;
32
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
367
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
368
--- a/hw/arm/bcm2836.c
34
--- a/include/fpu/softfloat-types.h
369
+++ b/hw/arm/bcm2836.c
35
+++ b/include/fpu/softfloat-types.h
370
@@ -XXX,XX +XXX,XX @@ static void bcm283x_init(Object *obj)
36
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
371
"vcram-size");
37
* softfloat-specialize.inc.c)
372
}
38
*/
373
39
bool snan_bit_is_one;
374
-bool bcm283x_common_realize(DeviceState *dev, Error **errp)
40
- bool use_first_nan;
375
+bool bcm283x_common_realize(DeviceState *dev, BCMSocPeripheralBaseState *ps,
41
bool no_signaling_nans;
376
+ Error **errp)
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)
377
{
51
{
378
- BCM283XState *s = BCM283X(dev);
52
- set_use_first_nan(use_first, &env->fp_status);
379
- BCM283XBaseState *s_base = BCM283X_BASE(dev);
53
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
380
+ BCM283XBaseState *s = BCM283X_BASE(dev);
54
&env->fp_status);
381
BCM283XBaseClass *bc = BCM283X_BASE_GET_CLASS(dev);
55
set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
382
Object *obj;
383
384
@@ -XXX,XX +XXX,XX @@ bool bcm283x_common_realize(DeviceState *dev, Error **errp)
385
386
obj = object_property_get_link(OBJECT(dev), "ram", &error_abort);
387
388
- object_property_add_const_link(OBJECT(&s->peripherals), "ram", obj);
389
+ object_property_add_const_link(OBJECT(ps), "ram", obj);
390
391
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->peripherals), errp)) {
392
+ if (!sysbus_realize(SYS_BUS_DEVICE(ps), errp)) {
393
return false;
394
}
395
396
- object_property_add_alias(OBJECT(s_base), "sd-bus",
397
- OBJECT(&s->peripherals), "sd-bus");
398
+ object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(ps), "sd-bus");
399
400
- sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals),
401
- 0, bc->peri_base, 1);
402
+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(ps), 0, bc->peri_base, 1);
403
return true;
404
}
405
406
@@ -XXX,XX +XXX,XX @@ static void bcm2835_realize(DeviceState *dev, Error **errp)
407
{
408
BCM283XState *s = BCM283X(dev);
409
BCM283XBaseState *s_base = BCM283X_BASE(dev);
410
+ BCMSocPeripheralBaseState *ps_base
411
+ = BCM_SOC_PERIPHERALS_BASE(&s->peripherals);
412
413
- if (!bcm283x_common_realize(dev, errp)) {
414
+ if (!bcm283x_common_realize(dev, ps_base, errp)) {
415
return;
416
}
417
418
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
419
BCM283XState *s = BCM283X(dev);
420
BCM283XBaseState *s_base = BCM283X_BASE(dev);
421
BCM283XBaseClass *bc = BCM283X_BASE_GET_CLASS(dev);
422
+ BCMSocPeripheralBaseState *ps_base
423
+ = BCM_SOC_PERIPHERALS_BASE(&s->peripherals);
424
425
- if (!bcm283x_common_realize(dev, errp)) {
426
+ if (!bcm283x_common_realize(dev, ps_base, errp)) {
427
return;
428
}
429
430
--
56
--
431
2.34.1
57
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
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.
2
8
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
9
Rearrange m68k_cpu_reset_hold() so that we initialize env->fp_status
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
earlier, and thus can pass it to floatx80_default_nan().
5
Message-id: 20240226000259.2752893-42-sergey.kambalin@auriga.com
11
6
[PMM: list PCIE and GENET as 'missing' for now, until we land
7
the patches which add those devices]
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
9
---
15
---
10
docs/system/arm/raspi.rst | 12 +++++++-----
16
target/m68k/cpu.c | 12 +++++++-----
11
1 file changed, 7 insertions(+), 5 deletions(-)
17
1 file changed, 7 insertions(+), 5 deletions(-)
12
18
13
diff --git a/docs/system/arm/raspi.rst b/docs/system/arm/raspi.rst
19
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/system/arm/raspi.rst
21
--- a/target/m68k/cpu.c
16
+++ b/docs/system/arm/raspi.rst
22
+++ b/target/m68k/cpu.c
17
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
18
-Raspberry Pi boards (``raspi0``, ``raspi1ap``, ``raspi2b``, ``raspi3ap``, ``raspi3b``)
24
CPUState *cs = CPU(obj);
19
-======================================================================================
25
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(obj);
20
+Raspberry Pi boards (``raspi0``, ``raspi1ap``, ``raspi2b``, ``raspi3ap``, ``raspi3b``, ``raspi4b``)
26
CPUM68KState *env = cpu_env(cs);
21
+===================================================================================================
27
- floatx80 nan = floatx80_default_nan(NULL);
22
28
+ floatx80 nan;
23
29
int i;
24
QEMU provides models of the following Raspberry Pi boards:
30
25
@@ -XXX,XX +XXX,XX @@ QEMU provides models of the following Raspberry Pi boards:
31
if (mcc->parent_phases.hold) {
26
Cortex-A53 (4 cores), 512 MiB of RAM
32
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
27
``raspi3b``
33
#else
28
Cortex-A53 (4 cores), 1 GiB of RAM
34
cpu_m68k_set_sr(env, SR_S | SR_I);
29
-
35
#endif
30
+``raspi4b``
36
- for (i = 0; i < 8; i++) {
31
+ Cortex-A72 (4 cores), 2 GiB of RAM
37
- env->fregs[i].d = nan;
32
38
- }
33
Implemented devices
39
- cpu_m68k_set_fpcr(env, 0);
34
-------------------
40
/*
35
41
* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
36
- * ARM1176JZF-S, Cortex-A7 or Cortex-A53 CPU
42
* 3.4 FLOATING-POINT INSTRUCTION DETAILS
37
+ * ARM1176JZF-S, Cortex-A7, Cortex-A53 or Cortex-A72 CPU
43
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
38
* Interrupt controller
44
* preceding paragraph for nonsignaling NaNs.
39
* DMA controller
45
*/
40
* Clock and reset controller (CPRMAN)
46
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
41
@@ -XXX,XX +XXX,XX @@ Implemented devices
47
+
42
* VideoCore firmware (property)
48
+ nan = floatx80_default_nan(&env->fp_status);
43
* Peripheral SPI controller (SPI)
49
+ for (i = 0; i < 8; i++) {
44
50
+ env->fregs[i].d = nan;
45
-
51
+ }
46
Missing devices
52
+ cpu_m68k_set_fpcr(env, 0);
47
---------------
53
env->fpsr = 0;
48
54
49
* Analog to Digital Converter (ADC)
55
/* TODO: We should set PC from the interrupt vector. */
50
* Pulse Width Modulation (PWM)
51
+ * PCIE Root Port (raspi4b)
52
+ * GENET Ethernet Controller (raspi4b)
53
--
56
--
54
2.34.1
57
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
We create our 128-bit default NaN by calling parts64_default_nan()
2
and then adjusting the result. We can do the same trick for creating
3
the floatx80 default NaN, which lets us drop a target ifdef.
2
4
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
5
floatx80 is used only by:
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
i386
5
Message-id: 20240226000259.2752893-8-sergey.kambalin@auriga.com
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
7
---
40
---
8
hw/gpio/bcm2838_gpio.c | 193 ++++++++++++++++++++++++++++++++++++++++-
41
fpu/softfloat-specialize.c.inc | 20 ++++++++++----------
9
1 file changed, 190 insertions(+), 3 deletions(-)
42
1 file changed, 10 insertions(+), 10 deletions(-)
10
43
11
diff --git a/hw/gpio/bcm2838_gpio.c b/hw/gpio/bcm2838_gpio.c
44
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
12
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/gpio/bcm2838_gpio.c
46
--- a/fpu/softfloat-specialize.c.inc
14
+++ b/hw/gpio/bcm2838_gpio.c
47
+++ b/fpu/softfloat-specialize.c.inc
15
@@ -XXX,XX +XXX,XX @@
48
@@ -XXX,XX +XXX,XX @@ static void parts128_silence_nan(FloatParts128 *p, float_status *status)
16
#include "hw/sysbus.h"
49
floatx80 floatx80_default_nan(float_status *status)
17
#include "migration/vmstate.h"
18
#include "hw/gpio/bcm2838_gpio.h"
19
+#include "hw/irq.h"
20
21
#define GPFSEL0 0x00
22
#define GPFSEL1 0x04
23
@@ -XXX,XX +XXX,XX @@
24
#define RESET_VAL_CNTRL_REG2 0x50AAA95A
25
#define RESET_VAL_CNTRL_REG3 0x00055555
26
27
+#define NUM_FSELN_IN_GPFSELN 10
28
+#define NUM_BITS_FSELN 3
29
+#define MASK_FSELN 0x7
30
+
31
#define BYTES_IN_WORD 4
32
33
+static uint32_t gpfsel_get(BCM2838GpioState *s, uint8_t reg)
34
+{
35
+ int i;
36
+ uint32_t value = 0;
37
+ for (i = 0; i < NUM_FSELN_IN_GPFSELN; i++) {
38
+ uint32_t index = NUM_FSELN_IN_GPFSELN * reg + i;
39
+ if (index < sizeof(s->fsel)) {
40
+ value |= (s->fsel[index] & MASK_FSELN) << (NUM_BITS_FSELN * i);
41
+ }
42
+ }
43
+ return value;
44
+}
45
+
46
+static void gpfsel_set(BCM2838GpioState *s, uint8_t reg, uint32_t value)
47
+{
48
+ int i;
49
+ for (i = 0; i < NUM_FSELN_IN_GPFSELN; i++) {
50
+ uint32_t index = NUM_FSELN_IN_GPFSELN * reg + i;
51
+ if (index < sizeof(s->fsel)) {
52
+ int fsel = (value >> (NUM_BITS_FSELN * i)) & MASK_FSELN;
53
+ s->fsel[index] = fsel;
54
+ }
55
+ }
56
+}
57
+
58
+static int gpfsel_is_out(BCM2838GpioState *s, int index)
59
+{
60
+ if (index >= 0 && index < BCM2838_GPIO_NUM) {
61
+ return s->fsel[index] == 1;
62
+ }
63
+ return 0;
64
+}
65
+
66
+static void gpset(BCM2838GpioState *s, uint32_t val, uint8_t start,
67
+ uint8_t count, uint32_t *lev)
68
+{
69
+ uint32_t changes = val & ~*lev;
70
+ uint32_t cur = 1;
71
+
72
+ int i;
73
+ for (i = 0; i < count; i++) {
74
+ if ((changes & cur) && (gpfsel_is_out(s, start + i))) {
75
+ qemu_set_irq(s->out[start + i], 1);
76
+ }
77
+ cur <<= 1;
78
+ }
79
+
80
+ *lev |= val;
81
+}
82
+
83
+static void gpclr(BCM2838GpioState *s, uint32_t val, uint8_t start,
84
+ uint8_t count, uint32_t *lev)
85
+{
86
+ uint32_t changes = val & *lev;
87
+ uint32_t cur = 1;
88
+
89
+ int i;
90
+ for (i = 0; i < count; i++) {
91
+ if ((changes & cur) && (gpfsel_is_out(s, start + i))) {
92
+ qemu_set_irq(s->out[start + i], 0);
93
+ }
94
+ cur <<= 1;
95
+ }
96
+
97
+ *lev &= ~val;
98
+}
99
+
100
static uint64_t bcm2838_gpio_read(void *opaque, hwaddr offset, unsigned size)
101
{
50
{
102
+ BCM2838GpioState *s = (BCM2838GpioState *)opaque;
51
floatx80 r;
103
uint64_t value = 0;
52
+ /*
104
53
+ * Extrapolate from the choices made by parts64_default_nan to fill
105
- qemu_log_mask(LOG_UNIMP, "%s: %s: not implemented for %"HWADDR_PRIx"\n",
54
+ * in the floatx80 format. We assume that floatx80's explicit
106
- TYPE_BCM2838_GPIO, __func__, offset);
55
+ * integer bit is always set (this is true for i386 and m68k,
107
+ switch (offset) {
56
+ * which are the only real users of this format).
108
+ case GPFSEL0:
57
+ */
109
+ case GPFSEL1:
58
+ FloatParts64 p64;
110
+ case GPFSEL2:
59
+ parts64_default_nan(&p64, status);
111
+ case GPFSEL3:
60
112
+ case GPFSEL4:
61
- /* None of the targets that have snan_bit_is_one use floatx80. */
113
+ case GPFSEL5:
62
- assert(!snan_bit_is_one(status));
114
+ value = gpfsel_get(s, offset / BYTES_IN_WORD);
63
-#if defined(TARGET_M68K)
115
+ break;
64
- r.low = UINT64_C(0xFFFFFFFFFFFFFFFF);
116
+ case GPSET0:
65
- r.high = 0x7FFF;
117
+ case GPSET1:
66
-#else
118
+ case GPCLR0:
67
- /* X86 */
119
+ case GPCLR1:
68
- r.low = UINT64_C(0xC000000000000000);
120
+ /* Write Only */
69
- r.high = 0xFFFF;
121
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: %s: Attempt reading from write only"
70
-#endif
122
+ " register. 0x%"PRIx64" will be returned."
71
+ r.high = 0x7FFF | (p64.sign << 15);
123
+ " Address 0x%"HWADDR_PRIx", size %u\n",
72
+ r.low = (1ULL << DECOMPOSED_BINARY_POINT) | p64.frac;
124
+ TYPE_BCM2838_GPIO, __func__, value, offset, size);
73
return r;
125
+ break;
126
+ case GPLEV0:
127
+ value = s->lev0;
128
+ break;
129
+ case GPLEV1:
130
+ value = s->lev1;
131
+ break;
132
+ case GPEDS0:
133
+ case GPEDS1:
134
+ case GPREN0:
135
+ case GPREN1:
136
+ case GPFEN0:
137
+ case GPFEN1:
138
+ case GPHEN0:
139
+ case GPHEN1:
140
+ case GPLEN0:
141
+ case GPLEN1:
142
+ case GPAREN0:
143
+ case GPAREN1:
144
+ case GPAFEN0:
145
+ case GPAFEN1:
146
+ /* Not implemented */
147
+ qemu_log_mask(LOG_UNIMP, "%s: %s: not implemented for %"HWADDR_PRIx"\n",
148
+ TYPE_BCM2838_GPIO, __func__, offset);
149
+ break;
150
+ case GPIO_PUP_PDN_CNTRL_REG0:
151
+ case GPIO_PUP_PDN_CNTRL_REG1:
152
+ case GPIO_PUP_PDN_CNTRL_REG2:
153
+ case GPIO_PUP_PDN_CNTRL_REG3:
154
+ value = s->pup_cntrl_reg[(offset - GPIO_PUP_PDN_CNTRL_REG0)
155
+ / sizeof(s->pup_cntrl_reg[0])];
156
+ break;
157
+ default:
158
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: %s: bad offset %"HWADDR_PRIx"\n",
159
+ TYPE_BCM2838_GPIO, __func__, offset);
160
+ break;
161
+ }
162
163
return value;
164
}
74
}
165
@@ -XXX,XX +XXX,XX @@ static uint64_t bcm2838_gpio_read(void *opaque, hwaddr offset, unsigned size)
166
static void bcm2838_gpio_write(void *opaque, hwaddr offset, uint64_t value,
167
unsigned size)
168
{
169
- qemu_log_mask(LOG_UNIMP, "%s: %s: not implemented for %"HWADDR_PRIx"\n",
170
+ BCM2838GpioState *s = (BCM2838GpioState *)opaque;
171
+
172
+ switch (offset) {
173
+ case GPFSEL0:
174
+ case GPFSEL1:
175
+ case GPFSEL2:
176
+ case GPFSEL3:
177
+ case GPFSEL4:
178
+ case GPFSEL5:
179
+ gpfsel_set(s, offset / BYTES_IN_WORD, value);
180
+ break;
181
+ case GPSET0:
182
+ gpset(s, value, 0, 32, &s->lev0);
183
+ break;
184
+ case GPSET1:
185
+ gpset(s, value, 32, 22, &s->lev1);
186
+ break;
187
+ case GPCLR0:
188
+ gpclr(s, value, 0, 32, &s->lev0);
189
+ break;
190
+ case GPCLR1:
191
+ gpclr(s, value, 32, 22, &s->lev1);
192
+ break;
193
+ case GPLEV0:
194
+ case GPLEV1:
195
+ /* Read Only */
196
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: %s: Attempt writing 0x%"PRIx64""
197
+ " to read only register. Ignored."
198
+ " Address 0x%"HWADDR_PRIx", size %u\n",
199
+ TYPE_BCM2838_GPIO, __func__, value, offset, size);
200
+ break;
201
+ case GPEDS0:
202
+ case GPEDS1:
203
+ case GPREN0:
204
+ case GPREN1:
205
+ case GPFEN0:
206
+ case GPFEN1:
207
+ case GPHEN0:
208
+ case GPHEN1:
209
+ case GPLEN0:
210
+ case GPLEN1:
211
+ case GPAREN0:
212
+ case GPAREN1:
213
+ case GPAFEN0:
214
+ case GPAFEN1:
215
+ /* Not implemented */
216
+ qemu_log_mask(LOG_UNIMP, "%s: %s: not implemented for %"HWADDR_PRIx"\n",
217
+ TYPE_BCM2838_GPIO, __func__, offset);
218
+ break;
219
+ case GPIO_PUP_PDN_CNTRL_REG0:
220
+ case GPIO_PUP_PDN_CNTRL_REG1:
221
+ case GPIO_PUP_PDN_CNTRL_REG2:
222
+ case GPIO_PUP_PDN_CNTRL_REG3:
223
+ s->pup_cntrl_reg[(offset - GPIO_PUP_PDN_CNTRL_REG0)
224
+ / sizeof(s->pup_cntrl_reg[0])] = value;
225
+ break;
226
+ default:
227
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: %s: bad offset %"HWADDR_PRIx"\n",
228
TYPE_BCM2838_GPIO, __func__, offset);
229
+ }
230
+ return;
231
}
232
233
static void bcm2838_gpio_reset(DeviceState *dev)
234
{
235
BCM2838GpioState *s = BCM2838_GPIO(dev);
236
237
+ memset(s->fsel, 0, sizeof(s->fsel));
238
+
239
s->lev0 = 0;
240
s->lev1 = 0;
241
75
242
--
76
--
243
2.34.1
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
Reimplement qemu_register_reset() via qemu_register_resettable().
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
We define a new LegacyReset object which implements Resettable and
8
To do this we need to pass the CPU env pointer in to the helper.
4
defines its reset hold phase method to call a QEMUResetHandler
5
function. When qemu_register_reset() is called, we create a new
6
LegacyReset object and add it to the simulation_reset
7
ResettableContainer. When qemu_unregister_reset() is called, we find
8
the LegacyReset object in the container and remove it.
9
10
This implementation of qemu_unregister_reset() means we'll end up
11
scanning the ResetContainer's list of child objects twice, once
12
to find the LegacyReset object, and once in g_ptr_array_remove().
13
In theory we could avoid this by having the ResettableContainer
14
interface include a resettable_container_remove_with_equal_func()
15
that took a callback method so that we could use
16
g_ptr_array_find_with_equal_func() and g_ptr_array_remove_index().
17
But we don't expect qemu_unregister_reset() to be called frequently
18
or in hot paths, and we expect the simulation_reset container to
19
usually not have many children.
20
9
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20241202131347.498124-33-peter.maydell@linaro.org
25
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
26
Message-id: 20240220160622.114437-9-peter.maydell@linaro.org
27
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
28
---
13
---
29
include/sysemu/reset.h | 7 ++-
14
target/sparc/helper.h | 4 ++--
30
hw/core/reset.c | 137 +++++++++++++++++++++++++++++++----------
15
target/sparc/fop_helper.c | 8 ++++----
31
2 files changed, 110 insertions(+), 34 deletions(-)
16
target/sparc/translate.c | 4 ++--
17
3 files changed, 8 insertions(+), 8 deletions(-)
32
18
33
diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h
19
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
34
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
35
--- a/include/sysemu/reset.h
21
--- a/target/sparc/helper.h
36
+++ b/include/sysemu/reset.h
22
+++ b/target/sparc/helper.h
37
@@ -XXX,XX +XXX,XX @@ void qemu_unregister_resettable(Object *obj);
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
38
* @opaque: opaque data to pass to @func
24
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
39
*
25
DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
40
* Register @func on the list of functions which are called when the
26
DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
41
- * entire system is reset. The functions are called in the order in
27
-DEF_HELPER_FLAGS_2(flcmps, TCG_CALL_NO_RWG_SE, i32, f32, f32)
42
- * which they are registered.
28
-DEF_HELPER_FLAGS_2(flcmpd, TCG_CALL_NO_RWG_SE, i32, f64, f64)
43
+ * entire system is reset. Functions registered with this API and
29
+DEF_HELPER_FLAGS_3(flcmps, TCG_CALL_NO_RWG_SE, i32, env, f32, f32)
44
+ * Resettable objects registered with qemu_register_resettable() are
30
+DEF_HELPER_FLAGS_3(flcmpd, TCG_CALL_NO_RWG_SE, i32, env, f64, f64)
45
+ * handled together, in the order in which they were registered.
31
DEF_HELPER_2(raise_exception, noreturn, env, int)
46
+ * Functions registered with this API are called in the 'hold' phase
32
47
+ * of the 3-phase reset.
33
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
48
*
34
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
49
* In general this function should not be used in new code where possible;
50
* for instance, device model reset is better accomplished using the
51
diff --git a/hw/core/reset.c b/hw/core/reset.c
52
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/core/reset.c
36
--- a/target/sparc/fop_helper.c
54
+++ b/hw/core/reset.c
37
+++ b/target/sparc/fop_helper.c
55
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@ uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
56
*/
39
return finish_fcmp(env, r, GETPC());
57
58
#include "qemu/osdep.h"
59
-#include "qemu/queue.h"
60
#include "sysemu/reset.h"
61
#include "hw/resettable.h"
62
#include "hw/core/resetcontainer.h"
63
@@ -XXX,XX +XXX,XX @@ static ResettableContainer *get_root_reset_container(void)
64
return root_reset_container;
65
}
40
}
66
41
67
-typedef struct QEMUResetEntry {
42
-uint32_t helper_flcmps(float32 src1, float32 src2)
68
- QTAILQ_ENTRY(QEMUResetEntry) entry;
43
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
69
+/*
70
+ * Reason why the currently in-progress qemu_devices_reset() was called.
71
+ * If we made at least SHUTDOWN_CAUSE_SNAPSHOT_LOAD have a corresponding
72
+ * ResetType we could perhaps avoid the need for this global.
73
+ */
74
+static ShutdownCause device_reset_reason;
75
+
76
+/*
77
+ * This is an Object which implements Resettable simply to call the
78
+ * callback function in the hold phase.
79
+ */
80
+#define TYPE_LEGACY_RESET "legacy-reset"
81
+OBJECT_DECLARE_SIMPLE_TYPE(LegacyReset, LEGACY_RESET)
82
+
83
+struct LegacyReset {
84
+ Object parent;
85
+ ResettableState reset_state;
86
QEMUResetHandler *func;
87
void *opaque;
88
bool skip_on_snapshot_load;
89
-} QEMUResetEntry;
90
+};
91
92
-static QTAILQ_HEAD(, QEMUResetEntry) reset_handlers =
93
- QTAILQ_HEAD_INITIALIZER(reset_handlers);
94
+OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(LegacyReset, legacy_reset, LEGACY_RESET, OBJECT, { TYPE_RESETTABLE_INTERFACE }, { })
95
+
96
+static ResettableState *legacy_reset_get_state(Object *obj)
97
+{
98
+ LegacyReset *lr = LEGACY_RESET(obj);
99
+ return &lr->reset_state;
100
+}
101
+
102
+static void legacy_reset_hold(Object *obj)
103
+{
104
+ LegacyReset *lr = LEGACY_RESET(obj);
105
+
106
+ if (device_reset_reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD &&
107
+ lr->skip_on_snapshot_load) {
108
+ return;
109
+ }
110
+ lr->func(lr->opaque);
111
+}
112
+
113
+static void legacy_reset_init(Object *obj)
114
+{
115
+}
116
+
117
+static void legacy_reset_finalize(Object *obj)
118
+{
119
+}
120
+
121
+static void legacy_reset_class_init(ObjectClass *klass, void *data)
122
+{
123
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
124
+
125
+ rc->get_state = legacy_reset_get_state;
126
+ rc->phases.hold = legacy_reset_hold;
127
+}
128
129
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
130
{
44
{
131
- QEMUResetEntry *re = g_new0(QEMUResetEntry, 1);
45
/*
132
+ Object *obj = object_new(TYPE_LEGACY_RESET);
46
* FLCMP never raises an exception nor modifies any FSR fields.
133
+ LegacyReset *lr = LEGACY_RESET(obj);
47
* Perform the comparison with a dummy fp environment.
134
48
*/
135
- re->func = func;
49
- float_status discard = { };
136
- re->opaque = opaque;
50
+ float_status discard = env->fp_status;
137
- QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
51
FloatRelation r;
138
+ lr->func = func;
52
139
+ lr->opaque = opaque;
53
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
140
+ qemu_register_resettable(obj);
54
@@ -XXX,XX +XXX,XX @@ uint32_t helper_flcmps(float32 src1, float32 src2)
55
g_assert_not_reached();
141
}
56
}
142
57
143
void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque)
58
-uint32_t helper_flcmpd(float64 src1, float64 src2)
59
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
144
{
60
{
145
- QEMUResetEntry *re = g_new0(QEMUResetEntry, 1);
61
- float_status discard = { };
146
+ Object *obj = object_new(TYPE_LEGACY_RESET);
62
+ float_status discard = env->fp_status;
147
+ LegacyReset *lr = LEGACY_RESET(obj);
63
FloatRelation r;
148
64
149
- re->func = func;
65
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
150
- re->opaque = opaque;
66
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
151
- re->skip_on_snapshot_load = true;
67
index XXXXXXX..XXXXXXX 100644
152
- QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
68
--- a/target/sparc/translate.c
153
+ lr->func = func;
69
+++ b/target/sparc/translate.c
154
+ lr->opaque = opaque;
70
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPs(DisasContext *dc, arg_FLCMPs *a)
155
+ lr->skip_on_snapshot_load = true;
71
156
+ qemu_register_resettable(obj);
72
src1 = gen_load_fpr_F(dc, a->rs1);
157
+}
73
src2 = gen_load_fpr_F(dc, a->rs2);
158
+
74
- gen_helper_flcmps(cpu_fcc[a->cc], src1, src2);
159
+typedef struct FindLegacyInfo {
75
+ gen_helper_flcmps(cpu_fcc[a->cc], tcg_env, src1, src2);
160
+ QEMUResetHandler *func;
76
return advance_pc(dc);
161
+ void *opaque;
162
+ LegacyReset *lr;
163
+} FindLegacyInfo;
164
+
165
+static void find_legacy_reset_cb(Object *obj, void *opaque, ResetType type)
166
+{
167
+ LegacyReset *lr;
168
+ FindLegacyInfo *fli = opaque;
169
+
170
+ /* Not everything in the ResettableContainer will be a LegacyReset */
171
+ lr = LEGACY_RESET(object_dynamic_cast(obj, TYPE_LEGACY_RESET));
172
+ if (lr && lr->func == fli->func && lr->opaque == fli->opaque) {
173
+ fli->lr = lr;
174
+ }
175
+}
176
+
177
+static LegacyReset *find_legacy_reset(QEMUResetHandler *func, void *opaque)
178
+{
179
+ /*
180
+ * Find the LegacyReset with the specified func and opaque,
181
+ * by getting the ResettableContainer to call our callback for
182
+ * every item in it.
183
+ */
184
+ ResettableContainer *rootcon = get_root_reset_container();
185
+ ResettableClass *rc = RESETTABLE_GET_CLASS(rootcon);
186
+ FindLegacyInfo fli;
187
+
188
+ fli.func = func;
189
+ fli.opaque = opaque;
190
+ fli.lr = NULL;
191
+ rc->child_foreach(OBJECT(rootcon), find_legacy_reset_cb,
192
+ &fli, RESET_TYPE_COLD);
193
+ return fli.lr;
194
}
77
}
195
78
196
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
79
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPd(DisasContext *dc, arg_FLCMPd *a)
197
{
80
198
- QEMUResetEntry *re;
81
src1 = gen_load_fpr_D(dc, a->rs1);
199
+ Object *obj = OBJECT(find_legacy_reset(func, opaque));
82
src2 = gen_load_fpr_D(dc, a->rs2);
200
83
- gen_helper_flcmpd(cpu_fcc[a->cc], src1, src2);
201
- QTAILQ_FOREACH(re, &reset_handlers, entry) {
84
+ gen_helper_flcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
202
- if (re->func == func && re->opaque == opaque) {
85
return advance_pc(dc);
203
- QTAILQ_REMOVE(&reset_handlers, re, entry);
204
- g_free(re);
205
- return;
206
- }
207
+ if (obj) {
208
+ qemu_unregister_resettable(obj);
209
+ object_unref(obj);
210
}
211
}
86
}
212
87
213
@@ -XXX,XX +XXX,XX @@ void qemu_unregister_resettable(Object *obj)
214
215
void qemu_devices_reset(ShutdownCause reason)
216
{
217
- QEMUResetEntry *re, *nre;
218
-
219
- /* reset all devices */
220
- QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
221
- if (reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD &&
222
- re->skip_on_snapshot_load) {
223
- continue;
224
- }
225
- re->func(re->opaque);
226
- }
227
+ device_reset_reason = reason;
228
229
/* Reset the simulation */
230
resettable_reset(OBJECT(get_root_reset_container()), RESET_TYPE_COLD);
231
--
88
--
232
2.34.1
89
2.34.1
233
234
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
Currently the qemu_register_reset() API permits the reset handler functions
1
From: Richard Henderson <richard.henderson@linaro.org>
2
registered with it to remove themselves from within the callback function.
3
This is fine with our current implementation, but is a bit odd, because
4
generally reset is supposed to be idempotent, and doesn't fit well in a
5
three-phase-reset world where a resettable object will get multiple
6
callbacks as the system is reset.
7
2
8
We now have only one user of qemu_register_reset() which makes use of
3
Now that float_status has a bunch of fp parameters,
9
the ability to unregister itself within the callback:
4
it is easier to copy an existing structure than create
10
restore_boot_order(). We want to change our implementation of
5
one from scratch. Begin by copying the structure that
11
qemu_register_reset() to something where it would be awkward to
6
corresponds to the FPSR and make only the adjustments
12
maintain the "can self-unregister" feature. Rather than making that
7
required for BFloat16 semantics.
13
reimplementation complicated, change restore_boot_order() so that it
14
doesn't unregister itself but instead returns doing nothing for any
15
calls after it has done the "restore the boot order" work.
16
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20241203203949.483774-2-richard.henderson@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
21
Acked-by: Richard Henderson <richard.henderson@linaro.org>
22
Message-id: 20240220160622.114437-4-peter.maydell@linaro.org
23
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
24
---
14
---
25
system/bootdevice.c | 25 ++++++++++++++-----------
15
target/arm/tcg/vec_helper.c | 20 +++++++-------------
26
1 file changed, 14 insertions(+), 11 deletions(-)
16
1 file changed, 7 insertions(+), 13 deletions(-)
27
17
28
diff --git a/system/bootdevice.c b/system/bootdevice.c
18
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
29
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
30
--- a/system/bootdevice.c
20
--- a/target/arm/tcg/vec_helper.c
31
+++ b/system/bootdevice.c
21
+++ b/target/arm/tcg/vec_helper.c
32
@@ -XXX,XX +XXX,XX @@ void validate_bootdevices(const char *devices, Error **errp)
22
@@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
33
void restore_boot_order(void *opaque)
23
* no effect on AArch32 instructions.
34
{
24
*/
35
char *normal_boot_order = opaque;
25
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
36
- static int first = 1;
26
- *statusp = (float_status){
37
+ static int bootcount;
27
- .tininess_before_rounding = float_tininess_before_rounding,
38
28
- .float_rounding_mode = float_round_to_odd_inf,
39
- /* Restore boot order and remove ourselves after the first boot */
29
- .flush_to_zero = true,
40
- if (first) {
30
- .flush_inputs_to_zero = true,
41
- first = 0;
31
- .default_nan_mode = true,
42
+ switch (bootcount++) {
32
- };
43
+ case 0:
33
+
44
+ /* First boot: use the one-time config */
34
+ *statusp = env->vfp.fp_status;
45
+ return;
35
+ set_default_nan_mode(true, statusp);
46
+ case 1:
36
47
+ /* Second boot: restore normal boot order */
37
if (ebf) {
48
+ if (boot_set_handler) {
38
- float_status *fpst = &env->vfp.fp_status;
49
+ qemu_boot_set(normal_boot_order, &error_abort);
39
- set_flush_to_zero(get_flush_to_zero(fpst), statusp);
50
+ }
40
- set_flush_inputs_to_zero(get_flush_inputs_to_zero(fpst), statusp);
51
+ g_free(normal_boot_order);
41
- set_float_rounding_mode(get_float_rounding_mode(fpst), statusp);
52
+ return;
42
-
53
+ default:
43
/* EBF=1 needs to do a step with round-to-odd semantics */
54
+ /* Subsequent boots: keep using normal boot order */
44
*oddstatusp = *statusp;
55
return;
45
set_float_rounding_mode(float_round_to_odd, oddstatusp);
46
+ } else {
47
+ set_flush_to_zero(true, statusp);
48
+ set_flush_inputs_to_zero(true, statusp);
49
+ set_float_rounding_mode(float_round_to_odd_inf, statusp);
56
}
50
}
57
-
51
-
58
- if (boot_set_handler) {
52
return ebf;
59
- qemu_boot_set(normal_boot_order, &error_abort);
60
- }
61
-
62
- qemu_unregister_reset(restore_boot_order, normal_boot_order);
63
- g_free(normal_boot_order);
64
}
53
}
65
54
66
void check_boot_index(int32_t bootindex, Error **errp)
67
--
55
--
68
2.34.1
56
2.34.1
69
57
70
58
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Currently we hardcode the default NaN value in parts64_default_nan()
2
using a compile-time ifdef ladder. This is awkward for two cases:
3
* for single-QEMU-binary we can't hard-code target-specifics like this
4
* for Arm FEAT_AFP the default NaN value depends on FPCR.AH
5
(specifically the sign bit is different)
2
6
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
7
Add a field to float_status to specify the default NaN value; fall
4
Message-id: 20240226000259.2752893-37-sergey.kambalin@auriga.com
8
back to the old ifdef behaviour if these are not set.
9
10
The default NaN value is specified by setting a uint8_t to a
11
pattern corresponding to the sign and upper fraction parts of
12
the NaN; the lower bits of the fraction are set from bit 0 of
13
the pattern.
14
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
7
---
18
---
8
tests/qtest/bcm2838-mailbox.c | 1 -
19
include/fpu/softfloat-helpers.h | 11 +++++++
9
tests/qtest/bcm2838-mbox-property-test.c | 207 +++++++++++++++++++++++
20
include/fpu/softfloat-types.h | 10 ++++++
10
tests/qtest/meson.build | 2 +-
21
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
11
3 files changed, 208 insertions(+), 2 deletions(-)
22
3 files changed, 54 insertions(+), 22 deletions(-)
12
create mode 100644 tests/qtest/bcm2838-mbox-property-test.c
13
23
14
diff --git a/tests/qtest/bcm2838-mailbox.c b/tests/qtest/bcm2838-mailbox.c
24
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qtest/bcm2838-mailbox.c
26
--- a/include/fpu/softfloat-helpers.h
17
+++ b/tests/qtest/bcm2838-mailbox.c
27
+++ b/include/fpu/softfloat-helpers.h
18
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
19
#include "hw/registerfields.h"
29
status->float_infzeronan_rule = rule;
20
#include "libqtest-single.h"
30
}
21
#include "bcm2838-mailbox.h"
31
22
-#include "hw/arm/raspberrypi-fw-defs.h"
32
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
23
33
+ float_status *status)
24
REG32(MBOX_EXCHNG_REG, 0)
34
+{
25
FIELD(MBOX_EXCHNG_REG, CHANNEL, 0, 4)
35
+ status->default_nan_pattern = dnan_pattern;
26
diff --git a/tests/qtest/bcm2838-mbox-property-test.c b/tests/qtest/bcm2838-mbox-property-test.c
27
new file mode 100644
28
index XXXXXXX..XXXXXXX
29
--- /dev/null
30
+++ b/tests/qtest/bcm2838-mbox-property-test.c
31
@@ -XXX,XX +XXX,XX @@
32
+/*
33
+ * Tests set for BCM2838 mailbox property interface.
34
+ *
35
+ * Copyright (c) 2022 Auriga
36
+ *
37
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
38
+ * See the COPYING file in the top-level directory.
39
+ */
40
+
41
+#include "qemu/osdep.h"
42
+#include "hw/registerfields.h"
43
+#include "libqtest-single.h"
44
+#include "bcm2838-mailbox.h"
45
+#include "hw/arm/raspberrypi-fw-defs.h"
46
+
47
+REG32(MBOX_SIZE_STAT, 0)
48
+FIELD(MBOX_SIZE_STAT, SIZE, 0, 31)
49
+FIELD(MBOX_SIZE_STAT, SUCCESS, 31, 1)
50
+
51
+REG32(SET_POWER_STATE_CMD, 0)
52
+FIELD(SET_POWER_STATE_CMD, EN, 0, 1)
53
+FIELD(SET_POWER_STATE_CMD, WAIT, 1, 1)
54
+
55
+REG32(GET_CLOCK_STATE_CMD, 0)
56
+FIELD(GET_CLOCK_STATE_CMD, EN, 0, 1)
57
+FIELD(GET_CLOCK_STATE_CMD, NPRES, 1, 1)
58
+
59
+#define MBOX_TEST_MESSAGE_ADDRESS 0x10000000
60
+
61
+#define TEST_TAG(x) RPI_FWREQ_ ## x
62
+#define TEST_TAG_TYPE(x) TAG_##x##_t
63
+
64
+#define TEST_FN_NAME(test, subtest) \
65
+ test ## _ ## subtest ## _test
66
+
67
+#define SETUP_FN_NAME(test, subtest) \
68
+ test ## _ ## subtest ## _setup
69
+
70
+#define CHECK_FN_NAME(test, subtest) \
71
+ test ## _ ## subtest ## _spec_check
72
+
73
+#define DECLARE_TEST_CASE_SETUP(testname, ...) \
74
+ void SETUP_FN_NAME(testname, __VA_ARGS__) \
75
+ (TEST_TAG_TYPE(testname) * tag)
76
+
77
+/*----------------------------------------------------------------------------*/
78
+#define DECLARE_TEST_CASE(testname, ...) \
79
+ __attribute__((weak)) \
80
+ void SETUP_FN_NAME(testname, __VA_ARGS__) \
81
+ (TEST_TAG_TYPE(testname) * tag); \
82
+ static void CHECK_FN_NAME(testname, __VA_ARGS__) \
83
+ (TEST_TAG_TYPE(testname) *tag); \
84
+ static void TEST_FN_NAME(testname, __VA_ARGS__)(void) { \
85
+ struct { \
86
+ MboxBufHeader header; \
87
+ TEST_TAG_TYPE(testname) tag; \
88
+ uint32_t end_tag; \
89
+ } mailbox_buffer = { 0 }; \
90
+ \
91
+ QTestState *qts = qtest_init("-machine raspi4b"); \
92
+ \
93
+ mailbox_buffer.header.size = sizeof(mailbox_buffer); \
94
+ mailbox_buffer.header.req_resp_code = MBOX_PROCESS_REQUEST; \
95
+ \
96
+ mailbox_buffer.tag.id = TEST_TAG(testname); \
97
+ mailbox_buffer.tag.value_buffer_size = MAX( \
98
+ sizeof(mailbox_buffer.tag.request.value), \
99
+ sizeof(mailbox_buffer.tag.response.value)); \
100
+ mailbox_buffer.tag.request.zero = 0; \
101
+ \
102
+ mailbox_buffer.end_tag = RPI_FWREQ_PROPERTY_END; \
103
+ \
104
+ if (SETUP_FN_NAME(testname, __VA_ARGS__)) { \
105
+ SETUP_FN_NAME(testname, __VA_ARGS__)(&mailbox_buffer.tag); \
106
+ } \
107
+ \
108
+ qtest_memwrite(qts, MBOX_TEST_MESSAGE_ADDRESS, \
109
+ &mailbox_buffer, sizeof(mailbox_buffer)); \
110
+ qtest_mbox1_write_message(qts, MBOX_CHANNEL_ID_PROPERTY, \
111
+ MBOX_TEST_MESSAGE_ADDRESS); \
112
+ \
113
+ qtest_mbox0_read_message(qts, MBOX_CHANNEL_ID_PROPERTY, \
114
+ &mailbox_buffer, sizeof(mailbox_buffer)); \
115
+ \
116
+ g_assert_cmphex(mailbox_buffer.header.req_resp_code, ==, MBOX_SUCCESS);\
117
+ \
118
+ g_assert_cmphex(mailbox_buffer.tag.id, ==, TEST_TAG(testname)); \
119
+ \
120
+ uint32_t size = FIELD_EX32(mailbox_buffer.tag.response.size_stat, \
121
+ MBOX_SIZE_STAT, SIZE); \
122
+ uint32_t success = FIELD_EX32(mailbox_buffer.tag.response.size_stat, \
123
+ MBOX_SIZE_STAT, SUCCESS); \
124
+ g_assert_cmpint(size, ==, sizeof(mailbox_buffer.tag.response.value)); \
125
+ g_assert_cmpint(success, ==, 1); \
126
+ \
127
+ CHECK_FN_NAME(testname, __VA_ARGS__)(&mailbox_buffer.tag); \
128
+ \
129
+ qtest_quit(qts); \
130
+ } \
131
+ static void CHECK_FN_NAME(testname, __VA_ARGS__) \
132
+ (TEST_TAG_TYPE(testname) * tag)
133
+
134
+/*----------------------------------------------------------------------------*/
135
+
136
+#define QTEST_ADD_TEST_CASE(testname, ...) \
137
+ qtest_add_func(stringify(/bcm2838/mbox/property/ \
138
+ TEST_FN_NAME(testname, __VA_ARGS__)-test), \
139
+ TEST_FN_NAME(testname, __VA_ARGS__))
140
+
141
+/*----------------------------------------------------------------------------*/
142
+DECLARE_TEST_CASE(GET_FIRMWARE_REVISION) {
143
+ g_assert_cmpint(tag->response.value.revision, ==, FIRMWARE_REVISION);
144
+}
36
+}
145
+
37
+
146
+/*----------------------------------------------------------------------------*/
38
static inline void set_flush_to_zero(bool val, float_status *status)
147
+DECLARE_TEST_CASE(GET_BOARD_REVISION) {
39
{
148
+ g_assert_cmpint(tag->response.value.revision, ==, BOARD_REVISION);
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)
46
+{
47
+ return status->default_nan_pattern;
149
+}
48
+}
150
+
49
+
151
+/*----------------------------------------------------------------------------*/
50
static inline bool get_flush_to_zero(float_status *status)
152
+DECLARE_TEST_CASE(GET_ARM_MEMORY) {
51
{
153
+ g_assert_cmphex(tag->response.value.base, ==, ARM_MEMORY_BASE);
52
return status->flush_to_zero;
154
+ g_assert_cmphex(tag->response.value.size, ==, ARM_MEMORY_SIZE);
53
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
155
+}
54
index XXXXXXX..XXXXXXX 100644
55
--- a/include/fpu/softfloat-types.h
56
+++ b/include/fpu/softfloat-types.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
58
/* should denormalised inputs go to zero and set the input_denormal flag? */
59
bool flush_inputs_to_zero;
60
bool default_nan_mode;
61
+ /*
62
+ * The pattern to use for the default NaN. Here the high bit specifies
63
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
64
+ * fractional part. The low bits of the fractional part are copies of bit 0.
65
+ * The exponent of the default NaN is (as for any NaN) always all 1s.
66
+ * Note that a value of 0 here is not a valid NaN. The target must set
67
+ * this to the correct non-zero value, or we will assert when trying to
68
+ * create a default NaN.
69
+ */
70
+ uint8_t default_nan_pattern;
71
/*
72
* The flags below are not used on all specializations and may
73
* constant fold away (see snan_bit_is_one()/no_signalling_nans() in
74
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
75
index XXXXXXX..XXXXXXX 100644
76
--- a/fpu/softfloat-specialize.c.inc
77
+++ b/fpu/softfloat-specialize.c.inc
78
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
79
{
80
bool sign = 0;
81
uint64_t frac;
82
+ uint8_t dnan_pattern = status->default_nan_pattern;
83
84
+ if (dnan_pattern == 0) {
85
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
86
- /* !snan_bit_is_one, set all bits */
87
- frac = (1ULL << DECOMPOSED_BINARY_POINT) - 1;
88
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
89
+ /* Sign bit clear, all frac bits set */
90
+ dnan_pattern = 0b01111111;
91
+#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
92
|| defined(TARGET_MICROBLAZE)
93
- /* !snan_bit_is_one, set sign and msb */
94
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
95
- sign = 1;
96
+ /* Sign bit set, most significant frac bit set */
97
+ dnan_pattern = 0b11000000;
98
#elif defined(TARGET_HPPA)
99
- /* snan_bit_is_one, set msb-1. */
100
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 2);
101
+ /* Sign bit clear, msb-1 frac bit set */
102
+ dnan_pattern = 0b00100000;
103
#elif defined(TARGET_HEXAGON)
104
- sign = 1;
105
- frac = ~0ULL;
106
+ /* Sign bit set, all frac bits set. */
107
+ dnan_pattern = 0b11111111;
108
#else
109
- /*
110
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
111
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
112
- * do not have floating-point.
113
- */
114
- if (snan_bit_is_one(status)) {
115
- /* set all bits other than msb */
116
- frac = (1ULL << (DECOMPOSED_BINARY_POINT - 1)) - 1;
117
- } else {
118
- /* set msb */
119
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
120
- }
121
+ /*
122
+ * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
123
+ * S390, SH4, TriCore, and Xtensa. Our other supported targets
124
+ * do not have floating-point.
125
+ */
126
+ if (snan_bit_is_one(status)) {
127
+ /* sign bit clear, set all frac bits other than msb */
128
+ dnan_pattern = 0b00111111;
129
+ } else {
130
+ /* sign bit clear, set frac msb */
131
+ dnan_pattern = 0b01000000;
132
+ }
133
#endif
134
+ }
135
+ assert(dnan_pattern != 0);
156
+
136
+
157
+/*----------------------------------------------------------------------------*/
137
+ sign = dnan_pattern >> 7;
158
+DECLARE_TEST_CASE(GET_VC_MEMORY) {
138
+ /*
159
+ g_assert_cmphex(tag->response.value.base, ==, VC_MEMORY_BASE);
139
+ * Place default_nan_pattern [6:0] into bits [62:56],
160
+ g_assert_cmphex(tag->response.value.size, ==, VC_MEMORY_SIZE);
140
+ * and replecate bit [0] down into [55:0]
161
+}
141
+ */
162
+
142
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
163
+/*----------------------------------------------------------------------------*/
143
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
164
+DECLARE_TEST_CASE(SET_POWER_STATE) {
144
165
+ uint32_t enabled =
145
*p = (FloatParts64) {
166
+ FIELD_EX32(tag->response.value.cmd, SET_POWER_STATE_CMD, EN);
146
.cls = float_class_qnan,
167
+ uint32_t wait =
168
+ FIELD_EX32(tag->response.value.cmd, SET_POWER_STATE_CMD, WAIT);
169
+ g_assert_cmphex(tag->response.value.device_id, ==, DEVICE_ID_UART0);
170
+ g_assert_cmpint(enabled, ==, 1);
171
+ g_assert_cmpint(wait, ==, 0);
172
+}
173
+DECLARE_TEST_CASE_SETUP(SET_POWER_STATE) {
174
+ tag->request.value.device_id = DEVICE_ID_UART0;
175
+ tag->response.value.cmd =
176
+ FIELD_DP32(tag->response.value.cmd, SET_POWER_STATE_CMD, EN, 1);
177
+ tag->response.value.cmd =
178
+ FIELD_DP32(tag->response.value.cmd, SET_POWER_STATE_CMD, WAIT, 1);
179
+}
180
+
181
+/*----------------------------------------------------------------------------*/
182
+DECLARE_TEST_CASE(GET_CLOCK_STATE) {
183
+ uint32_t enabled =
184
+ FIELD_EX32(tag->response.value.cmd, GET_CLOCK_STATE_CMD, EN);
185
+ uint32_t not_present =
186
+ FIELD_EX32(tag->response.value.cmd, GET_CLOCK_STATE_CMD, NPRES);
187
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_CORE);
188
+ g_assert_cmphex(enabled, ==, 1);
189
+ g_assert_cmphex(not_present, ==, 0);
190
+}
191
+DECLARE_TEST_CASE_SETUP(GET_CLOCK_STATE) {
192
+ tag->request.value.clock_id = CLOCK_ID_CORE;
193
+}
194
+
195
+/*----------------------------------------------------------------------------*/
196
+DECLARE_TEST_CASE(GET_CLOCK_RATE, EMMC) {
197
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_EMMC);
198
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_EMMC);
199
+}
200
+DECLARE_TEST_CASE_SETUP(GET_CLOCK_RATE, EMMC) {
201
+ tag->request.value.clock_id = CLOCK_ID_EMMC;
202
+}
203
+
204
+/*----------------------------------------------------------------------------*/
205
+DECLARE_TEST_CASE(GET_MAX_CLOCK_RATE, EMMC) {
206
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_EMMC);
207
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_EMMC);
208
+}
209
+DECLARE_TEST_CASE_SETUP(GET_MAX_CLOCK_RATE, EMMC) {
210
+ tag->request.value.clock_id = CLOCK_ID_EMMC;
211
+}
212
+
213
+/*----------------------------------------------------------------------------*/
214
+DECLARE_TEST_CASE(GET_MIN_CLOCK_RATE, EMMC) {
215
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_EMMC);
216
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_EMMC);
217
+}
218
+DECLARE_TEST_CASE_SETUP(GET_MIN_CLOCK_RATE, EMMC) {
219
+ tag->request.value.clock_id = CLOCK_ID_EMMC;
220
+}
221
+
222
+/*----------------------------------------------------------------------------*/
223
+int main(int argc, char **argv)
224
+{
225
+ g_test_init(&argc, &argv, NULL);
226
+
227
+ QTEST_ADD_TEST_CASE(GET_FIRMWARE_REVISION);
228
+ QTEST_ADD_TEST_CASE(GET_BOARD_REVISION);
229
+ QTEST_ADD_TEST_CASE(GET_ARM_MEMORY);
230
+ QTEST_ADD_TEST_CASE(GET_VC_MEMORY);
231
+ QTEST_ADD_TEST_CASE(SET_POWER_STATE);
232
+ QTEST_ADD_TEST_CASE(GET_CLOCK_STATE);
233
+ QTEST_ADD_TEST_CASE(GET_CLOCK_RATE, EMMC);
234
+ QTEST_ADD_TEST_CASE(GET_MAX_CLOCK_RATE, EMMC);
235
+ QTEST_ADD_TEST_CASE(GET_MIN_CLOCK_RATE, EMMC);
236
+
237
+ return g_test_run();
238
+}
239
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
240
index XXXXXXX..XXXXXXX 100644
241
--- a/tests/qtest/meson.build
242
+++ b/tests/qtest/meson.build
243
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
244
['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) + \
245
(config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
246
(config_all_devices.has_key('CONFIG_XLNX_VERSAL') ? ['xlnx-canfd-test', 'xlnx-versal-trng-test'] : []) + \
247
- (config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
248
+ (config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test', 'bcm2838-mbox-property-test'] : []) + \
249
(config_all_accel.has_key('CONFIG_TCG') and \
250
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
251
['arm-cpu-features',
252
--
147
--
253
2.34.1
148
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the tests/fp code.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-36-peter.maydell@linaro.org
6
---
7
tests/fp/fp-bench.c | 1 +
8
tests/fp/fp-test-log2.c | 1 +
9
tests/fp/fp-test.c | 1 +
10
3 files changed, 3 insertions(+)
11
12
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/fp/fp-bench.c
15
+++ b/tests/fp/fp-bench.c
16
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
17
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
18
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
19
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
20
+ set_float_default_nan_pattern(0b01000000, &soft_status);
21
22
f = bench_funcs[operation][precision];
23
g_assert(f);
24
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/tests/fp/fp-test-log2.c
27
+++ b/tests/fp/fp-test-log2.c
28
@@ -XXX,XX +XXX,XX @@ int main(int ac, char **av)
29
int i;
30
31
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
32
+ set_float_default_nan_pattern(0b01000000, &qsf);
33
set_float_rounding_mode(float_round_nearest_even, &qsf);
34
35
test.d = 0.0;
36
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/fp/fp-test.c
39
+++ b/tests/fp/fp-test.c
40
@@ -XXX,XX +XXX,XX @@ void run_test(void)
41
*/
42
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
43
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
44
+ set_float_default_nan_pattern(0b01000000, &qsf);
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
46
47
genCases_setLevel(test_level);
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-37-peter.maydell@linaro.org
7
---
8
target/microblaze/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/microblaze/cpu.c
15
+++ b/target/microblaze/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_reset_hold(Object *obj, ResetType type)
17
* this architecture.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
23
#if defined(CONFIG_USER_ONLY)
24
/* start in user mode with interrupts enabled. */
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
34
- || defined(TARGET_MICROBLAZE)
35
+#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
/* Sign bit set, most significant frac bit set */
37
dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
--
40
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
2
3
3
Our model of the bcm2835 mailbox is missing a few properties
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
that we need for the raspi4 kernel:
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
* RPI_FWREQ_GET_CLOCKS
6
Message-id: 20241202131347.498124-38-peter.maydell@linaro.org
6
* RPI_FWREQ_GET_THROTTLED
7
---
7
* RPI_FWREQ_VCHIQ_INIT
8
target/i386/tcg/fpu_helper.c | 4 ++++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 4 insertions(+), 3 deletions(-)
8
11
9
Add minimal implementations of them.
12
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
10
11
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
12
Message-id: 20240226000259.2752893-40-sergey.kambalin@auriga.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
[PMM: improved commit message]
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
include/hw/arm/raspberrypi-fw-defs.h | 11 +++++++++++
18
hw/misc/bcm2835_property.c | 21 +++++++++++++++++++++
19
2 files changed, 32 insertions(+)
20
21
diff --git a/include/hw/arm/raspberrypi-fw-defs.h b/include/hw/arm/raspberrypi-fw-defs.h
22
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/raspberrypi-fw-defs.h
14
--- a/target/i386/tcg/fpu_helper.c
24
+++ b/include/hw/arm/raspberrypi-fw-defs.h
15
+++ b/target/i386/tcg/fpu_helper.c
25
@@ -XXX,XX +XXX,XX @@ enum rpi_firmware_clk_id {
16
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
26
RPI_FIRMWARE_NUM_CLK_ID,
17
*/
27
};
18
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
28
19
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
29
+struct rpi_firmware_property_tag_header {
20
+ /* Default NaN: sign bit set, most significant frac bit set */
30
+ uint32_t tag;
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
31
+ uint32_t buf_size;
22
+ set_float_default_nan_pattern(0b11000000, &env->mmx_status);
32
+ uint32_t req_resp_size;
23
+ set_float_default_nan_pattern(0b11000000, &env->sse_status);
33
+};
24
}
34
+
25
35
+typedef struct rpi_firmware_prop_request {
26
static inline uint8_t save_exception_flags(CPUX86State *env)
36
+ struct rpi_firmware_property_tag_header hdr;
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
37
+ uint8_t payload[0];
38
+} rpi_firmware_prop_request_t;
39
+
40
#endif /* INCLUDE_HW_MISC_RASPBERRYPI_FW_DEFS_H_ */
41
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
42
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/misc/bcm2835_property.c
29
--- a/fpu/softfloat-specialize.c.inc
44
+++ b/hw/misc/bcm2835_property.c
30
+++ b/fpu/softfloat-specialize.c.inc
45
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
46
#include "trace.h"
32
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
47
#include "hw/arm/raspi_platform.h"
33
/* Sign bit clear, all frac bits set */
48
34
dnan_pattern = 0b01111111;
49
+#define VCHI_BUSADDR_SIZE sizeof(uint32_t)
35
-#elif defined(TARGET_I386) || defined(TARGET_X86_64)
50
+
36
- /* Sign bit set, most significant frac bit set */
51
/* https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface */
37
- dnan_pattern = 0b11000000;
52
38
#elif defined(TARGET_HPPA)
53
static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
39
/* Sign bit clear, msb-1 frac bit set */
54
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
40
dnan_pattern = 0b00100000;
55
resplen = 8;
56
break;
57
58
+ case RPI_FWREQ_GET_CLOCKS:
59
+ /* TODO: add more clock IDs if needed */
60
+ stl_le_phys(&s->dma_as, value + 12, 0);
61
+ stl_le_phys(&s->dma_as, value + 16, RPI_FIRMWARE_ARM_CLK_ID);
62
+ resplen = 8;
63
+ break;
64
+
65
case RPI_FWREQ_SET_CLOCK_RATE:
66
case RPI_FWREQ_SET_MAX_CLOCK_RATE:
67
case RPI_FWREQ_SET_MIN_CLOCK_RATE:
68
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
69
stl_le_phys(&s->dma_as, value + 12, 0);
70
resplen = 4;
71
break;
72
+
73
case RPI_FWREQ_FRAMEBUFFER_GET_NUM_DISPLAYS:
74
stl_le_phys(&s->dma_as, value + 12, 1);
75
resplen = 4;
76
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
77
resplen);
78
break;
79
80
+ case RPI_FWREQ_GET_THROTTLED:
81
+ stl_le_phys(&s->dma_as, value + 12, 0);
82
+ resplen = 4;
83
+ break;
84
+
85
+ case RPI_FWREQ_VCHIQ_INIT:
86
+ stl_le_phys(&s->dma_as,
87
+ value + offsetof(rpi_firmware_prop_request_t, payload),
88
+ 0);
89
+ resplen = VCHI_BUSADDR_SIZE;
90
+ break;
91
default:
92
qemu_log_mask(LOG_UNIMP,
93
"bcm2835_property: unhandled tag 0x%08x\n", tag);
94
--
41
--
95
2.34.1
42
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
2
3
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
4
Message-id: 20240226000259.2752893-39-sergey.kambalin@auriga.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-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
---
7
---
8
tests/qtest/bcm2838-mbox-property-test.c | 211 +++++++++++++++++++++++
8
target/hppa/fpu_helper.c | 2 ++
9
1 file changed, 211 insertions(+)
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 2 insertions(+), 3 deletions(-)
10
11
11
diff --git a/tests/qtest/bcm2838-mbox-property-test.c b/tests/qtest/bcm2838-mbox-property-test.c
12
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qtest/bcm2838-mbox-property-test.c
14
--- a/target/hppa/fpu_helper.c
14
+++ b/tests/qtest/bcm2838-mbox-property-test.c
15
+++ b/target/hppa/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT) {
16
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
16
tag->request.value.height = 600;
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);
17
}
22
}
18
23
19
+/*----------------------------------------------------------------------------*/
24
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
20
+DECLARE_TEST_CASE(FRAMEBUFFER_TEST_DEPTH) {
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
21
+ g_assert_cmpint(tag->response.value.bpp, ==, DUMMY_VALUE);
26
index XXXXXXX..XXXXXXX 100644
22
+}
27
--- a/fpu/softfloat-specialize.c.inc
23
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_TEST_DEPTH) {
28
+++ b/fpu/softfloat-specialize.c.inc
24
+ tag->request.value.bpp = DUMMY_VALUE;
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
25
+}
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
26
+
31
/* Sign bit clear, all frac bits set */
27
+/*----------------------------------------------------------------------------*/
32
dnan_pattern = 0b01111111;
28
+DECLARE_TEST_CASE(FRAMEBUFFER_GET_DEPTH) {
33
-#elif defined(TARGET_HPPA)
29
+ g_assert_cmpint(tag->response.value.bpp, ==, 16);
34
- /* Sign bit clear, msb-1 frac bit set */
30
+}
35
- dnan_pattern = 0b00100000;
31
+
36
#elif defined(TARGET_HEXAGON)
32
+/*----------------------------------------------------------------------------*/
37
/* Sign bit set, all frac bits set. */
33
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_DEPTH) {
38
dnan_pattern = 0b11111111;
34
+ g_assert_cmpint(tag->response.value.bpp, ==, 24);
35
+}
36
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_DEPTH) {
37
+ tag->request.value.bpp = 24;
38
+}
39
+
40
+/*----------------------------------------------------------------------------*/
41
+DECLARE_TEST_CASE(FRAMEBUFFER_TEST_PIXEL_ORDER) {
42
+ g_assert_cmphex(tag->response.value.pixel_order, ==, DUMMY_VALUE);
43
+}
44
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_TEST_PIXEL_ORDER) {
45
+ tag->request.value.pixel_order = DUMMY_VALUE;
46
+}
47
+
48
+/*----------------------------------------------------------------------------*/
49
+DECLARE_TEST_CASE(FRAMEBUFFER_GET_PIXEL_ORDER) {
50
+ g_assert_cmphex(tag->response.value.pixel_order, ==, PIXEL_ORDER_RGB);
51
+}
52
+
53
+/*----------------------------------------------------------------------------*/
54
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_PIXEL_ORDER, BGR) {
55
+ g_assert_cmphex(tag->response.value.pixel_order, ==, PIXEL_ORDER_BGR);
56
+}
57
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_PIXEL_ORDER, BGR) {
58
+ tag->request.value.pixel_order = PIXEL_ORDER_BGR;
59
+}
60
+
61
+/*----------------------------------------------------------------------------*/
62
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_PIXEL_ORDER, RGB) {
63
+ g_assert_cmphex(tag->response.value.pixel_order, ==, PIXEL_ORDER_BGR);
64
+}
65
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_PIXEL_ORDER, RGB) {
66
+ tag->request.value.pixel_order = PIXEL_ORDER_BGR;
67
+}
68
+
69
+/*----------------------------------------------------------------------------*/
70
+DECLARE_TEST_CASE(FRAMEBUFFER_TEST_ALPHA_MODE) {
71
+ g_assert_cmphex(tag->response.value.alpha_mode, ==, DUMMY_VALUE);
72
+}
73
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_TEST_ALPHA_MODE) {
74
+ tag->request.value.alpha_mode = DUMMY_VALUE;
75
+}
76
+
77
+/*----------------------------------------------------------------------------*/
78
+DECLARE_TEST_CASE(FRAMEBUFFER_GET_ALPHA_MODE) {
79
+ g_assert_cmphex(tag->response.value.alpha_mode, ==, ALPHA_MODE_IGNORED);
80
+}
81
+
82
+/*----------------------------------------------------------------------------*/
83
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_ALPHA_MODE, ENABLED) {
84
+ g_assert_cmphex(tag->response.value.alpha_mode, ==, ALPHA_MODE_ENABLED);
85
+}
86
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_ALPHA_MODE, ENABLED) {
87
+ tag->request.value.alpha_mode = ALPHA_MODE_ENABLED;
88
+}
89
+
90
+/*----------------------------------------------------------------------------*/
91
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_ALPHA_MODE, REVERSED) {
92
+ g_assert_cmphex(tag->response.value.alpha_mode, ==, ALPHA_MODE_REVERSED);
93
+}
94
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_ALPHA_MODE, REVERSED) {
95
+ tag->request.value.alpha_mode = ALPHA_MODE_REVERSED;
96
+}
97
+
98
+/*----------------------------------------------------------------------------*/
99
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_ALPHA_MODE, IGNORED) {
100
+ g_assert_cmphex(tag->response.value.alpha_mode, ==, ALPHA_MODE_IGNORED);
101
+}
102
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_ALPHA_MODE, IGNORED) {
103
+ tag->request.value.alpha_mode = ALPHA_MODE_IGNORED;
104
+}
105
+
106
+/*----------------------------------------------------------------------------*/
107
+DECLARE_TEST_CASE(FRAMEBUFFER_GET_PITCH) {
108
+ g_assert_cmpint(tag->response.value.pitch, ==, 1280);
109
+}
110
+
111
+/*----------------------------------------------------------------------------*/
112
+DECLARE_TEST_CASE(FRAMEBUFFER_TEST_VIRTUAL_OFFSET) {
113
+ g_assert_cmpint(tag->response.value.x, ==, DUMMY_VALUE);
114
+ g_assert_cmpint(tag->response.value.y, ==, DUMMY_VALUE);
115
+}
116
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_TEST_VIRTUAL_OFFSET) {
117
+ tag->request.value.x = DUMMY_VALUE;
118
+ tag->request.value.y = DUMMY_VALUE;
119
+}
120
+
121
+/*----------------------------------------------------------------------------*/
122
+DECLARE_TEST_CASE(FRAMEBUFFER_GET_VIRTUAL_OFFSET) {
123
+ g_assert_cmpint(tag->response.value.x, ==, 0);
124
+ g_assert_cmpint(tag->response.value.y, ==, 0);
125
+}
126
+
127
+/*----------------------------------------------------------------------------*/
128
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_VIRTUAL_OFFSET, _0_) {
129
+ g_assert_cmpint(tag->response.value.x, ==, 0);
130
+ g_assert_cmpint(tag->response.value.y, ==, 0);
131
+}
132
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_VIRTUAL_OFFSET, _0_) {
133
+ tag->request.value.x = 0;
134
+ tag->request.value.y = 0;
135
+}
136
+
137
+/*----------------------------------------------------------------------------*/
138
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_VIRTUAL_OFFSET, _42_) {
139
+ g_assert_cmpint(tag->response.value.x, ==, 42);
140
+ g_assert_cmpint(tag->response.value.y, ==, 42);
141
+}
142
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_VIRTUAL_OFFSET, _42_) {
143
+ tag->request.value.x = 42;
144
+ tag->request.value.y = 42;
145
+}
146
+
147
+/*----------------------------------------------------------------------------*/
148
+DECLARE_TEST_CASE(FRAMEBUFFER_GET_OVERSCAN) {
149
+ g_assert_cmpint(tag->response.value.top, ==, 0);
150
+ g_assert_cmpint(tag->response.value.bottom, ==, 0);
151
+ g_assert_cmpint(tag->response.value.left, ==, 0);
152
+ g_assert_cmpint(tag->response.value.right, ==, 0);
153
+}
154
+
155
+/*----------------------------------------------------------------------------*/
156
+DECLARE_TEST_CASE(FRAMEBUFFER_TEST_OVERSCAN) {
157
+ g_assert_cmpint(tag->response.value.top, ==, 0);
158
+ g_assert_cmpint(tag->response.value.bottom, ==, 0);
159
+ g_assert_cmpint(tag->response.value.left, ==, 0);
160
+ g_assert_cmpint(tag->response.value.right, ==, 0);
161
+}
162
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_TEST_OVERSCAN) {
163
+ tag->request.value.top = DUMMY_VALUE;
164
+ tag->request.value.bottom = DUMMY_VALUE;
165
+ tag->request.value.left = DUMMY_VALUE;
166
+ tag->request.value.right = DUMMY_VALUE;
167
+}
168
+
169
+/*----------------------------------------------------------------------------*/
170
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_OVERSCAN) {
171
+ g_assert_cmpint(tag->response.value.top, ==, 0);
172
+ g_assert_cmpint(tag->response.value.bottom, ==, 0);
173
+ g_assert_cmpint(tag->response.value.left, ==, 0);
174
+ g_assert_cmpint(tag->response.value.right, ==, 0);
175
+}
176
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_OVERSCAN) {
177
+ tag->request.value.top = DUMMY_VALUE;
178
+ tag->request.value.bottom = DUMMY_VALUE;
179
+ tag->request.value.left = DUMMY_VALUE;
180
+ tag->request.value.right = DUMMY_VALUE;
181
+}
182
+
183
+/*----------------------------------------------------------------------------*/
184
+DECLARE_TEST_CASE(GET_DMA_CHANNELS) {
185
+ g_assert_cmphex(tag->response.value.mask, ==, GPIO_MASK);
186
+}
187
+
188
+/*----------------------------------------------------------------------------*/
189
+DECLARE_TEST_CASE(GET_COMMAND_LINE) {
190
+ /* No special checks are needed for this test case */
191
+}
192
+
193
+/*----------------------------------------------------------------------------*/
194
+DECLARE_TEST_CASE(FRAMEBUFFER_GET_NUM_DISPLAYS) {
195
+ g_assert_cmpint(tag->response.value.num_displays, ==, 1);
196
+}
197
+
198
+/*----------------------------------------------------------------------------*/
199
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_PITCH) {
200
+ /* No special checks are needed for this test case */
201
+}
202
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_PITCH) {
203
+ tag->request.value.pitch = DUMMY_VALUE;
204
+}
205
+
206
/*----------------------------------------------------------------------------*/
207
int main(int argc, char **argv)
208
{
209
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
210
QTEST_ADD_TEST_CASE(FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT);
211
QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT, INITIAL);
212
QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT);
213
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_TEST_DEPTH);
214
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_DEPTH);
215
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_DEPTH);
216
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_TEST_PIXEL_ORDER);
217
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_PIXEL_ORDER);
218
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_PIXEL_ORDER, BGR);
219
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_PIXEL_ORDER, RGB);
220
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_TEST_ALPHA_MODE);
221
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_ALPHA_MODE);
222
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_ALPHA_MODE, ENABLED);
223
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_ALPHA_MODE, REVERSED);
224
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_ALPHA_MODE, IGNORED);
225
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_PITCH);
226
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_TEST_VIRTUAL_OFFSET);
227
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_VIRTUAL_OFFSET);
228
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_VIRTUAL_OFFSET, _0_);
229
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_VIRTUAL_OFFSET, _42_);
230
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_OVERSCAN);
231
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_TEST_OVERSCAN);
232
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_OVERSCAN);
233
+ QTEST_ADD_TEST_CASE(GET_DMA_CHANNELS);
234
+ QTEST_ADD_TEST_CASE(GET_COMMAND_LINE);
235
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_NUM_DISPLAYS);
236
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_PITCH);
237
238
return g_test_run();
239
}
240
--
39
--
241
2.34.1
40
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly for the alpha target.
2
2
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
4
Message-id: 20240226000259.2752893-36-sergey.kambalin@auriga.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-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
7
---
6
---
8
tests/qtest/bcm2838-mailbox.h | 78 +++++++++++++++++++++++++++++++++++
7
target/alpha/cpu.c | 2 ++
9
1 file changed, 78 insertions(+)
8
1 file changed, 2 insertions(+)
10
9
11
diff --git a/tests/qtest/bcm2838-mailbox.h b/tests/qtest/bcm2838-mailbox.h
10
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
12
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qtest/bcm2838-mailbox.h
12
--- a/target/alpha/cpu.c
14
+++ b/tests/qtest/bcm2838-mailbox.h
13
+++ b/target/alpha/cpu.c
15
@@ -XXX,XX +XXX,XX @@ DECLARE_TAG_TYPE(TAG_GET_DMA_CHANNELS_t,
14
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_initfn(Object *obj)
16
uint32_t mask;
15
* operand in Fa. That is float_2nan_prop_ba.
17
});
16
*/
18
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
19
+DECLARE_TAG_TYPE(TAG_GET_THROTTLED_t,
18
+ /* Default NaN: sign bit clear, msb frac bit set */
20
+ struct {},
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
21
+ struct {
20
#if defined(CONFIG_USER_ONLY)
22
+ uint32_t throttled;
21
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
23
+ });
22
cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD
24
+
25
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_NUM_DISPLAYS_t,
26
+ struct {},
27
+ struct {
28
+ uint32_t num_displays;
29
+ });
30
+
31
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_DISPLAY_SETTINGS_t,
32
+ struct {},
33
+ struct {
34
+ uint32_t display_num;
35
+ uint32_t phys_width;
36
+ uint32_t phys_height;
37
+ uint32_t bpp;
38
+ uint16_t pitch;
39
+ uint32_t virt_width;
40
+ uint32_t virt_height;
41
+ uint16_t virt_width_offset;
42
+ uint32_t virt_height_offset;
43
+ uint32_t fb_bus_address_lo;
44
+ uint32_t fb_bus_address_hi;
45
+ });
46
+
47
+DECLARE_TAG_TYPE(TAG_GET_GPIO_CONFIG_t,
48
+ struct {
49
+ uint32_t gpio_num;
50
+ },
51
+ struct {
52
+ uint32_t zero;
53
+ uint32_t direction;
54
+ uint32_t polarity;
55
+ uint32_t term_en;
56
+ uint32_t term_pull_up;
57
+ });
58
+
59
+
60
+DECLARE_TAG_TYPE(TAG_SET_GPIO_CONFIG_t,
61
+ struct {
62
+ uint32_t gpio_num;
63
+ uint32_t direction;
64
+ uint32_t polarity;
65
+ uint32_t term_en;
66
+ uint32_t term_pull_up;
67
+ uint32_t state;
68
+ },
69
+ struct {
70
+ uint32_t zero;
71
+ });
72
+
73
+DECLARE_TAG_TYPE(TAG_GET_GPIO_STATE_t,
74
+ struct {
75
+ uint32_t gpio_num;
76
+ },
77
+ struct {
78
+ uint32_t zero;
79
+ uint32_t state;
80
+ });
81
+
82
+DECLARE_TAG_TYPE(TAG_SET_GPIO_STATE_t,
83
+ struct {
84
+ uint32_t gpio_num;
85
+ uint32_t state;
86
+ },
87
+ struct {
88
+ uint32_t zero;
89
+ });
90
+
91
+DECLARE_TAG_TYPE(TAG_VCHIQ_INIT_t,
92
+ struct {},
93
+ struct {
94
+ uint32_t zero;
95
+ });
96
+
97
int mbox0_has_data(void);
98
void mbox0_read_message(uint8_t channel, void *msgbuf, size_t msgbuf_size);
99
void mbox1_write_message(uint8_t channel, uint32_t msg_addr);
100
--
23
--
101
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly for the arm target.
2
This includes setting it for the old linux-user nwfpe emulation.
3
For nwfpe, our default doesn't match the real kernel, but we
4
avoid making a behaviour change in this commit.
2
5
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
4
Message-id: 20240226000259.2752893-35-sergey.kambalin@auriga.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-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
7
---
9
---
8
tests/qtest/bcm2838-mailbox.h | 152 ++++++++++++++++++++++++++++++++++
10
linux-user/arm/nwfpe/fpa11.c | 5 +++++
9
1 file changed, 152 insertions(+)
11
target/arm/cpu.c | 2 ++
12
2 files changed, 7 insertions(+)
10
13
11
diff --git a/tests/qtest/bcm2838-mailbox.h b/tests/qtest/bcm2838-mailbox.h
14
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qtest/bcm2838-mailbox.h
16
--- a/linux-user/arm/nwfpe/fpa11.c
14
+++ b/tests/qtest/bcm2838-mailbox.h
17
+++ b/linux-user/arm/nwfpe/fpa11.c
15
@@ -XXX,XX +XXX,XX @@ DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT_t,
18
@@ -XXX,XX +XXX,XX @@ void resetFPA11(void)
16
uint32_t height;
19
* this late date.
17
});
20
*/
18
21
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
19
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_DEPTH_t,
22
+ /*
20
+ struct {},
23
+ * Use the same default NaN value as Arm VFP. This doesn't match
21
+ struct {
24
+ * the Linux kernel's nwfpe emulation, which uses an all-1s value.
22
+ uint32_t bpp;
25
+ */
23
+ });
26
+ set_float_default_nan_pattern(0b01000000, &fpa11->fp_status);
24
+
27
}
25
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_DEPTH_t,
28
26
+ struct {
29
void SetRoundingMode(const unsigned int opcode)
27
+ uint32_t bpp;
30
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
28
+ },
31
index XXXXXXX..XXXXXXX 100644
29
+ struct {
32
--- a/target/arm/cpu.c
30
+ uint32_t bpp;
33
+++ b/target/arm/cpu.c
31
+ });
34
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
32
+
35
* the pseudocode function the arguments are in the order c, a, b.
33
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_DEPTH_t,
36
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
34
+ struct {
37
* and the input NaN if it is signalling
35
+ uint32_t bpp;
38
+ * * Default NaN has sign bit clear, msb frac bit set
36
+ },
39
*/
37
+ struct {
40
static void arm_set_default_fp_behaviours(float_status *s)
38
+ uint32_t bpp;
41
{
39
+ });
42
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
40
+
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
41
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_PIXEL_ORDER_t,
44
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
42
+ struct {},
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
43
+ struct {
46
+ set_float_default_nan_pattern(0b01000000, s);
44
+ uint32_t pixel_order;
47
}
45
+ });
48
46
+
49
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
47
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_PIXEL_ORDER_t,
48
+ struct {
49
+ uint32_t pixel_order;
50
+ },
51
+ struct {
52
+ uint32_t pixel_order;
53
+ });
54
+
55
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_PIXEL_ORDER_t,
56
+ struct {
57
+ uint32_t pixel_order;
58
+ },
59
+ struct {
60
+ uint32_t pixel_order;
61
+ });
62
+
63
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_ALPHA_MODE_t,
64
+ struct {},
65
+ struct {
66
+ uint32_t alpha_mode;
67
+ });
68
+
69
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_ALPHA_MODE_t,
70
+ struct {
71
+ uint32_t alpha_mode;
72
+ },
73
+ struct {
74
+ uint32_t alpha_mode;
75
+ });
76
+
77
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_ALPHA_MODE_t,
78
+ struct {
79
+ uint32_t alpha_mode;
80
+ },
81
+ struct {
82
+ uint32_t alpha_mode;
83
+ });
84
+
85
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_PITCH_t,
86
+ struct {},
87
+ struct {
88
+ uint32_t pitch;
89
+ });
90
+
91
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_PITCH_t,
92
+ struct {
93
+ uint32_t pitch;
94
+ },
95
+ struct {});
96
+
97
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_VIRTUAL_OFFSET_t,
98
+ struct {},
99
+ struct {
100
+ uint32_t x;
101
+ uint32_t y;
102
+ });
103
+
104
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_VIRTUAL_OFFSET_t,
105
+ struct {
106
+ uint32_t x;
107
+ uint32_t y;
108
+ },
109
+ struct {
110
+ uint32_t x;
111
+ uint32_t y;
112
+ });
113
+
114
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_VIRTUAL_OFFSET_t,
115
+ struct {
116
+ uint32_t x;
117
+ uint32_t y;
118
+ },
119
+ struct {
120
+ uint32_t x;
121
+ uint32_t y;
122
+ });
123
+
124
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_OVERSCAN_t,
125
+ struct {},
126
+ struct {
127
+ uint32_t top;
128
+ uint32_t bottom;
129
+ uint32_t left;
130
+ uint32_t right;
131
+ });
132
+
133
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_OVERSCAN_t,
134
+ struct {
135
+ uint32_t top;
136
+ uint32_t bottom;
137
+ uint32_t left;
138
+ uint32_t right;
139
+ },
140
+ struct {
141
+ uint32_t top;
142
+ uint32_t bottom;
143
+ uint32_t left;
144
+ uint32_t right;
145
+ });
146
+
147
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_OVERSCAN_t,
148
+ struct {
149
+ uint32_t top;
150
+ uint32_t bottom;
151
+ uint32_t left;
152
+ uint32_t right;
153
+ },
154
+ struct {
155
+ uint32_t top;
156
+ uint32_t bottom;
157
+ uint32_t left;
158
+ uint32_t right;
159
+ });
160
+
161
+DECLARE_TAG_TYPE(TAG_GET_COMMAND_LINE_t,
162
+ struct {},
163
+ struct {});
164
+
165
+DECLARE_TAG_TYPE(TAG_GET_DMA_CHANNELS_t,
166
+ struct {},
167
+ struct {
168
+ uint32_t mask;
169
+ });
170
+
171
int mbox0_has_data(void);
172
void mbox0_read_message(uint8_t channel, void *msgbuf, size_t msgbuf_size);
173
void mbox1_write_message(uint8_t channel, uint32_t msg_addr);
174
--
50
--
175
2.34.1
51
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly for loongarch.
2
2
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240226000259.2752893-13-sergey.kambalin@auriga.com
6
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-42-peter.maydell@linaro.org
7
---
6
---
8
include/hw/arm/bcm2838_peripherals.h | 2 ++
7
target/loongarch/tcg/fpu_helper.c | 2 ++
9
include/hw/arm/raspi_platform.h | 2 +-
8
1 file changed, 2 insertions(+)
10
hw/arm/bcm2838_peripherals.c | 3 +++
11
3 files changed, 6 insertions(+), 1 deletion(-)
12
9
13
diff --git a/include/hw/arm/bcm2838_peripherals.h b/include/hw/arm/bcm2838_peripherals.h
10
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/bcm2838_peripherals.h
12
--- a/target/loongarch/tcg/fpu_helper.c
16
+++ b/include/hw/arm/bcm2838_peripherals.h
13
+++ b/target/loongarch/tcg/fpu_helper.c
17
@@ -XXX,XX +XXX,XX @@ struct BCM2838PeripheralState {
14
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
18
OrIRQState mmc_irq_orgate;
15
*/
19
OrIRQState dma_7_8_irq_orgate;
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
OrIRQState dma_9_10_irq_orgate;
17
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
21
+
18
+ /* Default NaN: sign bit clear, msb frac bit set */
22
+ UnimplementedDeviceState asb;
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
23
};
24
25
struct BCM2838PeripheralClass {
26
diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/arm/raspi_platform.h
29
+++ b/include/hw/arm/raspi_platform.h
30
@@ -XXX,XX +XXX,XX @@ uint64_t board_ram_size(uint32_t board_rev);
31
#define MPHI_OFFSET 0x6000 /* Message-based Parallel Host Intf. */
32
#define DMA_OFFSET 0x7000 /* DMA controller, channels 0-14 */
33
#define ARBA_OFFSET 0x9000
34
-#define BRDG_OFFSET 0xa000
35
+#define BRDG_OFFSET 0xa000 /* RPiVid ASB for BCM2838 (BCM2711) */
36
#define ARM_OFFSET 0xB000 /* ARM control block */
37
#define ARMCTRL_OFFSET (ARM_OFFSET + 0x000)
38
#define ARMCTRL_IC_OFFSET (ARM_OFFSET + 0x200) /* Interrupt controller */
39
diff --git a/hw/arm/bcm2838_peripherals.c b/hw/arm/bcm2838_peripherals.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/arm/bcm2838_peripherals.c
42
+++ b/hw/arm/bcm2838_peripherals.c
43
@@ -XXX,XX +XXX,XX @@ static void bcm2838_peripherals_realize(DeviceState *dev, Error **errp)
44
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gpio), 0));
45
46
object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->gpio), "sd-bus");
47
+
48
+ /* BCM2838 RPiVid ASB must be mapped to prevent kernel crash */
49
+ create_unimp(s_base, &s->asb, "bcm2838-asb", BRDG_OFFSET, 0x24);
50
}
20
}
51
21
52
static void bcm2838_peripherals_class_init(ObjectClass *oc, void *data)
22
int ieee_ex_to_loongarch(int xcpt)
53
--
23
--
54
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly for m68k.
2
2
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
4
Message-id: 20240226000259.2752893-34-sergey.kambalin@auriga.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-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
7
---
6
---
8
tests/qtest/bcm2838-mailbox.h | 177 ++++++++++++++++++++++++++++++++++
7
target/m68k/cpu.c | 2 ++
9
1 file changed, 177 insertions(+)
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 3 insertions(+), 1 deletion(-)
10
10
11
diff --git a/tests/qtest/bcm2838-mailbox.h b/tests/qtest/bcm2838-mailbox.h
11
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qtest/bcm2838-mailbox.h
13
--- a/target/m68k/cpu.c
14
+++ b/tests/qtest/bcm2838-mailbox.h
14
+++ b/target/m68k/cpu.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct { \
15
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
16
}; \
16
* preceding paragraph for nonsignaling NaNs.
17
} TypeName
17
*/
18
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
+DECLARE_TAG_TYPE(TAG_GET_FIRMWARE_REVISION_t,
19
+ /* Default NaN: sign bit clear, all frac bits set */
20
+ struct {},
20
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
21
+ struct {
21
22
+ uint32_t revision;
22
nan = floatx80_default_nan(&env->fp_status);
23
+ });
23
for (i = 0; i < 8; i++) {
24
+
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
+DECLARE_TAG_TYPE(TAG_GET_FIRMWARE_VARIANT_t,
25
index XXXXXXX..XXXXXXX 100644
26
+ struct {},
26
--- a/fpu/softfloat-specialize.c.inc
27
+ struct {
27
+++ b/fpu/softfloat-specialize.c.inc
28
+ uint32_t variant;
28
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
29
+ });
29
uint8_t dnan_pattern = status->default_nan_pattern;
30
+
30
31
+DECLARE_TAG_TYPE(TAG_GET_BOARD_REVISION_t,
31
if (dnan_pattern == 0) {
32
+ struct {},
32
-#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
+ struct {
33
+#if defined(TARGET_SPARC)
34
+ uint32_t revision;
34
/* Sign bit clear, all frac bits set */
35
+ });
35
dnan_pattern = 0b01111111;
36
+
36
#elif defined(TARGET_HEXAGON)
37
+DECLARE_TAG_TYPE(TAG_GET_ARM_MEMORY_t,
38
+ struct {},
39
+ struct {
40
+ uint32_t base;
41
+ uint32_t size;
42
+ });
43
+
44
+DECLARE_TAG_TYPE(TAG_GET_VC_MEMORY_t,
45
+ struct {},
46
+ struct {
47
+ uint32_t base;
48
+ uint32_t size;
49
+ });
50
+
51
+DECLARE_TAG_TYPE(TAG_SET_POWER_STATE_t,
52
+ struct {
53
+ uint32_t device_id;
54
+ uint32_t cmd;
55
+ },
56
+ struct {
57
+ uint32_t device_id;
58
+ uint32_t cmd;
59
+ });
60
+
61
+DECLARE_TAG_TYPE(TAG_GET_CLOCK_STATE_t,
62
+ struct {
63
+ uint32_t clock_id;
64
+ },
65
+ struct {
66
+ uint32_t clock_id;
67
+ uint32_t cmd;
68
+ });
69
+
70
+DECLARE_TAG_TYPE(TAG_GET_CLOCK_RATE_t,
71
+ struct {
72
+ uint32_t clock_id;
73
+ },
74
+ struct {
75
+ uint32_t clock_id;
76
+ uint32_t rate;
77
+ });
78
+
79
+DECLARE_TAG_TYPE(TAG_GET_MAX_CLOCK_RATE_t,
80
+ struct {
81
+ uint32_t clock_id;
82
+ },
83
+ struct {
84
+ uint32_t clock_id;
85
+ uint32_t rate;
86
+ });
87
+
88
+DECLARE_TAG_TYPE(TAG_GET_MIN_CLOCK_RATE_t,
89
+ struct {
90
+ uint32_t clock_id;
91
+ },
92
+ struct {
93
+ uint32_t clock_id;
94
+ uint32_t rate;
95
+ });
96
+
97
+DECLARE_TAG_TYPE(TAG_GET_CLOCKS_t,
98
+ struct {},
99
+ struct {
100
+ uint32_t root_clock;
101
+ uint32_t arm_clock;
102
+ });
103
+
104
+DECLARE_TAG_TYPE(TAG_GET_TEMPERATURE_t,
105
+ struct {
106
+ uint32_t temperature_id;
107
+ },
108
+ struct {
109
+ uint32_t temperature_id;
110
+ uint32_t temperature;
111
+ });
112
+
113
+DECLARE_TAG_TYPE(TAG_GET_MAX_TEMPERATURE_t,
114
+ struct {
115
+ uint32_t temperature_id;
116
+ },
117
+ struct {
118
+ uint32_t temperature_id;
119
+ uint32_t temperature;
120
+ });
121
+
122
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_ALLOCATE_t,
123
+ struct {
124
+ uint32_t alignment;
125
+ },
126
+ struct {
127
+ uint32_t base;
128
+ uint32_t size;
129
+ });
130
+
131
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_RELEASE_t,
132
+ struct {},
133
+ struct {});
134
+
135
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_BLANK_t,
136
+ struct {
137
+ uint32_t on;
138
+ },
139
+ struct {
140
+ uint32_t on;
141
+ });
142
+
143
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT_t,
144
+ struct {},
145
+ struct {
146
+ uint32_t width;
147
+ uint32_t height;
148
+ });
149
+
150
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT_t,
151
+ struct {
152
+ uint32_t width;
153
+ uint32_t height;
154
+ },
155
+ struct {
156
+ uint32_t width;
157
+ uint32_t height;
158
+ });
159
+
160
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT_t,
161
+ struct {
162
+ uint32_t width;
163
+ uint32_t height;
164
+ },
165
+ struct {
166
+ uint32_t width;
167
+ uint32_t height;
168
+ });
169
+
170
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT_t,
171
+ struct {},
172
+ struct {
173
+ uint32_t width;
174
+ uint32_t height;
175
+ });
176
+
177
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT_t,
178
+ struct {
179
+ uint32_t width;
180
+ uint32_t height;
181
+ },
182
+ struct {
183
+ uint32_t width;
184
+ uint32_t height;
185
+ });
186
+
187
+DECLARE_TAG_TYPE(TAG_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT_t,
188
+ struct {
189
+ uint32_t width;
190
+ uint32_t height;
191
+ },
192
+ struct {
193
+ uint32_t width;
194
+ uint32_t height;
195
+ });
196
197
int mbox0_has_data(void);
198
void mbox0_read_message(uint8_t channel, void *msgbuf, size_t msgbuf_size);
199
--
37
--
200
2.34.1
38
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly for MIPS. Note that this
2
is our only target which currently changes the default NaN
3
at runtime (which it was previously doing indirectly when it
4
changed the snan_bit_is_one setting).
2
5
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
4
Message-id: 20240226000259.2752893-38-sergey.kambalin@auriga.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-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
7
---
9
---
8
tests/qtest/bcm2838-mbox-property-test.c | 196 ++++++++++++++++++++++-
10
target/mips/fpu_helper.h | 7 +++++++
9
1 file changed, 195 insertions(+), 1 deletion(-)
11
target/mips/msa.c | 3 +++
12
2 files changed, 10 insertions(+)
10
13
11
diff --git a/tests/qtest/bcm2838-mbox-property-test.c b/tests/qtest/bcm2838-mbox-property-test.c
14
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qtest/bcm2838-mbox-property-test.c
16
--- a/target/mips/fpu_helper.h
14
+++ b/tests/qtest/bcm2838-mbox-property-test.c
17
+++ b/target/mips/fpu_helper.h
15
@@ -XXX,XX +XXX,XX @@ FIELD(GET_CLOCK_STATE_CMD, NPRES, 1, 1)
18
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
16
(TEST_TAG_TYPE(testname) * tag); \
19
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
17
static void CHECK_FN_NAME(testname, __VA_ARGS__) \
20
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
18
(TEST_TAG_TYPE(testname) *tag); \
21
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
19
- static void TEST_FN_NAME(testname, __VA_ARGS__)(void) { \
22
+ /*
20
+ static void TEST_FN_NAME(testname, __VA_ARGS__)(void) \
23
+ * With nan2008, the default NaN value has the sign bit clear and the
21
+ { \
24
+ * frac msb set; with the older mode, the sign bit is clear, and all
22
struct { \
25
+ * frac bits except the msb are set.
23
MboxBufHeader header; \
26
+ */
24
TEST_TAG_TYPE(testname) tag; \
27
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
25
@@ -XXX,XX +XXX,XX @@ DECLARE_TEST_CASE_SETUP(GET_MIN_CLOCK_RATE, EMMC) {
28
+ &env->active_fpu.fp_status);
26
tag->request.value.clock_id = CLOCK_ID_EMMC;
29
27
}
30
}
28
31
29
+/*----------------------------------------------------------------------------*/
32
diff --git a/target/mips/msa.c b/target/mips/msa.c
30
+DECLARE_TEST_CASE(GET_CLOCK_RATE, UART) {
33
index XXXXXXX..XXXXXXX 100644
31
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_UART);
34
--- a/target/mips/msa.c
32
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_UART);
35
+++ b/target/mips/msa.c
33
+}
36
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
34
+DECLARE_TEST_CASE_SETUP(GET_CLOCK_RATE, UART) {
37
/* Inf * 0 + NaN returns the input NaN */
35
+ tag->request.value.clock_id = CLOCK_ID_UART;
38
set_float_infzeronan_rule(float_infzeronan_dnan_never,
36
+}
39
&env->active_tc.msa_fp_status);
37
+
40
+ /* Default NaN: sign bit clear, frac msb set */
38
+/*----------------------------------------------------------------------------*/
41
+ set_float_default_nan_pattern(0b01000000,
39
+DECLARE_TEST_CASE(GET_MAX_CLOCK_RATE, UART) {
42
+ &env->active_tc.msa_fp_status);
40
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_UART);
41
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_UART);
42
+}
43
+DECLARE_TEST_CASE_SETUP(GET_MAX_CLOCK_RATE, UART) {
44
+ tag->request.value.clock_id = CLOCK_ID_UART;
45
+}
46
+
47
+/*----------------------------------------------------------------------------*/
48
+DECLARE_TEST_CASE(GET_MIN_CLOCK_RATE, UART) {
49
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_UART);
50
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_UART);
51
+}
52
+DECLARE_TEST_CASE_SETUP(GET_MIN_CLOCK_RATE, UART) {
53
+ tag->request.value.clock_id = CLOCK_ID_UART;
54
+}
55
+
56
+/*----------------------------------------------------------------------------*/
57
+DECLARE_TEST_CASE(GET_CLOCK_RATE, CORE) {
58
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_CORE);
59
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_CORE);
60
+}
61
+DECLARE_TEST_CASE_SETUP(GET_CLOCK_RATE, CORE) {
62
+ tag->request.value.clock_id = CLOCK_ID_CORE;
63
+}
64
+
65
+/*----------------------------------------------------------------------------*/
66
+DECLARE_TEST_CASE(GET_MAX_CLOCK_RATE, CORE) {
67
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_CORE);
68
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_CORE);
69
+}
70
+DECLARE_TEST_CASE_SETUP(GET_MAX_CLOCK_RATE, CORE) {
71
+ tag->request.value.clock_id = CLOCK_ID_CORE;
72
+}
73
+
74
+/*----------------------------------------------------------------------------*/
75
+DECLARE_TEST_CASE(GET_MIN_CLOCK_RATE, CORE) {
76
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_CORE);
77
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_CORE);
78
+}
79
+DECLARE_TEST_CASE_SETUP(GET_MIN_CLOCK_RATE, CORE) {
80
+ tag->request.value.clock_id = CLOCK_ID_CORE;
81
+}
82
+
83
+/*----------------------------------------------------------------------------*/
84
+DECLARE_TEST_CASE(GET_CLOCK_RATE, ANY) {
85
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_UNDEFINED);
86
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_ANY);
87
+}
88
+DECLARE_TEST_CASE_SETUP(GET_CLOCK_RATE, ANY) {
89
+ tag->request.value.clock_id = CLOCK_ID_UNDEFINED;
90
+}
91
+
92
+/*----------------------------------------------------------------------------*/
93
+DECLARE_TEST_CASE(GET_MAX_CLOCK_RATE, ANY) {
94
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_UNDEFINED);
95
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_ANY);
96
+}
97
+DECLARE_TEST_CASE_SETUP(GET_MAX_CLOCK_RATE, ANY) {
98
+ tag->request.value.clock_id = CLOCK_ID_UNDEFINED;
99
+}
100
+
101
+/*----------------------------------------------------------------------------*/
102
+DECLARE_TEST_CASE(GET_MIN_CLOCK_RATE, ANY) {
103
+ g_assert_cmphex(tag->response.value.clock_id, ==, CLOCK_ID_UNDEFINED);
104
+ g_assert_cmphex(tag->response.value.rate, ==, CLOCK_RATE_ANY);
105
+}
106
+DECLARE_TEST_CASE_SETUP(GET_MIN_CLOCK_RATE, ANY) {
107
+ tag->request.value.clock_id = CLOCK_ID_UNDEFINED;
108
+}
109
+
110
+/*----------------------------------------------------------------------------*/
111
+DECLARE_TEST_CASE(GET_TEMPERATURE) {
112
+ g_assert_cmphex(tag->response.value.temperature_id, ==, TEMPERATURE_ID_SOC);
113
+ g_assert_cmpint(tag->response.value.temperature, ==, TEMPERATURE_SOC);
114
+}
115
+DECLARE_TEST_CASE_SETUP(GET_TEMPERATURE) {
116
+ tag->request.value.temperature_id = TEMPERATURE_ID_SOC;
117
+}
118
+
119
+/*----------------------------------------------------------------------------*/
120
+DECLARE_TEST_CASE(GET_MAX_TEMPERATURE) {
121
+ g_assert_cmphex(tag->response.value.temperature_id, ==, TEMPERATURE_ID_SOC);
122
+ g_assert_cmpint(tag->response.value.temperature, ==, TEMPERATURE_SOC_MAX);
123
+}
124
+DECLARE_TEST_CASE_SETUP(GET_MAX_TEMPERATURE) {
125
+ tag->request.value.temperature_id = TEMPERATURE_ID_SOC;
126
+}
127
+
128
+/*----------------------------------------------------------------------------*/
129
+DECLARE_TEST_CASE(FRAMEBUFFER_ALLOCATE) {
130
+ g_assert_cmphex(tag->response.value.base, ==, VC_FB_BASE);
131
+ g_assert_cmphex(tag->response.value.size, ==, VC_FB_SIZE);
132
+}
133
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_ALLOCATE) {
134
+ tag->request.value.alignment = ALIGN_4K;
135
+}
136
+
137
+/*----------------------------------------------------------------------------*/
138
+DECLARE_TEST_CASE(FRAMEBUFFER_RELEASE) {
139
+ /* No special checks are needed for this test */
140
+}
141
+
142
+/*----------------------------------------------------------------------------*/
143
+DECLARE_TEST_CASE(FRAMEBUFFER_BLANK) {
144
+ g_assert_cmphex(tag->response.value.on, ==, 0);
145
+}
146
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_BLANK) {
147
+ tag->request.value.on = 0;
148
+}
149
+
150
+/*----------------------------------------------------------------------------*/
151
+DECLARE_TEST_CASE(FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT) {
152
+ g_assert_cmpint(tag->response.value.width, ==, DUMMY_VALUE);
153
+ g_assert_cmpint(tag->response.value.height, ==, DUMMY_VALUE);
154
+}
155
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT) {
156
+ tag->request.value.width = DUMMY_VALUE;
157
+ tag->request.value.height = DUMMY_VALUE;
158
+}
159
+
160
+/*----------------------------------------------------------------------------*/
161
+DECLARE_TEST_CASE(FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, INITIAL) {
162
+ g_assert_cmpint(tag->response.value.width, ==, 640);
163
+ g_assert_cmpint(tag->response.value.height, ==, 480);
164
+}
165
+
166
+/*----------------------------------------------------------------------------*/
167
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT) {
168
+ g_assert_cmpint(tag->response.value.width, ==, 800);
169
+ g_assert_cmpint(tag->response.value.height, ==, 600);
170
+}
171
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT) {
172
+ tag->request.value.width = 800;
173
+ tag->request.value.height = 600;
174
+}
175
+
176
+/*----------------------------------------------------------------------------*/
177
+DECLARE_TEST_CASE(FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT) {
178
+ g_assert_cmpint(tag->response.value.width, ==, DUMMY_VALUE);
179
+ g_assert_cmpint(tag->response.value.height, ==, DUMMY_VALUE);
180
+}
181
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT) {
182
+ tag->request.value.width = DUMMY_VALUE;
183
+ tag->request.value.height = DUMMY_VALUE;
184
+}
185
+
186
+/*----------------------------------------------------------------------------*/
187
+DECLARE_TEST_CASE(FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT, INITIAL) {
188
+ g_assert_cmpint(tag->response.value.width, ==, 640);
189
+ g_assert_cmpint(tag->response.value.height, ==, 480);
190
+}
191
+
192
+/*----------------------------------------------------------------------------*/
193
+DECLARE_TEST_CASE(FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT) {
194
+ g_assert_cmpint(tag->response.value.width, ==, 800);
195
+ g_assert_cmpint(tag->response.value.height, ==, 600);
196
+}
197
+DECLARE_TEST_CASE_SETUP(FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT) {
198
+ tag->request.value.width = 800;
199
+ tag->request.value.height = 600;
200
+}
201
+
202
/*----------------------------------------------------------------------------*/
203
int main(int argc, char **argv)
204
{
205
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
206
QTEST_ADD_TEST_CASE(GET_CLOCK_RATE, EMMC);
207
QTEST_ADD_TEST_CASE(GET_MAX_CLOCK_RATE, EMMC);
208
QTEST_ADD_TEST_CASE(GET_MIN_CLOCK_RATE, EMMC);
209
+ QTEST_ADD_TEST_CASE(GET_CLOCK_RATE, UART);
210
+ QTEST_ADD_TEST_CASE(GET_MAX_CLOCK_RATE, UART);
211
+ QTEST_ADD_TEST_CASE(GET_MIN_CLOCK_RATE, UART);
212
+ QTEST_ADD_TEST_CASE(GET_CLOCK_RATE, CORE);
213
+ QTEST_ADD_TEST_CASE(GET_MAX_CLOCK_RATE, CORE);
214
+ QTEST_ADD_TEST_CASE(GET_MIN_CLOCK_RATE, CORE);
215
+ QTEST_ADD_TEST_CASE(GET_CLOCK_RATE, ANY);
216
+ QTEST_ADD_TEST_CASE(GET_MAX_CLOCK_RATE, ANY);
217
+ QTEST_ADD_TEST_CASE(GET_MIN_CLOCK_RATE, ANY);
218
+ QTEST_ADD_TEST_CASE(GET_TEMPERATURE);
219
+ QTEST_ADD_TEST_CASE(GET_MAX_TEMPERATURE);
220
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_ALLOCATE);
221
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_RELEASE);
222
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_BLANK);
223
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT);
224
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, INITIAL);
225
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT);
226
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT);
227
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT, INITIAL);
228
+ QTEST_ADD_TEST_CASE(FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT);
229
230
return g_test_run();
231
}
43
}
232
--
44
--
233
2.34.1
45
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly for openrisc.
2
2
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
4
Message-id: 20240226000259.2752893-33-sergey.kambalin@auriga.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-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
7
---
6
---
8
tests/qtest/bcm2838-mailbox.h | 88 +++++++++++++++++++++++++++++++++++
7
target/openrisc/cpu.c | 2 ++
9
tests/qtest/bcm2838-mailbox.c | 1 +
8
1 file changed, 2 insertions(+)
10
2 files changed, 89 insertions(+)
11
9
12
diff --git a/tests/qtest/bcm2838-mailbox.h b/tests/qtest/bcm2838-mailbox.h
10
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qtest/bcm2838-mailbox.h
12
--- a/target/openrisc/cpu.c
15
+++ b/tests/qtest/bcm2838-mailbox.h
13
+++ b/target/openrisc/cpu.c
16
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
17
* See the COPYING file in the top-level directory.
15
*/
18
*/
16
set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
19
17
20
+#define MBOX0_BASE 0xFE00B880
18
+ /* Default NaN: sign bit clear, frac msb set */
21
+#define MBOX1_BASE 0xFE00B8A0
19
+ set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
22
+
20
23
+#define MBOX_REG_READ 0x00
21
#ifndef CONFIG_USER_ONLY
24
+#define MBOX_REG_WRITE 0x00
22
cpu->env.picmr = 0x00000000;
25
+#define MBOX_REG_PEEK 0x10
26
+#define MBOX_REG_SENDER 0x14
27
+#define MBOX_REG_STATUS 0x18
28
+#define MBOX_REG_CONFIG 0x1C
29
+
30
+#define MBOX_READ_EMPTY 0x40000000
31
+
32
+#define MBOX_CHANNEL_ID_PROPERTY 8
33
+
34
+#define MBOX_PROCESS_REQUEST 0x00000000
35
+#define MBOX_SUCCESS 0x80000000
36
+#define MBOX_ERROR_PARSING_BUFFER 0x80000001
37
+
38
+#define BOARD_REVISION 0xB03115
39
+#define FIRMWARE_REVISION 0x548E1
40
+#define FIRMWARE_VARIANT 0x77777777 /* TODO: Find the real value */
41
+
42
+#define ARM_MEMORY_BASE 0x00000000
43
+#define ARM_MEMORY_SIZE 0x3c000000
44
+#define VC_MEMORY_BASE 0x3c000000
45
+#define VC_MEMORY_SIZE 0x04000000
46
+#define VC_FB_BASE 0x3c100000
47
+#define VC_FB_SIZE 0x00096000
48
+
49
+#define CLOCK_ID_ROOT 0x00000000
50
+#define CLOCK_ID_EMMC 0x00000001
51
+#define CLOCK_ID_UART 0x00000002
52
+#define CLOCK_ID_ARM 0x00000003
53
+#define CLOCK_ID_CORE 0x00000004
54
+#define CLOCK_ID_UNDEFINED 0x12345678
55
+
56
+#define CLOCK_RATE_EMMC 50000000
57
+#define CLOCK_RATE_UART 3000000
58
+#define CLOCK_RATE_CORE 350000000
59
+#define CLOCK_RATE_ANY 700000000
60
+
61
+#define DEVICE_ID_SD_CARD 0x00000000
62
+#define DEVICE_ID_UART0 0x00000001
63
+#define DEVICE_ID_UART1 0x00000002
64
+#define DEVICE_ID_USB HCD 0x00000003
65
+#define DEVICE_ID_I2C0 0x00000004
66
+#define DEVICE_ID_I2C1 0x00000005
67
+#define DEVICE_ID_I2C2 0x00000006
68
+#define DEVICE_ID_SPI 0x00000007
69
+#define DEVICE_ID_CCP2TX 0x00000008
70
+#define DEVICE_ID_UNKNOWN_0 0x00000009
71
+#define DEVICE_ID_UNKNOWN_1 0x0000000a
72
+
73
+#define TEMPERATURE_ID_SOC 0x00000000
74
+
75
+#define TEMPERATURE_SOC 25000
76
+#define TEMPERATURE_SOC_MAX 99000
77
+
78
+#define ALIGN_4K 4096
79
+
80
+#define PIXEL_ORDER_BGR 0
81
+#define PIXEL_ORDER_RGB 1
82
+
83
+#define ALPHA_MODE_ENABLED 0
84
+#define ALPHA_MODE_REVERSED 1
85
+#define ALPHA_MODE_IGNORED 2
86
+
87
+#define GPIO_MASK 0x003c
88
+
89
+#define GPIO_0 0x00000080
90
+
91
+#define GPIO_DIRECTION_IN 0
92
+#define GPIO_DIRECTION_OUT 1
93
+
94
+#define GPIO_TERMINATION_DISABLED 0
95
+#define GPIO_TERMINATION_ENABLED 1
96
+
97
+#define GPIO_TERMINATION_PULLUP_DISABLED 0
98
+#define GPIO_TERMINATION_PULLUP_ENABLED 1
99
+
100
+#define GPIO_POLARITY_LOW 0
101
+#define GPIO_POLARITY_HIGH 1
102
+
103
+#define GPIO_STATE_DOWN 0
104
+
105
+/* Used to test stubs that don't perform actual work */
106
+#define DUMMY_VALUE 0x12345678
107
+
108
typedef struct {
109
uint32_t size;
110
uint32_t req_resp_code;
111
diff --git a/tests/qtest/bcm2838-mailbox.c b/tests/qtest/bcm2838-mailbox.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/tests/qtest/bcm2838-mailbox.c
114
+++ b/tests/qtest/bcm2838-mailbox.c
115
@@ -XXX,XX +XXX,XX @@
116
#include "hw/registerfields.h"
117
#include "libqtest-single.h"
118
#include "bcm2838-mailbox.h"
119
+#include "hw/arm/raspberrypi-fw-defs.h"
120
121
REG32(MBOX_EXCHNG_REG, 0)
122
FIELD(MBOX_EXCHNG_REG, CHANNEL, 0, 4)
123
--
23
--
124
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
Move the reset of the sysbus (and thus all devices and buses anywhere
1
Set the default NaN pattern explicitly for ppc.
2
on the qbus tree) from qemu_register_reset() to qemu_register_resettable().
3
4
This is a behaviour change: because qemu_register_resettable() is
5
aware of three-phase reset, this now means that:
6
* 'enter' phase reset methods of devices and buses are called
7
before any legacy reset callbacks registered with qemu_register_reset()
8
* 'exit' phase reset methods of devices and buses are called
9
after any legacy qemu_register_reset() callbacks
10
11
Put another way, a qemu_register_reset() callback is now correctly
12
ordered in the 'hold' phase along with any other 'hold' phase methods.
13
14
The motivation for doing this is that we will now be able to resolve
15
some reset-ordering issues using the three-phase mechanism, because
16
the 'exit' phase is always after the 'hold' phase, even when the
17
'hold' phase function was registered with qemu_register_reset().
18
2
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20241202131347.498124-46-peter.maydell@linaro.org
23
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
24
Message-id: 20240220160622.114437-10-peter.maydell@linaro.org
25
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
26
---
6
---
27
hw/core/machine.c | 7 +++----
7
target/ppc/cpu_init.c | 4 ++++
28
1 file changed, 3 insertions(+), 4 deletions(-)
8
1 file changed, 4 insertions(+)
29
9
30
diff --git a/hw/core/machine.c b/hw/core/machine.c
10
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
31
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/core/machine.c
12
--- a/target/ppc/cpu_init.c
33
+++ b/hw/core/machine.c
13
+++ b/target/ppc/cpu_init.c
34
@@ -XXX,XX +XXX,XX @@ void qdev_machine_creation_done(void)
14
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
35
/* TODO: once all bus devices are qdevified, this should be done
15
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
36
* when bus is created by qdev.c */
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
37
/*
17
38
- * TODO: If we had a main 'reset container' that the whole system
18
+ /* Default NaN: sign bit clear, set frac msb */
39
- * lived in, we could reset that using the multi-phase reset
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
40
- * APIs. For the moment, we just reset the sysbus, which will cause
20
+ set_float_default_nan_pattern(0b01000000, &env->vec_status);
41
+ * This is where we arrange for the sysbus to be reset when the
21
+
42
+ * whole simulation is reset. In turn, resetting the sysbus will cause
22
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
43
* all devices hanging off it (and all their child buses, recursively)
23
ppc_spr_t *spr = &env->spr_cb[i];
44
* to be reset. Note that this will *not* reset any Device objects
45
* which are not attached to some part of the qbus tree!
46
*/
47
- qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
48
+ qemu_register_resettable(OBJECT(sysbus_get_default()));
49
50
notifier_list_notify(&machine_init_done_notifiers, NULL);
51
24
52
--
25
--
53
2.34.1
26
2.34.1
54
55
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly for sh4. Note that sh4
2
is one of the only three targets (the others being HPPA and
3
sometimes MIPS) that has snan_bit_is_one set.
2
4
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240226000259.2752893-10-sergey.kambalin@auriga.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-47-peter.maydell@linaro.org
7
---
8
---
8
include/hw/arm/bcm2838_peripherals.h | 8 ++
9
target/sh4/cpu.c | 2 ++
9
hw/arm/bcm2838_peripherals.c | 143 +++++++++++++++++++++++++++
10
1 file changed, 2 insertions(+)
10
2 files changed, 151 insertions(+)
11
11
12
diff --git a/include/hw/arm/bcm2838_peripherals.h b/include/hw/arm/bcm2838_peripherals.h
12
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/bcm2838_peripherals.h
14
--- a/target/sh4/cpu.c
15
+++ b/include/hw/arm/bcm2838_peripherals.h
15
+++ b/target/sh4/cpu.c
16
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_reset_hold(Object *obj, ResetType type)
17
#define BCM2838_PERIPHERALS_H
17
set_flush_to_zero(1, &env->fp_status);
18
18
#endif
19
#include "hw/arm/bcm2835_peripherals.h"
19
set_default_nan_mode(1, &env->fp_status);
20
+#include "hw/sd/sdhci.h"
20
+ /* sign bit clear, set all frac bits other than msb */
21
+#include "hw/gpio/bcm2838_gpio.h"
21
+ set_float_default_nan_pattern(0b00111111, &env->fp_status);
22
23
/* SPI */
24
#define GIC_SPI_INTERRUPT_MBOX 33
25
@@ -XXX,XX +XXX,XX @@
26
#define GPU_INTERRUPT_DMA14 28
27
#define GPU_INTERRUPT_DMA15 31
28
29
+#define BCM2838_MPHI_OFFSET 0xb200
30
+#define BCM2838_MPHI_SIZE 0x200
31
+
32
#define TYPE_BCM2838_PERIPHERALS "bcm2838-peripherals"
33
OBJECT_DECLARE_TYPE(BCM2838PeripheralState, BCM2838PeripheralClass,
34
BCM2838_PERIPHERALS)
35
@@ -XXX,XX +XXX,XX @@ struct BCM2838PeripheralState {
36
MemoryRegion peri_low_mr_alias;
37
MemoryRegion mphi_mr_alias;
38
39
+ SDHCIState emmc2;
40
+ BCM2838GpioState gpio;
41
+
42
OrIRQState mmc_irq_orgate;
43
OrIRQState dma_7_8_irq_orgate;
44
OrIRQState dma_9_10_irq_orgate;
45
diff --git a/hw/arm/bcm2838_peripherals.c b/hw/arm/bcm2838_peripherals.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/bcm2838_peripherals.c
48
+++ b/hw/arm/bcm2838_peripherals.c
49
@@ -XXX,XX +XXX,XX @@
50
/* Lower peripheral base address on the VC (GPU) system bus */
51
#define BCM2838_VC_PERI_LOW_BASE 0x7c000000
52
53
+/* Capabilities for SD controller: no DMA, high-speed, default clocks etc. */
54
+#define BCM2835_SDHC_CAPAREG 0x52134b4
55
+
56
static void bcm2838_peripherals_init(Object *obj)
57
{
58
BCM2838PeripheralState *s = BCM2838_PERIPHERALS(obj);
59
BCM2838PeripheralClass *bc = BCM2838_PERIPHERALS_GET_CLASS(obj);
60
+ BCMSocPeripheralBaseState *s_base = BCM_SOC_PERIPHERALS_BASE(obj);
61
62
/* Lower memory region for peripheral devices (exported to the Soc) */
63
memory_region_init(&s->peri_low_mr, obj, "bcm2838-peripherals",
64
bc->peri_low_size);
65
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->peri_low_mr);
66
67
+ /* Extended Mass Media Controller 2 */
68
+ object_initialize_child(obj, "emmc2", &s->emmc2, TYPE_SYSBUS_SDHCI);
69
+
70
+ /* GPIO */
71
+ object_initialize_child(obj, "gpio", &s->gpio, TYPE_BCM2838_GPIO);
72
+
73
+ object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhci",
74
+ OBJECT(&s_base->sdhci.sdbus));
75
+ object_property_add_const_link(OBJECT(&s->gpio), "sdbus-sdhost",
76
+ OBJECT(&s_base->sdhost.sdbus));
77
+
78
+ object_initialize_child(obj, "mmc_irq_orgate", &s->mmc_irq_orgate,
79
+ TYPE_OR_IRQ);
80
+ object_property_set_int(OBJECT(&s->mmc_irq_orgate), "num-lines", 2,
81
+ &error_abort);
82
+
83
+ object_initialize_child(obj, "dma_7_8_irq_orgate", &s->dma_7_8_irq_orgate,
84
+ TYPE_OR_IRQ);
85
+ object_property_set_int(OBJECT(&s->dma_7_8_irq_orgate), "num-lines", 2,
86
+ &error_abort);
87
+
88
+ object_initialize_child(obj, "dma_9_10_irq_orgate", &s->dma_9_10_irq_orgate,
89
+ TYPE_OR_IRQ);
90
+ object_property_set_int(OBJECT(&s->dma_9_10_irq_orgate), "num-lines", 2,
91
+ &error_abort);
92
}
22
}
93
23
94
static void bcm2838_peripherals_realize(DeviceState *dev, Error **errp)
24
static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
95
{
96
+ DeviceState *mmc_irq_orgate;
97
+ DeviceState *dma_7_8_irq_orgate;
98
+ DeviceState *dma_9_10_irq_orgate;
99
+ MemoryRegion *mphi_mr;
100
BCM2838PeripheralState *s = BCM2838_PERIPHERALS(dev);
101
BCMSocPeripheralBaseState *s_base = BCM_SOC_PERIPHERALS_BASE(dev);
102
+ int n;
103
104
bcm_soc_peripherals_common_realize(dev, errp);
105
106
@@ -XXX,XX +XXX,XX @@ static void bcm2838_peripherals_realize(DeviceState *dev, Error **errp)
107
BCM2838_VC_PERI_LOW_BASE,
108
&s->peri_low_mr_alias, 1);
109
110
+ /* Extended Mass Media Controller 2 */
111
+ object_property_set_uint(OBJECT(&s->emmc2), "sd-spec-version", 3,
112
+ &error_abort);
113
+ object_property_set_uint(OBJECT(&s->emmc2), "capareg",
114
+ BCM2835_SDHC_CAPAREG, &error_abort);
115
+ object_property_set_bool(OBJECT(&s->emmc2), "pending-insert-quirk", true,
116
+ &error_abort);
117
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->emmc2), errp)) {
118
+ return;
119
+ }
120
+
121
+ memory_region_add_subregion(&s_base->peri_mr, EMMC2_OFFSET,
122
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->emmc2),
123
+ 0));
124
+
125
+ /* According to DTS, EMMC and EMMC2 share one irq */
126
+ if (!qdev_realize(DEVICE(&s->mmc_irq_orgate), NULL, errp)) {
127
+ return;
128
+ }
129
+
130
+ mmc_irq_orgate = DEVICE(&s->mmc_irq_orgate);
131
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->emmc2), 0,
132
+ qdev_get_gpio_in(mmc_irq_orgate, 0));
133
+
134
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s_base->sdhci), 0,
135
+ qdev_get_gpio_in(mmc_irq_orgate, 1));
136
+
137
+ /* Connect EMMC and EMMC2 to the interrupt controller */
138
+ qdev_connect_gpio_out(mmc_irq_orgate, 0,
139
+ qdev_get_gpio_in_named(DEVICE(&s_base->ic),
140
+ BCM2835_IC_GPU_IRQ,
141
+ INTERRUPT_ARASANSDIO));
142
+
143
+ /* Connect DMA 0-6 to the interrupt controller */
144
+ for (n = 0; n < 7; n++) {
145
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s_base->dma), n,
146
+ qdev_get_gpio_in_named(DEVICE(&s_base->ic),
147
+ BCM2835_IC_GPU_IRQ,
148
+ GPU_INTERRUPT_DMA0 + n));
149
+ }
150
+
151
+ /* According to DTS, DMA 7 and 8 share one irq */
152
+ if (!qdev_realize(DEVICE(&s->dma_7_8_irq_orgate), NULL, errp)) {
153
+ return;
154
+ }
155
+ dma_7_8_irq_orgate = DEVICE(&s->dma_7_8_irq_orgate);
156
+
157
+ /* Connect DMA 7-8 to the interrupt controller */
158
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s_base->dma), 7,
159
+ qdev_get_gpio_in(dma_7_8_irq_orgate, 0));
160
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s_base->dma), 8,
161
+ qdev_get_gpio_in(dma_7_8_irq_orgate, 1));
162
+
163
+ qdev_connect_gpio_out(dma_7_8_irq_orgate, 0,
164
+ qdev_get_gpio_in_named(DEVICE(&s_base->ic),
165
+ BCM2835_IC_GPU_IRQ,
166
+ GPU_INTERRUPT_DMA7_8));
167
+
168
+ /* According to DTS, DMA 9 and 10 share one irq */
169
+ if (!qdev_realize(DEVICE(&s->dma_9_10_irq_orgate), NULL, errp)) {
170
+ return;
171
+ }
172
+ dma_9_10_irq_orgate = DEVICE(&s->dma_9_10_irq_orgate);
173
+
174
+ /* Connect DMA 9-10 to the interrupt controller */
175
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s_base->dma), 9,
176
+ qdev_get_gpio_in(dma_9_10_irq_orgate, 0));
177
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s_base->dma), 10,
178
+ qdev_get_gpio_in(dma_9_10_irq_orgate, 1));
179
+
180
+ qdev_connect_gpio_out(dma_9_10_irq_orgate, 0,
181
+ qdev_get_gpio_in_named(DEVICE(&s_base->ic),
182
+ BCM2835_IC_GPU_IRQ,
183
+ GPU_INTERRUPT_DMA9_10));
184
+
185
+ /* Connect DMA 11-14 to the interrupt controller */
186
+ for (n = 11; n < 15; n++) {
187
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s_base->dma), n,
188
+ qdev_get_gpio_in_named(DEVICE(&s_base->ic),
189
+ BCM2835_IC_GPU_IRQ,
190
+ GPU_INTERRUPT_DMA11 + n
191
+ - 11));
192
+ }
193
+
194
+ /*
195
+ * Connect DMA 15 to the interrupt controller, it is physically removed
196
+ * from other DMA channels and exclusively used by the GPU
197
+ */
198
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s_base->dma), 15,
199
+ qdev_get_gpio_in_named(DEVICE(&s_base->ic),
200
+ BCM2835_IC_GPU_IRQ,
201
+ GPU_INTERRUPT_DMA15));
202
+
203
+ /* Map MPHI to BCM2838 memory map */
204
+ mphi_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s_base->mphi), 0);
205
+ memory_region_init_alias(&s->mphi_mr_alias, OBJECT(s), "mphi", mphi_mr, 0,
206
+ BCM2838_MPHI_SIZE);
207
+ memory_region_add_subregion(&s_base->peri_mr, BCM2838_MPHI_OFFSET,
208
+ &s->mphi_mr_alias);
209
+
210
+ /* GPIO */
211
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
212
+ return;
213
+ }
214
+ memory_region_add_subregion(
215
+ &s_base->peri_mr, GPIO_OFFSET,
216
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gpio), 0));
217
+
218
+ object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->gpio), "sd-bus");
219
}
220
221
static void bcm2838_peripherals_class_init(ObjectClass *oc, void *data)
222
--
25
--
223
2.34.1
26
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly for rx.
2
2
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240226000259.2752893-9-sergey.kambalin@auriga.com
6
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-48-peter.maydell@linaro.org
7
---
6
---
8
include/hw/gpio/bcm2838_gpio.h | 5 ++++
7
target/rx/cpu.c | 2 ++
9
hw/gpio/bcm2838_gpio.c | 52 +++++++++++++++++++++++++++++++++-
8
1 file changed, 2 insertions(+)
10
2 files changed, 56 insertions(+), 1 deletion(-)
11
9
12
diff --git a/include/hw/gpio/bcm2838_gpio.h b/include/hw/gpio/bcm2838_gpio.h
10
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/gpio/bcm2838_gpio.h
12
--- a/target/rx/cpu.c
15
+++ b/include/hw/gpio/bcm2838_gpio.h
13
+++ b/target/rx/cpu.c
16
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_reset_hold(Object *obj, ResetType type)
17
#ifndef BCM2838_GPIO_H
15
* then prefer dest over source", which is float_2nan_prop_s_ab.
18
#define BCM2838_GPIO_H
16
*/
19
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
20
+#include "hw/sd/sd.h"
18
+ /* Default NaN value: sign bit clear, set frac msb */
21
#include "hw/sysbus.h"
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
22
#include "qom/object.h"
23
24
@@ -XXX,XX +XXX,XX @@ struct BCM2838GpioState {
25
26
MemoryRegion iomem;
27
28
+ /* SDBus selector */
29
+ SDBus sdbus;
30
+ SDBus *sdbus_sdhci;
31
+ SDBus *sdbus_sdhost;
32
33
uint8_t fsel[BCM2838_GPIO_NUM];
34
uint32_t lev0, lev1;
35
diff --git a/hw/gpio/bcm2838_gpio.c b/hw/gpio/bcm2838_gpio.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/gpio/bcm2838_gpio.c
38
+++ b/hw/gpio/bcm2838_gpio.c
39
@@ -XXX,XX +XXX,XX @@
40
#include "qapi/error.h"
41
#include "hw/sysbus.h"
42
#include "migration/vmstate.h"
43
+#include "hw/sd/sd.h"
44
#include "hw/gpio/bcm2838_gpio.h"
45
#include "hw/irq.h"
46
47
@@ -XXX,XX +XXX,XX @@
48
49
#define BYTES_IN_WORD 4
50
51
+/* bcm,function property */
52
+#define BCM2838_FSEL_GPIO_IN 0
53
+#define BCM2838_FSEL_GPIO_OUT 1
54
+#define BCM2838_FSEL_ALT5 2
55
+#define BCM2838_FSEL_ALT4 3
56
+#define BCM2838_FSEL_ALT0 4
57
+#define BCM2838_FSEL_ALT1 5
58
+#define BCM2838_FSEL_ALT2 6
59
+#define BCM2838_FSEL_ALT3 7
60
+
61
static uint32_t gpfsel_get(BCM2838GpioState *s, uint8_t reg)
62
{
63
int i;
64
@@ -XXX,XX +XXX,XX @@ static void gpfsel_set(BCM2838GpioState *s, uint8_t reg, uint32_t value)
65
s->fsel[index] = fsel;
66
}
67
}
68
+
69
+ /* SD controller selection (48-53) */
70
+ if (s->sd_fsel != BCM2838_FSEL_GPIO_IN
71
+ && (s->fsel[48] == BCM2838_FSEL_GPIO_IN)
72
+ && (s->fsel[49] == BCM2838_FSEL_GPIO_IN)
73
+ && (s->fsel[50] == BCM2838_FSEL_GPIO_IN)
74
+ && (s->fsel[51] == BCM2838_FSEL_GPIO_IN)
75
+ && (s->fsel[52] == BCM2838_FSEL_GPIO_IN)
76
+ && (s->fsel[53] == BCM2838_FSEL_GPIO_IN)
77
+ ) {
78
+ /* SDHCI controller selected */
79
+ sdbus_reparent_card(s->sdbus_sdhost, s->sdbus_sdhci);
80
+ s->sd_fsel = BCM2838_FSEL_GPIO_IN;
81
+ } else if (s->sd_fsel != BCM2838_FSEL_ALT0
82
+ && (s->fsel[48] == BCM2838_FSEL_ALT0) /* SD_CLK_R */
83
+ && (s->fsel[49] == BCM2838_FSEL_ALT0) /* SD_CMD_R */
84
+ && (s->fsel[50] == BCM2838_FSEL_ALT0) /* SD_DATA0_R */
85
+ && (s->fsel[51] == BCM2838_FSEL_ALT0) /* SD_DATA1_R */
86
+ && (s->fsel[52] == BCM2838_FSEL_ALT0) /* SD_DATA2_R */
87
+ && (s->fsel[53] == BCM2838_FSEL_ALT0) /* SD_DATA3_R */
88
+ ) {
89
+ /* SDHost controller selected */
90
+ sdbus_reparent_card(s->sdbus_sdhci, s->sdbus_sdhost);
91
+ s->sd_fsel = BCM2838_FSEL_ALT0;
92
+ }
93
}
20
}
94
21
95
static int gpfsel_is_out(BCM2838GpioState *s, int index)
22
static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
96
@@ -XXX,XX +XXX,XX @@ static void bcm2838_gpio_reset(DeviceState *dev)
97
98
memset(s->fsel, 0, sizeof(s->fsel));
99
100
+ s->sd_fsel = 0;
101
+
102
+ /* SDHCI is selected by default */
103
+ sdbus_reparent_card(&s->sdbus, s->sdbus_sdhci);
104
+
105
s->lev0 = 0;
106
s->lev1 = 0;
107
108
@@ -XXX,XX +XXX,XX @@ static void bcm2838_gpio_init(Object *obj)
109
DeviceState *dev = DEVICE(obj);
110
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
111
112
+ qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS, DEVICE(s), "sd-bus");
113
+
114
memory_region_init_io(&s->iomem, obj, &bcm2838_gpio_ops, s,
115
"bcm2838_gpio", BCM2838_GPIO_REGS_SIZE);
116
sysbus_init_mmio(sbd, &s->iomem);
117
@@ -XXX,XX +XXX,XX @@ static void bcm2838_gpio_init(Object *obj)
118
119
static void bcm2838_gpio_realize(DeviceState *dev, Error **errp)
120
{
121
- /* Temporary stub. Do nothing */
122
+ BCM2838GpioState *s = BCM2838_GPIO(dev);
123
+ Object *obj;
124
+
125
+ obj = object_property_get_link(OBJECT(dev), "sdbus-sdhci", &error_abort);
126
+ s->sdbus_sdhci = SD_BUS(obj);
127
+
128
+ obj = object_property_get_link(OBJECT(dev), "sdbus-sdhost", &error_abort);
129
+ s->sdbus_sdhost = SD_BUS(obj);
130
}
131
132
static void bcm2838_gpio_class_init(ObjectClass *klass, void *data)
133
--
23
--
134
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly for s390x.
2
2
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240226000259.2752893-5-sergey.kambalin@auriga.com
6
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-49-peter.maydell@linaro.org
7
---
6
---
8
include/hw/arm/bcm2838.h | 29 ++++++++
7
target/s390x/cpu.c | 2 ++
9
include/hw/arm/bcm2838_peripherals.h | 36 ++++++++++
8
1 file changed, 2 insertions(+)
10
hw/arm/bcm2838.c | 98 ++++++++++++++++++++++++++++
11
hw/arm/bcm2838_peripherals.c | 72 ++++++++++++++++++++
12
hw/arm/meson.build | 2 +
13
5 files changed, 237 insertions(+)
14
create mode 100644 include/hw/arm/bcm2838.h
15
create mode 100644 include/hw/arm/bcm2838_peripherals.h
16
create mode 100644 hw/arm/bcm2838.c
17
create mode 100644 hw/arm/bcm2838_peripherals.c
18
9
19
diff --git a/include/hw/arm/bcm2838.h b/include/hw/arm/bcm2838.h
10
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
20
new file mode 100644
21
index XXXXXXX..XXXXXXX
22
--- /dev/null
23
+++ b/include/hw/arm/bcm2838.h
24
@@ -XXX,XX +XXX,XX @@
25
+/*
26
+ * BCM2838 SoC emulation
27
+ *
28
+ * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com>
29
+ *
30
+ * SPDX-License-Identifier: GPL-2.0-or-later
31
+ */
32
+
33
+#ifndef BCM2838_H
34
+#define BCM2838_H
35
+
36
+#include "hw/arm/bcm2836.h"
37
+#include "hw/arm/bcm2838_peripherals.h"
38
+
39
+#define BCM2838_PERI_LOW_BASE 0xfc000000
40
+#define BCM2838_GIC_BASE 0x40000
41
+
42
+#define TYPE_BCM2838 "bcm2838"
43
+
44
+OBJECT_DECLARE_TYPE(BCM2838State, BCM2838Class, BCM2838)
45
+
46
+struct BCM2838State {
47
+ /*< private >*/
48
+ BCM283XBaseState parent_obj;
49
+ /*< public >*/
50
+ BCM2838PeripheralState peripherals;
51
+};
52
+
53
+#endif /* BCM2838_H */
54
diff --git a/include/hw/arm/bcm2838_peripherals.h b/include/hw/arm/bcm2838_peripherals.h
55
new file mode 100644
56
index XXXXXXX..XXXXXXX
57
--- /dev/null
58
+++ b/include/hw/arm/bcm2838_peripherals.h
59
@@ -XXX,XX +XXX,XX @@
60
+/*
61
+ * BCM2838 peripherals emulation
62
+ *
63
+ * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com>
64
+ *
65
+ * SPDX-License-Identifier: GPL-2.0-or-later
66
+ */
67
+
68
+#ifndef BCM2838_PERIPHERALS_H
69
+#define BCM2838_PERIPHERALS_H
70
+
71
+#include "hw/arm/bcm2835_peripherals.h"
72
+
73
+
74
+#define TYPE_BCM2838_PERIPHERALS "bcm2838-peripherals"
75
+OBJECT_DECLARE_TYPE(BCM2838PeripheralState, BCM2838PeripheralClass,
76
+ BCM2838_PERIPHERALS)
77
+
78
+struct BCM2838PeripheralState {
79
+ /*< private >*/
80
+ BCMSocPeripheralBaseState parent_obj;
81
+
82
+ /*< public >*/
83
+ MemoryRegion peri_low_mr;
84
+ MemoryRegion peri_low_mr_alias;
85
+ MemoryRegion mphi_mr_alias;
86
+};
87
+
88
+struct BCM2838PeripheralClass {
89
+ /*< private >*/
90
+ BCMSocPeripheralBaseClass parent_class;
91
+ /*< public >*/
92
+ uint64_t peri_low_size; /* Peripheral lower range size */
93
+};
94
+
95
+#endif /* BCM2838_PERIPHERALS_H */
96
diff --git a/hw/arm/bcm2838.c b/hw/arm/bcm2838.c
97
new file mode 100644
98
index XXXXXXX..XXXXXXX
99
--- /dev/null
100
+++ b/hw/arm/bcm2838.c
101
@@ -XXX,XX +XXX,XX @@
102
+/*
103
+ * BCM2838 SoC emulation
104
+ *
105
+ * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com>
106
+ *
107
+ * SPDX-License-Identifier: GPL-2.0-or-later
108
+ */
109
+
110
+#include "qemu/osdep.h"
111
+#include "qapi/error.h"
112
+#include "qemu/module.h"
113
+#include "hw/arm/raspi_platform.h"
114
+#include "hw/sysbus.h"
115
+#include "hw/arm/bcm2838.h"
116
+#include "trace.h"
117
+
118
+#define VIRTUAL_PMU_IRQ 7
119
+
120
+static void bcm2838_init(Object *obj)
121
+{
122
+ BCM2838State *s = BCM2838(obj);
123
+
124
+ object_initialize_child(obj, "peripherals", &s->peripherals,
125
+ TYPE_BCM2838_PERIPHERALS);
126
+ object_property_add_alias(obj, "board-rev", OBJECT(&s->peripherals),
127
+ "board-rev");
128
+ object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
129
+ "vcram-size");
130
+ object_property_add_alias(obj, "command-line", OBJECT(&s->peripherals),
131
+ "command-line");
132
+}
133
+
134
+static void bcm2838_realize(DeviceState *dev, Error **errp)
135
+{
136
+ int n;
137
+ BCM2838State *s = BCM2838(dev);
138
+ BCM283XBaseState *s_base = BCM283X_BASE(dev);
139
+ BCM283XBaseClass *bc_base = BCM283X_BASE_GET_CLASS(dev);
140
+ BCM2838PeripheralState *ps = BCM2838_PERIPHERALS(&s->peripherals);
141
+ BCMSocPeripheralBaseState *ps_base =
142
+ BCM_SOC_PERIPHERALS_BASE(&s->peripherals);
143
+
144
+ if (!bcm283x_common_realize(dev, ps_base, errp)) {
145
+ return;
146
+ }
147
+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(ps), 1, BCM2838_PERI_LOW_BASE, 1);
148
+
149
+ /* bcm2836 interrupt controller (and mailboxes, etc.) */
150
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s_base->control), errp)) {
151
+ return;
152
+ }
153
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s_base->control), 0, bc_base->ctrl_base);
154
+
155
+ /* Create cores */
156
+ for (n = 0; n < bc_base->core_count; n++) {
157
+
158
+ object_property_set_int(OBJECT(&s_base->cpu[n].core), "mp-affinity",
159
+ (bc_base->clusterid << 8) | n, &error_abort);
160
+
161
+ /* start powered off if not enabled */
162
+ object_property_set_bool(OBJECT(&s_base->cpu[n].core),
163
+ "start-powered-off",
164
+ n >= s_base->enabled_cpus, &error_abort);
165
+
166
+ if (!qdev_realize(DEVICE(&s_base->cpu[n].core), NULL, errp)) {
167
+ return;
168
+ }
169
+ }
170
+}
171
+
172
+static void bcm2838_class_init(ObjectClass *oc, void *data)
173
+{
174
+ DeviceClass *dc = DEVICE_CLASS(oc);
175
+ BCM283XBaseClass *bc_base = BCM283X_BASE_CLASS(oc);
176
+
177
+ bc_base->cpu_type = ARM_CPU_TYPE_NAME("cortex-a72");
178
+ bc_base->core_count = BCM283X_NCPUS;
179
+ bc_base->peri_base = 0xfe000000;
180
+ bc_base->ctrl_base = 0xff800000;
181
+ bc_base->clusterid = 0x0;
182
+ dc->realize = bcm2838_realize;
183
+}
184
+
185
+static const TypeInfo bcm2838_type = {
186
+ .name = TYPE_BCM2838,
187
+ .parent = TYPE_BCM283X_BASE,
188
+ .instance_size = sizeof(BCM2838State),
189
+ .instance_init = bcm2838_init,
190
+ .class_size = sizeof(BCM283XBaseClass),
191
+ .class_init = bcm2838_class_init,
192
+};
193
+
194
+static void bcm2838_register_types(void)
195
+{
196
+ type_register_static(&bcm2838_type);
197
+}
198
+
199
+type_init(bcm2838_register_types);
200
diff --git a/hw/arm/bcm2838_peripherals.c b/hw/arm/bcm2838_peripherals.c
201
new file mode 100644
202
index XXXXXXX..XXXXXXX
203
--- /dev/null
204
+++ b/hw/arm/bcm2838_peripherals.c
205
@@ -XXX,XX +XXX,XX @@
206
+/*
207
+ * BCM2838 peripherals emulation
208
+ *
209
+ * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com>
210
+ *
211
+ * SPDX-License-Identifier: GPL-2.0-or-later
212
+ */
213
+
214
+#include "qemu/osdep.h"
215
+#include "qapi/error.h"
216
+#include "qemu/module.h"
217
+#include "hw/arm/raspi_platform.h"
218
+#include "hw/arm/bcm2838_peripherals.h"
219
+
220
+/* Lower peripheral base address on the VC (GPU) system bus */
221
+#define BCM2838_VC_PERI_LOW_BASE 0x7c000000
222
+
223
+static void bcm2838_peripherals_init(Object *obj)
224
+{
225
+ BCM2838PeripheralState *s = BCM2838_PERIPHERALS(obj);
226
+ BCM2838PeripheralClass *bc = BCM2838_PERIPHERALS_GET_CLASS(obj);
227
+
228
+ /* Lower memory region for peripheral devices (exported to the Soc) */
229
+ memory_region_init(&s->peri_low_mr, obj, "bcm2838-peripherals",
230
+ bc->peri_low_size);
231
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->peri_low_mr);
232
+
233
+}
234
+
235
+static void bcm2838_peripherals_realize(DeviceState *dev, Error **errp)
236
+{
237
+ BCM2838PeripheralState *s = BCM2838_PERIPHERALS(dev);
238
+ BCMSocPeripheralBaseState *s_base = BCM_SOC_PERIPHERALS_BASE(dev);
239
+
240
+ bcm_soc_peripherals_common_realize(dev, errp);
241
+
242
+ /* Map lower peripherals into the GPU address space */
243
+ memory_region_init_alias(&s->peri_low_mr_alias, OBJECT(s),
244
+ "bcm2838-peripherals", &s->peri_low_mr, 0,
245
+ memory_region_size(&s->peri_low_mr));
246
+ memory_region_add_subregion_overlap(&s_base->gpu_bus_mr,
247
+ BCM2838_VC_PERI_LOW_BASE,
248
+ &s->peri_low_mr_alias, 1);
249
+
250
+}
251
+
252
+static void bcm2838_peripherals_class_init(ObjectClass *oc, void *data)
253
+{
254
+ DeviceClass *dc = DEVICE_CLASS(oc);
255
+ BCM2838PeripheralClass *bc = BCM2838_PERIPHERALS_CLASS(oc);
256
+ BCMSocPeripheralBaseClass *bc_base = BCM_SOC_PERIPHERALS_BASE_CLASS(oc);
257
+
258
+ bc->peri_low_size = 0x2000000;
259
+ bc_base->peri_size = 0x1800000;
260
+ dc->realize = bcm2838_peripherals_realize;
261
+}
262
+
263
+static const TypeInfo bcm2838_peripherals_type_info = {
264
+ .name = TYPE_BCM2838_PERIPHERALS,
265
+ .parent = TYPE_BCM_SOC_PERIPHERALS_BASE,
266
+ .instance_size = sizeof(BCM2838PeripheralState),
267
+ .instance_init = bcm2838_peripherals_init,
268
+ .class_size = sizeof(BCM2838PeripheralClass),
269
+ .class_init = bcm2838_peripherals_class_init,
270
+};
271
+
272
+static void bcm2838_peripherals_register_types(void)
273
+{
274
+ type_register_static(&bcm2838_peripherals_type_info);
275
+}
276
+
277
+type_init(bcm2838_peripherals_register_types)
278
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
279
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
280
--- a/hw/arm/meson.build
12
--- a/target/s390x/cpu.c
281
+++ b/hw/arm/meson.build
13
+++ b/target/s390x/cpu.c
282
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubi
14
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
283
arm_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 'orangepi.c'))
15
set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
284
arm_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40.c', 'bananapi_m2u.c'))
16
set_float_infzeronan_rule(float_infzeronan_dnan_always,
285
arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c'))
17
&env->fpu_status);
286
+arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files('bcm2838.c'))
18
+ /* Default NaN value: sign bit clear, frac msb set */
287
arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
19
+ set_float_default_nan_pattern(0b01000000, &env->fpu_status);
288
arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
20
/* fall through */
289
arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
21
case RESET_TYPE_S390_CPU_NORMAL:
290
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_GUMSTIX', if_true: files('gumstix.c'))
22
env->psw.mask &= ~PSW_MASK_RI;
291
system_ss.add(when: 'CONFIG_NETDUINO2', if_true: files('netduino2.c'))
292
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap2.c'))
293
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_peripherals.c'))
294
+system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2838_peripherals.c'))
295
system_ss.add(when: 'CONFIG_SPITZ', if_true: files('spitz.c'))
296
system_ss.add(when: 'CONFIG_STRONGARM', if_true: files('strongarm.c'))
297
system_ss.add(when: 'CONFIG_SX1', if_true: files('omap_sx1.c'))
298
--
23
--
299
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
Now that system reset uses a three-phase-reset, update the reset
1
Set the default NaN pattern explicitly for SPARC, and remove
2
documentation to include a section describing how this works.
2
the ifdef from parts64_default_nan.
3
Include documentation of the current major beartrap in reset, which
4
is that only devices on the qbus tree will get automatically reset.
5
3
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20241202131347.498124-50-peter.maydell@linaro.org
10
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
11
Message-id: 20240220160622.114437-11-peter.maydell@linaro.org
12
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
13
---
7
---
14
docs/devel/reset.rst | 44 ++++++++++++++++++++++++++++++++++++++++++--
8
target/sparc/cpu.c | 2 ++
15
1 file changed, 42 insertions(+), 2 deletions(-)
9
fpu/softfloat-specialize.c.inc | 5 +----
10
2 files changed, 3 insertions(+), 4 deletions(-)
16
11
17
diff --git a/docs/devel/reset.rst b/docs/devel/reset.rst
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/devel/reset.rst
14
--- a/target/sparc/cpu.c
20
+++ b/docs/devel/reset.rst
15
+++ b/target/sparc/cpu.c
21
@@ -XXX,XX +XXX,XX @@ whole group can be reset consistently. Each individual member object does not
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
22
have to care about others; in particular, problems of order (which object is
17
set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
23
reset first) are addressed.
18
/* For inf * 0 + NaN, return the input NaN */
24
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
25
-As of now DeviceClass and BusClass implement this interface.
20
+ /* Default NaN value: sign bit clear, all frac bits set */
26
-
21
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
27
+The main object types which implement this interface are DeviceClass
22
28
+and BusClass.
23
cpu_exec_realizefn(cs, &local_err);
29
24
if (local_err != NULL) {
30
Triggering reset
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
31
----------------
26
index XXXXXXX..XXXXXXX 100644
32
@@ -XXX,XX +XXX,XX @@ There is currently 2 cases where this function is used:
27
--- a/fpu/softfloat-specialize.c.inc
33
2. *hot bus change*; it means an existing live device is added, moved or
28
+++ b/fpu/softfloat-specialize.c.inc
34
removed in the bus hierarchy. At the moment, it occurs only in the raspi
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
35
machines for changing the sdbus used by sd card.
30
uint8_t dnan_pattern = status->default_nan_pattern;
36
+
31
37
+Reset of the complete system
32
if (dnan_pattern == 0) {
38
+----------------------------
33
-#if defined(TARGET_SPARC)
39
+
34
- /* Sign bit clear, all frac bits set */
40
+Reset of the complete system is a little complicated. The typical
35
- dnan_pattern = 0b01111111;
41
+flow is:
36
-#elif defined(TARGET_HEXAGON)
42
+
37
+#if defined(TARGET_HEXAGON)
43
+1. Code which wishes to reset the entire system does so by calling
38
/* Sign bit set, all frac bits set. */
44
+ ``qemu_system_reset_request()``. This schedules a reset, but the
39
dnan_pattern = 0b11111111;
45
+ reset will happen asynchronously after the function returns.
40
#else
46
+ That makes this safe to call from, for example, device models.
47
+
48
+2. The function which is called to make the reset happen is
49
+ ``qemu_system_reset()``. Generally only core system code should
50
+ call this directly.
51
+
52
+3. ``qemu_system_reset()`` calls the ``MachineClass::reset`` method of
53
+ the current machine, if it has one. That method must call
54
+ ``qemu_devices_reset()``. If the machine has no reset method,
55
+ ``qemu_system_reset()`` calls ``qemu_devices_reset()`` directly.
56
+
57
+4. ``qemu_devices_reset()`` performs a reset of the system, using
58
+ the three-phase mechanism listed above. It resets all objects
59
+ that were registered with it using ``qemu_register_resettable()``.
60
+ It also calls all the functions registered with it using
61
+ ``qemu_register_reset()``. Those functions are called during the
62
+ "hold" phase of this reset.
63
+
64
+5. The most important object that this reset resets is the
65
+ 'sysbus' bus. The sysbus bus is the root of the qbus tree. This
66
+ means that all devices on the sysbus are reset, and all their
67
+ child buses, and all the devices on those child buses.
68
+
69
+6. Devices which are not on the qbus tree are *not* automatically
70
+ reset! (The most obvious example of this is CPU objects, but
71
+ anything that directly inherits from ``TYPE_OBJECT`` or ``TYPE_DEVICE``
72
+ rather than from ``TYPE_SYS_BUS_DEVICE`` or some other plugs-into-a-bus
73
+ type will be in this category.) You need to therefore arrange for these
74
+ to be reset in some other way (e.g. using ``qemu_register_resettable()``
75
+ or ``qemu_register_reset()``).
76
--
41
--
77
2.34.1
42
2.34.1
78
79
diff view generated by jsdifflib
1
From: Abhiram Tilak <atp.exp@gmail.com>
1
Set the default NaN pattern explicitly for xtensa.
2
2
3
A few watchdog devices use qemu_system_reset_request(). This is not ideal since
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
behaviour of watchdog-expiry can't be changed by QMP using `watchdog_action`.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
As stated in BiteSizedTasks wiki page, instead of using qemu_system_reset_request()
5
Message-id: 20241202131347.498124-51-peter.maydell@linaro.org
6
to reset when a watchdog timer expires, let watchdog_perform_action() decide
6
---
7
what to do.
7
target/xtensa/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
8
9
9
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2124
10
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
10
Signed-off-by: Abhiram Tilak <atp.exp@gmail.com>
11
Message-id: 20240216192612.30838-5-atp.exp@gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/timer/pxa2xx_timer.c | 3 ++-
16
1 file changed, 2 insertions(+), 1 deletion(-)
17
18
diff --git a/hw/timer/pxa2xx_timer.c b/hw/timer/pxa2xx_timer.c
19
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/timer/pxa2xx_timer.c
12
--- a/target/xtensa/cpu.c
21
+++ b/hw/timer/pxa2xx_timer.c
13
+++ b/target/xtensa/cpu.c
22
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
23
#include "qemu/log.h"
15
/* For inf * 0 + NaN, return the input NaN */
24
#include "qemu/module.h"
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
25
#include "qom/object.h"
17
set_no_signaling_nans(!dfpu, &env->fp_status);
26
+#include "sysemu/watchdog.h"
18
+ /* Default NaN value: sign bit clear, set frac msb */
27
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
28
#define OSMR0    0x00
20
xtensa_use_first_nan(env, !dfpu);
29
#define OSMR1    0x04
30
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_timer_tick(void *opaque)
31
if (t->num == 3)
32
if (i->reset3 & 1) {
33
i->reset3 = 0;
34
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
35
+ watchdog_perform_action();
36
}
37
}
21
}
38
22
39
--
23
--
40
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
1
Set the default NaN pattern explicitly for hexagon.
2
Remove the ifdef from parts64_default_nan(); the only
3
remaining unconverted targets all use the default case.
2
4
3
The OSPI DMA reads flash data through the OSPI linear address space (the
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
iomem_dac region), because of this the reentrancy guard introduced in
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
commit a2e1753b ("memory: prevent dma-reentracy issues") is disabled for
7
Message-id: 20241202131347.498124-52-peter.maydell@linaro.org
6
the memory region.
8
---
9
target/hexagon/cpu.c | 2 ++
10
fpu/softfloat-specialize.c.inc | 5 -----
11
2 files changed, 2 insertions(+), 5 deletions(-)
7
12
8
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
13
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
9
Message-id: 20240219105637.65052-1-sai.pavan.boddu@amd.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/ssi/xlnx-versal-ospi.c | 6 ++++++
14
1 file changed, 6 insertions(+)
15
16
diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/xlnx-versal-ospi.c
15
--- a/target/hexagon/cpu.c
19
+++ b/hw/ssi/xlnx-versal-ospi.c
16
+++ b/target/hexagon/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void xlnx_versal_ospi_init(Object *obj)
17
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
21
memory_region_init_io(&s->iomem_dac, obj, &ospi_dac_ops, s,
18
22
TYPE_XILINX_VERSAL_OSPI "-dac", 0x20000000);
19
set_default_nan_mode(1, &env->fp_status);
23
sysbus_init_mmio(sbd, &s->iomem_dac);
20
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
24
+ /*
21
+ /* Default NaN value: sign bit set, all frac bits set */
25
+ * The OSPI DMA reads flash data through the OSPI linear address space (the
22
+ set_float_default_nan_pattern(0b11111111, &env->fp_status);
26
+ * iomem_dac region), because of this the reentrancy guard needs to be
23
}
27
+ * disabled.
24
28
+ */
25
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
29
+ s->iomem_dac.disable_reentrancy_guard = true;
26
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
27
index XXXXXXX..XXXXXXX 100644
31
sysbus_init_irq(sbd, &s->irq);
28
--- a/fpu/softfloat-specialize.c.inc
29
+++ b/fpu/softfloat-specialize.c.inc
30
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
31
uint8_t dnan_pattern = status->default_nan_pattern;
32
33
if (dnan_pattern == 0) {
34
-#if defined(TARGET_HEXAGON)
35
- /* Sign bit set, all frac bits set. */
36
- dnan_pattern = 0b11111111;
37
-#else
38
/*
39
* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
40
* S390, SH4, TriCore, and Xtensa. Our other supported targets
41
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
42
/* sign bit clear, set frac msb */
43
dnan_pattern = 0b01000000;
44
}
45
-#endif
46
}
47
assert(dnan_pattern != 0);
32
48
33
--
49
--
34
2.34.1
50
2.34.1
diff view generated by jsdifflib
1
Add the usual boilerplate license/copyright comment to reset.h (using
1
Set the default NaN pattern explicitly for riscv.
2
the text from reset.c), and document the existing functions.
3
2
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20241202131347.498124-53-peter.maydell@linaro.org
8
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
9
Message-id: 20240220160622.114437-6-peter.maydell@linaro.org
10
---
6
---
11
include/sysemu/reset.h | 79 ++++++++++++++++++++++++++++++++++++++++++
7
target/riscv/cpu.c | 2 ++
12
1 file changed, 79 insertions(+)
8
1 file changed, 2 insertions(+)
13
9
14
diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h
10
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/include/sysemu/reset.h
12
--- a/target/riscv/cpu.c
17
+++ b/include/sysemu/reset.h
13
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
19
+/*
15
cs->exception_index = RISCV_EXCP_NONE;
20
+ * Reset handlers.
16
env->load_res = -1;
21
+ *
17
set_default_nan_mode(1, &env->fp_status);
22
+ * Copyright (c) 2003-2008 Fabrice Bellard
18
+ /* Default NaN value: sign bit clear, frac msb set */
23
+ * Copyright (c) 2016 Red Hat, Inc.
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
24
+ * Copyright (c) 2024 Linaro, Ltd.
20
env->vill = true;
25
+ *
21
26
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
22
#ifndef CONFIG_USER_ONLY
27
+ * of this software and associated documentation files (the "Software"), to deal
28
+ * in the Software without restriction, including without limitation the rights
29
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30
+ * copies of the Software, and to permit persons to whom the Software is
31
+ * furnished to do so, subject to the following conditions:
32
+ *
33
+ * The above copyright notice and this permission notice shall be included in
34
+ * all copies or substantial portions of the Software.
35
+ *
36
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
39
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
42
+ * THE SOFTWARE.
43
+ */
44
+
45
#ifndef QEMU_SYSEMU_RESET_H
46
#define QEMU_SYSEMU_RESET_H
47
48
@@ -XXX,XX +XXX,XX @@
49
50
typedef void QEMUResetHandler(void *opaque);
51
52
+/**
53
+ * qemu_register_reset: Register a callback for system reset
54
+ * @func: function to call
55
+ * @opaque: opaque data to pass to @func
56
+ *
57
+ * Register @func on the list of functions which are called when the
58
+ * entire system is reset. The functions are called in the order in
59
+ * which they are registered.
60
+ *
61
+ * In general this function should not be used in new code where possible;
62
+ * for instance, device model reset is better accomplished using the
63
+ * methods on DeviceState.
64
+ *
65
+ * It is not permitted to register or unregister reset functions from
66
+ * within the @func callback.
67
+ *
68
+ * We assume that the caller holds the BQL.
69
+ */
70
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
71
+
72
+/**
73
+ * qemu_register_reset_nosnapshotload: Register a callback for system reset
74
+ * @func: function to call
75
+ * @opaque: opaque data to pass to @func
76
+ *
77
+ * This is the same as qemu_register_reset(), except that @func is
78
+ * not called if the reason that the system is being reset is to
79
+ * put it into a clean state prior to loading a snapshot (i.e. for
80
+ * SHUTDOWN_CAUSE_SNAPSHOT_LOAD).
81
+ */
82
void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque);
83
+
84
+/**
85
+ * qemu_unregister_reset: Unregister a system reset callback
86
+ * @func: function registered with qemu_register_reset()
87
+ * @opaque: the same opaque data that was passed to qemu_register_reset()
88
+ *
89
+ * Undo the effects of a qemu_register_reset(). The @func and @opaque
90
+ * must both match the arguments originally used with qemu_register_reset().
91
+ *
92
+ * We assume that the caller holds the BQL.
93
+ */
94
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
95
+
96
+/**
97
+ * qemu_devices_reset: Perform a complete system reset
98
+ * @reason: reason for the reset
99
+ *
100
+ * This function performs the low-level work needed to do a complete reset
101
+ * of the system (calling all the callbacks registered with
102
+ * qemu_register_reset()). It should only be called by the code in a
103
+ * MachineClass reset method.
104
+ *
105
+ * If you want to trigger a system reset from, for instance, a device
106
+ * model, don't use this function. Use qemu_system_reset_request().
107
+ */
108
void qemu_devices_reset(ShutdownCause reason);
109
110
#endif
111
--
23
--
112
2.34.1
24
2.34.1
113
114
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
Set the default NaN pattern explicitly for tricore.
2
2
3
Pre setup for BCM2838 introduction
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-54-peter.maydell@linaro.org
6
---
7
target/tricore/helper.c | 2 ++
8
1 file changed, 2 insertions(+)
4
9
5
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
10
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20240226000259.2752893-2-sergey.kambalin@auriga.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
include/hw/arm/bcm2836.h | 26 +++++++++-
11
hw/arm/bcm2836.c | 103 ++++++++++++++++++++++-----------------
12
hw/arm/raspi.c | 2 +-
13
3 files changed, 84 insertions(+), 47 deletions(-)
14
15
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/bcm2836.h
12
--- a/target/tricore/helper.c
18
+++ b/include/hw/arm/bcm2836.h
13
+++ b/target/tricore/helper.c
19
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ void fpu_set_state(CPUTriCoreState *env)
20
#include "target/arm/cpu.h"
15
set_flush_to_zero(1, &env->fp_status);
21
#include "qom/object.h"
16
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
22
17
set_default_nan_mode(1, &env->fp_status);
23
+#define TYPE_BCM283X_BASE "bcm283x-base"
18
+ /* Default NaN pattern: sign bit clear, frac msb set */
24
+OBJECT_DECLARE_TYPE(BCM283XBaseState, BCM283XBaseClass, BCM283X_BASE)
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
25
#define TYPE_BCM283X "bcm283x"
26
-OBJECT_DECLARE_TYPE(BCM283XState, BCM283XClass, BCM283X)
27
+OBJECT_DECLARE_SIMPLE_TYPE(BCM283XState, BCM283X)
28
29
#define BCM283X_NCPUS 4
30
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(BCM283XState, BCM283XClass, BCM283X)
32
#define TYPE_BCM2836 "bcm2836"
33
#define TYPE_BCM2837 "bcm2837"
34
35
-struct BCM283XState {
36
+struct BCM283XBaseState {
37
/*< private >*/
38
DeviceState parent_obj;
39
/*< public >*/
40
@@ -XXX,XX +XXX,XX @@ struct BCM283XState {
41
ARMCPU core;
42
} cpu[BCM283X_NCPUS];
43
BCM2836ControlState control;
44
+};
45
+
46
+struct BCM283XBaseClass {
47
+ /*< private >*/
48
+ DeviceClass parent_class;
49
+ /*< public >*/
50
+ const char *name;
51
+ const char *cpu_type;
52
+ unsigned core_count;
53
+ hwaddr peri_base; /* Peripheral base address seen by the CPU */
54
+ hwaddr ctrl_base; /* Interrupt controller and mailboxes etc. */
55
+ int clusterid;
56
+};
57
+
58
+struct BCM283XState {
59
+ /*< private >*/
60
+ BCM283XBaseState parent_obj;
61
+ /*< public >*/
62
BCM2835PeripheralState peripherals;
63
};
64
65
+bool bcm283x_common_realize(DeviceState *dev, Error **errp);
66
+
67
#endif /* BCM2836_H */
68
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/bcm2836.c
71
+++ b/hw/arm/bcm2836.c
72
@@ -XXX,XX +XXX,XX @@ struct BCM283XClass {
73
};
74
75
static Property bcm2836_enabled_cores_property =
76
- DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus, 0);
77
+ DEFINE_PROP_UINT32("enabled-cpus", BCM283XBaseState, enabled_cpus, 0);
78
79
-static void bcm2836_init(Object *obj)
80
+static void bcm283x_base_init(Object *obj)
81
{
82
- BCM283XState *s = BCM283X(obj);
83
- BCM283XClass *bc = BCM283X_GET_CLASS(obj);
84
+ BCM283XBaseState *s = BCM283X_BASE(obj);
85
+ BCM283XBaseClass *bc = BCM283X_BASE_GET_CLASS(obj);
86
int n;
87
88
for (n = 0; n < bc->core_count; n++) {
89
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
90
object_initialize_child(obj, "control", &s->control,
91
TYPE_BCM2836_CONTROL);
92
}
93
+}
94
+
95
+static void bcm283x_init(Object *obj)
96
+{
97
+ BCM283XState *s = BCM283X(obj);
98
99
object_initialize_child(obj, "peripherals", &s->peripherals,
100
TYPE_BCM2835_PERIPHERALS);
101
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
102
"vcram-size");
103
}
20
}
104
21
105
-static bool bcm283x_common_realize(DeviceState *dev, Error **errp)
22
uint32_t psw_read(CPUTriCoreState *env)
106
+bool bcm283x_common_realize(DeviceState *dev, Error **errp)
107
{
108
BCM283XState *s = BCM283X(dev);
109
- BCM283XClass *bc = BCM283X_GET_CLASS(dev);
110
+ BCM283XBaseState *s_base = BCM283X_BASE(dev);
111
+ BCM283XBaseClass *bc = BCM283X_BASE_GET_CLASS(dev);
112
Object *obj;
113
114
/* common peripherals from bcm2835 */
115
@@ -XXX,XX +XXX,XX @@ static bool bcm283x_common_realize(DeviceState *dev, Error **errp)
116
return false;
117
}
118
119
- object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->peripherals),
120
- "sd-bus");
121
+ object_property_add_alias(OBJECT(s_base), "sd-bus",
122
+ OBJECT(&s->peripherals), "sd-bus");
123
124
- sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0,
125
- bc->peri_base, 1);
126
+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals),
127
+ 0, bc->peri_base, 1);
128
return true;
129
}
130
131
static void bcm2835_realize(DeviceState *dev, Error **errp)
132
{
133
BCM283XState *s = BCM283X(dev);
134
+ BCM283XBaseState *s_base = BCM283X_BASE(dev);
135
136
if (!bcm283x_common_realize(dev, errp)) {
137
return;
138
}
139
140
- if (!qdev_realize(DEVICE(&s->cpu[0].core), NULL, errp)) {
141
+ if (!qdev_realize(DEVICE(&s_base->cpu[0].core), NULL, errp)) {
142
return;
143
}
144
145
/* Connect irq/fiq outputs from the interrupt controller. */
146
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 0,
147
- qdev_get_gpio_in(DEVICE(&s->cpu[0].core), ARM_CPU_IRQ));
148
+ qdev_get_gpio_in(DEVICE(&s_base->cpu[0].core), ARM_CPU_IRQ));
149
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
150
- qdev_get_gpio_in(DEVICE(&s->cpu[0].core), ARM_CPU_FIQ));
151
+ qdev_get_gpio_in(DEVICE(&s_base->cpu[0].core), ARM_CPU_FIQ));
152
}
153
154
static void bcm2836_realize(DeviceState *dev, Error **errp)
155
{
156
- BCM283XState *s = BCM283X(dev);
157
- BCM283XClass *bc = BCM283X_GET_CLASS(dev);
158
int n;
159
+ BCM283XState *s = BCM283X(dev);
160
+ BCM283XBaseState *s_base = BCM283X_BASE(dev);
161
+ BCM283XBaseClass *bc = BCM283X_BASE_GET_CLASS(dev);
162
163
if (!bcm283x_common_realize(dev, errp)) {
164
return;
165
}
166
167
/* bcm2836 interrupt controller (and mailboxes, etc.) */
168
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->control), errp)) {
169
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s_base->control), errp)) {
170
return;
171
}
172
173
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->control), 0, bc->ctrl_base);
174
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s_base->control), 0, bc->ctrl_base);
175
176
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 0,
177
- qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-irq", 0));
178
+ qdev_get_gpio_in_named(DEVICE(&s_base->control), "gpu-irq", 0));
179
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
180
- qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
181
+ qdev_get_gpio_in_named(DEVICE(&s_base->control), "gpu-fiq", 0));
182
183
for (n = 0; n < BCM283X_NCPUS; n++) {
184
- object_property_set_int(OBJECT(&s->cpu[n].core), "mp-affinity",
185
+ object_property_set_int(OBJECT(&s_base->cpu[n].core), "mp-affinity",
186
(bc->clusterid << 8) | n, &error_abort);
187
188
/* set periphbase/CBAR value for CPU-local registers */
189
- object_property_set_int(OBJECT(&s->cpu[n].core), "reset-cbar",
190
+ object_property_set_int(OBJECT(&s_base->cpu[n].core), "reset-cbar",
191
bc->peri_base, &error_abort);
192
193
/* start powered off if not enabled */
194
- object_property_set_bool(OBJECT(&s->cpu[n].core), "start-powered-off",
195
- n >= s->enabled_cpus, &error_abort);
196
+ object_property_set_bool(OBJECT(&s_base->cpu[n].core),
197
+ "start-powered-off",
198
+ n >= s_base->enabled_cpus, &error_abort);
199
200
- if (!qdev_realize(DEVICE(&s->cpu[n].core), NULL, errp)) {
201
+ if (!qdev_realize(DEVICE(&s_base->cpu[n].core), NULL, errp)) {
202
return;
203
}
204
205
/* Connect irq/fiq outputs from the interrupt controller. */
206
- qdev_connect_gpio_out_named(DEVICE(&s->control), "irq", n,
207
- qdev_get_gpio_in(DEVICE(&s->cpu[n].core), ARM_CPU_IRQ));
208
- qdev_connect_gpio_out_named(DEVICE(&s->control), "fiq", n,
209
- qdev_get_gpio_in(DEVICE(&s->cpu[n].core), ARM_CPU_FIQ));
210
+ qdev_connect_gpio_out_named(DEVICE(&s_base->control), "irq", n,
211
+ qdev_get_gpio_in(DEVICE(&s_base->cpu[n].core), ARM_CPU_IRQ));
212
+ qdev_connect_gpio_out_named(DEVICE(&s_base->control), "fiq", n,
213
+ qdev_get_gpio_in(DEVICE(&s_base->cpu[n].core), ARM_CPU_FIQ));
214
215
/* Connect timers from the CPU to the interrupt controller */
216
- qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_PHYS,
217
- qdev_get_gpio_in_named(DEVICE(&s->control), "cntpnsirq", n));
218
- qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_VIRT,
219
- qdev_get_gpio_in_named(DEVICE(&s->control), "cntvirq", n));
220
- qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_HYP,
221
- qdev_get_gpio_in_named(DEVICE(&s->control), "cnthpirq", n));
222
- qdev_connect_gpio_out(DEVICE(&s->cpu[n].core), GTIMER_SEC,
223
- qdev_get_gpio_in_named(DEVICE(&s->control), "cntpsirq", n));
224
+ qdev_connect_gpio_out(DEVICE(&s_base->cpu[n].core), GTIMER_PHYS,
225
+ qdev_get_gpio_in_named(DEVICE(&s_base->control), "cntpnsirq", n));
226
+ qdev_connect_gpio_out(DEVICE(&s_base->cpu[n].core), GTIMER_VIRT,
227
+ qdev_get_gpio_in_named(DEVICE(&s_base->control), "cntvirq", n));
228
+ qdev_connect_gpio_out(DEVICE(&s_base->cpu[n].core), GTIMER_HYP,
229
+ qdev_get_gpio_in_named(DEVICE(&s_base->control), "cnthpirq", n));
230
+ qdev_connect_gpio_out(DEVICE(&s_base->cpu[n].core), GTIMER_SEC,
231
+ qdev_get_gpio_in_named(DEVICE(&s_base->control), "cntpsirq", n));
232
}
233
}
234
235
-static void bcm283x_class_init(ObjectClass *oc, void *data)
236
+static void bcm283x_base_class_init(ObjectClass *oc, void *data)
237
{
238
DeviceClass *dc = DEVICE_CLASS(oc);
239
240
@@ -XXX,XX +XXX,XX @@ static void bcm283x_class_init(ObjectClass *oc, void *data)
241
static void bcm2835_class_init(ObjectClass *oc, void *data)
242
{
243
DeviceClass *dc = DEVICE_CLASS(oc);
244
- BCM283XClass *bc = BCM283X_CLASS(oc);
245
+ BCM283XBaseClass *bc = BCM283X_BASE_CLASS(oc);
246
247
bc->cpu_type = ARM_CPU_TYPE_NAME("arm1176");
248
bc->core_count = 1;
249
@@ -XXX,XX +XXX,XX @@ static void bcm2835_class_init(ObjectClass *oc, void *data)
250
static void bcm2836_class_init(ObjectClass *oc, void *data)
251
{
252
DeviceClass *dc = DEVICE_CLASS(oc);
253
- BCM283XClass *bc = BCM283X_CLASS(oc);
254
+ BCM283XBaseClass *bc = BCM283X_BASE_CLASS(oc);
255
256
bc->cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
257
bc->core_count = BCM283X_NCPUS;
258
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
259
static void bcm2837_class_init(ObjectClass *oc, void *data)
260
{
261
DeviceClass *dc = DEVICE_CLASS(oc);
262
- BCM283XClass *bc = BCM283X_CLASS(oc);
263
+ BCM283XBaseClass *bc = BCM283X_BASE_CLASS(oc);
264
265
bc->cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
266
bc->core_count = BCM283X_NCPUS;
267
@@ -XXX,XX +XXX,XX @@ static const TypeInfo bcm283x_types[] = {
268
#endif
269
}, {
270
.name = TYPE_BCM283X,
271
- .parent = TYPE_DEVICE,
272
+ .parent = TYPE_BCM283X_BASE,
273
.instance_size = sizeof(BCM283XState),
274
- .instance_init = bcm2836_init,
275
- .class_size = sizeof(BCM283XClass),
276
- .class_init = bcm283x_class_init,
277
+ .instance_init = bcm283x_init,
278
+ .abstract = true,
279
+ }, {
280
+ .name = TYPE_BCM283X_BASE,
281
+ .parent = TYPE_DEVICE,
282
+ .instance_size = sizeof(BCM283XBaseState),
283
+ .instance_init = bcm283x_base_init,
284
+ .class_size = sizeof(BCM283XBaseClass),
285
+ .class_init = bcm283x_base_class_init,
286
.abstract = true,
287
}
288
};
289
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
290
index XXXXXXX..XXXXXXX 100644
291
--- a/hw/arm/raspi.c
292
+++ b/hw/arm/raspi.c
293
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, RaspiProcessorId processor_id,
294
s->binfo.firmware_loaded = true;
295
}
296
297
- arm_load_kernel(&s->soc.cpu[0].core, machine, &s->binfo);
298
+ arm_load_kernel(&s->soc.parent_obj.cpu[0].core, machine, &s->binfo);
299
}
300
301
static void raspi_machine_init(MachineState *machine)
302
--
23
--
303
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
We have an OBJECT_DEFINE_TYPE_EXTENDED macro, plus several variations
1
Now that all our targets have bene converted to explicitly specify
2
on it, which emits the boilerplate for the TypeInfo and ensures it is
2
their pattern for the default NaN value we can remove the remaining
3
registered with the type system. However, all the existing macros
3
fallback code in parts64_default_nan().
4
insist that the type being defined has its own FooClass struct, so
5
they aren't useful for the common case of a simple leaf class which
6
doesn't have any new methods or any other need for its own class
7
struct (that is, for the kind of type that OBJECT_DECLARE_SIMPLE_TYPE
8
declares).
9
4
10
Pull the actual implementation of OBJECT_DEFINE_TYPE_EXTENDED out
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
into a new DO_OBJECT_DEFINE_TYPE_EXTENDED which parameterizes the
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
value we use for the class_size field. This lets us add a new
7
Message-id: 20241202131347.498124-55-peter.maydell@linaro.org
13
OBJECT_DEFINE_SIMPLE_TYPE which does the same job as the various
8
---
14
existing OBJECT_DEFINE_*_TYPE_* family macros for this kind of simple
9
fpu/softfloat-specialize.c.inc | 14 --------------
15
type, and the variant OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES for
10
1 file changed, 14 deletions(-)
16
when the type will implement some interfaces.
17
11
18
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
12
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
23
Message-id: 20240220160622.114437-5-peter.maydell@linaro.org
24
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
25
---
26
docs/devel/qom.rst | 34 +++++++++++--
27
include/qom/object.h | 114 +++++++++++++++++++++++++++++++++----------
28
2 files changed, 117 insertions(+), 31 deletions(-)
29
30
diff --git a/docs/devel/qom.rst b/docs/devel/qom.rst
31
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
32
--- a/docs/devel/qom.rst
14
--- a/fpu/softfloat-specialize.c.inc
33
+++ b/docs/devel/qom.rst
15
+++ b/fpu/softfloat-specialize.c.inc
34
@@ -XXX,XX +XXX,XX @@ used. This does the same as OBJECT_DECLARE_SIMPLE_TYPE(), but without
16
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
35
the 'struct MyDeviceClass' definition.
17
uint64_t frac;
36
18
uint8_t dnan_pattern = status->default_nan_pattern;
37
To implement the type, the OBJECT_DEFINE macro family is available.
19
38
-In the simple case the OBJECT_DEFINE_TYPE macro is suitable:
20
- if (dnan_pattern == 0) {
39
+For the simplest case of a leaf class which doesn't need any of its
21
- /*
40
+own virtual functions (i.e. which was declared with OBJECT_DECLARE_SIMPLE_TYPE)
22
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
41
+the OBJECT_DEFINE_SIMPLE_TYPE macro is suitable:
23
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
42
24
- * do not have floating-point.
43
.. code-block:: c
25
- */
44
:caption: Defining a simple type
26
- if (snan_bit_is_one(status)) {
45
27
- /* sign bit clear, set all frac bits other than msb */
46
- OBJECT_DEFINE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
28
- dnan_pattern = 0b00111111;
47
+ OBJECT_DEFINE_SIMPLE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
29
- } else {
48
30
- /* sign bit clear, set frac msb */
49
This is equivalent to the following:
31
- dnan_pattern = 0b01000000;
50
32
- }
51
@@ -XXX,XX +XXX,XX @@ This is equivalent to the following:
33
- }
52
.instance_size = sizeof(MyDevice),
34
assert(dnan_pattern != 0);
53
.instance_init = my_device_init,
35
54
.instance_finalize = my_device_finalize,
36
sign = dnan_pattern >> 7;
55
- .class_size = sizeof(MyDeviceClass),
56
.class_init = my_device_class_init,
57
};
58
59
@@ -XXX,XX +XXX,XX @@ This is sufficient to get the type registered with the type
60
system, and the three standard methods now need to be implemented
61
along with any other logic required for the type.
62
63
+If the class needs its own virtual methods, or has some other
64
+per-class state it needs to store in its own class struct,
65
+then you can use the OBJECT_DEFINE_TYPE macro. This does the
66
+same thing as OBJECT_DEFINE_SIMPLE_TYPE, but it also sets the
67
+class_size of the type to the size of the class struct.
68
+
69
+.. code-block:: c
70
+ :caption: Defining a type which needs a class struct
71
+
72
+ OBJECT_DEFINE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
73
+
74
If the type needs to implement one or more interfaces, then the
75
-OBJECT_DEFINE_TYPE_WITH_INTERFACES() macro can be used instead.
76
-This accepts an array of interface type names.
77
+OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES() and
78
+OBJECT_DEFINE_TYPE_WITH_INTERFACES() macros can be used instead.
79
+These accept an array of interface type names. The difference between
80
+them is that the former is for simple leaf classes that don't need
81
+a class struct, and the latter is for when you will be defining
82
+a class struct.
83
84
.. code-block:: c
85
:caption: Defining a simple type implementing interfaces
86
87
+ OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(MyDevice, my_device,
88
+ MY_DEVICE, DEVICE,
89
+ { TYPE_USER_CREATABLE },
90
+ { NULL })
91
+
92
+.. code-block:: c
93
+ :caption: Defining a type implementing interfaces
94
+
95
OBJECT_DEFINE_TYPE_WITH_INTERFACES(MyDevice, my_device,
96
MY_DEVICE, DEVICE,
97
{ TYPE_USER_CREATABLE },
98
diff --git a/include/qom/object.h b/include/qom/object.h
99
index XXXXXXX..XXXXXXX 100644
100
--- a/include/qom/object.h
101
+++ b/include/qom/object.h
102
@@ -XXX,XX +XXX,XX @@ struct Object
103
DECLARE_INSTANCE_CHECKER(InstanceType, MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)
104
105
106
+/**
107
+ * DO_OBJECT_DEFINE_TYPE_EXTENDED:
108
+ * @ModuleObjName: the object name with initial caps
109
+ * @module_obj_name: the object name in lowercase with underscore separators
110
+ * @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
111
+ * @PARENT_MODULE_OBJ_NAME: the parent object name in uppercase with underscore
112
+ * separators
113
+ * @ABSTRACT: boolean flag to indicate whether the object can be instantiated
114
+ * @CLASS_SIZE: size of the type's class
115
+ * @...: list of initializers for "InterfaceInfo" to declare implemented interfaces
116
+ *
117
+ * This is the base macro used to implement all the OBJECT_DEFINE_*
118
+ * macros. It should never be used directly in a source file.
119
+ */
120
+#define DO_OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
121
+ MODULE_OBJ_NAME, \
122
+ PARENT_MODULE_OBJ_NAME, \
123
+ ABSTRACT, CLASS_SIZE, ...) \
124
+ static void \
125
+ module_obj_name##_finalize(Object *obj); \
126
+ static void \
127
+ module_obj_name##_class_init(ObjectClass *oc, void *data); \
128
+ static void \
129
+ module_obj_name##_init(Object *obj); \
130
+ \
131
+ static const TypeInfo module_obj_name##_info = { \
132
+ .parent = TYPE_##PARENT_MODULE_OBJ_NAME, \
133
+ .name = TYPE_##MODULE_OBJ_NAME, \
134
+ .instance_size = sizeof(ModuleObjName), \
135
+ .instance_align = __alignof__(ModuleObjName), \
136
+ .instance_init = module_obj_name##_init, \
137
+ .instance_finalize = module_obj_name##_finalize, \
138
+ .class_size = CLASS_SIZE, \
139
+ .class_init = module_obj_name##_class_init, \
140
+ .abstract = ABSTRACT, \
141
+ .interfaces = (InterfaceInfo[]) { __VA_ARGS__ } , \
142
+ }; \
143
+ \
144
+ static void \
145
+ module_obj_name##_register_types(void) \
146
+ { \
147
+ type_register_static(&module_obj_name##_info); \
148
+ } \
149
+ type_init(module_obj_name##_register_types);
150
+
151
/**
152
* OBJECT_DEFINE_TYPE_EXTENDED:
153
* @ModuleObjName: the object name with initial caps
154
@@ -XXX,XX +XXX,XX @@ struct Object
155
#define OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
156
MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
157
ABSTRACT, ...) \
158
- static void \
159
- module_obj_name##_finalize(Object *obj); \
160
- static void \
161
- module_obj_name##_class_init(ObjectClass *oc, void *data); \
162
- static void \
163
- module_obj_name##_init(Object *obj); \
164
- \
165
- static const TypeInfo module_obj_name##_info = { \
166
- .parent = TYPE_##PARENT_MODULE_OBJ_NAME, \
167
- .name = TYPE_##MODULE_OBJ_NAME, \
168
- .instance_size = sizeof(ModuleObjName), \
169
- .instance_align = __alignof__(ModuleObjName), \
170
- .instance_init = module_obj_name##_init, \
171
- .instance_finalize = module_obj_name##_finalize, \
172
- .class_size = sizeof(ModuleObjName##Class), \
173
- .class_init = module_obj_name##_class_init, \
174
- .abstract = ABSTRACT, \
175
- .interfaces = (InterfaceInfo[]) { __VA_ARGS__ } , \
176
- }; \
177
- \
178
- static void \
179
- module_obj_name##_register_types(void) \
180
- { \
181
- type_register_static(&module_obj_name##_info); \
182
- } \
183
- type_init(module_obj_name##_register_types);
184
+ DO_OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
185
+ MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
186
+ ABSTRACT, sizeof(ModuleObjName##Class), \
187
+ __VA_ARGS__)
188
189
/**
190
* OBJECT_DEFINE_TYPE:
191
@@ -XXX,XX +XXX,XX @@ struct Object
192
MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
193
true, { NULL })
194
195
+/**
196
+ * OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES:
197
+ * @ModuleObjName: the object name with initial caps
198
+ * @module_obj_name: the object name in lowercase with underscore separators
199
+ * @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
200
+ * @PARENT_MODULE_OBJ_NAME: the parent object name in uppercase with underscore
201
+ * separators
202
+ *
203
+ * This is a variant of OBJECT_DEFINE_TYPE_EXTENDED, which is suitable for
204
+ * the case of a non-abstract type, with interfaces, and with no requirement
205
+ * for a class struct.
206
+ */
207
+#define OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(ModuleObjName, \
208
+ module_obj_name, \
209
+ MODULE_OBJ_NAME, \
210
+ PARENT_MODULE_OBJ_NAME, ...) \
211
+ DO_OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
212
+ MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
213
+ false, 0, __VA_ARGS__)
214
+
215
+/**
216
+ * OBJECT_DEFINE_SIMPLE_TYPE:
217
+ * @ModuleObjName: the object name with initial caps
218
+ * @module_obj_name: the object name in lowercase with underscore separators
219
+ * @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
220
+ * @PARENT_MODULE_OBJ_NAME: the parent object name in uppercase with underscore
221
+ * separators
222
+ *
223
+ * This is a variant of OBJECT_DEFINE_TYPE_EXTENDED, which is suitable for
224
+ * the common case of a non-abstract type, without any interfaces, and with
225
+ * no requirement for a class struct. If you declared your type with
226
+ * OBJECT_DECLARE_SIMPLE_TYPE then this is probably the right choice for
227
+ * defining it.
228
+ */
229
+#define OBJECT_DEFINE_SIMPLE_TYPE(ModuleObjName, module_obj_name, \
230
+ MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME) \
231
+ OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(ModuleObjName, module_obj_name, \
232
+ MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, { NULL })
233
+
234
/**
235
* struct TypeInfo:
236
* @name: The name of the type.
237
--
37
--
238
2.34.1
38
2.34.1
239
240
diff view generated by jsdifflib
1
Implement new functions qemu_register_resettable() and
1
From: Richard Henderson <richard.henderson@linaro.org>
2
qemu_unregister_resettable(). These are intended to be
3
three-phase-reset aware equivalents of the old qemu_register_reset()
4
and qemu_unregister_reset(). Instead of passing in a function
5
pointer and opaque, you register any QOM object that implements the
6
Resettable interface.
7
2
8
The implementation is simple: we have a single global instance of a
3
Inline pickNaNMulAdd into its only caller. This makes
9
ResettableContainer, which we reset in qemu_devices_reset(), and
4
one assert redundant with the immediately preceding IF.
10
the Resettable objects passed to qemu_register_resettable() are
11
added to it.
12
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-3-richard.henderson@linaro.org
9
[PMM: keep comment from old code in new location]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
18
Message-id: 20240220160622.114437-8-peter.maydell@linaro.org
19
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
20
---
11
---
21
include/sysemu/reset.h | 37 ++++++++++++++++++++++++++++++++++---
12
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
22
hw/core/reset.c | 31 +++++++++++++++++++++++++++++--
13
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
23
2 files changed, 63 insertions(+), 5 deletions(-)
14
2 files changed, 40 insertions(+), 55 deletions(-)
24
15
25
diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/include/sysemu/reset.h
18
--- a/fpu/softfloat-parts.c.inc
28
+++ b/include/sysemu/reset.h
19
+++ b/fpu/softfloat-parts.c.inc
29
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
21
}
31
typedef void QEMUResetHandler(void *opaque);
22
32
23
if (s->default_nan_mode) {
33
+/**
24
+ /*
34
+ * qemu_register_resettable: Register an object to be reset
25
+ * We guarantee not to require the target to tell us how to
35
+ * @obj: object to be reset: it must implement the Resettable interface
26
+ * pick a NaN if we're always returning the default NaN.
36
+ *
27
+ * But if we're not in default-NaN mode then the target must
37
+ * Register @obj on the list of objects which will be reset when the
28
+ * specify.
38
+ * simulation is reset. These objects will be reset in the order
29
+ */
39
+ * they were added, using the three-phase Resettable protocol,
30
which = 3;
40
+ * so first all objects go through the enter phase, then all objects
31
+ } else if (infzero) {
41
+ * go through the hold phase, and then finally all go through the
32
+ /*
42
+ * exit phase.
33
+ * Inf * 0 + NaN -- some implementations return the
43
+ *
34
+ * default NaN here, and some return the input NaN.
44
+ * It is not permitted to register or unregister reset functions or
35
+ */
45
+ * resettable objects from within any of the reset phase methods of @obj.
36
+ switch (s->float_infzeronan_rule) {
46
+ *
37
+ case float_infzeronan_dnan_never:
47
+ * We assume that the caller holds the BQL.
38
+ which = 2;
48
+ */
39
+ break;
49
+void qemu_register_resettable(Object *obj);
40
+ case float_infzeronan_dnan_always:
41
+ which = 3;
42
+ break;
43
+ case float_infzeronan_dnan_if_qnan:
44
+ which = is_qnan(c->cls) ? 3 : 2;
45
+ break;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
} else {
50
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
51
+ FloatClass cls[3] = { a->cls, b->cls, c->cls };
52
+ Float3NaNPropRule rule = s->float_3nan_prop_rule;
50
+
53
+
51
+/**
54
+ assert(rule != float_3nan_prop_none);
52
+ * qemu_unregister_resettable: Unregister an object to be reset
55
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
53
+ * @obj: object to unregister
56
+ /* We have at least one SNaN input and should prefer it */
54
+ *
57
+ do {
55
+ * Remove @obj from the list of objects which are reset when the
58
+ which = rule & R_3NAN_1ST_MASK;
56
+ * simulation is reset. It must have been previously added to
59
+ rule >>= R_3NAN_1ST_LENGTH;
57
+ * the list via qemu_register_resettable().
60
+ } while (!is_snan(cls[which]));
58
+ *
61
+ } else {
59
+ * We assume that the caller holds the BQL.
62
+ do {
60
+ */
63
+ which = rule & R_3NAN_1ST_MASK;
61
+void qemu_unregister_resettable(Object *obj);
64
+ rule >>= R_3NAN_1ST_LENGTH;
62
+
65
+ } while (!is_nan(cls[which]));
63
/**
66
+ }
64
* qemu_register_reset: Register a callback for system reset
67
}
65
* @func: function to call
68
66
@@ -XXX,XX +XXX,XX @@ typedef void QEMUResetHandler(void *opaque);
69
if (which == 3) {
67
* for instance, device model reset is better accomplished using the
70
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
68
* methods on DeviceState.
69
*
70
- * It is not permitted to register or unregister reset functions from
71
- * within the @func callback.
72
+ * It is not permitted to register or unregister reset functions or
73
+ * resettable objects from within the @func callback.
74
*
75
* We assume that the caller holds the BQL.
76
*/
77
@@ -XXX,XX +XXX,XX @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
78
*
79
* This function performs the low-level work needed to do a complete reset
80
* of the system (calling all the callbacks registered with
81
- * qemu_register_reset()). It should only be called by the code in a
82
+ * qemu_register_reset() and resetting all the Resettable objects registered
83
+ * with qemu_register_resettable()). It should only be called by the code in a
84
* MachineClass reset method.
85
*
86
* If you want to trigger a system reset from, for instance, a device
87
diff --git a/hw/core/reset.c b/hw/core/reset.c
88
index XXXXXXX..XXXXXXX 100644
71
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/core/reset.c
72
--- a/fpu/softfloat-specialize.c.inc
90
+++ b/hw/core/reset.c
73
+++ b/fpu/softfloat-specialize.c.inc
91
@@ -XXX,XX +XXX,XX @@
74
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
92
#include "qemu/osdep.h"
93
#include "qemu/queue.h"
94
#include "sysemu/reset.h"
95
+#include "hw/resettable.h"
96
+#include "hw/core/resetcontainer.h"
97
98
-/* reset/shutdown handler */
99
+/*
100
+ * Return a pointer to the singleton container that holds all the Resettable
101
+ * items that will be reset when qemu_devices_reset() is called.
102
+ */
103
+static ResettableContainer *get_root_reset_container(void)
104
+{
105
+ static ResettableContainer *root_reset_container;
106
+
107
+ if (!root_reset_container) {
108
+ root_reset_container =
109
+ RESETTABLE_CONTAINER(object_new(TYPE_RESETTABLE_CONTAINER));
110
+ }
111
+ return root_reset_container;
112
+}
113
114
typedef struct QEMUResetEntry {
115
QTAILQ_ENTRY(QEMUResetEntry) entry;
116
@@ -XXX,XX +XXX,XX @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
117
}
75
}
118
}
76
}
119
77
120
+void qemu_register_resettable(Object *obj)
78
-/*----------------------------------------------------------------------------
121
+{
79
-| Select which NaN to propagate for a three-input operation.
122
+ resettable_container_add(get_root_reset_container(), obj);
80
-| For the moment we assume that no CPU needs the 'larger significand'
123
+}
81
-| information.
124
+
82
-| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
125
+void qemu_unregister_resettable(Object *obj)
83
-*----------------------------------------------------------------------------*/
126
+{
84
-static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
127
+ resettable_container_remove(get_root_reset_container(), obj);
85
- bool infzero, bool have_snan, float_status *status)
128
+}
86
-{
129
+
87
- FloatClass cls[3] = { a_cls, b_cls, c_cls };
130
void qemu_devices_reset(ShutdownCause reason)
88
- Float3NaNPropRule rule = status->float_3nan_prop_rule;
131
{
89
- int which;
132
QEMUResetEntry *re, *nre;
90
-
133
@@ -XXX,XX +XXX,XX @@ void qemu_devices_reset(ShutdownCause reason)
91
- /*
134
}
92
- * We guarantee not to require the target to tell us how to
135
re->func(re->opaque);
93
- * pick a NaN if we're always returning the default NaN.
136
}
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;
137
-}
130
-}
138
131
-
139
+ /* Reset the simulation */
132
/*----------------------------------------------------------------------------
140
+ resettable_reset(OBJECT(get_root_reset_container()), RESET_TYPE_COLD);
133
| Returns 1 if the double-precision floating-point value `a' is a quiet
141
+}
134
| NaN; otherwise returns 0.
142
--
135
--
143
2.34.1
136
2.34.1
144
137
145
138
diff view generated by jsdifflib
1
From: Jessica Clarke <jrtc27@jrtc27.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The PL031 allows you to read RTCLR, which is meant to give you the last
3
Remove "3" as a special case for which and simply
4
value written. PL031State has an lr field which is used when reading
4
branch to return the desired value.
5
from RTCLR, and is present in the VM migration state, but we never
6
actually update it, so it always reads as its initial 0 value.
7
5
8
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20241203203949.483774-4-richard.henderson@linaro.org
11
Message-id: 20240222000341.1562443-1-jrtc27@jrtc27.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
hw/rtc/pl031.c | 1 +
11
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
16
1 file changed, 1 insertion(+)
12
1 file changed, 10 insertions(+), 10 deletions(-)
17
13
18
diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/rtc/pl031.c
16
--- a/fpu/softfloat-parts.c.inc
21
+++ b/hw/rtc/pl031.c
17
+++ b/fpu/softfloat-parts.c.inc
22
@@ -XXX,XX +XXX,XX @@ static void pl031_write(void * opaque, hwaddr offset,
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
23
g_autofree const char *qom_path = object_get_canonical_path(opaque);
19
* But if we're not in default-NaN mode then the target must
24
struct tm tm;
20
* specify.
25
21
*/
26
+ s->lr = value;
22
- which = 3;
27
s->tick_offset += value - pl031_get_count(s);
23
+ goto default_nan;
28
24
} else if (infzero) {
29
qemu_get_timedate(&tm, s->tick_offset);
25
/*
26
* Inf * 0 + NaN -- some implementations return the
27
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
28
*/
29
switch (s->float_infzeronan_rule) {
30
case float_infzeronan_dnan_never:
31
- which = 2;
32
break;
33
case float_infzeronan_dnan_always:
34
- which = 3;
35
- break;
36
+ goto default_nan;
37
case float_infzeronan_dnan_if_qnan:
38
- which = is_qnan(c->cls) ? 3 : 2;
39
+ if (is_qnan(c->cls)) {
40
+ goto default_nan;
41
+ }
42
break;
43
default:
44
g_assert_not_reached();
45
}
46
+ which = 2;
47
} else {
48
FloatClass cls[3] = { a->cls, b->cls, c->cls };
49
Float3NaNPropRule rule = s->float_3nan_prop_rule;
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
51
}
52
}
53
54
- if (which == 3) {
55
- parts_default_nan(a, s);
56
- return a;
57
- }
58
-
59
switch (which) {
60
case 0:
61
break;
62
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
63
parts_silence_nan(a, s);
64
}
65
return a;
66
+
67
+ default_nan:
68
+ parts_default_nan(a, s);
69
+ return a;
70
}
71
72
/*
30
--
73
--
31
2.34.1
74
2.34.1
32
75
33
76
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
There is no point in checking do we have PCIe if first thing after check
3
Assign the pointer return value to 'a' directly,
4
is adding PCIe card without checking.
4
rather than going through an intermediary index.
5
5
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20240215153311.186772-1-marcin.juszkiewicz@linaro.org
8
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
hw/arm/sbsa-ref.c | 5 ++---
11
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
12
1 file changed, 2 insertions(+), 3 deletions(-)
12
1 file changed, 10 insertions(+), 22 deletions(-)
13
13
14
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/sbsa-ref.c
16
--- a/fpu/softfloat-parts.c.inc
17
+++ b/hw/arm/sbsa-ref.c
17
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms)
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
19
FloatPartsN *c, float_status *s,
20
int ab_mask, int abc_mask)
21
{
22
- int which;
23
bool infzero = (ab_mask == float_cmask_infzero);
24
bool have_snan = (abc_mask & float_cmask_snan);
25
+ FloatPartsN *ret;
26
27
if (unlikely(have_snan)) {
28
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
default:
31
g_assert_not_reached();
32
}
33
- which = 2;
34
+ ret = c;
35
} else {
36
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
37
+ FloatPartsN *val[3] = { a, b, c };
38
Float3NaNPropRule rule = s->float_3nan_prop_rule;
39
40
assert(rule != float_3nan_prop_none);
41
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
42
/* We have at least one SNaN input and should prefer it */
43
do {
44
- which = rule & R_3NAN_1ST_MASK;
45
+ ret = val[rule & R_3NAN_1ST_MASK];
46
rule >>= R_3NAN_1ST_LENGTH;
47
- } while (!is_snan(cls[which]));
48
+ } while (!is_snan(ret->cls));
49
} else {
50
do {
51
- which = rule & R_3NAN_1ST_MASK;
52
+ ret = val[rule & R_3NAN_1ST_MASK];
53
rule >>= R_3NAN_1ST_LENGTH;
54
- } while (!is_nan(cls[which]));
55
+ } while (!is_nan(ret->cls));
56
}
19
}
57
}
20
58
21
pci = PCI_HOST_BRIDGE(dev);
59
- switch (which) {
22
- if (pci->bus) {
60
- case 0:
23
- pci_init_nic_devices(pci->bus, mc->default_nic);
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);
24
- }
75
- }
25
+
76
- return a;
26
+ pci_init_nic_devices(pci->bus, mc->default_nic);
77
+ return ret;
27
78
28
pci_create_simple(pci->bus, -1, "bochs-display");
79
default_nan:
29
80
parts_default_nan(a, s);
30
--
81
--
31
2.34.1
82
2.34.1
32
83
33
84
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
3
While all indices into val[] should be in [0-2], the mask
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
applied is two bits. To help static analysis see there is
5
no possibility of read beyond the end of the array, pad the
6
array to 4 entries, with the final being (implicitly) NULL.
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20241203203949.483774-6-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
include/hw/arm/bcm2838_peripherals.h | 1 +
13
fpu/softfloat-parts.c.inc | 2 +-
9
hw/arm/bcm2838_peripherals.c | 6 ++++++
14
1 file changed, 1 insertion(+), 1 deletion(-)
10
2 files changed, 7 insertions(+)
11
15
12
diff --git a/include/hw/arm/bcm2838_peripherals.h b/include/hw/arm/bcm2838_peripherals.h
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/bcm2838_peripherals.h
18
--- a/fpu/softfloat-parts.c.inc
15
+++ b/include/hw/arm/bcm2838_peripherals.h
19
+++ b/fpu/softfloat-parts.c.inc
16
@@ -XXX,XX +XXX,XX @@ struct BCM2838PeripheralState {
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
17
OrIRQState dma_9_10_irq_orgate;
21
}
18
22
ret = c;
19
UnimplementedDeviceState asb;
23
} else {
20
+ UnimplementedDeviceState clkisp;
24
- FloatPartsN *val[3] = { a, b, c };
21
};
25
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
22
26
Float3NaNPropRule rule = s->float_3nan_prop_rule;
23
struct BCM2838PeripheralClass {
27
24
diff --git a/hw/arm/bcm2838_peripherals.c b/hw/arm/bcm2838_peripherals.c
28
assert(rule != float_3nan_prop_none);
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/bcm2838_peripherals.c
27
+++ b/hw/arm/bcm2838_peripherals.c
28
@@ -XXX,XX +XXX,XX @@
29
#include "hw/arm/raspi_platform.h"
30
#include "hw/arm/bcm2838_peripherals.h"
31
32
+#define CLOCK_ISP_OFFSET 0xc11000
33
+#define CLOCK_ISP_SIZE 0x100
34
+
35
/* Lower peripheral base address on the VC (GPU) system bus */
36
#define BCM2838_VC_PERI_LOW_BASE 0x7c000000
37
38
@@ -XXX,XX +XXX,XX @@ static void bcm2838_peripherals_realize(DeviceState *dev, Error **errp)
39
memory_region_add_subregion(&s_base->peri_mr, BCM2838_MPHI_OFFSET,
40
&s->mphi_mr_alias);
41
42
+ create_unimp(s_base, &s->clkisp, "bcm2835-clkisp", CLOCK_ISP_OFFSET,
43
+ CLOCK_ISP_SIZE);
44
+
45
/* GPIO */
46
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
47
return;
48
--
29
--
49
2.34.1
30
2.34.1
50
31
51
32
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This commit adds RPi4B device tree modifications:
3
This function is part of the public interface and
4
- disable pcie, rng200, thermal sensor and genet devices
4
is not "specialized" to any target in any way.
5
(they're going to be re-enabled in the following commits)
6
- create additional memory region in device tree
7
if RAM amount exceeds VC base address.
8
5
9
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240226000259.2752893-12-sergey.kambalin@auriga.com
8
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
include/hw/arm/raspi_platform.h | 4 +++
11
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
15
hw/arm/raspi.c | 5 +--
12
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
16
hw/arm/raspi4b.c | 62 +++++++++++++++++++++++++++++++++
13
2 files changed, 52 insertions(+), 52 deletions(-)
17
3 files changed, 67 insertions(+), 4 deletions(-)
18
14
19
diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/arm/raspi_platform.h
17
--- a/fpu/softfloat.c
22
+++ b/include/hw/arm/raspi_platform.h
18
+++ b/fpu/softfloat.c
23
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
24
#include "hw/boards.h"
20
*zExpPtr = 1 - shiftCount;
25
#include "hw/arm/boot.h"
21
}
26
22
27
+/* Registered machine type (matches RPi Foundation bootloader and U-Boot) */
23
+/*----------------------------------------------------------------------------
28
+#define MACH_TYPE_BCM2708 3138
24
+| Takes two extended double-precision floating-point values `a' and `b', one
25
+| of which is a NaN, and returns the appropriate NaN result. If either `a' or
26
+| `b' is a signaling NaN, the invalid exception is raised.
27
+*----------------------------------------------------------------------------*/
29
+
28
+
30
#define TYPE_RASPI_BASE_MACHINE MACHINE_TYPE_NAME("raspi-base")
29
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
31
OBJECT_DECLARE_TYPE(RaspiBaseMachineState, RaspiBaseMachineClass,
32
RASPI_BASE_MACHINE)
33
@@ -XXX,XX +XXX,XX @@ void raspi_base_machine_init(MachineState *machine,
34
35
void raspi_machine_class_common_init(MachineClass *mc,
36
uint32_t board_rev);
37
+uint64_t board_ram_size(uint32_t board_rev);
38
39
#define MSYNC_OFFSET 0x0000 /* Multicore Sync Block */
40
#define CCPT_OFFSET 0x1000 /* Compact Camera Port 2 TX */
41
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/raspi.c
44
+++ b/hw/arm/raspi.c
45
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(RaspiMachineState, RASPI_MACHINE)
46
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
47
#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
48
49
-/* Registered machine type (matches RPi Foundation bootloader and U-Boot) */
50
-#define MACH_TYPE_BCM2708 3138
51
-
52
struct RaspiMachineState {
53
/*< private >*/
54
RaspiBaseMachineState parent_obj;
55
@@ -XXX,XX +XXX,XX @@ static const struct {
56
[PROCESSOR_ID_BCM2838] = {TYPE_BCM2838, BCM283X_NCPUS},
57
};
58
59
-static uint64_t board_ram_size(uint32_t board_rev)
60
+uint64_t board_ram_size(uint32_t board_rev)
61
{
62
assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */
63
return 256 * MiB << FIELD_EX32(board_rev, REV_CODE, MEMORY_SIZE);
64
diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/arm/raspi4b.c
67
+++ b/hw/arm/raspi4b.c
68
@@ -XXX,XX +XXX,XX @@
69
#include "hw/arm/boot.h"
70
#include "qom/object.h"
71
#include "hw/arm/bcm2838.h"
72
+#include <libfdt.h>
73
74
#define TYPE_RASPI4B_MACHINE MACHINE_TYPE_NAME("raspi4b")
75
OBJECT_DECLARE_SIMPLE_TYPE(Raspi4bMachineState, RASPI4B_MACHINE)
76
@@ -XXX,XX +XXX,XX @@ struct Raspi4bMachineState {
77
BCM2838State soc;
78
};
79
80
+/*
81
+ * Add second memory region if board RAM amount exceeds VC base address
82
+ * (see https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf
83
+ * 1.2 Address Map)
84
+ */
85
+static int raspi_add_memory_node(void *fdt, hwaddr mem_base, hwaddr mem_len)
86
+{
30
+{
87
+ int ret;
31
+ bool aIsLargerSignificand;
88
+ uint32_t acells, scells;
32
+ FloatClass a_cls, b_cls;
89
+ char *nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
90
+
33
+
91
+ acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells",
34
+ /* This is not complete, but is good enough for pickNaN. */
92
+ NULL, &error_fatal);
35
+ a_cls = (!floatx80_is_any_nan(a)
93
+ scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells",
36
+ ? float_class_normal
94
+ NULL, &error_fatal);
37
+ : floatx80_is_signaling_nan(a, status)
95
+ if (acells == 0 || scells == 0) {
38
+ ? float_class_snan
96
+ fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n");
39
+ : float_class_qnan);
97
+ ret = -1;
40
+ b_cls = (!floatx80_is_any_nan(b)
98
+ } else {
41
+ ? float_class_normal
99
+ qemu_fdt_add_subnode(fdt, nodename);
42
+ : floatx80_is_signaling_nan(b, status)
100
+ qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
43
+ ? float_class_snan
101
+ ret = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
44
+ : float_class_qnan);
102
+ acells, mem_base,
45
+
103
+ scells, mem_len);
46
+ if (is_snan(a_cls) || is_snan(b_cls)) {
47
+ float_raise(float_flag_invalid, status);
104
+ }
48
+ }
105
+
49
+
106
+ g_free(nodename);
50
+ if (status->default_nan_mode) {
107
+ return ret;
51
+ return floatx80_default_nan(status);
108
+}
109
+
110
+static void raspi4_modify_dtb(const struct arm_boot_info *info, void *fdt)
111
+{
112
+ uint64_t ram_size;
113
+
114
+ /* Temporarily disable following devices until they are implemented */
115
+ const char *nodes_to_remove[] = {
116
+ "brcm,bcm2711-pcie",
117
+ "brcm,bcm2711-rng200",
118
+ "brcm,bcm2711-thermal",
119
+ "brcm,bcm2711-genet-v5",
120
+ };
121
+
122
+ for (int i = 0; i < ARRAY_SIZE(nodes_to_remove); i++) {
123
+ const char *dev_str = nodes_to_remove[i];
124
+
125
+ int offset = fdt_node_offset_by_compatible(fdt, -1, dev_str);
126
+ if (offset >= 0) {
127
+ if (!fdt_nop_node(fdt, offset)) {
128
+ warn_report("bcm2711 dtc: %s has been disabled!", dev_str);
129
+ }
130
+ }
131
+ }
52
+ }
132
+
53
+
133
+ ram_size = board_ram_size(info->board_id);
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
+ }
134
+
61
+
135
+ if (info->ram_size > UPPER_RAM_BASE) {
62
+ if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
136
+ raspi_add_memory_node(fdt, UPPER_RAM_BASE, ram_size - UPPER_RAM_BASE);
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;
137
+ }
72
+ }
138
+}
73
+}
139
+
74
+
140
static void raspi4b_machine_init(MachineState *machine)
75
/*----------------------------------------------------------------------------
141
{
76
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
142
Raspi4bMachineState *s = RASPI4B_MACHINE(machine);
77
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
143
@@ -XXX,XX +XXX,XX @@ static void raspi4b_machine_init(MachineState *machine)
78
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
144
RaspiBaseMachineClass *mc = RASPI_BASE_MACHINE_GET_CLASS(machine);
79
index XXXXXXX..XXXXXXX 100644
145
BCM2838State *soc = &s->soc;
80
--- a/fpu/softfloat-specialize.c.inc
146
81
+++ b/fpu/softfloat-specialize.c.inc
147
+ s_base->binfo.modify_dtb = raspi4_modify_dtb;
82
@@ -XXX,XX +XXX,XX @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
148
s_base->binfo.board_id = mc->board_rev;
83
return a;
149
84
}
150
object_initialize_child(OBJECT(machine), "soc", soc,
85
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.
151
--
141
--
152
2.34.1
142
2.34.1
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
3
Unpacking and repacking the parts may be slightly more work
4
Message-id: 20240226000259.2752893-32-sergey.kambalin@auriga.com
4
than we did before, but we get to reuse more code. For a
5
code path handling exceptional values, this is an improvement.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241203203949.483774-8-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
tests/qtest/bcm2838-mailbox.h | 37 +++++++++++++++++++++
12
fpu/softfloat.c | 43 +++++--------------------------------------
9
tests/qtest/bcm2838-mailbox.c | 60 +++++++++++++++++++++++++++++++++++
13
1 file changed, 5 insertions(+), 38 deletions(-)
10
tests/qtest/meson.build | 1 +
11
3 files changed, 98 insertions(+)
12
create mode 100644 tests/qtest/bcm2838-mailbox.h
13
create mode 100644 tests/qtest/bcm2838-mailbox.c
14
14
15
diff --git a/tests/qtest/bcm2838-mailbox.h b/tests/qtest/bcm2838-mailbox.h
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
16
new file mode 100644
17
index XXXXXXX..XXXXXXX
18
--- /dev/null
19
+++ b/tests/qtest/bcm2838-mailbox.h
20
@@ -XXX,XX +XXX,XX @@
21
+/*
22
+ * Declarations for BCM2838 mailbox test.
23
+ *
24
+ * Copyright (c) 2023 Auriga LLC
25
+ *
26
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
27
+ * See the COPYING file in the top-level directory.
28
+ */
29
+
30
+typedef struct {
31
+ uint32_t size;
32
+ uint32_t req_resp_code;
33
+} MboxBufHeader;
34
+
35
+#define DECLARE_TAG_TYPE(TypeName, RequestValueType, ResponseValueType) \
36
+typedef struct { \
37
+ uint32_t id; \
38
+ uint32_t value_buffer_size; \
39
+ union { \
40
+ struct { \
41
+ uint32_t zero; \
42
+ RequestValueType value; \
43
+ } request; \
44
+ struct { \
45
+ uint32_t size_stat; \
46
+ ResponseValueType value; \
47
+ } response; \
48
+ }; \
49
+} TypeName
50
+
51
+
52
+int mbox0_has_data(void);
53
+void mbox0_read_message(uint8_t channel, void *msgbuf, size_t msgbuf_size);
54
+void mbox1_write_message(uint8_t channel, uint32_t msg_addr);
55
+int qtest_mbox0_has_data(QTestState *s);
56
+void qtest_mbox0_read_message(QTestState *s, uint8_t channel, void *msgbuf, size_t msgbuf_size);
57
+void qtest_mbox1_write_message(QTestState *s, uint8_t channel, uint32_t msg_addr);
58
diff --git a/tests/qtest/bcm2838-mailbox.c b/tests/qtest/bcm2838-mailbox.c
59
new file mode 100644
60
index XXXXXXX..XXXXXXX
61
--- /dev/null
62
+++ b/tests/qtest/bcm2838-mailbox.c
63
@@ -XXX,XX +XXX,XX @@
64
+/*
65
+ * Helper functions to work with BCM2838 mailbox via qtest interface.
66
+ *
67
+ * Copyright (c) 2023 Auriga LLC
68
+ *
69
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
70
+ * See the COPYING file in the top-level directory.
71
+ */
72
+
73
+#include "qemu/osdep.h"
74
+#include "hw/registerfields.h"
75
+#include "libqtest-single.h"
76
+#include "bcm2838-mailbox.h"
77
+
78
+REG32(MBOX_EXCHNG_REG, 0)
79
+FIELD(MBOX_EXCHNG_REG, CHANNEL, 0, 4)
80
+FIELD(MBOX_EXCHNG_REG, DATA, 4, 28)
81
+
82
+static uint32_t qtest_mbox0_read_reg32(QTestState *s, uint32_t offset)
83
+{
84
+ return qtest_readl(s, MBOX0_BASE + offset);
85
+}
86
+
87
+static void qtest_mbox1_write_reg32(QTestState *s, uint32_t offset, uint32_t value)
88
+{
89
+ return qtest_writel(s, MBOX1_BASE + offset, value);
90
+}
91
+
92
+static void qtest_mbox1_write(QTestState *s, uint8_t channel, uint32_t data)
93
+{
94
+ uint32_t mbox_reg = 0;
95
+
96
+ mbox_reg = FIELD_DP32(mbox_reg, MBOX_EXCHNG_REG, CHANNEL, channel);
97
+ mbox_reg = FIELD_DP32(mbox_reg, MBOX_EXCHNG_REG, DATA, data);
98
+ qtest_mbox1_write_reg32(s, MBOX_REG_WRITE, mbox_reg);
99
+}
100
+
101
+int qtest_mbox0_has_data(QTestState *s) {
102
+ return !(qtest_mbox0_read_reg32(s, MBOX_REG_STATUS) & MBOX_READ_EMPTY);
103
+}
104
+
105
+void qtest_mbox0_read_message(QTestState *s,
106
+ uint8_t channel,
107
+ void *msgbuf,
108
+ size_t msgbuf_size)
109
+{
110
+ uint32_t mbox_reg;
111
+ uint32_t msgaddr;
112
+
113
+ g_assert(qtest_mbox0_has_data(s));
114
+ mbox_reg = qtest_mbox0_read_reg32(s, MBOX_REG_READ);
115
+ g_assert_cmphex(FIELD_EX32(mbox_reg, MBOX_EXCHNG_REG, CHANNEL), ==, channel);
116
+ msgaddr = FIELD_EX32(mbox_reg, MBOX_EXCHNG_REG, DATA) << 4;
117
+ qtest_memread(s, msgaddr, msgbuf, msgbuf_size);
118
+}
119
+
120
+void qtest_mbox1_write_message(QTestState *s, uint8_t channel, uint32_t msg_addr)
121
+{
122
+ qtest_mbox1_write(s, channel, msg_addr >> 4);
123
+}
124
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
125
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
126
--- a/tests/qtest/meson.build
17
--- a/fpu/softfloat.c
127
+++ b/tests/qtest/meson.build
18
+++ b/fpu/softfloat.c
128
@@ -XXX,XX +XXX,XX @@ qtests = {
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
129
'virtio-net-failover': files('migration-helpers.c'),
20
130
'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'),
21
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
131
'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
22
{
132
+ 'bcm2838-mbox-property-test' : files('bcm2838-mailbox.c'),
23
- bool aIsLargerSignificand;
24
- FloatClass a_cls, b_cls;
25
+ FloatParts128 pa, pb, *pr;
26
27
- /* This is not complete, but is good enough for pickNaN. */
28
- a_cls = (!floatx80_is_any_nan(a)
29
- ? float_class_normal
30
- : floatx80_is_signaling_nan(a, status)
31
- ? float_class_snan
32
- : float_class_qnan);
33
- b_cls = (!floatx80_is_any_nan(b)
34
- ? float_class_normal
35
- : floatx80_is_signaling_nan(b, status)
36
- ? float_class_snan
37
- : float_class_qnan);
38
-
39
- if (is_snan(a_cls) || is_snan(b_cls)) {
40
- float_raise(float_flag_invalid, status);
41
- }
42
-
43
- if (status->default_nan_mode) {
44
+ if (!floatx80_unpack_canonical(&pa, a, status) ||
45
+ !floatx80_unpack_canonical(&pb, b, status)) {
46
return floatx80_default_nan(status);
47
}
48
49
- if (a.low < b.low) {
50
- aIsLargerSignificand = 0;
51
- } else if (b.low < a.low) {
52
- aIsLargerSignificand = 1;
53
- } else {
54
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
55
- }
56
-
57
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
58
- if (is_snan(b_cls)) {
59
- return floatx80_silence_nan(b, status);
60
- }
61
- return b;
62
- } else {
63
- if (is_snan(a_cls)) {
64
- return floatx80_silence_nan(a, status);
65
- }
66
- return a;
67
- }
68
+ pr = parts_pick_nan(&pa, &pb, status);
69
+ return floatx80_round_pack_canonical(pr, status);
133
}
70
}
134
71
135
if vnc.found()
72
/*----------------------------------------------------------------------------
136
--
73
--
137
2.34.1
74
2.34.1
diff view generated by jsdifflib
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Fixes: 52671f69f7a4 ("[PATCH v8 0/3] Add device STM32L4x5 EXTI")
3
Inline pickNaN into its only caller. This makes one assert
4
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
4
redundant with the immediately preceding IF.
5
Message-id: 20240220184145.106107-2-ines.varhol@telecom-paris.fr
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-9-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
include/hw/arm/stm32l4x5_soc.h | 4 ++
11
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
11
hw/arm/stm32l4x5_soc.c | 80 +++++++++++++++++++++++++++++-----
12
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
12
2 files changed, 74 insertions(+), 10 deletions(-)
13
2 files changed, 73 insertions(+), 105 deletions(-)
13
14
14
diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h
15
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/stm32l4x5_soc.h
17
--- a/fpu/softfloat-parts.c.inc
17
+++ b/include/hw/arm/stm32l4x5_soc.h
18
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
19
20
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
20
#include "exec/memory.h"
21
float_status *s)
21
#include "hw/arm/armv7m.h"
22
{
22
+#include "hw/or-irq.h"
23
+ int cmp, which;
23
#include "hw/misc/stm32l4x5_syscfg.h"
24
#include "hw/misc/stm32l4x5_exti.h"
25
#include "qom/object.h"
26
@@ -XXX,XX +XXX,XX @@
27
#define TYPE_STM32L4X5XG_SOC "stm32l4x5xg-soc"
28
OBJECT_DECLARE_TYPE(Stm32l4x5SocState, Stm32l4x5SocClass, STM32L4X5_SOC)
29
30
+#define NUM_EXTI_OR_GATES 4
31
+
24
+
32
struct Stm32l4x5SocState {
25
if (is_snan(a->cls) || is_snan(b->cls)) {
33
SysBusDevice parent_obj;
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
34
27
}
35
ARMv7MState armv7m;
28
36
29
if (s->default_nan_mode) {
37
Stm32l4x5ExtiState exti;
30
parts_default_nan(a, s);
38
+ OrIRQState exti_or_gates[NUM_EXTI_OR_GATES];
31
- } else {
39
Stm32l4x5SyscfgState syscfg;
32
- int cmp = frac_cmp(a, b);
40
33
- if (cmp == 0) {
41
MemoryRegion sram1;
34
- cmp = a->sign < b->sign;
42
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
35
- }
43
index XXXXXXX..XXXXXXX 100644
36
+ return a;
44
--- a/hw/arm/stm32l4x5_soc.c
37
+ }
45
+++ b/hw/arm/stm32l4x5_soc.c
38
46
@@ -XXX,XX +XXX,XX @@
39
- if (pickNaN(a->cls, b->cls, cmp > 0, s)) {
47
#include "qapi/error.h"
40
- a = b;
48
#include "exec/address-spaces.h"
41
- }
49
#include "sysemu/sysemu.h"
42
+ cmp = frac_cmp(a, b);
50
+#include "hw/or-irq.h"
43
+ if (cmp == 0) {
51
#include "hw/arm/stm32l4x5_soc.h"
44
+ cmp = a->sign < b->sign;
52
#include "hw/qdev-clock.h"
45
+ }
53
#include "hw/misc/unimp.h"
54
@@ -XXX,XX +XXX,XX @@
55
#define NUM_EXTI_IRQ 40
56
/* Match exti line connections with their CPU IRQ number */
57
/* See Vector Table (Reference Manual p.396) */
58
+/*
59
+ * Some IRQs are connected to the same CPU IRQ (denoted by -1)
60
+ * and require an intermediary OR gate to function correctly.
61
+ */
62
static const int exti_irq[NUM_EXTI_IRQ] = {
63
6, /* GPIO[0] */
64
7, /* GPIO[1] */
65
8, /* GPIO[2] */
66
9, /* GPIO[3] */
67
10, /* GPIO[4] */
68
- 23, 23, 23, 23, 23, /* GPIO[5..9] */
69
- 40, 40, 40, 40, 40, 40, /* GPIO[10..15] */
70
- 1, /* PVD */
71
+ -1, -1, -1, -1, -1, /* GPIO[5..9] OR gate 23 */
72
+ -1, -1, -1, -1, -1, -1, /* GPIO[10..15] OR gate 40 */
73
+ -1, /* PVD OR gate 1 */
74
67, /* OTG_FS_WKUP, Direct */
75
41, /* RTC_ALARM */
76
2, /* RTC_TAMP_STAMP2/CSS_LSE */
77
3, /* RTC wakeup timer */
78
- 63, /* COMP1 */
79
- 63, /* COMP2 */
80
+ -1, -1, /* COMP[1..2] OR gate 63 */
81
31, /* I2C1 wakeup, Direct */
82
33, /* I2C2 wakeup, Direct */
83
72, /* I2C3 wakeup, Direct */
84
@@ -XXX,XX +XXX,XX @@ static const int exti_irq[NUM_EXTI_IRQ] = {
85
65, /* LPTIM1, Direct */
86
66, /* LPTIM2, Direct */
87
76, /* SWPMI1 wakeup, Direct */
88
- 1, /* PVM1 wakeup */
89
- 1, /* PVM2 wakeup */
90
- 1, /* PVM3 wakeup */
91
- 1, /* PVM4 wakeup */
92
+ -1, -1, -1, -1, /* PVM[1..4] OR gate 1 */
93
78 /* LCD wakeup, Direct */
94
};
95
96
+static const int exti_or_gates_out[NUM_EXTI_OR_GATES] = {
97
+ 23, 40, 63, 1,
98
+};
99
+
46
+
100
+static const int exti_or_gates_num_lines_in[NUM_EXTI_OR_GATES] = {
47
+ switch (s->float_2nan_prop_rule) {
101
+ 5, 6, 2, 5,
48
+ case float_2nan_prop_s_ab:
102
+};
49
if (is_snan(a->cls)) {
103
+
50
- parts_silence_nan(a, s);
104
+/* 3 OR gates with consecutive inputs */
51
+ which = 0;
105
+#define NUM_EXTI_SIMPLE_OR_GATES 3
52
+ } else if (is_snan(b->cls)) {
106
+static const int exti_or_gates_first_line_in[NUM_EXTI_SIMPLE_OR_GATES] = {
53
+ which = 1;
107
+ 5, 10, 21,
54
+ } else if (is_qnan(a->cls)) {
108
+};
55
+ which = 0;
109
+
56
+ } else {
110
+/* 1 OR gate with non-consecutive inputs */
57
+ which = 1;
111
+#define EXTI_OR_GATE1_NUM_LINES_IN 5
58
}
112
+static const int exti_or_gate1_lines_in[EXTI_OR_GATE1_NUM_LINES_IN] = {
59
+ break;
113
+ 16, 35, 36, 37, 38,
60
+ case float_2nan_prop_s_ba:
114
+};
61
+ if (is_snan(b->cls)) {
115
+
62
+ which = 1;
116
static void stm32l4x5_soc_initfn(Object *obj)
63
+ } else if (is_snan(a->cls)) {
117
{
64
+ which = 0;
118
Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
65
+ } else if (is_qnan(b->cls)) {
119
66
+ which = 1;
120
object_initialize_child(obj, "exti", &s->exti, TYPE_STM32L4X5_EXTI);
67
+ } else {
121
+ for (unsigned i = 0; i < NUM_EXTI_OR_GATES; i++) {
68
+ which = 0;
122
+ object_initialize_child(obj, "exti_or_gates[*]", &s->exti_or_gates[i],
123
+ TYPE_OR_IRQ);
124
+ }
125
object_initialize_child(obj, "syscfg", &s->syscfg, TYPE_STM32L4X5_SYSCFG);
126
127
s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
128
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
129
return;
130
}
131
sysbus_mmio_map(busdev, 0, EXTI_ADDR);
132
+
133
+ /* IRQs with fan-in that require an OR gate */
134
+ for (unsigned i = 0; i < NUM_EXTI_OR_GATES; i++) {
135
+ if (!object_property_set_int(OBJECT(&s->exti_or_gates[i]), "num-lines",
136
+ exti_or_gates_num_lines_in[i], errp)) {
137
+ return;
138
+ }
69
+ }
139
+ if (!qdev_realize(DEVICE(&s->exti_or_gates[i]), NULL, errp)) {
70
+ break;
140
+ return;
71
+ case float_2nan_prop_ab:
141
+ }
72
+ which = is_nan(a->cls) ? 0 : 1;
142
+
73
+ break;
143
+ qdev_connect_gpio_out(DEVICE(&s->exti_or_gates[i]), 0,
74
+ case float_2nan_prop_ba:
144
+ qdev_get_gpio_in(armv7m, exti_or_gates_out[i]));
75
+ which = is_nan(b->cls) ? 1 : 0;
145
+
76
+ break;
146
+ if (i < NUM_EXTI_SIMPLE_OR_GATES) {
77
+ case float_2nan_prop_x87:
147
+ /* consecutive inputs for OR gates 23, 40, 63 */
78
+ /*
148
+ for (unsigned j = 0; j < exti_or_gates_num_lines_in[i]; j++) {
79
+ * This implements x87 NaN propagation rules:
149
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->exti),
80
+ * SNaN + QNaN => return the QNaN
150
+ exti_or_gates_first_line_in[i] + j,
81
+ * two SNaNs => return the one with the larger significand, silenced
151
+ qdev_get_gpio_in(DEVICE(&s->exti_or_gates[i]), j));
82
+ * two QNaNs => return the one with the larger significand
83
+ * SNaN and a non-NaN => return the SNaN, silenced
84
+ * QNaN and a non-NaN => return the QNaN
85
+ *
86
+ * If we get down to comparing significands and they are the same,
87
+ * return the NaN with the positive sign bit (if any).
88
+ */
89
+ if (is_snan(a->cls)) {
90
+ if (is_snan(b->cls)) {
91
+ which = cmp > 0 ? 0 : 1;
92
+ } else {
93
+ which = is_qnan(b->cls) ? 1 : 0;
94
+ }
95
+ } else if (is_qnan(a->cls)) {
96
+ if (is_snan(b->cls) || !is_qnan(b->cls)) {
97
+ which = 0;
98
+ } else {
99
+ which = cmp > 0 ? 0 : 1;
152
+ }
100
+ }
153
+ } else {
101
+ } else {
154
+ /* non-consecutive inputs for OR gate 1 */
102
+ which = 1;
155
+ for (unsigned j = 0; j < EXTI_OR_GATE1_NUM_LINES_IN; j++) {
156
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->exti),
157
+ exti_or_gate1_lines_in[j],
158
+ qdev_get_gpio_in(DEVICE(&s->exti_or_gates[i]), j));
159
+ }
160
+ }
103
+ }
104
+ break;
105
+ default:
106
+ g_assert_not_reached();
161
+ }
107
+ }
162
+
108
+
163
+ /* IRQs that don't require fan-in */
109
+ if (which) {
164
for (unsigned i = 0; i < NUM_EXTI_IRQ; i++) {
110
+ a = b;
165
- sysbus_connect_irq(busdev, i, qdev_get_gpio_in(armv7m, exti_irq[i]));
111
+ }
166
+ if (exti_irq[i] != -1) {
112
+ if (is_snan(a->cls)) {
167
+ sysbus_connect_irq(busdev, i,
113
+ parts_silence_nan(a, s);
168
+ qdev_get_gpio_in(armv7m, exti_irq[i]));
169
+ }
170
}
114
}
171
115
return a;
172
for (unsigned i = 0; i < 16; i++) {
116
}
117
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
118
index XXXXXXX..XXXXXXX 100644
119
--- a/fpu/softfloat-specialize.c.inc
120
+++ b/fpu/softfloat-specialize.c.inc
121
@@ -XXX,XX +XXX,XX @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
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.
173
--
224
--
174
2.34.1
225
2.34.1
175
226
176
227
diff view generated by jsdifflib
1
From: Sergey Kambalin <serg.oker@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Pre-setup for raspberry pi 4 introduction
3
Remember if there was an SNaN, and use that to simplify
4
float_2nan_prop_s_{ab,ba} to only the snan component.
5
Then, fall through to the corresponding
6
float_2nan_prop_{ab,ba} case to handle any remaining
7
nans, which must be quiet.
4
8
5
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20240226000259.2752893-4-sergey.kambalin@auriga.com
11
Message-id: 20241203203949.483774-10-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
include/hw/arm/raspi_platform.h | 21 ++++++
14
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
11
hw/arm/raspi.c | 112 ++++++++++++++++++--------------
15
1 file changed, 12 insertions(+), 20 deletions(-)
12
2 files changed, 85 insertions(+), 48 deletions(-)
13
16
14
diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/raspi_platform.h
19
--- a/fpu/softfloat-parts.c.inc
17
+++ b/include/hw/arm/raspi_platform.h
20
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
19
#ifndef HW_ARM_RASPI_PLATFORM_H
22
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
20
#define HW_ARM_RASPI_PLATFORM_H
23
float_status *s)
21
22
+#include "hw/boards.h"
23
+#include "hw/arm/boot.h"
24
+
25
+#define TYPE_RASPI_BASE_MACHINE MACHINE_TYPE_NAME("raspi-base")
26
+OBJECT_DECLARE_TYPE(RaspiBaseMachineState, RaspiBaseMachineClass,
27
+ RASPI_BASE_MACHINE)
28
+
29
+struct RaspiBaseMachineState {
30
+ /*< private >*/
31
+ MachineState parent_obj;
32
+ /*< public >*/
33
+ struct arm_boot_info binfo;
34
+};
35
+
36
+struct RaspiBaseMachineClass {
37
+ /*< private >*/
38
+ MachineClass parent_obj;
39
+ /*< public >*/
40
+ uint32_t board_rev;
41
+};
42
+
43
#define MSYNC_OFFSET 0x0000 /* Multicore Sync Block */
44
#define CCPT_OFFSET 0x1000 /* Compact Camera Port 2 TX */
45
#define INTE_OFFSET 0x2000 /* VC Interrupt controller */
46
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/raspi.c
49
+++ b/hw/arm/raspi.c
50
@@ -XXX,XX +XXX,XX @@
51
#include "qapi/error.h"
52
#include "hw/arm/boot.h"
53
#include "hw/arm/bcm2836.h"
54
+#include "hw/arm/raspi_platform.h"
55
#include "hw/registerfields.h"
56
#include "qemu/error-report.h"
57
#include "hw/boards.h"
58
@@ -XXX,XX +XXX,XX @@
59
#include "hw/arm/boot.h"
60
#include "qom/object.h"
61
62
+#define TYPE_RASPI_MACHINE MACHINE_TYPE_NAME("raspi-common")
63
+OBJECT_DECLARE_SIMPLE_TYPE(RaspiMachineState, RASPI_MACHINE)
64
+
65
#define SMPBOOT_ADDR 0x300 /* this should leave enough space for ATAGS */
66
#define MVBAR_ADDR 0x400 /* secure vectors */
67
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
68
@@ -XXX,XX +XXX,XX @@
69
70
struct RaspiMachineState {
71
/*< private >*/
72
- MachineState parent_obj;
73
+ RaspiBaseMachineState parent_obj;
74
/*< public >*/
75
BCM283XState soc;
76
- struct arm_boot_info binfo;
77
};
78
-typedef struct RaspiMachineState RaspiMachineState;
79
-
80
-struct RaspiMachineClass {
81
- /*< private >*/
82
- MachineClass parent_obj;
83
- /*< public >*/
84
- uint32_t board_rev;
85
-};
86
-typedef struct RaspiMachineClass RaspiMachineClass;
87
-
88
-#define TYPE_RASPI_MACHINE MACHINE_TYPE_NAME("raspi-common")
89
-DECLARE_OBJ_CHECKERS(RaspiMachineState, RaspiMachineClass,
90
- RASPI_MACHINE, TYPE_RASPI_MACHINE)
91
-
92
93
/*
94
* Board revision codes:
95
@@ -XXX,XX +XXX,XX @@ static const struct {
96
[PROCESSOR_ID_BCM2837] = {TYPE_BCM2837, BCM283X_NCPUS},
97
};
98
99
+static void raspi_base_machine_init(MachineState *machine,
100
+ BCM283XBaseState *soc);
101
+static void raspi_machine_class_common_init(MachineClass *mc,
102
+ uint32_t board_rev);
103
+
104
static uint64_t board_ram_size(uint32_t board_rev)
105
{
24
{
106
assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */
25
+ bool have_snan = false;
107
@@ -XXX,XX +XXX,XX @@ static void reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
26
int cmp, which;
108
cpu_set_pc(cs, info->smp_loader_start);
27
109
}
28
if (is_snan(a->cls) || is_snan(b->cls)) {
110
29
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
111
-static void setup_boot(MachineState *machine, RaspiProcessorId processor_id,
30
+ have_snan = true;
112
- size_t ram_size)
113
+static void setup_boot(MachineState *machine, ARMCPU *cpu,
114
+ RaspiProcessorId processor_id, size_t ram_size)
115
{
116
- RaspiMachineState *s = RASPI_MACHINE(machine);
117
+ RaspiBaseMachineState *s = RASPI_BASE_MACHINE(machine);
118
int r;
119
120
- s->binfo.board_id = MACH_TYPE_BCM2708;
121
s->binfo.ram_size = ram_size;
122
123
if (processor_id <= PROCESSOR_ID_BCM2836) {
124
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, RaspiProcessorId processor_id,
125
s->binfo.firmware_loaded = true;
126
}
31
}
127
32
128
- arm_load_kernel(&s->soc.parent_obj.cpu[0].core, machine, &s->binfo);
33
if (s->default_nan_mode) {
129
+ arm_load_kernel(cpu, machine, &s->binfo);
34
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
130
}
35
131
36
switch (s->float_2nan_prop_rule) {
132
-static void raspi_machine_init(MachineState *machine)
37
case float_2nan_prop_s_ab:
133
+static void raspi_base_machine_init(MachineState *machine,
38
- if (is_snan(a->cls)) {
134
+ BCM283XBaseState *soc)
39
- which = 0;
135
{
40
- } else if (is_snan(b->cls)) {
136
- RaspiMachineClass *mc = RASPI_MACHINE_GET_CLASS(machine);
41
- which = 1;
137
- RaspiMachineState *s = RASPI_MACHINE(machine);
42
- } else if (is_qnan(a->cls)) {
138
+ RaspiBaseMachineClass *mc = RASPI_BASE_MACHINE_GET_CLASS(machine);
43
- which = 0;
139
uint32_t board_rev = mc->board_rev;
44
- } else {
140
uint64_t ram_size = board_ram_size(board_rev);
45
- which = 1;
141
uint32_t vcram_size;
46
+ if (have_snan) {
142
@@ -XXX,XX +XXX,XX @@ static void raspi_machine_init(MachineState *machine)
47
+ which = is_snan(a->cls) ? 0 : 1;
143
machine->ram, 0);
48
+ break;
144
49
}
145
/* Setup the SOC */
50
- break;
146
- object_initialize_child(OBJECT(machine), "soc", &s->soc,
51
- case float_2nan_prop_s_ba:
147
- board_soc_type(board_rev));
52
- if (is_snan(b->cls)) {
148
- object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(machine->ram));
53
- which = 1;
149
- object_property_set_int(OBJECT(&s->soc), "board-rev", board_rev,
54
- } else if (is_snan(a->cls)) {
150
+ object_property_add_const_link(OBJECT(soc), "ram", OBJECT(machine->ram));
55
- which = 0;
151
+ object_property_set_int(OBJECT(soc), "board-rev", board_rev,
56
- } else if (is_qnan(b->cls)) {
152
&error_abort);
57
- which = 1;
153
- object_property_set_str(OBJECT(&s->soc), "command-line",
58
- } else {
154
+ object_property_set_str(OBJECT(soc), "command-line",
59
- which = 0;
155
machine->kernel_cmdline, &error_abort);
60
- }
156
- qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
61
- break;
157
+ qdev_realize(DEVICE(soc), NULL, &error_fatal);
62
+ /* fall through */
158
63
case float_2nan_prop_ab:
159
/* Create and plug in the SD cards */
64
which = is_nan(a->cls) ? 0 : 1;
160
di = drive_get(IF_SD, 0, 0);
65
break;
161
blk = di ? blk_by_legacy_dinfo(di) : NULL;
66
+ case float_2nan_prop_s_ba:
162
- bus = qdev_get_child_bus(DEVICE(&s->soc), "sd-bus");
67
+ if (have_snan) {
163
+ bus = qdev_get_child_bus(DEVICE(soc), "sd-bus");
68
+ which = is_snan(b->cls) ? 1 : 0;
164
if (bus == NULL) {
69
+ break;
165
error_report("No SD bus found in SOC object");
70
+ }
166
exit(1);
71
+ /* fall through */
167
@@ -XXX,XX +XXX,XX @@ static void raspi_machine_init(MachineState *machine)
72
case float_2nan_prop_ba:
168
qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal);
73
which = is_nan(b->cls) ? 1 : 0;
169
qdev_realize_and_unref(carddev, bus, &error_fatal);
74
break;
170
171
- vcram_size = object_property_get_uint(OBJECT(&s->soc), "vcram-size",
172
+ vcram_size = object_property_get_uint(OBJECT(soc), "vcram-size",
173
&error_abort);
174
- setup_boot(machine, board_processor_id(mc->board_rev),
175
+ setup_boot(machine, &soc->cpu[0].core, board_processor_id(board_rev),
176
machine->ram_size - vcram_size);
177
}
178
179
-static void raspi_machine_class_common_init(MachineClass *mc,
180
- uint32_t board_rev)
181
+static void raspi_machine_init(MachineState *machine)
182
+{
183
+ RaspiMachineState *s = RASPI_MACHINE(machine);
184
+ RaspiBaseMachineState *s_base = RASPI_BASE_MACHINE(machine);
185
+ RaspiBaseMachineClass *mc = RASPI_BASE_MACHINE_GET_CLASS(machine);
186
+ BCM283XState *soc = &s->soc;
187
+
188
+ s_base->binfo.board_id = MACH_TYPE_BCM2708;
189
+
190
+ object_initialize_child(OBJECT(machine), "soc", soc,
191
+ board_soc_type(mc->board_rev));
192
+ raspi_base_machine_init(machine, &soc->parent_obj);
193
+}
194
+
195
+void raspi_machine_class_common_init(MachineClass *mc,
196
+ uint32_t board_rev)
197
{
198
mc->desc = g_strdup_printf("Raspberry Pi %s (revision 1.%u)",
199
board_type(board_rev),
200
FIELD_EX32(board_rev, REV_CODE, REVISION));
201
- mc->init = raspi_machine_init;
202
mc->block_default_type = IF_SD;
203
mc->no_parallel = 1;
204
mc->no_floppy = 1;
205
@@ -XXX,XX +XXX,XX @@ static void raspi_machine_class_common_init(MachineClass *mc,
206
mc->default_ram_id = "ram";
207
};
208
209
+static void raspi_machine_class_init(MachineClass *mc,
210
+ uint32_t board_rev)
211
+{
212
+ raspi_machine_class_common_init(mc, board_rev);
213
+ mc->init = raspi_machine_init;
214
+};
215
+
216
static void raspi0_machine_class_init(ObjectClass *oc, void *data)
217
{
218
MachineClass *mc = MACHINE_CLASS(oc);
219
- RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc);
220
+ RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc);
221
222
rmc->board_rev = 0x920092; /* Revision 1.2 */
223
- raspi_machine_class_common_init(mc, rmc->board_rev);
224
+ raspi_machine_class_init(mc, rmc->board_rev);
225
};
226
227
static void raspi1ap_machine_class_init(ObjectClass *oc, void *data)
228
{
229
MachineClass *mc = MACHINE_CLASS(oc);
230
- RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc);
231
+ RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc);
232
233
rmc->board_rev = 0x900021; /* Revision 1.1 */
234
- raspi_machine_class_common_init(mc, rmc->board_rev);
235
+ raspi_machine_class_init(mc, rmc->board_rev);
236
};
237
238
static void raspi2b_machine_class_init(ObjectClass *oc, void *data)
239
{
240
MachineClass *mc = MACHINE_CLASS(oc);
241
- RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc);
242
+ RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc);
243
244
rmc->board_rev = 0xa21041;
245
- raspi_machine_class_common_init(mc, rmc->board_rev);
246
+ raspi_machine_class_init(mc, rmc->board_rev);
247
};
248
249
#ifdef TARGET_AARCH64
250
static void raspi3ap_machine_class_init(ObjectClass *oc, void *data)
251
{
252
MachineClass *mc = MACHINE_CLASS(oc);
253
- RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc);
254
+ RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc);
255
256
rmc->board_rev = 0x9020e0; /* Revision 1.0 */
257
- raspi_machine_class_common_init(mc, rmc->board_rev);
258
+ raspi_machine_class_init(mc, rmc->board_rev);
259
};
260
261
static void raspi3b_machine_class_init(ObjectClass *oc, void *data)
262
{
263
MachineClass *mc = MACHINE_CLASS(oc);
264
- RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc);
265
+ RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc);
266
267
rmc->board_rev = 0xa02082;
268
- raspi_machine_class_common_init(mc, rmc->board_rev);
269
+ raspi_machine_class_init(mc, rmc->board_rev);
270
};
271
#endif /* TARGET_AARCH64 */
272
273
@@ -XXX,XX +XXX,XX @@ static const TypeInfo raspi_machine_types[] = {
274
#endif
275
}, {
276
.name = TYPE_RASPI_MACHINE,
277
- .parent = TYPE_MACHINE,
278
+ .parent = TYPE_RASPI_BASE_MACHINE,
279
.instance_size = sizeof(RaspiMachineState),
280
- .class_size = sizeof(RaspiMachineClass),
281
+ .abstract = true,
282
+ }, {
283
+ .name = TYPE_RASPI_BASE_MACHINE,
284
+ .parent = TYPE_MACHINE,
285
+ .instance_size = sizeof(RaspiBaseMachineState),
286
+ .class_size = sizeof(RaspiBaseMachineClass),
287
.abstract = true,
288
}
289
};
290
--
75
--
291
2.34.1
76
2.34.1
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add Micro 2Gb OSPI flash part with sfdp data.
3
Move the fractional comparison to the end of the
4
float_2nan_prop_x87 case. This is not required for
5
any other 2nan propagation rule. Reorganize the
6
x87 case itself to break out of the switch when the
7
fractional comparison is not required.
4
8
5
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20240220091721.82954-2-sai.pavan.boddu@amd.com
11
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
hw/block/m25p80_sfdp.h | 1 +
14
fpu/softfloat-parts.c.inc | 19 +++++++++----------
11
hw/block/m25p80.c | 3 +++
15
1 file changed, 9 insertions(+), 10 deletions(-)
12
hw/block/m25p80_sfdp.c | 36 ++++++++++++++++++++++++++++++++++++
13
3 files changed, 40 insertions(+)
14
16
15
diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/block/m25p80_sfdp.h
19
--- a/fpu/softfloat-parts.c.inc
18
+++ b/hw/block/m25p80_sfdp.h
20
+++ b/fpu/softfloat-parts.c.inc
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
20
#define M25P80_SFDP_MAX_SIZE (1 << 24)
22
return a;
21
23
}
22
uint8_t m25p80_sfdp_n25q256a(uint32_t addr);
24
23
+uint8_t m25p80_sfdp_mt35xu02g(uint32_t addr);
25
- cmp = frac_cmp(a, b);
24
26
- if (cmp == 0) {
25
uint8_t m25p80_sfdp_mx25l25635e(uint32_t addr);
27
- cmp = a->sign < b->sign;
26
uint8_t m25p80_sfdp_mx25l25635f(uint32_t addr);
28
- }
27
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
29
-
28
index XXXXXXX..XXXXXXX 100644
30
switch (s->float_2nan_prop_rule) {
29
--- a/hw/block/m25p80.c
31
case float_2nan_prop_s_ab:
30
+++ b/hw/block/m25p80.c
32
if (have_snan) {
31
@@ -XXX,XX +XXX,XX @@ static const FlashPartInfo known_devices[] = {
33
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
32
{ INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
34
* return the NaN with the positive sign bit (if any).
33
{ INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
35
*/
34
ER_4K | ER_32K, 2) },
36
if (is_snan(a->cls)) {
35
+ { INFO_STACKED("mt35xu02gbba", 0x2c5b1c, 0x104100, 128 << 10, 2048,
37
- if (is_snan(b->cls)) {
36
+ ER_4K | ER_32K, 4),
38
- which = cmp > 0 ? 0 : 1;
37
+ .sfdp_read = m25p80_sfdp_mt35xu02g },
39
- } else {
38
{ INFO_STACKED("n25q00", 0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
40
+ if (!is_snan(b->cls)) {
39
{ INFO_STACKED("n25q00a", 0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
41
which = is_qnan(b->cls) ? 1 : 0;
40
{ INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
42
+ break;
41
diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c
43
}
42
index XXXXXXX..XXXXXXX 100644
44
} else if (is_qnan(a->cls)) {
43
--- a/hw/block/m25p80_sfdp.c
45
if (is_snan(b->cls) || !is_qnan(b->cls)) {
44
+++ b/hw/block/m25p80_sfdp.c
46
which = 0;
45
@@ -XXX,XX +XXX,XX @@ static const uint8_t sfdp_n25q256a[] = {
47
- } else {
46
};
48
- which = cmp > 0 ? 0 : 1;
47
define_sfdp_read(n25q256a);
49
+ break;
48
50
}
49
+static const uint8_t sfdp_mt35xu02g[] = {
51
} else {
50
+ 0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x01, 0xff,
52
which = 1;
51
+ 0x00, 0x06, 0x01, 0x10, 0x30, 0x00, 0x00, 0xff,
53
+ break;
52
+ 0x84, 0x00, 0x01, 0x02, 0x80, 0x00, 0x00, 0xff,
54
}
53
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
55
+ cmp = frac_cmp(a, b);
54
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
56
+ if (cmp == 0) {
55
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
57
+ cmp = a->sign < b->sign;
56
+ 0xe5, 0x20, 0x8a, 0xff, 0xff, 0xff, 0xff, 0x7f,
58
+ }
57
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59
+ which = cmp > 0 ? 0 : 1;
58
+ 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
60
break;
59
+ 0xff, 0xff, 0x00, 0x00, 0x0c, 0x20, 0x11, 0xd8,
61
default:
60
+ 0x0f, 0x52, 0x00, 0x00, 0x24, 0x5a, 0x99, 0x00,
62
g_assert_not_reached();
61
+ 0x8b, 0x8e, 0x03, 0xe1, 0xac, 0x01, 0x27, 0x38,
62
+ 0x7a, 0x75, 0x7a, 0x75, 0xfb, 0xbd, 0xd5, 0x5c,
63
+ 0x00, 0x00, 0x70, 0xff, 0x81, 0xb0, 0x38, 0x36,
64
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
65
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
66
+ 0x43, 0x0e, 0xff, 0xff, 0x21, 0xdc, 0x5c, 0xff,
67
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
68
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
69
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
70
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
71
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
72
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
73
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
74
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
75
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
76
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
77
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
78
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
79
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
80
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
81
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
82
+};
83
+
84
+define_sfdp_read(mt35xu02g);
85
86
/*
87
* Matronix
88
--
63
--
89
2.34.1
64
2.34.1
diff view generated by jsdifflib
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This commit adds a QTest that verifies each input line of a specific
3
Replace the "index" selecting between A and B with a result variable
4
EXTI OR gate can influence the output line.
4
of the proper type. This improves clarity within the function.
5
5
6
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20240220184145.106107-3-ines.varhol@telecom-paris.fr
8
Message-id: 20241203203949.483774-12-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
tests/qtest/stm32l4x5_exti-test.c | 37 +++++++++++++++++++++++++++++++
11
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
12
1 file changed, 37 insertions(+)
12
1 file changed, 13 insertions(+), 15 deletions(-)
13
13
14
diff --git a/tests/qtest/stm32l4x5_exti-test.c b/tests/qtest/stm32l4x5_exti-test.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qtest/stm32l4x5_exti-test.c
16
--- a/fpu/softfloat-parts.c.inc
17
+++ b/tests/qtest/stm32l4x5_exti-test.c
17
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
19
19
float_status *s)
20
#define EXTI0_IRQ 6
20
{
21
#define EXTI1_IRQ 7
21
bool have_snan = false;
22
+#define EXTI5_9_IRQ 23
22
- int cmp, which;
23
#define EXTI35_IRQ 1
23
+ FloatPartsN *ret;
24
24
+ int cmp;
25
static void enable_nvic_irq(unsigned int n)
25
26
@@ -XXX,XX +XXX,XX @@ static void test_interrupt(void)
26
if (is_snan(a->cls) || is_snan(b->cls)) {
27
g_assert_false(check_nvic_pending(EXTI1_IRQ));
27
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
28
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
29
switch (s->float_2nan_prop_rule) {
30
case float_2nan_prop_s_ab:
31
if (have_snan) {
32
- which = is_snan(a->cls) ? 0 : 1;
33
+ ret = is_snan(a->cls) ? a : b;
34
break;
35
}
36
/* fall through */
37
case float_2nan_prop_ab:
38
- which = is_nan(a->cls) ? 0 : 1;
39
+ ret = is_nan(a->cls) ? a : b;
40
break;
41
case float_2nan_prop_s_ba:
42
if (have_snan) {
43
- which = is_snan(b->cls) ? 1 : 0;
44
+ ret = is_snan(b->cls) ? b : a;
45
break;
46
}
47
/* fall through */
48
case float_2nan_prop_ba:
49
- which = is_nan(b->cls) ? 1 : 0;
50
+ ret = is_nan(b->cls) ? b : a;
51
break;
52
case float_2nan_prop_x87:
53
/*
54
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
55
*/
56
if (is_snan(a->cls)) {
57
if (!is_snan(b->cls)) {
58
- which = is_qnan(b->cls) ? 1 : 0;
59
+ ret = is_qnan(b->cls) ? b : a;
60
break;
61
}
62
} else if (is_qnan(a->cls)) {
63
if (is_snan(b->cls) || !is_qnan(b->cls)) {
64
- which = 0;
65
+ ret = a;
66
break;
67
}
68
} else {
69
- which = 1;
70
+ ret = b;
71
break;
72
}
73
cmp = frac_cmp(a, b);
74
if (cmp == 0) {
75
cmp = a->sign < b->sign;
76
}
77
- which = cmp > 0 ? 0 : 1;
78
+ ret = cmp > 0 ? a : b;
79
break;
80
default:
81
g_assert_not_reached();
82
}
83
84
- if (which) {
85
- a = b;
86
+ if (is_snan(ret->cls)) {
87
+ parts_silence_nan(ret, s);
88
}
89
- if (is_snan(a->cls)) {
90
- parts_silence_nan(a, s);
91
- }
92
- return a;
93
+ return ret;
28
}
94
}
29
95
30
+static void test_orred_interrupts(void)
96
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
31
+{
32
+ /*
33
+ * For lines EXTI5..9 (fanned-in to NVIC irq 23),
34
+ * test that raising the line pends interrupt
35
+ * 23 in NVIC.
36
+ */
37
+ enable_nvic_irq(EXTI5_9_IRQ);
38
+ /* Check that there are no interrupts already pending in PR */
39
+ g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
40
+ /* Check that this specific interrupt isn't pending in NVIC */
41
+ g_assert_false(check_nvic_pending(EXTI5_9_IRQ));
42
+
43
+ /* Enable interrupt lines EXTI[5..9] */
44
+ exti_writel(EXTI_IMR1, (0x1F << 5));
45
+
46
+ /* Configure interrupt on rising edge */
47
+ exti_writel(EXTI_RTSR1, (0x1F << 5));
48
+
49
+ /* Raise GPIO line i, check that the interrupt is pending */
50
+ for (unsigned i = 5; i < 10; i++) {
51
+ exti_set_irq(i, 1);
52
+ g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 1 << i);
53
+ g_assert_true(check_nvic_pending(EXTI5_9_IRQ));
54
+
55
+ exti_writel(EXTI_PR1, 1 << i);
56
+ g_assert_cmpuint(exti_readl(EXTI_PR1), ==, 0x00000000);
57
+ g_assert_true(check_nvic_pending(EXTI5_9_IRQ));
58
+
59
+ unpend_nvic_irq(EXTI5_9_IRQ);
60
+ g_assert_false(check_nvic_pending(EXTI5_9_IRQ));
61
+ }
62
+}
63
+
64
int main(int argc, char **argv)
65
{
66
int ret;
67
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
68
qtest_add_func("stm32l4x5/exti/masked_interrupt", test_masked_interrupt);
69
qtest_add_func("stm32l4x5/exti/interrupt", test_interrupt);
70
qtest_add_func("stm32l4x5/exti/test_edge_selector", test_edge_selector);
71
+ qtest_add_func("stm32l4x5/exti/test_orred_interrupts",
72
+ test_orred_interrupts);
73
74
qtest_start("-machine b-l475e-iot01a");
75
ret = g_test_run();
76
--
97
--
77
2.34.1
98
2.34.1
78
99
79
100
diff view generated by jsdifflib
1
Implement a ResetContainer. This is a subclass of Object, and it
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
implements the Resettable interface. The container holds a list of
3
arbitrary other objects which implement Resettable, and when the
4
container is reset, all the objects it contains are also reset.
5
2
6
This will allow us to have a 3-phase-reset equivalent of the old
3
I'm migrating to Qualcomm's new open source email infrastructure, so
7
qemu_register_reset() API: we will have a single "simulation reset"
4
update my email address, and update the mailmap to match.
8
top level ResetContainer, and objects in it are the equivalent of the
9
old QEMUResetHandler functions.
10
5
11
The qemu_register_reset() API manages its list of callbacks using a
6
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
12
QTAILQ, but here we use a GPtrArray for our list of Resettable
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
13
children: we expect the "remove" operation (which will need to do an
8
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
14
iteration through the list) to be fairly uncommon, and we get simpler
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
code with fewer memory allocations.
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
11
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
17
Since there is currently no listed owner in MAINTAINERS for the
18
existing reset-related source files, create a new section for
19
them, and add these new files there also.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
25
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
26
Message-id: 20240220160622.114437-7-peter.maydell@linaro.org
27
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
28
---
13
---
29
MAINTAINERS | 10 +++++
14
MAINTAINERS | 2 +-
30
include/hw/core/resetcontainer.h | 48 ++++++++++++++++++++
15
.mailmap | 5 +++--
31
hw/core/resetcontainer.c | 77 ++++++++++++++++++++++++++++++++
16
2 files changed, 4 insertions(+), 3 deletions(-)
32
hw/core/meson.build | 1 +
33
4 files changed, 136 insertions(+)
34
create mode 100644 include/hw/core/resetcontainer.h
35
create mode 100644 hw/core/resetcontainer.c
36
17
37
diff --git a/MAINTAINERS b/MAINTAINERS
18
diff --git a/MAINTAINERS b/MAINTAINERS
38
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
39
--- a/MAINTAINERS
20
--- a/MAINTAINERS
40
+++ b/MAINTAINERS
21
+++ b/MAINTAINERS
41
@@ -XXX,XX +XXX,XX @@ F: hw/core/clock-vmstate.c
22
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
42
F: hw/core/qdev-clock.c
23
SBSA-REF
43
F: docs/devel/clocks.rst
24
M: Radoslaw Biernacki <rad@semihalf.com>
44
25
M: Peter Maydell <peter.maydell@linaro.org>
45
+Reset framework
26
-R: Leif Lindholm <quic_llindhol@quicinc.com>
46
+M: Peter Maydell <peter.maydell@linaro.org>
27
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
47
+S: Maintained
28
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
48
+F: include/hw/resettable.h
29
L: qemu-arm@nongnu.org
49
+F: include/hw/core/resetcontainer.h
30
S: Maintained
50
+F: include/sysemu/reset.h
31
diff --git a/.mailmap b/.mailmap
51
+F: hw/core/reset.c
52
+F: hw/core/resettable.c
53
+F: hw/core/resetcontainer.c
54
+
55
Usermode Emulation
56
------------------
57
Overall usermode emulation
58
diff --git a/include/hw/core/resetcontainer.h b/include/hw/core/resetcontainer.h
59
new file mode 100644
60
index XXXXXXX..XXXXXXX
61
--- /dev/null
62
+++ b/include/hw/core/resetcontainer.h
63
@@ -XXX,XX +XXX,XX @@
64
+/*
65
+ * Reset container
66
+ *
67
+ * Copyright (c) 2024 Linaro, Ltd
68
+ *
69
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
70
+ * See the COPYING file in the top-level directory.
71
+ */
72
+
73
+#ifndef HW_RESETCONTAINER_H
74
+#define HW_RESETCONTAINER_H
75
+
76
+/*
77
+ * The "reset container" is an object which implements the Resettable
78
+ * interface. It contains a list of arbitrary other objects which also
79
+ * implement Resettable. Resetting the reset container resets all the
80
+ * objects in it.
81
+ */
82
+
83
+#include "qom/object.h"
84
+
85
+#define TYPE_RESETTABLE_CONTAINER "resettable-container"
86
+OBJECT_DECLARE_TYPE(ResettableContainer, ResettableContainerClass, RESETTABLE_CONTAINER)
87
+
88
+/**
89
+ * resettable_container_add: Add a resettable object to the container
90
+ * @rc: container
91
+ * @obj: object to add to the container
92
+ *
93
+ * Add @obj to the ResettableContainer @rc. @obj must implement the
94
+ * Resettable interface.
95
+ *
96
+ * When @rc is reset, it will reset every object that has been added
97
+ * to it, in the order they were added.
98
+ */
99
+void resettable_container_add(ResettableContainer *rc, Object *obj);
100
+
101
+/**
102
+ * resettable_container_remove: Remove an object from the container
103
+ * @rc: container
104
+ * @obj: object to remove from the container
105
+ *
106
+ * Remove @obj from the ResettableContainer @rc. @obj must have been
107
+ * previously added to this container.
108
+ */
109
+void resettable_container_remove(ResettableContainer *rc, Object *obj);
110
+
111
+#endif
112
diff --git a/hw/core/resetcontainer.c b/hw/core/resetcontainer.c
113
new file mode 100644
114
index XXXXXXX..XXXXXXX
115
--- /dev/null
116
+++ b/hw/core/resetcontainer.c
117
@@ -XXX,XX +XXX,XX @@
118
+/*
119
+ * Reset container
120
+ *
121
+ * Copyright (c) 2024 Linaro, Ltd
122
+ *
123
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
124
+ * See the COPYING file in the top-level directory.
125
+ */
126
+
127
+/*
128
+ * The "reset container" is an object which implements the Resettable
129
+ * interface. It contains a list of arbitrary other objects which also
130
+ * implement Resettable. Resetting the reset container resets all the
131
+ * objects in it.
132
+ */
133
+
134
+#include "qemu/osdep.h"
135
+#include "hw/resettable.h"
136
+#include "hw/core/resetcontainer.h"
137
+
138
+struct ResettableContainer {
139
+ Object parent;
140
+ ResettableState reset_state;
141
+ GPtrArray *children;
142
+};
143
+
144
+OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(ResettableContainer, resettable_container, RESETTABLE_CONTAINER, OBJECT, { TYPE_RESETTABLE_INTERFACE }, { })
145
+
146
+void resettable_container_add(ResettableContainer *rc, Object *obj)
147
+{
148
+ INTERFACE_CHECK(void, obj, TYPE_RESETTABLE_INTERFACE);
149
+ g_ptr_array_add(rc->children, obj);
150
+}
151
+
152
+void resettable_container_remove(ResettableContainer *rc, Object *obj)
153
+{
154
+ g_ptr_array_remove(rc->children, obj);
155
+}
156
+
157
+static ResettableState *resettable_container_get_state(Object *obj)
158
+{
159
+ ResettableContainer *rc = RESETTABLE_CONTAINER(obj);
160
+ return &rc->reset_state;
161
+}
162
+
163
+static void resettable_container_child_foreach(Object *obj,
164
+ ResettableChildCallback cb,
165
+ void *opaque, ResetType type)
166
+{
167
+ ResettableContainer *rc = RESETTABLE_CONTAINER(obj);
168
+ unsigned int len = rc->children->len;
169
+
170
+ for (unsigned int i = 0; i < len; i++) {
171
+ cb(g_ptr_array_index(rc->children, i), opaque, type);
172
+ /* Detect callbacks trying to unregister themselves */
173
+ assert(len == rc->children->len);
174
+ }
175
+}
176
+
177
+static void resettable_container_init(Object *obj)
178
+{
179
+ ResettableContainer *rc = RESETTABLE_CONTAINER(obj);
180
+
181
+ rc->children = g_ptr_array_new();
182
+}
183
+
184
+static void resettable_container_finalize(Object *obj)
185
+{
186
+}
187
+
188
+static void resettable_container_class_init(ObjectClass *klass, void *data)
189
+{
190
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
191
+
192
+ rc->get_state = resettable_container_get_state;
193
+ rc->child_foreach = resettable_container_child_foreach;
194
+}
195
diff --git a/hw/core/meson.build b/hw/core/meson.build
196
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
197
--- a/hw/core/meson.build
33
--- a/.mailmap
198
+++ b/hw/core/meson.build
34
+++ b/.mailmap
199
@@ -XXX,XX +XXX,XX @@ hwcore_ss.add(files(
35
@@ -XXX,XX +XXX,XX @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
200
'qdev-properties.c',
36
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
201
'qdev.c',
37
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
202
'reset.c',
38
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
203
+ 'resetcontainer.c',
39
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
204
'resettable.c',
40
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
205
'vmstate-if.c',
41
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
206
# irq.c needed for qdev GPIO handling:
42
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
43
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
44
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
45
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
46
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
207
--
47
--
208
2.34.1
48
2.34.1
209
49
210
50
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
2
2
3
This code -- which was moved many times around -- was added in
3
Previously, maintainer role was paused due to inactive email id. Commit id:
4
commit 377e214539 ("ahci: Add allwinner AHCI") and belong to the
4
c009d715721861984c4987bcc78b7ee183e86d75.
5
AllWinner machines. See also commit dca625768a ("arm: allwinner-a10:
6
Add SATA").
7
5
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
9
Message-id: 20240215160713.80409-1-philmd@linaro.org
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
MAINTAINERS | 1 +
11
MAINTAINERS | 2 ++
13
1 file changed, 1 insertion(+)
12
1 file changed, 2 insertions(+)
14
13
15
diff --git a/MAINTAINERS b/MAINTAINERS
14
diff --git a/MAINTAINERS b/MAINTAINERS
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
16
--- a/MAINTAINERS
18
+++ b/MAINTAINERS
17
+++ b/MAINTAINERS
19
@@ -XXX,XX +XXX,XX @@ R: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
18
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-sb16-test.c
20
L: qemu-arm@nongnu.org
19
21
S: Odd Fixes
20
Xilinx CAN
22
F: hw/*/allwinner*
21
M: Francisco Iglesias <francisco.iglesias@amd.com>
23
+F: hw/ide/ahci-allwinner.c
22
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
24
F: include/hw/*/allwinner*
23
S: Maintained
25
F: hw/arm/cubieboard.c
24
F: hw/net/can/xlnx-*
26
F: docs/system/arm/cubieboard.rst
25
F: include/hw/net/xlnx-*
26
@@ -XXX,XX +XXX,XX @@ F: include/hw/rx/
27
CAN bus subsystem and hardware
28
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
29
M: Francisco Iglesias <francisco.iglesias@amd.com>
30
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
31
S: Maintained
32
W: https://canbus.pages.fel.cvut.cz/
33
F: net/can/*
27
--
34
--
28
2.34.1
35
2.34.1
29
30
diff view generated by jsdifflib