1
This pullreq has a few miscellaneous fixes, plus the
1
First arm pullreq of the cycle; this is mostly my softfloat NaN
2
non-controversial (and largely reviewed) parts of my
2
handling series. (Lots more in my to-review queue, but I don't
3
series removing deprecated arm boards. (The rest of that
3
like pullreqs growing too close to a hundred patches at a time :-))
4
series I will send out a v2 for once this lands.)
5
4
5
thanks
6
-- PMM
6
-- PMM
7
7
8
The following changes since commit 718780d20470c66a3a36d036b29148d5809dc855:
8
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
9
9
10
Merge tag 'pull-nvme-20241001' of https://gitlab.com/birkelund/qemu into staging (2024-10-01 11:34:07 +0100)
10
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
11
11
12
are available in the Git repository at:
12
are available in the Git repository at:
13
13
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241001
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
15
15
16
for you to fetch changes up to be025ce676d0f8fd094d17b34e87305a1c8fb595:
16
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
17
17
18
hw: Remove omap2 specific defines and enums (2024-10-01 16:08:02 +0100)
18
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
19
19
20
----------------------------------------------------------------
20
----------------------------------------------------------------
21
target-arm queue:
21
target-arm queue:
22
* MAINTAINERS: Update STM32L4x5 and B-L475E-IOT01A maintainers
22
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
23
* hw/arm/xlnx: Connect secondary CGEM IRQs
23
* fpu: Make muladd NaN handling runtime-selected, not compile-time
24
* m25p80: Add SFDP table for mt35xu01g flash
24
* fpu: Make default NaN pattern runtime-selected, not compile-time
25
* target/arm: Avoid target_ulong for physical address lookups
25
* fpu: Minor NaN-related cleanups
26
* hw/ssi/xilinx_spips: Fix flash erase assert in dual parallel configuration
26
* MAINTAINERS: email address updates
27
* hw: fix memory leak in IRQState allocation
28
* hw/sd/sdcard: Fix handling of disabled boot partitions
29
* arm: Remove deprecated board models
30
27
31
----------------------------------------------------------------
28
----------------------------------------------------------------
32
Ard Biesheuvel (1):
29
Bernhard Beschow (5):
33
target/arm: Avoid target_ulong for physical address lookups
30
hw/net/lan9118: Extract lan9118_phy
31
hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations
32
hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register
33
hw/net/lan9118_phy: Reuse MII constants
34
hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement
34
35
35
Inès Varhol (1):
36
Leif Lindholm (1):
36
MAINTAINERS: Update STM32L4x5 and B-L475E-IOT01A maintainers
37
MAINTAINERS: update email address for Leif Lindholm
37
38
38
Jan Luebbe (1):
39
Peter Maydell (54):
39
hw/sd/sdcard: Fix handling of disabled boot partitions
40
fpu: handle raising Invalid for infzero in pick_nan_muladd
41
fpu: Check for default_nan_mode before calling pickNaNMulAdd
42
softfloat: Allow runtime choice of inf * 0 + NaN result
43
tests/fp: Explicitly set inf-zero-nan rule
44
target/arm: Set FloatInfZeroNaNRule explicitly
45
target/s390: Set FloatInfZeroNaNRule explicitly
46
target/ppc: Set FloatInfZeroNaNRule explicitly
47
target/mips: Set FloatInfZeroNaNRule explicitly
48
target/sparc: Set FloatInfZeroNaNRule explicitly
49
target/xtensa: Set FloatInfZeroNaNRule explicitly
50
target/x86: Set FloatInfZeroNaNRule explicitly
51
target/loongarch: Set FloatInfZeroNaNRule explicitly
52
target/hppa: Set FloatInfZeroNaNRule explicitly
53
softfloat: Pass have_snan to pickNaNMulAdd
54
softfloat: Allow runtime choice of NaN propagation for muladd
55
tests/fp: Explicitly set 3-NaN propagation rule
56
target/arm: Set Float3NaNPropRule explicitly
57
target/loongarch: Set Float3NaNPropRule explicitly
58
target/ppc: Set Float3NaNPropRule explicitly
59
target/s390x: Set Float3NaNPropRule explicitly
60
target/sparc: Set Float3NaNPropRule explicitly
61
target/mips: Set Float3NaNPropRule explicitly
62
target/xtensa: Set Float3NaNPropRule explicitly
63
target/i386: Set Float3NaNPropRule explicitly
64
target/hppa: Set Float3NaNPropRule explicitly
65
fpu: Remove use_first_nan field from float_status
66
target/m68k: Don't pass NULL float_status to floatx80_default_nan()
67
softfloat: Create floatx80 default NaN from parts64_default_nan
68
target/loongarch: Use normal float_status in fclass_s and fclass_d helpers
69
target/m68k: In frem helper, initialize local float_status from env->fp_status
70
target/m68k: Init local float_status from env fp_status in gdb get/set reg
71
target/sparc: Initialize local scratch float_status from env->fp_status
72
target/ppc: Use env->fp_status in helper_compute_fprf functions
73
fpu: Allow runtime choice of default NaN value
74
tests/fp: Set default NaN pattern explicitly
75
target/microblaze: Set default NaN pattern explicitly
76
target/i386: Set default NaN pattern explicitly
77
target/hppa: Set default NaN pattern explicitly
78
target/alpha: Set default NaN pattern explicitly
79
target/arm: Set default NaN pattern explicitly
80
target/loongarch: Set default NaN pattern explicitly
81
target/m68k: Set default NaN pattern explicitly
82
target/mips: Set default NaN pattern explicitly
83
target/openrisc: Set default NaN pattern explicitly
84
target/ppc: Set default NaN pattern explicitly
85
target/sh4: Set default NaN pattern explicitly
86
target/rx: Set default NaN pattern explicitly
87
target/s390x: Set default NaN pattern explicitly
88
target/sparc: Set default NaN pattern explicitly
89
target/xtensa: Set default NaN pattern explicitly
90
target/hexagon: Set default NaN pattern explicitly
91
target/riscv: Set default NaN pattern explicitly
92
target/tricore: Set default NaN pattern explicitly
93
fpu: Remove default handling for dnan_pattern
40
94
41
Kinsey Moore (1):
95
Richard Henderson (11):
42
hw/arm/xlnx: Connect secondary CGEM IRQs
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
Matheus Tavares Bernardino (1):
108
Vikram Garhwal (1):
45
hw: fix memory leak in IRQState allocation
109
MAINTAINERS: Add correct email address for Vikram Garhwal
46
110
47
Peter Maydell (47):
111
MAINTAINERS | 4 +-
48
hw/arm: Remove deprecated akita, borzoi, spitz, terrier, tosa boards
112
include/fpu/softfloat-helpers.h | 38 +++-
49
hw/input: Drop ADS7846 device
113
include/fpu/softfloat-types.h | 89 +++++++-
50
hw/display: Remove tc6393xb device
114
include/hw/net/imx_fec.h | 9 +-
51
hw/arm/KConfig: Replace ZAURUS with ZAURUS_SCOOP
115
include/hw/net/lan9118_phy.h | 37 ++++
52
hw/arm: Remove 'cheetah' machine
116
include/hw/net/mii.h | 6 +
53
hw/arm: Remove 'connex' and 'verdex' machines
117
target/mips/fpu_helper.h | 20 ++
54
hw/arm: Remove 'mainstone' machine
118
target/sparc/helper.h | 4 +-
55
hw/misc: Remove MAINSTONE_FPGA device
119
fpu/softfloat.c | 19 ++
56
hw/arm: Remove 'z2' machine
120
hw/net/imx_fec.c | 146 ++------------
57
hw/arm: Remove STRONGARM->PXA2XX dependency
121
hw/net/lan9118.c | 137 ++-----------
58
hw/timer/pxa2xx_timer: Remove use of pxa.h header
122
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
59
hw/arm: Remove pxa2xx.c
123
linux-user/arm/nwfpe/fpa11.c | 5 +
60
hw/sd: Remove pxa2xx_mmci.c
124
target/alpha/cpu.c | 2 +
61
hw/input: Remove pxa2xx_keypad
125
target/arm/cpu.c | 10 +
62
hw/display: Remove pxa2xx_lcd.c
126
target/arm/tcg/vec_helper.c | 20 +-
63
hw/dma: Remove pxa2xx_dma
127
target/hexagon/cpu.c | 2 +
64
hw/pcmcia: Remove pxa2xx pcmcia device
128
target/hppa/fpu_helper.c | 12 ++
65
hw/arm: Remove pxa2xx_gpio
129
target/i386/tcg/fpu_helper.c | 12 ++
66
hw/arm: Remove pxa2xx_pic
130
target/loongarch/tcg/fpu_helper.c | 14 +-
67
hw/timer: Remove pxa27x-timer
131
target/m68k/cpu.c | 14 +-
68
hw/arm: Remove 'n800' and 'n810' machines
132
target/m68k/fpu_helper.c | 6 +-
69
hw/misc: Remove cbus
133
target/m68k/helper.c | 6 +-
70
hw/display: Remove Blizzard display device
134
target/microblaze/cpu.c | 2 +
71
hw/input: Remove tsc2005 touchscreen controller
135
target/mips/msa.c | 10 +
72
hw/input: Remove tsc210x device
136
target/openrisc/cpu.c | 2 +
73
hw/rtc: Remove twl92230 device
137
target/ppc/cpu_init.c | 19 ++
74
hw/input: Remove lm832x device
138
target/ppc/fpu_helper.c | 3 +-
75
hw/block: Remove OneNAND device
139
target/riscv/cpu.c | 2 +
76
hw/usb: Remove tusb6010 USB controller
140
target/rx/cpu.c | 2 +
77
hw/usb: Remove MUSB USB host controller
141
target/s390x/cpu.c | 5 +
78
docs: Document removal of old Arm boards
142
target/sh4/cpu.c | 2 +
79
hw/arm: Remove omap2.c
143
target/sparc/cpu.c | 6 +
80
hw/gpio: Remove TYPE_OMAP2_GPIO
144
target/sparc/fop_helper.c | 8 +-
81
hw/char: Remove omap2_uart
145
target/sparc/translate.c | 4 +-
82
hw/intc: Remove omap2-intc device
146
target/tricore/helper.c | 2 +
83
hw/sd: Remove omap2_mmc device
147
target/xtensa/cpu.c | 4 +
84
hw/misc: Remove omap_sdrc device
148
target/xtensa/fpu_helper.c | 3 +-
85
hw/misc: Remove omap_gpmc
149
tests/fp/fp-bench.c | 7 +
86
hw/timer: Remove omap_gptimer
150
tests/fp/fp-test-log2.c | 1 +
87
hw/timer: Remove omap_synctimer
151
tests/fp/fp-test.c | 7 +
88
hw/ssi: Remove omap_mcspi
152
fpu/softfloat-parts.c.inc | 152 +++++++++++---
89
hw/misc: Remove omap_tap device
153
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
90
hw/display: Remove omap_dss
154
.mailmap | 5 +-
91
hw/misc: Remove omap_l4 device
155
hw/net/Kconfig | 5 +
92
hw/misc/omap_clk: Remove OMAP2-specifics
156
hw/net/meson.build | 1 +
93
hw/dma: Remove omap_dma4 device
157
hw/net/trace-events | 10 +-
94
hw: Remove omap2 specific defines and enums
158
47 files changed, 778 insertions(+), 730 deletions(-)
95
159
create mode 100644 include/hw/net/lan9118_phy.h
96
Shiva sagar Myana (2):
160
create mode 100644 hw/net/lan9118_phy.c
97
m25p80: Add SFDP table for mt35xu01g flash
98
hw/ssi/xilinx_spips: Fix flash erase assert in dual parallel configuration
99
100
MAINTAINERS | 99 +-
101
docs/about/deprecated.rst | 15 -
102
docs/about/removed-features.rst | 14 +
103
docs/system/arm/gumstix.rst | 21 -
104
docs/system/arm/mainstone.rst | 25 -
105
docs/system/arm/nseries.rst | 33 -
106
docs/system/arm/palm.rst | 23 -
107
docs/system/arm/xscale.rst | 35 -
108
docs/system/target-arm.rst | 5 -
109
configs/devices/arm-softmmu/default.mak | 7 -
110
hw/block/m25p80_sfdp.h | 1 +
111
include/hw/arm/omap.h | 350 +---
112
include/hw/arm/pxa.h | 197 ---
113
include/hw/arm/xlnx-versal.h | 1 +
114
include/hw/arm/xlnx-zynqmp.h | 1 +
115
include/hw/block/flash.h | 3 -
116
include/hw/display/blizzard.h | 21 -
117
include/hw/display/tc6393xb.h | 21 -
118
include/hw/input/lm832x.h | 28 -
119
include/hw/input/tsc2xxx.h | 41 -
120
include/hw/misc/cbus.h | 31 -
121
include/hw/usb/hcd-musb.h | 49 -
122
target/arm/internals.h | 4 +-
123
hw/arm/gumstix.c | 141 --
124
hw/arm/mainstone.c | 175 --
125
hw/arm/nseries.c | 1473 -----------------
126
hw/arm/omap2.c | 2715 -------------------------------
127
hw/arm/palm.c | 324 ----
128
hw/arm/pxa2xx.c | 2393 ---------------------------
129
hw/arm/pxa2xx_gpio.c | 365 -----
130
hw/arm/pxa2xx_pic.c | 359 ----
131
hw/arm/spitz.c | 1284 ---------------
132
hw/arm/tosa.c | 327 ----
133
hw/arm/xlnx-versal.c | 12 +-
134
hw/arm/xlnx-zynqmp.c | 11 +-
135
hw/arm/z2.c | 355 ----
136
hw/block/m25p80.c | 3 +-
137
hw/block/m25p80_sfdp.c | 37 +
138
hw/block/onenand.c | 872 ----------
139
hw/char/omap_uart.c | 113 --
140
hw/core/irq.c | 19 +-
141
hw/display/blizzard.c | 1026 ------------
142
hw/display/omap_dss.c | 1093 -------------
143
hw/display/pxa2xx_lcd.c | 1451 -----------------
144
hw/display/tc6393xb.c | 568 -------
145
hw/dma/omap_dma.c | 451 +----
146
hw/dma/pxa2xx_dma.c | 591 -------
147
hw/gpio/omap_gpio.c | 557 -------
148
hw/input/ads7846.c | 186 ---
149
hw/input/lm832x.c | 528 ------
150
hw/input/pxa2xx_keypad.c | 331 ----
151
hw/input/tsc2005.c | 571 -------
152
hw/input/tsc210x.c | 1241 --------------
153
hw/intc/omap_intc.c | 276 ----
154
hw/misc/cbus.c | 619 -------
155
hw/misc/mst_fpga.c | 269 ---
156
hw/misc/omap_clk.c | 527 +-----
157
hw/misc/omap_gpmc.c | 898 ----------
158
hw/misc/omap_l4.c | 162 --
159
hw/misc/omap_sdrc.c | 167 --
160
hw/misc/omap_tap.c | 117 --
161
hw/pcmcia/pxa2xx.c | 248 ---
162
hw/rtc/twl92230.c | 882 ----------
163
hw/sd/omap_mmc.c | 63 -
164
hw/sd/pxa2xx_mmci.c | 594 -------
165
hw/sd/sd.c | 7 -
166
hw/ssi/omap_spi.c | 380 -----
167
hw/ssi/xilinx_spips.c | 4 +-
168
hw/timer/omap_gptimer.c | 512 ------
169
hw/timer/omap_synctimer.c | 110 --
170
hw/timer/pxa2xx_timer.c | 25 -
171
hw/usb/hcd-musb.c | 1553 ------------------
172
hw/usb/tusb6010.c | 850 ----------
173
target/arm/ptw.c | 16 +-
174
tests/qtest/libqos/arm-n800-machine.c | 92 --
175
hw/arm/Kconfig | 89 +-
176
hw/arm/meson.build | 9 -
177
hw/block/Kconfig | 3 -
178
hw/block/meson.build | 1 -
179
hw/display/Kconfig | 3 -
180
hw/display/meson.build | 4 -
181
hw/dma/meson.build | 1 -
182
hw/gpio/Kconfig | 3 +
183
hw/gpio/meson.build | 2 +-
184
hw/input/Kconfig | 13 -
185
hw/input/meson.build | 5 -
186
hw/input/trace-events | 3 -
187
hw/misc/meson.build | 6 -
188
hw/pcmcia/meson.build | 1 -
189
hw/rtc/Kconfig | 4 -
190
hw/rtc/meson.build | 1 -
191
hw/sd/meson.build | 1 -
192
hw/sd/trace-events | 4 -
193
hw/ssi/meson.build | 1 -
194
hw/timer/Kconfig | 3 +
195
hw/timer/meson.build | 4 +-
196
hw/usb/Kconfig | 8 -
197
hw/usb/meson.build | 2 -
198
tests/avocado/machine_arm_n8x0.py | 49 -
199
tests/qtest/libqos/meson.build | 1 -
200
100 files changed, 146 insertions(+), 29043 deletions(-)
201
delete mode 100644 docs/system/arm/gumstix.rst
202
delete mode 100644 docs/system/arm/mainstone.rst
203
delete mode 100644 docs/system/arm/nseries.rst
204
delete mode 100644 docs/system/arm/palm.rst
205
delete mode 100644 docs/system/arm/xscale.rst
206
delete mode 100644 include/hw/arm/pxa.h
207
delete mode 100644 include/hw/display/blizzard.h
208
delete mode 100644 include/hw/display/tc6393xb.h
209
delete mode 100644 include/hw/input/lm832x.h
210
delete mode 100644 include/hw/input/tsc2xxx.h
211
delete mode 100644 include/hw/misc/cbus.h
212
delete mode 100644 include/hw/usb/hcd-musb.h
213
delete mode 100644 hw/arm/gumstix.c
214
delete mode 100644 hw/arm/mainstone.c
215
delete mode 100644 hw/arm/nseries.c
216
delete mode 100644 hw/arm/omap2.c
217
delete mode 100644 hw/arm/palm.c
218
delete mode 100644 hw/arm/pxa2xx.c
219
delete mode 100644 hw/arm/pxa2xx_gpio.c
220
delete mode 100644 hw/arm/pxa2xx_pic.c
221
delete mode 100644 hw/arm/spitz.c
222
delete mode 100644 hw/arm/tosa.c
223
delete mode 100644 hw/arm/z2.c
224
delete mode 100644 hw/block/onenand.c
225
delete mode 100644 hw/display/blizzard.c
226
delete mode 100644 hw/display/omap_dss.c
227
delete mode 100644 hw/display/pxa2xx_lcd.c
228
delete mode 100644 hw/display/tc6393xb.c
229
delete mode 100644 hw/dma/pxa2xx_dma.c
230
delete mode 100644 hw/input/ads7846.c
231
delete mode 100644 hw/input/lm832x.c
232
delete mode 100644 hw/input/pxa2xx_keypad.c
233
delete mode 100644 hw/input/tsc2005.c
234
delete mode 100644 hw/input/tsc210x.c
235
delete mode 100644 hw/misc/cbus.c
236
delete mode 100644 hw/misc/mst_fpga.c
237
delete mode 100644 hw/misc/omap_gpmc.c
238
delete mode 100644 hw/misc/omap_l4.c
239
delete mode 100644 hw/misc/omap_sdrc.c
240
delete mode 100644 hw/misc/omap_tap.c
241
delete mode 100644 hw/pcmcia/pxa2xx.c
242
delete mode 100644 hw/rtc/twl92230.c
243
delete mode 100644 hw/sd/pxa2xx_mmci.c
244
delete mode 100644 hw/ssi/omap_spi.c
245
delete mode 100644 hw/timer/omap_gptimer.c
246
delete mode 100644 hw/timer/omap_synctimer.c
247
delete mode 100644 hw/usb/hcd-musb.c
248
delete mode 100644 hw/usb/tusb6010.c
249
delete mode 100644 tests/qtest/libqos/arm-n800-machine.c
250
delete mode 100755 tests/avocado/machine_arm_n8x0.py
251
diff view generated by jsdifflib
1
All the callers of pxa270_init() and pxa255_init() have now been removed,
1
From: Bernhard Beschow <shentey@gmail.com>
2
so we can remove pxa2xx.c. This also removes the only uses of a lot of
3
pxa2xx specific devices, which will be removed in subsequent commits.
4
2
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>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Message-id: 20241102125724.532843-2-shentey@gmail.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20240903160751.4100218-16-peter.maydell@linaro.org
9
---
22
---
10
include/hw/arm/pxa.h | 78 --
23
include/hw/net/lan9118_phy.h | 37 ++++++++
11
hw/arm/pxa2xx.c | 2393 ------------------------------------------
24
hw/net/lan9118.c | 137 +++++-----------------------
12
hw/arm/meson.build | 2 +-
25
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
13
3 files changed, 1 insertion(+), 2472 deletions(-)
26
hw/net/Kconfig | 4 +
14
delete mode 100644 hw/arm/pxa2xx.c
27
hw/net/meson.build | 1 +
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
15
31
16
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
32
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/hw/net/lan9118_phy.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * SMSC LAN9118 PHY emulation
40
+ *
41
+ * Copyright (c) 2009 CodeSourcery, LLC.
42
+ * Written by Paul Brook
43
+ *
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
45
+ * See the COPYING file in the top-level directory.
46
+ */
47
+
48
+#ifndef HW_NET_LAN9118_PHY_H
49
+#define HW_NET_LAN9118_PHY_H
50
+
51
+#include "qom/object.h"
52
+#include "hw/sysbus.h"
53
+
54
+#define TYPE_LAN9118_PHY "lan9118-phy"
55
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
56
+
57
+typedef struct Lan9118PhyState {
58
+ SysBusDevice parent_obj;
59
+
60
+ uint16_t status;
61
+ uint16_t control;
62
+ uint16_t advertise;
63
+ uint16_t ints;
64
+ uint16_t int_mask;
65
+ qemu_irq irq;
66
+ bool link_down;
67
+} Lan9118PhyState;
68
+
69
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down);
70
+void lan9118_phy_reset(Lan9118PhyState *s);
71
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg);
72
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val);
73
+
74
+#endif
75
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
17
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/pxa.h
77
--- a/hw/net/lan9118.c
19
+++ b/include/hw/arm/pxa.h
78
+++ b/hw/net/lan9118.c
20
@@ -XXX,XX +XXX,XX @@ PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem,
21
void pxa27x_register_keypad(PXA2xxKeyPadState *kp,
22
const struct keymap *map, int size);
23
24
-/* pxa2xx.c */
25
-#define TYPE_PXA2XX_I2C "pxa2xx_i2c"
26
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxI2CState, PXA2XX_I2C)
27
-
28
-PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
29
- qemu_irq irq, uint32_t page_size);
30
-I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s);
31
-
32
-typedef struct PXA2xxI2SState PXA2xxI2SState;
33
-
34
-#define TYPE_PXA2XX_FIR "pxa2xx-fir"
35
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxFIrState, PXA2XX_FIR)
36
-
37
-typedef struct {
38
- ARMCPU *cpu;
39
- DeviceState *pic;
40
- qemu_irq reset;
41
- MemoryRegion sdram;
42
- MemoryRegion internal;
43
- MemoryRegion cm_iomem;
44
- MemoryRegion mm_iomem;
45
- MemoryRegion pm_iomem;
46
- DeviceState *dma;
47
- DeviceState *gpio;
48
- PXA2xxLCDState *lcd;
49
- SSIBus **ssp;
50
- PXA2xxI2CState *i2c[2];
51
- PXA2xxMMCIState *mmc;
52
- PXA2xxPCMCIAState *pcmcia[2];
53
- PXA2xxI2SState *i2s;
54
- PXA2xxFIrState *fir;
55
- PXA2xxKeyPadState *kp;
56
-
57
- /* Power management */
58
- hwaddr pm_base;
59
- uint32_t pm_regs[0x40];
60
-
61
- /* Clock management */
62
- hwaddr cm_base;
63
- uint32_t cm_regs[4];
64
- uint32_t clkcfg;
65
-
66
- /* Memory management */
67
- hwaddr mm_base;
68
- uint32_t mm_regs[0x1a];
69
-
70
- /* Performance monitoring */
71
- uint32_t pmnc;
72
-} PXA2xxState;
73
-
74
-struct PXA2xxI2SState {
75
- MemoryRegion iomem;
76
- qemu_irq irq;
77
- qemu_irq rx_dma;
78
- qemu_irq tx_dma;
79
- void (*data_req)(void *, int, int);
80
-
81
- uint32_t control[2];
82
- uint32_t status;
83
- uint32_t mask;
84
- uint32_t clk;
85
-
86
- int enable;
87
- int rx_len;
88
- int tx_len;
89
- void (*codec_out)(void *, uint32_t);
90
- uint32_t (*codec_in)(void *);
91
- void *opaque;
92
-
93
- int fifo_len;
94
- uint32_t fifo[16];
95
-};
96
-
97
-# define PA_FMT            "0x%08lx"
98
-
99
-PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision);
100
-PXA2xxState *pxa255_init(unsigned int sdram_size);
101
-
102
#endif /* PXA_H */
103
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
104
deleted file mode 100644
105
index XXXXXXX..XXXXXXX
106
--- a/hw/arm/pxa2xx.c
107
+++ /dev/null
108
@@ -XXX,XX +XXX,XX @@
79
@@ -XXX,XX +XXX,XX @@
109
-/*
80
#include "net/net.h"
110
- * Intel XScale PXA255/270 processor support.
81
#include "net/eth.h"
111
- *
82
#include "hw/irq.h"
112
- * Copyright (c) 2006 Openedhand Ltd.
83
+#include "hw/net/lan9118_phy.h"
113
- * Written by Andrzej Zaborowski <balrog@zabor.org>
84
#include "hw/net/lan9118.h"
114
- *
85
#include "hw/ptimer.h"
115
- * This code is licensed under the GPL.
86
#include "hw/qdev-properties.h"
116
- */
87
@@ -XXX,XX +XXX,XX @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
117
-
88
#define MAC_CR_RXEN 0x00000004
118
-#include "qemu/osdep.h"
89
#define MAC_CR_RESERVED 0x7f404213
119
-#include "qemu/error-report.h"
90
120
-#include "qemu/module.h"
91
-#define PHY_INT_ENERGYON 0x80
121
-#include "qapi/error.h"
92
-#define PHY_INT_AUTONEG_COMPLETE 0x40
122
-#include "exec/address-spaces.h"
93
-#define PHY_INT_FAULT 0x20
123
-#include "cpu.h"
94
-#define PHY_INT_DOWN 0x10
124
-#include "hw/sysbus.h"
95
-#define PHY_INT_AUTONEG_LP 0x08
125
-#include "migration/vmstate.h"
96
-#define PHY_INT_PARFAULT 0x04
126
-#include "hw/arm/pxa.h"
97
-#define PHY_INT_AUTONEG_PAGE 0x02
127
-#include "sysemu/sysemu.h"
98
-
128
-#include "hw/char/serial.h"
99
#define GPT_TIMER_EN 0x20000000
129
-#include "hw/i2c/i2c.h"
100
130
-#include "hw/irq.h"
101
/*
131
-#include "hw/qdev-properties.h"
102
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
132
-#include "hw/qdev-properties-system.h"
103
uint32_t mac_mii_data;
133
-#include "hw/ssi/ssi.h"
104
uint32_t mac_flow;
134
-#include "hw/sd/sd.h"
105
135
-#include "chardev/char-fe.h"
106
- uint32_t phy_status;
136
-#include "sysemu/blockdev.h"
107
- uint32_t phy_control;
137
-#include "sysemu/qtest.h"
108
- uint32_t phy_advertise;
138
-#include "sysemu/rtc.h"
109
- uint32_t phy_int;
139
-#include "qemu/cutils.h"
110
- uint32_t phy_int_mask;
140
-#include "qemu/log.h"
111
+ Lan9118PhyState mii;
141
-#include "qom/object.h"
112
+ IRQState mii_irq;
142
-#include "target/arm/cpregs.h"
113
143
-
114
int32_t eeprom_writable;
144
-static struct {
115
uint8_t eeprom[128];
145
- hwaddr io_base;
116
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
146
- int irqn;
117
147
-} pxa255_serial[] = {
118
static const VMStateDescription vmstate_lan9118 = {
148
- { 0x40100000, PXA2XX_PIC_FFUART },
119
.name = "lan9118",
149
- { 0x40200000, PXA2XX_PIC_BTUART },
120
- .version_id = 2,
150
- { 0x40700000, PXA2XX_PIC_STUART },
121
- .minimum_version_id = 1,
151
- { 0x41600000, PXA25X_PIC_HWUART },
122
+ .version_id = 3,
152
- { 0, 0 }
123
+ .minimum_version_id = 3,
153
-}, pxa270_serial[] = {
124
.fields = (const VMStateField[]) {
154
- { 0x40100000, PXA2XX_PIC_FFUART },
125
VMSTATE_PTIMER(timer, lan9118_state),
155
- { 0x40200000, PXA2XX_PIC_BTUART },
126
VMSTATE_UINT32(irq_cfg, lan9118_state),
156
- { 0x40700000, PXA2XX_PIC_STUART },
127
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118 = {
157
- { 0, 0 }
128
VMSTATE_UINT32(mac_mii_acc, lan9118_state),
158
-};
129
VMSTATE_UINT32(mac_mii_data, lan9118_state),
159
-
130
VMSTATE_UINT32(mac_flow, lan9118_state),
160
-typedef struct PXASSPDef {
131
- VMSTATE_UINT32(phy_status, lan9118_state),
161
- hwaddr io_base;
132
- VMSTATE_UINT32(phy_control, lan9118_state),
162
- int irqn;
133
- VMSTATE_UINT32(phy_advertise, lan9118_state),
163
-} PXASSPDef;
134
- VMSTATE_UINT32(phy_int, lan9118_state),
164
-
135
- VMSTATE_UINT32(phy_int_mask, lan9118_state),
165
-#if 0
136
VMSTATE_INT32(eeprom_writable, lan9118_state),
166
-static PXASSPDef pxa250_ssp[] = {
137
VMSTATE_UINT8_ARRAY(eeprom, lan9118_state, 128),
167
- { 0x41000000, PXA2XX_PIC_SSP },
138
VMSTATE_INT32(tx_fifo_size, lan9118_state),
168
- { 0, 0 }
139
@@ -XXX,XX +XXX,XX @@ static void lan9118_reload_eeprom(lan9118_state *s)
169
-};
140
lan9118_mac_changed(s);
170
-#endif
141
}
171
-
142
172
-static PXASSPDef pxa255_ssp[] = {
143
-static void phy_update_irq(lan9118_state *s)
173
- { 0x41000000, PXA2XX_PIC_SSP },
144
+static void lan9118_update_irq(void *opaque, int n, int level)
174
- { 0x41400000, PXA25X_PIC_NSSP },
145
{
175
- { 0, 0 }
146
- if (s->phy_int & s->phy_int_mask) {
176
-};
147
+ lan9118_state *s = opaque;
177
-
148
+
178
-#if 0
149
+ if (level) {
179
-static PXASSPDef pxa26x_ssp[] = {
150
s->int_sts |= PHY_INT;
180
- { 0x41000000, PXA2XX_PIC_SSP },
151
} else {
181
- { 0x41400000, PXA25X_PIC_NSSP },
152
s->int_sts &= ~PHY_INT;
182
- { 0x41500000, PXA26X_PIC_ASSP },
153
@@ -XXX,XX +XXX,XX @@ static void phy_update_irq(lan9118_state *s)
183
- { 0, 0 }
154
lan9118_update(s);
184
-};
155
}
185
-#endif
156
186
-
157
-static void phy_update_link(lan9118_state *s)
187
-static PXASSPDef pxa27x_ssp[] = {
188
- { 0x41000000, PXA2XX_PIC_SSP },
189
- { 0x41700000, PXA27X_PIC_SSP2 },
190
- { 0x41900000, PXA2XX_PIC_SSP3 },
191
- { 0, 0 }
192
-};
193
-
194
-#define PMCR    0x00    /* Power Manager Control register */
195
-#define PSSR    0x04    /* Power Manager Sleep Status register */
196
-#define PSPR    0x08    /* Power Manager Scratch-Pad register */
197
-#define PWER    0x0c    /* Power Manager Wake-Up Enable register */
198
-#define PRER    0x10    /* Power Manager Rising-Edge Detect Enable register */
199
-#define PFER    0x14    /* Power Manager Falling-Edge Detect Enable register */
200
-#define PEDR    0x18    /* Power Manager Edge-Detect Status register */
201
-#define PCFR    0x1c    /* Power Manager General Configuration register */
202
-#define PGSR0    0x20    /* Power Manager GPIO Sleep-State register 0 */
203
-#define PGSR1    0x24    /* Power Manager GPIO Sleep-State register 1 */
204
-#define PGSR2    0x28    /* Power Manager GPIO Sleep-State register 2 */
205
-#define PGSR3    0x2c    /* Power Manager GPIO Sleep-State register 3 */
206
-#define RCSR    0x30    /* Reset Controller Status register */
207
-#define PSLR    0x34    /* Power Manager Sleep Configuration register */
208
-#define PTSR    0x38    /* Power Manager Standby Configuration register */
209
-#define PVCR    0x40    /* Power Manager Voltage Change Control register */
210
-#define PUCR    0x4c    /* Power Manager USIM Card Control/Status register */
211
-#define PKWR    0x50    /* Power Manager Keyboard Wake-Up Enable register */
212
-#define PKSR    0x54    /* Power Manager Keyboard Level-Detect Status */
213
-#define PCMD0    0x80    /* Power Manager I2C Command register File 0 */
214
-#define PCMD31    0xfc    /* Power Manager I2C Command register File 31 */
215
-
216
-static uint64_t pxa2xx_pm_read(void *opaque, hwaddr addr,
217
- unsigned size)
218
-{
158
-{
219
- PXA2xxState *s = (PXA2xxState *) opaque;
159
- /* Autonegotiation status mirrors link status. */
220
-
160
- if (qemu_get_queue(s->nic)->link_down) {
221
- switch (addr) {
161
- s->phy_status &= ~0x0024;
222
- case PMCR ... PCMD31:
162
- s->phy_int |= PHY_INT_DOWN;
223
- if (addr & 3)
163
- } else {
224
- goto fail;
164
- s->phy_status |= 0x0024;
225
-
165
- s->phy_int |= PHY_INT_ENERGYON;
226
- return s->pm_regs[addr >> 2];
166
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
227
- default:
228
- fail:
229
- qemu_log_mask(LOG_GUEST_ERROR,
230
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
231
- __func__, addr);
232
- break;
233
- }
167
- }
234
- return 0;
168
- phy_update_irq(s);
235
-}
169
-}
236
-
170
-
237
-static void pxa2xx_pm_write(void *opaque, hwaddr addr,
171
static void lan9118_set_link(NetClientState *nc)
238
- uint64_t value, unsigned size)
172
{
173
- phy_update_link(qemu_get_nic_opaque(nc));
174
-}
175
-
176
-static void phy_reset(lan9118_state *s)
239
-{
177
-{
240
- PXA2xxState *s = (PXA2xxState *) opaque;
178
- s->phy_status = 0x7809;
241
-
179
- s->phy_control = 0x3000;
242
- switch (addr) {
180
- s->phy_advertise = 0x01e1;
243
- case PMCR:
181
- s->phy_int_mask = 0;
244
- /* Clear the write-one-to-clear bits... */
182
- s->phy_int = 0;
245
- s->pm_regs[addr >> 2] &= ~(value & 0x2a);
183
- phy_update_link(s);
246
- /* ...and set the plain r/w bits */
184
+ lan9118_phy_update_link(&LAN9118(qemu_get_nic_opaque(nc))->mii,
247
- s->pm_regs[addr >> 2] &= ~0x15;
185
+ nc->link_down);
248
- s->pm_regs[addr >> 2] |= value & 0x15;
186
}
249
- break;
187
250
-
188
static void lan9118_reset(DeviceState *d)
251
- case PSSR:    /* Read-clean registers */
189
@@ -XXX,XX +XXX,XX @@ static void lan9118_reset(DeviceState *d)
252
- case RCSR:
190
s->read_word_n = 0;
253
- case PKSR:
191
s->write_word_n = 0;
254
- s->pm_regs[addr >> 2] &= ~value;
192
255
- break;
193
- phy_reset(s);
256
-
194
-
257
- default:    /* Read-write registers */
195
s->eeprom_writable = 0;
258
- if (!(addr & 3)) {
196
lan9118_reload_eeprom(s);
259
- s->pm_regs[addr >> 2] = value;
197
}
260
- break;
198
@@ -XXX,XX +XXX,XX @@ static void do_tx_packet(lan9118_state *s)
261
- }
199
uint32_t status;
262
- qemu_log_mask(LOG_GUEST_ERROR,
200
263
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
201
/* FIXME: Honor TX disable, and allow queueing of packets. */
264
- __func__, addr);
202
- if (s->phy_control & 0x4000) {
265
- break;
203
+ if (s->mii.control & 0x4000) {
266
- }
204
/* This assumes the receive routine doesn't touch the VLANClient. */
267
-}
205
qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
268
-
206
} else {
269
-static const MemoryRegionOps pxa2xx_pm_ops = {
207
@@ -XXX,XX +XXX,XX @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
270
- .read = pxa2xx_pm_read,
208
}
271
- .write = pxa2xx_pm_write,
209
}
272
- .endianness = DEVICE_NATIVE_ENDIAN,
210
273
-};
211
-static uint32_t do_phy_read(lan9118_state *s, int reg)
274
-
275
-static const VMStateDescription vmstate_pxa2xx_pm = {
276
- .name = "pxa2xx_pm",
277
- .version_id = 0,
278
- .minimum_version_id = 0,
279
- .fields = (const VMStateField[]) {
280
- VMSTATE_UINT32_ARRAY(pm_regs, PXA2xxState, 0x40),
281
- VMSTATE_END_OF_LIST()
282
- }
283
-};
284
-
285
-#define CCCR    0x00    /* Core Clock Configuration register */
286
-#define CKEN    0x04    /* Clock Enable register */
287
-#define OSCC    0x08    /* Oscillator Configuration register */
288
-#define CCSR    0x0c    /* Core Clock Status register */
289
-
290
-static uint64_t pxa2xx_cm_read(void *opaque, hwaddr addr,
291
- unsigned size)
292
-{
212
-{
293
- PXA2xxState *s = (PXA2xxState *) opaque;
213
- uint32_t val;
294
-
214
-
295
- switch (addr) {
215
- switch (reg) {
296
- case CCCR:
216
- case 0: /* Basic Control */
297
- case CKEN:
217
- return s->phy_control;
298
- case OSCC:
218
- case 1: /* Basic Status */
299
- return s->cm_regs[addr >> 2];
219
- return s->phy_status;
300
-
220
- case 2: /* ID1 */
301
- case CCSR:
221
- return 0x0007;
302
- return s->cm_regs[CCCR >> 2] | (3 << 28);
222
- case 3: /* ID2 */
303
-
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;
304
- default:
238
- default:
305
- qemu_log_mask(LOG_GUEST_ERROR,
239
- qemu_log_mask(LOG_GUEST_ERROR,
306
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
240
- "do_phy_read: PHY read reg %d\n", reg);
307
- __func__, addr);
308
- break;
309
- }
310
- return 0;
311
-}
312
-
313
-static void pxa2xx_cm_write(void *opaque, hwaddr addr,
314
- uint64_t value, unsigned size)
315
-{
316
- PXA2xxState *s = (PXA2xxState *) opaque;
317
-
318
- switch (addr) {
319
- case CCCR:
320
- case CKEN:
321
- s->cm_regs[addr >> 2] = value;
322
- break;
323
-
324
- case OSCC:
325
- s->cm_regs[addr >> 2] &= ~0x6c;
326
- s->cm_regs[addr >> 2] |= value & 0x6e;
327
- if ((value >> 1) & 1)            /* OON */
328
- s->cm_regs[addr >> 2] |= 1 << 0;    /* Oscillator is now stable */
329
- break;
330
-
331
- default:
332
- qemu_log_mask(LOG_GUEST_ERROR,
333
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
334
- __func__, addr);
335
- break;
336
- }
337
-}
338
-
339
-static const MemoryRegionOps pxa2xx_cm_ops = {
340
- .read = pxa2xx_cm_read,
341
- .write = pxa2xx_cm_write,
342
- .endianness = DEVICE_NATIVE_ENDIAN,
343
-};
344
-
345
-static const VMStateDescription vmstate_pxa2xx_cm = {
346
- .name = "pxa2xx_cm",
347
- .version_id = 0,
348
- .minimum_version_id = 0,
349
- .fields = (const VMStateField[]) {
350
- VMSTATE_UINT32_ARRAY(cm_regs, PXA2xxState, 4),
351
- VMSTATE_UINT32(clkcfg, PXA2xxState),
352
- VMSTATE_UINT32(pmnc, PXA2xxState),
353
- VMSTATE_END_OF_LIST()
354
- }
355
-};
356
-
357
-static uint64_t pxa2xx_clkcfg_read(CPUARMState *env, const ARMCPRegInfo *ri)
358
-{
359
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
360
- return s->clkcfg;
361
-}
362
-
363
-static void pxa2xx_clkcfg_write(CPUARMState *env, const ARMCPRegInfo *ri,
364
- uint64_t value)
365
-{
366
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
367
- s->clkcfg = value & 0xf;
368
- if (value & 2) {
369
- printf("%s: CPU frequency change attempt\n", __func__);
370
- }
371
-}
372
-
373
-static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
374
- uint64_t value)
375
-{
376
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
377
- static const char *pwrmode[8] = {
378
- "Normal", "Idle", "Deep-idle", "Standby",
379
- "Sleep", "reserved (!)", "reserved (!)", "Deep-sleep",
380
- };
381
-
382
- if (value & 8) {
383
- printf("%s: CPU voltage change attempt\n", __func__);
384
- }
385
- switch (value & 7) {
386
- case 0:
387
- /* Do nothing */
388
- break;
389
-
390
- case 1:
391
- /* Idle */
392
- if (!(s->cm_regs[CCCR >> 2] & (1U << 31))) { /* CPDIS */
393
- cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
394
- break;
395
- }
396
- /* Fall through. */
397
-
398
- case 2:
399
- /* Deep-Idle */
400
- cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
401
- s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */
402
- goto message;
403
-
404
- case 3:
405
- s->cpu->env.uncached_cpsr = ARM_CPU_MODE_SVC;
406
- s->cpu->env.daif = PSTATE_A | PSTATE_F | PSTATE_I;
407
- s->cpu->env.cp15.sctlr_ns = 0;
408
- s->cpu->env.cp15.cpacr_el1 = 0;
409
- s->cpu->env.cp15.ttbr0_el[1] = 0;
410
- s->cpu->env.cp15.dacr_ns = 0;
411
- s->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */
412
- s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */
413
-
414
- /*
415
- * The scratch-pad register is almost universally used
416
- * for storing the return address on suspend. For the
417
- * lack of a resuming bootloader, perform a jump
418
- * directly to that address.
419
- */
420
- memset(s->cpu->env.regs, 0, 4 * 15);
421
- s->cpu->env.regs[15] = s->pm_regs[PSPR >> 2];
422
-
423
-#if 0
424
- buffer = 0xe59ff000; /* ldr pc, [pc, #0] */
425
- cpu_physical_memory_write(0, &buffer, 4);
426
- buffer = s->pm_regs[PSPR >> 2];
427
- cpu_physical_memory_write(8, &buffer, 4);
428
-#endif
429
-
430
- /* Suspend */
431
- cpu_interrupt(current_cpu, CPU_INTERRUPT_HALT);
432
-
433
- goto message;
434
-
435
- default:
436
- message:
437
- printf("%s: machine entered %s mode\n", __func__,
438
- pwrmode[value & 7]);
439
- }
440
-}
441
-
442
-static uint64_t pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri)
443
-{
444
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
445
- return s->pmnc;
446
-}
447
-
448
-static void pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri,
449
- uint64_t value)
450
-{
451
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
452
- s->pmnc = value;
453
-}
454
-
455
-static uint64_t pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
456
-{
457
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
458
- if (s->pmnc & 1) {
459
- return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
460
- } else {
461
- return 0;
241
- return 0;
462
- }
242
- }
463
-}
243
-}
464
-
244
-
465
-static const ARMCPRegInfo pxa_cp_reginfo[] = {
245
-static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
466
- /* cp14 crm==1: perf registers */
467
- { .name = "CPPMNC", .cp = 14, .crn = 0, .crm = 1, .opc1 = 0, .opc2 = 0,
468
- .access = PL1_RW, .type = ARM_CP_IO,
469
- .readfn = pxa2xx_cppmnc_read, .writefn = pxa2xx_cppmnc_write },
470
- { .name = "CPCCNT", .cp = 14, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
471
- .access = PL1_RW, .type = ARM_CP_IO,
472
- .readfn = pxa2xx_cpccnt_read, .writefn = arm_cp_write_ignore },
473
- { .name = "CPINTEN", .cp = 14, .crn = 4, .crm = 1, .opc1 = 0, .opc2 = 0,
474
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
475
- { .name = "CPFLAG", .cp = 14, .crn = 5, .crm = 1, .opc1 = 0, .opc2 = 0,
476
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
477
- { .name = "CPEVTSEL", .cp = 14, .crn = 8, .crm = 1, .opc1 = 0, .opc2 = 0,
478
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
479
- /* cp14 crm==2: performance count registers */
480
- { .name = "CPPMN0", .cp = 14, .crn = 0, .crm = 2, .opc1 = 0, .opc2 = 0,
481
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
482
- { .name = "CPPMN1", .cp = 14, .crn = 1, .crm = 2, .opc1 = 0, .opc2 = 0,
483
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
484
- { .name = "CPPMN2", .cp = 14, .crn = 2, .crm = 2, .opc1 = 0, .opc2 = 0,
485
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
486
- { .name = "CPPMN3", .cp = 14, .crn = 2, .crm = 3, .opc1 = 0, .opc2 = 0,
487
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
488
- /* cp14 crn==6: CLKCFG */
489
- { .name = "CLKCFG", .cp = 14, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
490
- .access = PL1_RW, .type = ARM_CP_IO,
491
- .readfn = pxa2xx_clkcfg_read, .writefn = pxa2xx_clkcfg_write },
492
- /* cp14 crn==7: PWRMODE */
493
- { .name = "PWRMODE", .cp = 14, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 0,
494
- .access = PL1_RW, .type = ARM_CP_IO,
495
- .readfn = arm_cp_read_zero, .writefn = pxa2xx_pwrmode_write },
496
-};
497
-
498
-static void pxa2xx_setup_cp14(PXA2xxState *s)
499
-{
246
-{
500
- define_arm_cp_regs_with_opaque(s->cpu, pxa_cp_reginfo, s);
247
- switch (reg) {
501
-}
248
- case 0: /* Basic Control */
502
-
249
- if (val & 0x8000) {
503
-#define MDCNFG        0x00    /* SDRAM Configuration register */
250
- phy_reset(s);
504
-#define MDREFR        0x04    /* SDRAM Refresh Control register */
505
-#define MSC0        0x08    /* Static Memory Control register 0 */
506
-#define MSC1        0x0c    /* Static Memory Control register 1 */
507
-#define MSC2        0x10    /* Static Memory Control register 2 */
508
-#define MECR        0x14    /* Expansion Memory Bus Config register */
509
-#define SXCNFG        0x1c    /* Synchronous Static Memory Config register */
510
-#define MCMEM0        0x28    /* PC Card Memory Socket 0 Timing register */
511
-#define MCMEM1        0x2c    /* PC Card Memory Socket 1 Timing register */
512
-#define MCATT0        0x30    /* PC Card Attribute Socket 0 register */
513
-#define MCATT1        0x34    /* PC Card Attribute Socket 1 register */
514
-#define MCIO0        0x38    /* PC Card I/O Socket 0 Timing register */
515
-#define MCIO1        0x3c    /* PC Card I/O Socket 1 Timing register */
516
-#define MDMRS        0x40    /* SDRAM Mode Register Set Config register */
517
-#define BOOT_DEF    0x44    /* Boot-time Default Configuration register */
518
-#define ARB_CNTL    0x48    /* Arbiter Control register */
519
-#define BSCNTR0        0x4c    /* Memory Buffer Strength Control register 0 */
520
-#define BSCNTR1        0x50    /* Memory Buffer Strength Control register 1 */
521
-#define LCDBSCNTR    0x54    /* LCD Buffer Strength Control register */
522
-#define MDMRSLP        0x58    /* Low Power SDRAM Mode Set Config register */
523
-#define BSCNTR2        0x5c    /* Memory Buffer Strength Control register 2 */
524
-#define BSCNTR3        0x60    /* Memory Buffer Strength Control register 3 */
525
-#define SA1110        0x64    /* SA-1110 Memory Compatibility register */
526
-
527
-static uint64_t pxa2xx_mm_read(void *opaque, hwaddr addr,
528
- unsigned size)
529
-{
530
- PXA2xxState *s = (PXA2xxState *) opaque;
531
-
532
- switch (addr) {
533
- case MDCNFG ... SA1110:
534
- if ((addr & 3) == 0)
535
- return s->mm_regs[addr >> 2];
536
- /* fall through */
537
- default:
538
- qemu_log_mask(LOG_GUEST_ERROR,
539
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
540
- __func__, addr);
541
- break;
542
- }
543
- return 0;
544
-}
545
-
546
-static void pxa2xx_mm_write(void *opaque, hwaddr addr,
547
- uint64_t value, unsigned size)
548
-{
549
- PXA2xxState *s = (PXA2xxState *) opaque;
550
-
551
- switch (addr) {
552
- case MDCNFG ... SA1110:
553
- if ((addr & 3) == 0) {
554
- s->mm_regs[addr >> 2] = value;
555
- break;
251
- break;
556
- }
252
- }
557
- /* fallthrough */
253
- s->phy_control = val & 0x7980;
558
- default:
254
- /* Complete autonegotiation immediately. */
559
- qemu_log_mask(LOG_GUEST_ERROR,
255
- if (val & 0x1000) {
560
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
256
- s->phy_status |= 0x0020;
561
- __func__, addr);
562
- break;
563
- }
564
-}
565
-
566
-static const MemoryRegionOps pxa2xx_mm_ops = {
567
- .read = pxa2xx_mm_read,
568
- .write = pxa2xx_mm_write,
569
- .endianness = DEVICE_NATIVE_ENDIAN,
570
-};
571
-
572
-static const VMStateDescription vmstate_pxa2xx_mm = {
573
- .name = "pxa2xx_mm",
574
- .version_id = 0,
575
- .minimum_version_id = 0,
576
- .fields = (const VMStateField[]) {
577
- VMSTATE_UINT32_ARRAY(mm_regs, PXA2xxState, 0x1a),
578
- VMSTATE_END_OF_LIST()
579
- }
580
-};
581
-
582
-#define TYPE_PXA2XX_SSP "pxa2xx-ssp"
583
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxSSPState, PXA2XX_SSP)
584
-
585
-/* Synchronous Serial Ports */
586
-struct PXA2xxSSPState {
587
- /*< private >*/
588
- SysBusDevice parent_obj;
589
- /*< public >*/
590
-
591
- MemoryRegion iomem;
592
- qemu_irq irq;
593
- uint32_t enable;
594
- SSIBus *bus;
595
-
596
- uint32_t sscr[2];
597
- uint32_t sspsp;
598
- uint32_t ssto;
599
- uint32_t ssitr;
600
- uint32_t sssr;
601
- uint8_t sstsa;
602
- uint8_t ssrsa;
603
- uint8_t ssacd;
604
-
605
- uint32_t rx_fifo[16];
606
- uint32_t rx_level;
607
- uint32_t rx_start;
608
-};
609
-
610
-static bool pxa2xx_ssp_vmstate_validate(void *opaque, int version_id)
611
-{
612
- PXA2xxSSPState *s = opaque;
613
-
614
- return s->rx_start < sizeof(s->rx_fifo);
615
-}
616
-
617
-static const VMStateDescription vmstate_pxa2xx_ssp = {
618
- .name = "pxa2xx-ssp",
619
- .version_id = 1,
620
- .minimum_version_id = 1,
621
- .fields = (const VMStateField[]) {
622
- VMSTATE_UINT32(enable, PXA2xxSSPState),
623
- VMSTATE_UINT32_ARRAY(sscr, PXA2xxSSPState, 2),
624
- VMSTATE_UINT32(sspsp, PXA2xxSSPState),
625
- VMSTATE_UINT32(ssto, PXA2xxSSPState),
626
- VMSTATE_UINT32(ssitr, PXA2xxSSPState),
627
- VMSTATE_UINT32(sssr, PXA2xxSSPState),
628
- VMSTATE_UINT8(sstsa, PXA2xxSSPState),
629
- VMSTATE_UINT8(ssrsa, PXA2xxSSPState),
630
- VMSTATE_UINT8(ssacd, PXA2xxSSPState),
631
- VMSTATE_UINT32(rx_level, PXA2xxSSPState),
632
- VMSTATE_UINT32(rx_start, PXA2xxSSPState),
633
- VMSTATE_VALIDATE("fifo is 16 bytes", pxa2xx_ssp_vmstate_validate),
634
- VMSTATE_UINT32_ARRAY(rx_fifo, PXA2xxSSPState, 16),
635
- VMSTATE_END_OF_LIST()
636
- }
637
-};
638
-
639
-#define SSCR0    0x00    /* SSP Control register 0 */
640
-#define SSCR1    0x04    /* SSP Control register 1 */
641
-#define SSSR    0x08    /* SSP Status register */
642
-#define SSITR    0x0c    /* SSP Interrupt Test register */
643
-#define SSDR    0x10    /* SSP Data register */
644
-#define SSTO    0x28    /* SSP Time-Out register */
645
-#define SSPSP    0x2c    /* SSP Programmable Serial Protocol register */
646
-#define SSTSA    0x30    /* SSP TX Time Slot Active register */
647
-#define SSRSA    0x34    /* SSP RX Time Slot Active register */
648
-#define SSTSS    0x38    /* SSP Time Slot Status register */
649
-#define SSACD    0x3c    /* SSP Audio Clock Divider register */
650
-
651
-/* Bitfields for above registers */
652
-#define SSCR0_SPI(x)    (((x) & 0x30) == 0x00)
653
-#define SSCR0_SSP(x)    (((x) & 0x30) == 0x10)
654
-#define SSCR0_UWIRE(x)    (((x) & 0x30) == 0x20)
655
-#define SSCR0_PSP(x)    (((x) & 0x30) == 0x30)
656
-#define SSCR0_SSE    (1 << 7)
657
-#define SSCR0_RIM    (1 << 22)
658
-#define SSCR0_TIM    (1 << 23)
659
-#define SSCR0_MOD (1U << 31)
660
-#define SSCR0_DSS(x)    (((((x) >> 16) & 0x10) | ((x) & 0xf)) + 1)
661
-#define SSCR1_RIE    (1 << 0)
662
-#define SSCR1_TIE    (1 << 1)
663
-#define SSCR1_LBM    (1 << 2)
664
-#define SSCR1_MWDS    (1 << 5)
665
-#define SSCR1_TFT(x)    ((((x) >> 6) & 0xf) + 1)
666
-#define SSCR1_RFT(x)    ((((x) >> 10) & 0xf) + 1)
667
-#define SSCR1_EFWR    (1 << 14)
668
-#define SSCR1_PINTE    (1 << 18)
669
-#define SSCR1_TINTE    (1 << 19)
670
-#define SSCR1_RSRE    (1 << 20)
671
-#define SSCR1_TSRE    (1 << 21)
672
-#define SSCR1_EBCEI    (1 << 29)
673
-#define SSITR_INT    (7 << 5)
674
-#define SSSR_TNF    (1 << 2)
675
-#define SSSR_RNE    (1 << 3)
676
-#define SSSR_TFS    (1 << 5)
677
-#define SSSR_RFS    (1 << 6)
678
-#define SSSR_ROR    (1 << 7)
679
-#define SSSR_PINT    (1 << 18)
680
-#define SSSR_TINT    (1 << 19)
681
-#define SSSR_EOC    (1 << 20)
682
-#define SSSR_TUR    (1 << 21)
683
-#define SSSR_BCE    (1 << 23)
684
-#define SSSR_RW        0x00bc0080
685
-
686
-static void pxa2xx_ssp_int_update(PXA2xxSSPState *s)
687
-{
688
- int level = 0;
689
-
690
- level |= s->ssitr & SSITR_INT;
691
- level |= (s->sssr & SSSR_BCE) && (s->sscr[1] & SSCR1_EBCEI);
692
- level |= (s->sssr & SSSR_TUR) && !(s->sscr[0] & SSCR0_TIM);
693
- level |= (s->sssr & SSSR_EOC) && (s->sssr & (SSSR_TINT | SSSR_PINT));
694
- level |= (s->sssr & SSSR_TINT) && (s->sscr[1] & SSCR1_TINTE);
695
- level |= (s->sssr & SSSR_PINT) && (s->sscr[1] & SSCR1_PINTE);
696
- level |= (s->sssr & SSSR_ROR) && !(s->sscr[0] & SSCR0_RIM);
697
- level |= (s->sssr & SSSR_RFS) && (s->sscr[1] & SSCR1_RIE);
698
- level |= (s->sssr & SSSR_TFS) && (s->sscr[1] & SSCR1_TIE);
699
- qemu_set_irq(s->irq, !!level);
700
-}
701
-
702
-static void pxa2xx_ssp_fifo_update(PXA2xxSSPState *s)
703
-{
704
- s->sssr &= ~(0xf << 12);    /* Clear RFL */
705
- s->sssr &= ~(0xf << 8);    /* Clear TFL */
706
- s->sssr &= ~SSSR_TFS;
707
- s->sssr &= ~SSSR_TNF;
708
- if (s->enable) {
709
- s->sssr |= ((s->rx_level - 1) & 0xf) << 12;
710
- if (s->rx_level >= SSCR1_RFT(s->sscr[1]))
711
- s->sssr |= SSSR_RFS;
712
- else
713
- s->sssr &= ~SSSR_RFS;
714
- if (s->rx_level)
715
- s->sssr |= SSSR_RNE;
716
- else
717
- s->sssr &= ~SSSR_RNE;
718
- /* TX FIFO is never filled, so it is always in underrun
719
- condition if SSP is enabled */
720
- s->sssr |= SSSR_TFS;
721
- s->sssr |= SSSR_TNF;
722
- }
723
-
724
- pxa2xx_ssp_int_update(s);
725
-}
726
-
727
-static uint64_t pxa2xx_ssp_read(void *opaque, hwaddr addr,
728
- unsigned size)
729
-{
730
- PXA2xxSSPState *s = (PXA2xxSSPState *) opaque;
731
- uint32_t retval;
732
-
733
- switch (addr) {
734
- case SSCR0:
735
- return s->sscr[0];
736
- case SSCR1:
737
- return s->sscr[1];
738
- case SSPSP:
739
- return s->sspsp;
740
- case SSTO:
741
- return s->ssto;
742
- case SSITR:
743
- return s->ssitr;
744
- case SSSR:
745
- return s->sssr | s->ssitr;
746
- case SSDR:
747
- if (!s->enable)
748
- return 0xffffffff;
749
- if (s->rx_level < 1) {
750
- printf("%s: SSP Rx Underrun\n", __func__);
751
- return 0xffffffff;
752
- }
753
- s->rx_level --;
754
- retval = s->rx_fifo[s->rx_start ++];
755
- s->rx_start &= 0xf;
756
- pxa2xx_ssp_fifo_update(s);
757
- return retval;
758
- case SSTSA:
759
- return s->sstsa;
760
- case SSRSA:
761
- return s->ssrsa;
762
- case SSTSS:
763
- return 0;
764
- case SSACD:
765
- return s->ssacd;
766
- default:
767
- qemu_log_mask(LOG_GUEST_ERROR,
768
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
769
- __func__, addr);
770
- break;
771
- }
772
- return 0;
773
-}
774
-
775
-static void pxa2xx_ssp_write(void *opaque, hwaddr addr,
776
- uint64_t value64, unsigned size)
777
-{
778
- PXA2xxSSPState *s = (PXA2xxSSPState *) opaque;
779
- uint32_t value = value64;
780
-
781
- switch (addr) {
782
- case SSCR0:
783
- s->sscr[0] = value & 0xc7ffffff;
784
- s->enable = value & SSCR0_SSE;
785
- if (value & SSCR0_MOD)
786
- printf("%s: Attempt to use network mode\n", __func__);
787
- if (s->enable && SSCR0_DSS(value) < 4)
788
- printf("%s: Wrong data size: %u bits\n", __func__,
789
- SSCR0_DSS(value));
790
- if (!(value & SSCR0_SSE)) {
791
- s->sssr = 0;
792
- s->ssitr = 0;
793
- s->rx_level = 0;
794
- }
795
- pxa2xx_ssp_fifo_update(s);
796
- break;
797
-
798
- case SSCR1:
799
- s->sscr[1] = value;
800
- if (value & (SSCR1_LBM | SSCR1_EFWR))
801
- printf("%s: Attempt to use SSP test mode\n", __func__);
802
- pxa2xx_ssp_fifo_update(s);
803
- break;
804
-
805
- case SSPSP:
806
- s->sspsp = value;
807
- break;
808
-
809
- case SSTO:
810
- s->ssto = value;
811
- break;
812
-
813
- case SSITR:
814
- s->ssitr = value & SSITR_INT;
815
- pxa2xx_ssp_int_update(s);
816
- break;
817
-
818
- case SSSR:
819
- s->sssr &= ~(value & SSSR_RW);
820
- pxa2xx_ssp_int_update(s);
821
- break;
822
-
823
- case SSDR:
824
- if (SSCR0_UWIRE(s->sscr[0])) {
825
- if (s->sscr[1] & SSCR1_MWDS)
826
- value &= 0xffff;
827
- else
828
- value &= 0xff;
829
- } else
830
- /* Note how 32bits overflow does no harm here */
831
- value &= (1 << SSCR0_DSS(s->sscr[0])) - 1;
832
-
833
- /* Data goes from here to the Tx FIFO and is shifted out from
834
- * there directly to the slave, no need to buffer it.
835
- */
836
- if (s->enable) {
837
- uint32_t readval;
838
- readval = ssi_transfer(s->bus, value);
839
- if (s->rx_level < 0x10) {
840
- s->rx_fifo[(s->rx_start + s->rx_level ++) & 0xf] = readval;
841
- } else {
842
- s->sssr |= SSSR_ROR;
843
- }
844
- }
845
- pxa2xx_ssp_fifo_update(s);
846
- break;
847
-
848
- case SSTSA:
849
- s->sstsa = value;
850
- break;
851
-
852
- case SSRSA:
853
- s->ssrsa = value;
854
- break;
855
-
856
- case SSACD:
857
- s->ssacd = value;
858
- break;
859
-
860
- default:
861
- qemu_log_mask(LOG_GUEST_ERROR,
862
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
863
- __func__, addr);
864
- break;
865
- }
866
-}
867
-
868
-static const MemoryRegionOps pxa2xx_ssp_ops = {
869
- .read = pxa2xx_ssp_read,
870
- .write = pxa2xx_ssp_write,
871
- .endianness = DEVICE_NATIVE_ENDIAN,
872
-};
873
-
874
-static void pxa2xx_ssp_reset(DeviceState *d)
875
-{
876
- PXA2xxSSPState *s = PXA2XX_SSP(d);
877
-
878
- s->enable = 0;
879
- s->sscr[0] = s->sscr[1] = 0;
880
- s->sspsp = 0;
881
- s->ssto = 0;
882
- s->ssitr = 0;
883
- s->sssr = 0;
884
- s->sstsa = 0;
885
- s->ssrsa = 0;
886
- s->ssacd = 0;
887
- s->rx_start = s->rx_level = 0;
888
-}
889
-
890
-static void pxa2xx_ssp_init(Object *obj)
891
-{
892
- DeviceState *dev = DEVICE(obj);
893
- PXA2xxSSPState *s = PXA2XX_SSP(obj);
894
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
895
- sysbus_init_irq(sbd, &s->irq);
896
-
897
- memory_region_init_io(&s->iomem, obj, &pxa2xx_ssp_ops, s,
898
- "pxa2xx-ssp", 0x1000);
899
- sysbus_init_mmio(sbd, &s->iomem);
900
-
901
- s->bus = ssi_create_bus(dev, "ssi");
902
-}
903
-
904
-/* Real-Time Clock */
905
-#define RCNR        0x00    /* RTC Counter register */
906
-#define RTAR        0x04    /* RTC Alarm register */
907
-#define RTSR        0x08    /* RTC Status register */
908
-#define RTTR        0x0c    /* RTC Timer Trim register */
909
-#define RDCR        0x10    /* RTC Day Counter register */
910
-#define RYCR        0x14    /* RTC Year Counter register */
911
-#define RDAR1        0x18    /* RTC Wristwatch Day Alarm register 1 */
912
-#define RYAR1        0x1c    /* RTC Wristwatch Year Alarm register 1 */
913
-#define RDAR2        0x20    /* RTC Wristwatch Day Alarm register 2 */
914
-#define RYAR2        0x24    /* RTC Wristwatch Year Alarm register 2 */
915
-#define SWCR        0x28    /* RTC Stopwatch Counter register */
916
-#define SWAR1        0x2c    /* RTC Stopwatch Alarm register 1 */
917
-#define SWAR2        0x30    /* RTC Stopwatch Alarm register 2 */
918
-#define RTCPICR        0x34    /* RTC Periodic Interrupt Counter register */
919
-#define PIAR        0x38    /* RTC Periodic Interrupt Alarm register */
920
-
921
-#define TYPE_PXA2XX_RTC "pxa2xx_rtc"
922
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxRTCState, PXA2XX_RTC)
923
-
924
-struct PXA2xxRTCState {
925
- /*< private >*/
926
- SysBusDevice parent_obj;
927
- /*< public >*/
928
-
929
- MemoryRegion iomem;
930
- uint32_t rttr;
931
- uint32_t rtsr;
932
- uint32_t rtar;
933
- uint32_t rdar1;
934
- uint32_t rdar2;
935
- uint32_t ryar1;
936
- uint32_t ryar2;
937
- uint32_t swar1;
938
- uint32_t swar2;
939
- uint32_t piar;
940
- uint32_t last_rcnr;
941
- uint32_t last_rdcr;
942
- uint32_t last_rycr;
943
- uint32_t last_swcr;
944
- uint32_t last_rtcpicr;
945
- int64_t last_hz;
946
- int64_t last_sw;
947
- int64_t last_pi;
948
- QEMUTimer *rtc_hz;
949
- QEMUTimer *rtc_rdal1;
950
- QEMUTimer *rtc_rdal2;
951
- QEMUTimer *rtc_swal1;
952
- QEMUTimer *rtc_swal2;
953
- QEMUTimer *rtc_pi;
954
- qemu_irq rtc_irq;
955
-};
956
-
957
-static inline void pxa2xx_rtc_int_update(PXA2xxRTCState *s)
958
-{
959
- qemu_set_irq(s->rtc_irq, !!(s->rtsr & 0x2553));
960
-}
961
-
962
-static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s)
963
-{
964
- int64_t rt = qemu_clock_get_ms(rtc_clock);
965
- s->last_rcnr += ((rt - s->last_hz) << 15) /
966
- (1000 * ((s->rttr & 0xffff) + 1));
967
- s->last_rdcr += ((rt - s->last_hz) << 15) /
968
- (1000 * ((s->rttr & 0xffff) + 1));
969
- s->last_hz = rt;
970
-}
971
-
972
-static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)
973
-{
974
- int64_t rt = qemu_clock_get_ms(rtc_clock);
975
- if (s->rtsr & (1 << 12))
976
- s->last_swcr += (rt - s->last_sw) / 10;
977
- s->last_sw = rt;
978
-}
979
-
980
-static void pxa2xx_rtc_piupdate(PXA2xxRTCState *s)
981
-{
982
- int64_t rt = qemu_clock_get_ms(rtc_clock);
983
- if (s->rtsr & (1 << 15))
984
- s->last_swcr += rt - s->last_pi;
985
- s->last_pi = rt;
986
-}
987
-
988
-static inline void pxa2xx_rtc_alarm_update(PXA2xxRTCState *s,
989
- uint32_t rtsr)
990
-{
991
- if ((rtsr & (1 << 2)) && !(rtsr & (1 << 0)))
992
- timer_mod(s->rtc_hz, s->last_hz +
993
- (((s->rtar - s->last_rcnr) * 1000 *
994
- ((s->rttr & 0xffff) + 1)) >> 15));
995
- else
996
- timer_del(s->rtc_hz);
997
-
998
- if ((rtsr & (1 << 5)) && !(rtsr & (1 << 4)))
999
- timer_mod(s->rtc_rdal1, s->last_hz +
1000
- (((s->rdar1 - s->last_rdcr) * 1000 *
1001
- ((s->rttr & 0xffff) + 1)) >> 15)); /* TODO: fixup */
1002
- else
1003
- timer_del(s->rtc_rdal1);
1004
-
1005
- if ((rtsr & (1 << 7)) && !(rtsr & (1 << 6)))
1006
- timer_mod(s->rtc_rdal2, s->last_hz +
1007
- (((s->rdar2 - s->last_rdcr) * 1000 *
1008
- ((s->rttr & 0xffff) + 1)) >> 15)); /* TODO: fixup */
1009
- else
1010
- timer_del(s->rtc_rdal2);
1011
-
1012
- if ((rtsr & 0x1200) == 0x1200 && !(rtsr & (1 << 8)))
1013
- timer_mod(s->rtc_swal1, s->last_sw +
1014
- (s->swar1 - s->last_swcr) * 10); /* TODO: fixup */
1015
- else
1016
- timer_del(s->rtc_swal1);
1017
-
1018
- if ((rtsr & 0x1800) == 0x1800 && !(rtsr & (1 << 10)))
1019
- timer_mod(s->rtc_swal2, s->last_sw +
1020
- (s->swar2 - s->last_swcr) * 10); /* TODO: fixup */
1021
- else
1022
- timer_del(s->rtc_swal2);
1023
-
1024
- if ((rtsr & 0xc000) == 0xc000 && !(rtsr & (1 << 13)))
1025
- timer_mod(s->rtc_pi, s->last_pi +
1026
- (s->piar & 0xffff) - s->last_rtcpicr);
1027
- else
1028
- timer_del(s->rtc_pi);
1029
-}
1030
-
1031
-static inline void pxa2xx_rtc_hz_tick(void *opaque)
1032
-{
1033
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
1034
- s->rtsr |= (1 << 0);
1035
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1036
- pxa2xx_rtc_int_update(s);
1037
-}
1038
-
1039
-static inline void pxa2xx_rtc_rdal1_tick(void *opaque)
1040
-{
1041
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
1042
- s->rtsr |= (1 << 4);
1043
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1044
- pxa2xx_rtc_int_update(s);
1045
-}
1046
-
1047
-static inline void pxa2xx_rtc_rdal2_tick(void *opaque)
1048
-{
1049
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
1050
- s->rtsr |= (1 << 6);
1051
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1052
- pxa2xx_rtc_int_update(s);
1053
-}
1054
-
1055
-static inline void pxa2xx_rtc_swal1_tick(void *opaque)
1056
-{
1057
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
1058
- s->rtsr |= (1 << 8);
1059
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1060
- pxa2xx_rtc_int_update(s);
1061
-}
1062
-
1063
-static inline void pxa2xx_rtc_swal2_tick(void *opaque)
1064
-{
1065
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
1066
- s->rtsr |= (1 << 10);
1067
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1068
- pxa2xx_rtc_int_update(s);
1069
-}
1070
-
1071
-static inline void pxa2xx_rtc_pi_tick(void *opaque)
1072
-{
1073
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
1074
- s->rtsr |= (1 << 13);
1075
- pxa2xx_rtc_piupdate(s);
1076
- s->last_rtcpicr = 0;
1077
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1078
- pxa2xx_rtc_int_update(s);
1079
-}
1080
-
1081
-static uint64_t pxa2xx_rtc_read(void *opaque, hwaddr addr,
1082
- unsigned size)
1083
-{
1084
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
1085
-
1086
- switch (addr) {
1087
- case RTTR:
1088
- return s->rttr;
1089
- case RTSR:
1090
- return s->rtsr;
1091
- case RTAR:
1092
- return s->rtar;
1093
- case RDAR1:
1094
- return s->rdar1;
1095
- case RDAR2:
1096
- return s->rdar2;
1097
- case RYAR1:
1098
- return s->ryar1;
1099
- case RYAR2:
1100
- return s->ryar2;
1101
- case SWAR1:
1102
- return s->swar1;
1103
- case SWAR2:
1104
- return s->swar2;
1105
- case PIAR:
1106
- return s->piar;
1107
- case RCNR:
1108
- return s->last_rcnr +
1109
- ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
1110
- (1000 * ((s->rttr & 0xffff) + 1));
1111
- case RDCR:
1112
- return s->last_rdcr +
1113
- ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
1114
- (1000 * ((s->rttr & 0xffff) + 1));
1115
- case RYCR:
1116
- return s->last_rycr;
1117
- case SWCR:
1118
- if (s->rtsr & (1 << 12))
1119
- return s->last_swcr +
1120
- (qemu_clock_get_ms(rtc_clock) - s->last_sw) / 10;
1121
- else
1122
- return s->last_swcr;
1123
- default:
1124
- qemu_log_mask(LOG_GUEST_ERROR,
1125
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
1126
- __func__, addr);
1127
- break;
1128
- }
1129
- return 0;
1130
-}
1131
-
1132
-static void pxa2xx_rtc_write(void *opaque, hwaddr addr,
1133
- uint64_t value64, unsigned size)
1134
-{
1135
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
1136
- uint32_t value = value64;
1137
-
1138
- switch (addr) {
1139
- case RTTR:
1140
- if (!(s->rttr & (1U << 31))) {
1141
- pxa2xx_rtc_hzupdate(s);
1142
- s->rttr = value;
1143
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1144
- }
257
- }
1145
- break;
258
- break;
1146
-
259
- case 4: /* Auto-neg advertisement */
1147
- case RTSR:
260
- s->phy_advertise = (val & 0x2d7f) | 0x80;
1148
- if ((s->rtsr ^ value) & (1 << 15))
1149
- pxa2xx_rtc_piupdate(s);
1150
-
1151
- if ((s->rtsr ^ value) & (1 << 12))
1152
- pxa2xx_rtc_swupdate(s);
1153
-
1154
- if (((s->rtsr ^ value) & 0x4aac) | (value & ~0xdaac))
1155
- pxa2xx_rtc_alarm_update(s, value);
1156
-
1157
- s->rtsr = (value & 0xdaac) | (s->rtsr & ~(value & ~0xdaac));
1158
- pxa2xx_rtc_int_update(s);
1159
- break;
261
- break;
1160
-
262
- /* TODO 17, 18, 27, 31 */
1161
- case RTAR:
263
- case 30: /* Interrupt mask */
1162
- s->rtar = value;
264
- s->phy_int_mask = val & 0xff;
1163
- pxa2xx_rtc_alarm_update(s, s->rtsr);
265
- phy_update_irq(s);
1164
- break;
1165
-
1166
- case RDAR1:
1167
- s->rdar1 = value;
1168
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1169
- break;
1170
-
1171
- case RDAR2:
1172
- s->rdar2 = value;
1173
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1174
- break;
1175
-
1176
- case RYAR1:
1177
- s->ryar1 = value;
1178
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1179
- break;
1180
-
1181
- case RYAR2:
1182
- s->ryar2 = value;
1183
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1184
- break;
1185
-
1186
- case SWAR1:
1187
- pxa2xx_rtc_swupdate(s);
1188
- s->swar1 = value;
1189
- s->last_swcr = 0;
1190
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1191
- break;
1192
-
1193
- case SWAR2:
1194
- s->swar2 = value;
1195
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1196
- break;
1197
-
1198
- case PIAR:
1199
- s->piar = value;
1200
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1201
- break;
1202
-
1203
- case RCNR:
1204
- pxa2xx_rtc_hzupdate(s);
1205
- s->last_rcnr = value;
1206
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1207
- break;
1208
-
1209
- case RDCR:
1210
- pxa2xx_rtc_hzupdate(s);
1211
- s->last_rdcr = value;
1212
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1213
- break;
1214
-
1215
- case RYCR:
1216
- s->last_rycr = value;
1217
- break;
1218
-
1219
- case SWCR:
1220
- pxa2xx_rtc_swupdate(s);
1221
- s->last_swcr = value;
1222
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1223
- break;
1224
-
1225
- case RTCPICR:
1226
- pxa2xx_rtc_piupdate(s);
1227
- s->last_rtcpicr = value & 0xffff;
1228
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1229
- break;
1230
-
1231
- default:
1232
- qemu_log_mask(LOG_GUEST_ERROR,
1233
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
1234
- __func__, addr);
1235
- }
1236
-}
1237
-
1238
-static const MemoryRegionOps pxa2xx_rtc_ops = {
1239
- .read = pxa2xx_rtc_read,
1240
- .write = pxa2xx_rtc_write,
1241
- .endianness = DEVICE_NATIVE_ENDIAN,
1242
-};
1243
-
1244
-static void pxa2xx_rtc_init(Object *obj)
1245
-{
1246
- PXA2xxRTCState *s = PXA2XX_RTC(obj);
1247
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
1248
- struct tm tm;
1249
- int wom;
1250
-
1251
- s->rttr = 0x7fff;
1252
- s->rtsr = 0;
1253
-
1254
- qemu_get_timedate(&tm, 0);
1255
- wom = ((tm.tm_mday - 1) / 7) + 1;
1256
-
1257
- s->last_rcnr = (uint32_t) mktimegm(&tm);
1258
- s->last_rdcr = (wom << 20) | ((tm.tm_wday + 1) << 17) |
1259
- (tm.tm_hour << 12) | (tm.tm_min << 6) | tm.tm_sec;
1260
- s->last_rycr = ((tm.tm_year + 1900) << 9) |
1261
- ((tm.tm_mon + 1) << 5) | tm.tm_mday;
1262
- s->last_swcr = (tm.tm_hour << 19) |
1263
- (tm.tm_min << 13) | (tm.tm_sec << 7);
1264
- s->last_rtcpicr = 0;
1265
- s->last_hz = s->last_sw = s->last_pi = qemu_clock_get_ms(rtc_clock);
1266
-
1267
- sysbus_init_irq(dev, &s->rtc_irq);
1268
-
1269
- memory_region_init_io(&s->iomem, obj, &pxa2xx_rtc_ops, s,
1270
- "pxa2xx-rtc", 0x10000);
1271
- sysbus_init_mmio(dev, &s->iomem);
1272
-}
1273
-
1274
-static void pxa2xx_rtc_realize(DeviceState *dev, Error **errp)
1275
-{
1276
- PXA2xxRTCState *s = PXA2XX_RTC(dev);
1277
- s->rtc_hz = timer_new_ms(rtc_clock, pxa2xx_rtc_hz_tick, s);
1278
- s->rtc_rdal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s);
1279
- s->rtc_rdal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s);
1280
- s->rtc_swal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s);
1281
- s->rtc_swal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s);
1282
- s->rtc_pi = timer_new_ms(rtc_clock, pxa2xx_rtc_pi_tick, s);
1283
-}
1284
-
1285
-static int pxa2xx_rtc_pre_save(void *opaque)
1286
-{
1287
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
1288
-
1289
- pxa2xx_rtc_hzupdate(s);
1290
- pxa2xx_rtc_piupdate(s);
1291
- pxa2xx_rtc_swupdate(s);
1292
-
1293
- return 0;
1294
-}
1295
-
1296
-static int pxa2xx_rtc_post_load(void *opaque, int version_id)
1297
-{
1298
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
1299
-
1300
- pxa2xx_rtc_alarm_update(s, s->rtsr);
1301
-
1302
- return 0;
1303
-}
1304
-
1305
-static const VMStateDescription vmstate_pxa2xx_rtc_regs = {
1306
- .name = "pxa2xx_rtc",
1307
- .version_id = 0,
1308
- .minimum_version_id = 0,
1309
- .pre_save = pxa2xx_rtc_pre_save,
1310
- .post_load = pxa2xx_rtc_post_load,
1311
- .fields = (const VMStateField[]) {
1312
- VMSTATE_UINT32(rttr, PXA2xxRTCState),
1313
- VMSTATE_UINT32(rtsr, PXA2xxRTCState),
1314
- VMSTATE_UINT32(rtar, PXA2xxRTCState),
1315
- VMSTATE_UINT32(rdar1, PXA2xxRTCState),
1316
- VMSTATE_UINT32(rdar2, PXA2xxRTCState),
1317
- VMSTATE_UINT32(ryar1, PXA2xxRTCState),
1318
- VMSTATE_UINT32(ryar2, PXA2xxRTCState),
1319
- VMSTATE_UINT32(swar1, PXA2xxRTCState),
1320
- VMSTATE_UINT32(swar2, PXA2xxRTCState),
1321
- VMSTATE_UINT32(piar, PXA2xxRTCState),
1322
- VMSTATE_UINT32(last_rcnr, PXA2xxRTCState),
1323
- VMSTATE_UINT32(last_rdcr, PXA2xxRTCState),
1324
- VMSTATE_UINT32(last_rycr, PXA2xxRTCState),
1325
- VMSTATE_UINT32(last_swcr, PXA2xxRTCState),
1326
- VMSTATE_UINT32(last_rtcpicr, PXA2xxRTCState),
1327
- VMSTATE_INT64(last_hz, PXA2xxRTCState),
1328
- VMSTATE_INT64(last_sw, PXA2xxRTCState),
1329
- VMSTATE_INT64(last_pi, PXA2xxRTCState),
1330
- VMSTATE_END_OF_LIST(),
1331
- },
1332
-};
1333
-
1334
-static void pxa2xx_rtc_sysbus_class_init(ObjectClass *klass, void *data)
1335
-{
1336
- DeviceClass *dc = DEVICE_CLASS(klass);
1337
-
1338
- dc->desc = "PXA2xx RTC Controller";
1339
- dc->vmsd = &vmstate_pxa2xx_rtc_regs;
1340
- dc->realize = pxa2xx_rtc_realize;
1341
-}
1342
-
1343
-static const TypeInfo pxa2xx_rtc_sysbus_info = {
1344
- .name = TYPE_PXA2XX_RTC,
1345
- .parent = TYPE_SYS_BUS_DEVICE,
1346
- .instance_size = sizeof(PXA2xxRTCState),
1347
- .instance_init = pxa2xx_rtc_init,
1348
- .class_init = pxa2xx_rtc_sysbus_class_init,
1349
-};
1350
-
1351
-/* I2C Interface */
1352
-
1353
-#define TYPE_PXA2XX_I2C_SLAVE "pxa2xx-i2c-slave"
1354
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxI2CSlaveState, PXA2XX_I2C_SLAVE)
1355
-
1356
-struct PXA2xxI2CSlaveState {
1357
- I2CSlave parent_obj;
1358
-
1359
- PXA2xxI2CState *host;
1360
-};
1361
-
1362
-struct PXA2xxI2CState {
1363
- /*< private >*/
1364
- SysBusDevice parent_obj;
1365
- /*< public >*/
1366
-
1367
- MemoryRegion iomem;
1368
- PXA2xxI2CSlaveState *slave;
1369
- I2CBus *bus;
1370
- qemu_irq irq;
1371
- uint32_t offset;
1372
- uint32_t region_size;
1373
-
1374
- uint16_t control;
1375
- uint16_t status;
1376
- uint8_t ibmr;
1377
- uint8_t data;
1378
-};
1379
-
1380
-#define IBMR    0x80    /* I2C Bus Monitor register */
1381
-#define IDBR    0x88    /* I2C Data Buffer register */
1382
-#define ICR    0x90    /* I2C Control register */
1383
-#define ISR    0x98    /* I2C Status register */
1384
-#define ISAR    0xa0    /* I2C Slave Address register */
1385
-
1386
-static void pxa2xx_i2c_update(PXA2xxI2CState *s)
1387
-{
1388
- uint16_t level = 0;
1389
- level |= s->status & s->control & (1 << 10);        /* BED */
1390
- level |= (s->status & (1 << 7)) && (s->control & (1 << 9));    /* IRF */
1391
- level |= (s->status & (1 << 6)) && (s->control & (1 << 8));    /* ITE */
1392
- level |= s->status & (1 << 9);                /* SAD */
1393
- qemu_set_irq(s->irq, !!level);
1394
-}
1395
-
1396
-/* These are only stubs now. */
1397
-static int pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
1398
-{
1399
- PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
1400
- PXA2xxI2CState *s = slave->host;
1401
-
1402
- switch (event) {
1403
- case I2C_START_SEND:
1404
- s->status |= (1 << 9);                /* set SAD */
1405
- s->status &= ~(1 << 0);                /* clear RWM */
1406
- break;
1407
- case I2C_START_RECV:
1408
- s->status |= (1 << 9);                /* set SAD */
1409
- s->status |= 1 << 0;                /* set RWM */
1410
- break;
1411
- case I2C_FINISH:
1412
- s->status |= (1 << 4);                /* set SSD */
1413
- break;
1414
- case I2C_NACK:
1415
- s->status |= 1 << 1;                /* set ACKNAK */
1416
- break;
1417
- default:
1418
- return -1;
1419
- }
1420
- pxa2xx_i2c_update(s);
1421
-
1422
- return 0;
1423
-}
1424
-
1425
-static uint8_t pxa2xx_i2c_rx(I2CSlave *i2c)
1426
-{
1427
- PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
1428
- PXA2xxI2CState *s = slave->host;
1429
-
1430
- if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) {
1431
- return 0;
1432
- }
1433
-
1434
- if (s->status & (1 << 0)) {            /* RWM */
1435
- s->status |= 1 << 6;            /* set ITE */
1436
- }
1437
- pxa2xx_i2c_update(s);
1438
-
1439
- return s->data;
1440
-}
1441
-
1442
-static int pxa2xx_i2c_tx(I2CSlave *i2c, uint8_t data)
1443
-{
1444
- PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
1445
- PXA2xxI2CState *s = slave->host;
1446
-
1447
- if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) {
1448
- return 1;
1449
- }
1450
-
1451
- if (!(s->status & (1 << 0))) {        /* RWM */
1452
- s->status |= 1 << 7;            /* set IRF */
1453
- s->data = data;
1454
- }
1455
- pxa2xx_i2c_update(s);
1456
-
1457
- return 1;
1458
-}
1459
-
1460
-static uint64_t pxa2xx_i2c_read(void *opaque, hwaddr addr,
1461
- unsigned size)
1462
-{
1463
- PXA2xxI2CState *s = (PXA2xxI2CState *) opaque;
1464
- I2CSlave *slave;
1465
-
1466
- addr -= s->offset;
1467
- switch (addr) {
1468
- case ICR:
1469
- return s->control;
1470
- case ISR:
1471
- return s->status | (i2c_bus_busy(s->bus) << 2);
1472
- case ISAR:
1473
- slave = I2C_SLAVE(s->slave);
1474
- return slave->address;
1475
- case IDBR:
1476
- return s->data;
1477
- case IBMR:
1478
- if (s->status & (1 << 2))
1479
- s->ibmr ^= 3;    /* Fake SCL and SDA pin changes */
1480
- else
1481
- s->ibmr = 0;
1482
- return s->ibmr;
1483
- default:
1484
- qemu_log_mask(LOG_GUEST_ERROR,
1485
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
1486
- __func__, addr);
1487
- break;
1488
- }
1489
- return 0;
1490
-}
1491
-
1492
-static void pxa2xx_i2c_write(void *opaque, hwaddr addr,
1493
- uint64_t value64, unsigned size)
1494
-{
1495
- PXA2xxI2CState *s = (PXA2xxI2CState *) opaque;
1496
- uint32_t value = value64;
1497
- int ack;
1498
-
1499
- addr -= s->offset;
1500
- switch (addr) {
1501
- case ICR:
1502
- s->control = value & 0xfff7;
1503
- if ((value & (1 << 3)) && (value & (1 << 6))) {    /* TB and IUE */
1504
- /* TODO: slave mode */
1505
- if (value & (1 << 0)) {            /* START condition */
1506
- if (s->data & 1)
1507
- s->status |= 1 << 0;        /* set RWM */
1508
- else
1509
- s->status &= ~(1 << 0);        /* clear RWM */
1510
- ack = !i2c_start_transfer(s->bus, s->data >> 1, s->data & 1);
1511
- } else {
1512
- if (s->status & (1 << 0)) {        /* RWM */
1513
- s->data = i2c_recv(s->bus);
1514
- if (value & (1 << 2))        /* ACKNAK */
1515
- i2c_nack(s->bus);
1516
- ack = 1;
1517
- } else
1518
- ack = !i2c_send(s->bus, s->data);
1519
- }
1520
-
1521
- if (value & (1 << 1))            /* STOP condition */
1522
- i2c_end_transfer(s->bus);
1523
-
1524
- if (ack) {
1525
- if (value & (1 << 0))            /* START condition */
1526
- s->status |= 1 << 6;        /* set ITE */
1527
- else
1528
- if (s->status & (1 << 0))        /* RWM */
1529
- s->status |= 1 << 7;        /* set IRF */
1530
- else
1531
- s->status |= 1 << 6;        /* set ITE */
1532
- s->status &= ~(1 << 1);            /* clear ACKNAK */
1533
- } else {
1534
- s->status |= 1 << 6;            /* set ITE */
1535
- s->status |= 1 << 10;            /* set BED */
1536
- s->status |= 1 << 1;            /* set ACKNAK */
1537
- }
1538
- }
1539
- if (!(value & (1 << 3)) && (value & (1 << 6)))    /* !TB and IUE */
1540
- if (value & (1 << 4))            /* MA */
1541
- i2c_end_transfer(s->bus);
1542
- pxa2xx_i2c_update(s);
1543
- break;
1544
-
1545
- case ISR:
1546
- s->status &= ~(value & 0x07f0);
1547
- pxa2xx_i2c_update(s);
1548
- break;
1549
-
1550
- case ISAR:
1551
- i2c_slave_set_address(I2C_SLAVE(s->slave), value & 0x7f);
1552
- break;
1553
-
1554
- case IDBR:
1555
- s->data = value & 0xff;
1556
- break;
1557
-
1558
- default:
1559
- qemu_log_mask(LOG_GUEST_ERROR,
1560
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
1561
- __func__, addr);
1562
- }
1563
-}
1564
-
1565
-static const MemoryRegionOps pxa2xx_i2c_ops = {
1566
- .read = pxa2xx_i2c_read,
1567
- .write = pxa2xx_i2c_write,
1568
- .endianness = DEVICE_NATIVE_ENDIAN,
1569
-};
1570
-
1571
-static const VMStateDescription vmstate_pxa2xx_i2c_slave = {
1572
- .name = "pxa2xx_i2c_slave",
1573
- .version_id = 1,
1574
- .minimum_version_id = 1,
1575
- .fields = (const VMStateField[]) {
1576
- VMSTATE_I2C_SLAVE(parent_obj, PXA2xxI2CSlaveState),
1577
- VMSTATE_END_OF_LIST()
1578
- }
1579
-};
1580
-
1581
-static const VMStateDescription vmstate_pxa2xx_i2c = {
1582
- .name = "pxa2xx_i2c",
1583
- .version_id = 1,
1584
- .minimum_version_id = 1,
1585
- .fields = (const VMStateField[]) {
1586
- VMSTATE_UINT16(control, PXA2xxI2CState),
1587
- VMSTATE_UINT16(status, PXA2xxI2CState),
1588
- VMSTATE_UINT8(ibmr, PXA2xxI2CState),
1589
- VMSTATE_UINT8(data, PXA2xxI2CState),
1590
- VMSTATE_STRUCT_POINTER(slave, PXA2xxI2CState,
1591
- vmstate_pxa2xx_i2c_slave, PXA2xxI2CSlaveState),
1592
- VMSTATE_END_OF_LIST()
1593
- }
1594
-};
1595
-
1596
-static void pxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data)
1597
-{
1598
- I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
1599
-
1600
- k->event = pxa2xx_i2c_event;
1601
- k->recv = pxa2xx_i2c_rx;
1602
- k->send = pxa2xx_i2c_tx;
1603
-}
1604
-
1605
-static const TypeInfo pxa2xx_i2c_slave_info = {
1606
- .name = TYPE_PXA2XX_I2C_SLAVE,
1607
- .parent = TYPE_I2C_SLAVE,
1608
- .instance_size = sizeof(PXA2xxI2CSlaveState),
1609
- .class_init = pxa2xx_i2c_slave_class_init,
1610
-};
1611
-
1612
-PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
1613
- qemu_irq irq, uint32_t region_size)
1614
-{
1615
- DeviceState *dev;
1616
- SysBusDevice *i2c_dev;
1617
- PXA2xxI2CState *s;
1618
- I2CBus *i2cbus;
1619
-
1620
- dev = qdev_new(TYPE_PXA2XX_I2C);
1621
- qdev_prop_set_uint32(dev, "size", region_size + 1);
1622
- qdev_prop_set_uint32(dev, "offset", base & region_size);
1623
-
1624
- /* FIXME: Should the slave device really be on a separate bus? */
1625
- i2cbus = i2c_init_bus(dev, "dummy");
1626
-
1627
- i2c_dev = SYS_BUS_DEVICE(dev);
1628
- sysbus_realize_and_unref(i2c_dev, &error_fatal);
1629
- sysbus_mmio_map(i2c_dev, 0, base & ~region_size);
1630
- sysbus_connect_irq(i2c_dev, 0, irq);
1631
-
1632
- s = PXA2XX_I2C(i2c_dev);
1633
- s->slave = PXA2XX_I2C_SLAVE(i2c_slave_create_simple(i2cbus,
1634
- TYPE_PXA2XX_I2C_SLAVE,
1635
- 0));
1636
- s->slave->host = s;
1637
-
1638
- return s;
1639
-}
1640
-
1641
-static void pxa2xx_i2c_initfn(Object *obj)
1642
-{
1643
- DeviceState *dev = DEVICE(obj);
1644
- PXA2xxI2CState *s = PXA2XX_I2C(obj);
1645
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1646
-
1647
- s->bus = i2c_init_bus(dev, NULL);
1648
-
1649
- memory_region_init_io(&s->iomem, obj, &pxa2xx_i2c_ops, s,
1650
- "pxa2xx-i2c", s->region_size);
1651
- sysbus_init_mmio(sbd, &s->iomem);
1652
- sysbus_init_irq(sbd, &s->irq);
1653
-}
1654
-
1655
-I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s)
1656
-{
1657
- return s->bus;
1658
-}
1659
-
1660
-static Property pxa2xx_i2c_properties[] = {
1661
- DEFINE_PROP_UINT32("size", PXA2xxI2CState, region_size, 0x10000),
1662
- DEFINE_PROP_UINT32("offset", PXA2xxI2CState, offset, 0),
1663
- DEFINE_PROP_END_OF_LIST(),
1664
-};
1665
-
1666
-static void pxa2xx_i2c_class_init(ObjectClass *klass, void *data)
1667
-{
1668
- DeviceClass *dc = DEVICE_CLASS(klass);
1669
-
1670
- dc->desc = "PXA2xx I2C Bus Controller";
1671
- dc->vmsd = &vmstate_pxa2xx_i2c;
1672
- device_class_set_props(dc, pxa2xx_i2c_properties);
1673
-}
1674
-
1675
-static const TypeInfo pxa2xx_i2c_info = {
1676
- .name = TYPE_PXA2XX_I2C,
1677
- .parent = TYPE_SYS_BUS_DEVICE,
1678
- .instance_size = sizeof(PXA2xxI2CState),
1679
- .instance_init = pxa2xx_i2c_initfn,
1680
- .class_init = pxa2xx_i2c_class_init,
1681
-};
1682
-
1683
-/* PXA Inter-IC Sound Controller */
1684
-static void pxa2xx_i2s_reset(PXA2xxI2SState *i2s)
1685
-{
1686
- i2s->rx_len = 0;
1687
- i2s->tx_len = 0;
1688
- i2s->fifo_len = 0;
1689
- i2s->clk = 0x1a;
1690
- i2s->control[0] = 0x00;
1691
- i2s->control[1] = 0x00;
1692
- i2s->status = 0x00;
1693
- i2s->mask = 0x00;
1694
-}
1695
-
1696
-#define SACR_TFTH(val)    ((val >> 8) & 0xf)
1697
-#define SACR_RFTH(val)    ((val >> 12) & 0xf)
1698
-#define SACR_DREC(val)    (val & (1 << 3))
1699
-#define SACR_DPRL(val)    (val & (1 << 4))
1700
-
1701
-static inline void pxa2xx_i2s_update(PXA2xxI2SState *i2s)
1702
-{
1703
- int rfs, tfs;
1704
- rfs = SACR_RFTH(i2s->control[0]) < i2s->rx_len &&
1705
- !SACR_DREC(i2s->control[1]);
1706
- tfs = (i2s->tx_len || i2s->fifo_len < SACR_TFTH(i2s->control[0])) &&
1707
- i2s->enable && !SACR_DPRL(i2s->control[1]);
1708
-
1709
- qemu_set_irq(i2s->rx_dma, rfs);
1710
- qemu_set_irq(i2s->tx_dma, tfs);
1711
-
1712
- i2s->status &= 0xe0;
1713
- if (i2s->fifo_len < 16 || !i2s->enable)
1714
- i2s->status |= 1 << 0;            /* TNF */
1715
- if (i2s->rx_len)
1716
- i2s->status |= 1 << 1;            /* RNE */
1717
- if (i2s->enable)
1718
- i2s->status |= 1 << 2;            /* BSY */
1719
- if (tfs)
1720
- i2s->status |= 1 << 3;            /* TFS */
1721
- if (rfs)
1722
- i2s->status |= 1 << 4;            /* RFS */
1723
- if (!(i2s->tx_len && i2s->enable))
1724
- i2s->status |= i2s->fifo_len << 8;    /* TFL */
1725
- i2s->status |= MAX(i2s->rx_len, 0xf) << 12;    /* RFL */
1726
-
1727
- qemu_set_irq(i2s->irq, i2s->status & i2s->mask);
1728
-}
1729
-
1730
-#define SACR0    0x00    /* Serial Audio Global Control register */
1731
-#define SACR1    0x04    /* Serial Audio I2S/MSB-Justified Control register */
1732
-#define SASR0    0x0c    /* Serial Audio Interface and FIFO Status register */
1733
-#define SAIMR    0x14    /* Serial Audio Interrupt Mask register */
1734
-#define SAICR    0x18    /* Serial Audio Interrupt Clear register */
1735
-#define SADIV    0x60    /* Serial Audio Clock Divider register */
1736
-#define SADR    0x80    /* Serial Audio Data register */
1737
-
1738
-static uint64_t pxa2xx_i2s_read(void *opaque, hwaddr addr,
1739
- unsigned size)
1740
-{
1741
- PXA2xxI2SState *s = (PXA2xxI2SState *) opaque;
1742
-
1743
- switch (addr) {
1744
- case SACR0:
1745
- return s->control[0];
1746
- case SACR1:
1747
- return s->control[1];
1748
- case SASR0:
1749
- return s->status;
1750
- case SAIMR:
1751
- return s->mask;
1752
- case SAICR:
1753
- return 0;
1754
- case SADIV:
1755
- return s->clk;
1756
- case SADR:
1757
- if (s->rx_len > 0) {
1758
- s->rx_len --;
1759
- pxa2xx_i2s_update(s);
1760
- return s->codec_in(s->opaque);
1761
- }
1762
- return 0;
1763
- default:
1764
- qemu_log_mask(LOG_GUEST_ERROR,
1765
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
1766
- __func__, addr);
1767
- break;
1768
- }
1769
- return 0;
1770
-}
1771
-
1772
-static void pxa2xx_i2s_write(void *opaque, hwaddr addr,
1773
- uint64_t value, unsigned size)
1774
-{
1775
- PXA2xxI2SState *s = (PXA2xxI2SState *) opaque;
1776
- uint32_t *sample;
1777
-
1778
- switch (addr) {
1779
- case SACR0:
1780
- if (value & (1 << 3))                /* RST */
1781
- pxa2xx_i2s_reset(s);
1782
- s->control[0] = value & 0xff3d;
1783
- if (!s->enable && (value & 1) && s->tx_len) {    /* ENB */
1784
- for (sample = s->fifo; s->fifo_len > 0; s->fifo_len --, sample ++)
1785
- s->codec_out(s->opaque, *sample);
1786
- s->status &= ~(1 << 7);            /* I2SOFF */
1787
- }
1788
- if (value & (1 << 4))                /* EFWR */
1789
- printf("%s: Attempt to use special function\n", __func__);
1790
- s->enable = (value & 9) == 1;            /* ENB && !RST*/
1791
- pxa2xx_i2s_update(s);
1792
- break;
1793
- case SACR1:
1794
- s->control[1] = value & 0x0039;
1795
- if (value & (1 << 5))                /* ENLBF */
1796
- printf("%s: Attempt to use loopback function\n", __func__);
1797
- if (value & (1 << 4))                /* DPRL */
1798
- s->fifo_len = 0;
1799
- pxa2xx_i2s_update(s);
1800
- break;
1801
- case SAIMR:
1802
- s->mask = value & 0x0078;
1803
- pxa2xx_i2s_update(s);
1804
- break;
1805
- case SAICR:
1806
- s->status &= ~(value & (3 << 5));
1807
- pxa2xx_i2s_update(s);
1808
- break;
1809
- case SADIV:
1810
- s->clk = value & 0x007f;
1811
- break;
1812
- case SADR:
1813
- if (s->tx_len && s->enable) {
1814
- s->tx_len --;
1815
- pxa2xx_i2s_update(s);
1816
- s->codec_out(s->opaque, value);
1817
- } else if (s->fifo_len < 16) {
1818
- s->fifo[s->fifo_len ++] = value;
1819
- pxa2xx_i2s_update(s);
1820
- }
1821
- break;
266
- break;
1822
- default:
267
- default:
1823
- qemu_log_mask(LOG_GUEST_ERROR,
268
- qemu_log_mask(LOG_GUEST_ERROR,
1824
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
269
- "do_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
1825
- __func__, addr);
1826
- }
270
- }
1827
-}
271
-}
1828
-
272
-
1829
-static const MemoryRegionOps pxa2xx_i2s_ops = {
273
static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
1830
- .read = pxa2xx_i2s_read,
274
{
1831
- .write = pxa2xx_i2s_write,
275
switch (reg) {
1832
- .endianness = DEVICE_NATIVE_ENDIAN,
276
@@ -XXX,XX +XXX,XX @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
1833
-};
277
if (val & 2) {
1834
-
278
DPRINTF("PHY write %d = 0x%04x\n",
1835
-static const VMStateDescription vmstate_pxa2xx_i2s = {
279
(val >> 6) & 0x1f, s->mac_mii_data);
1836
- .name = "pxa2xx_i2s",
280
- do_phy_write(s, (val >> 6) & 0x1f, s->mac_mii_data);
1837
- .version_id = 0,
281
+ lan9118_phy_write(&s->mii, (val >> 6) & 0x1f, s->mac_mii_data);
1838
- .minimum_version_id = 0,
282
} else {
1839
- .fields = (const VMStateField[]) {
283
- s->mac_mii_data = do_phy_read(s, (val >> 6) & 0x1f);
1840
- VMSTATE_UINT32_ARRAY(control, PXA2xxI2SState, 2),
284
+ s->mac_mii_data = lan9118_phy_read(&s->mii, (val >> 6) & 0x1f);
1841
- VMSTATE_UINT32(status, PXA2xxI2SState),
285
DPRINTF("PHY read %d = 0x%04x\n",
1842
- VMSTATE_UINT32(mask, PXA2xxI2SState),
286
(val >> 6) & 0x1f, s->mac_mii_data);
1843
- VMSTATE_UINT32(clk, PXA2xxI2SState),
287
}
1844
- VMSTATE_INT32(enable, PXA2xxI2SState),
288
@@ -XXX,XX +XXX,XX @@ static void lan9118_writel(void *opaque, hwaddr offset,
1845
- VMSTATE_INT32(rx_len, PXA2xxI2SState),
289
break;
1846
- VMSTATE_INT32(tx_len, PXA2xxI2SState),
290
case CSR_PMT_CTRL:
1847
- VMSTATE_INT32(fifo_len, PXA2xxI2SState),
291
if (val & 0x400) {
1848
- VMSTATE_END_OF_LIST()
292
- phy_reset(s);
1849
- }
293
+ lan9118_phy_reset(&s->mii);
1850
-};
294
}
1851
-
295
s->pmt_ctrl &= ~0x34e;
1852
-static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx)
296
s->pmt_ctrl |= (val & 0x34e);
1853
-{
297
@@ -XXX,XX +XXX,XX @@ static void lan9118_realize(DeviceState *dev, Error **errp)
1854
- PXA2xxI2SState *s = (PXA2xxI2SState *) opaque;
298
const MemoryRegionOps *mem_ops =
1855
- uint32_t *sample;
299
s->mode_16bit ? &lan9118_16bit_mem_ops : &lan9118_mem_ops;
1856
-
300
1857
- /* Signal FIFO errors */
301
+ qemu_init_irq(&s->mii_irq, lan9118_update_irq, s, 0);
1858
- if (s->enable && s->tx_len)
302
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
1859
- s->status |= 1 << 5;        /* TUR */
303
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
1860
- if (s->enable && s->rx_len)
304
+ return;
1861
- s->status |= 1 << 6;        /* ROR */
305
+ }
1862
-
306
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
1863
- /* Should be tx - MIN(tx, s->fifo_len) but we don't really need to
307
+
1864
- * handle the cases where it makes a difference. */
308
memory_region_init_io(&s->mmio, OBJECT(dev), mem_ops, s,
1865
- s->tx_len = tx - s->fifo_len;
309
"lan9118-mmio", 0x100);
1866
- s->rx_len = rx;
310
sysbus_init_mmio(sbd, &s->mmio);
1867
- /* Note that is s->codec_out wasn't set, we wouldn't get called. */
311
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
1868
- if (s->enable)
312
new file mode 100644
1869
- for (sample = s->fifo; s->fifo_len; s->fifo_len --, sample ++)
313
index XXXXXXX..XXXXXXX
1870
- s->codec_out(s->opaque, *sample);
314
--- /dev/null
1871
- pxa2xx_i2s_update(s);
315
+++ b/hw/net/lan9118_phy.c
1872
-}
316
@@ -XXX,XX +XXX,XX @@
1873
-
317
+/*
1874
-static PXA2xxI2SState *pxa2xx_i2s_init(MemoryRegion *sysmem,
318
+ * SMSC LAN9118 PHY emulation
1875
- hwaddr base,
319
+ *
1876
- qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma)
320
+ * Copyright (c) 2009 CodeSourcery, LLC.
1877
-{
321
+ * Written by Paul Brook
1878
- PXA2xxI2SState *s = g_new0(PXA2xxI2SState, 1);
322
+ *
1879
-
323
+ * This code is licensed under the GNU GPL v2
1880
- s->irq = irq;
324
+ *
1881
- s->rx_dma = rx_dma;
325
+ * Contributions after 2012-01-13 are licensed under the terms of the
1882
- s->tx_dma = tx_dma;
326
+ * GNU GPL, version 2 or (at your option) any later version.
1883
- s->data_req = pxa2xx_i2s_data_req;
327
+ */
1884
-
328
+
1885
- pxa2xx_i2s_reset(s);
329
+#include "qemu/osdep.h"
1886
-
330
+#include "hw/net/lan9118_phy.h"
1887
- memory_region_init_io(&s->iomem, NULL, &pxa2xx_i2s_ops, s,
331
+#include "hw/irq.h"
1888
- "pxa2xx-i2s", 0x100000);
332
+#include "hw/resettable.h"
1889
- memory_region_add_subregion(sysmem, base, &s->iomem);
333
+#include "migration/vmstate.h"
1890
-
334
+#include "qemu/log.h"
1891
- vmstate_register(NULL, base, &vmstate_pxa2xx_i2s, s);
335
+
1892
-
336
+#define PHY_INT_ENERGYON (1 << 7)
1893
- return s;
337
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
1894
-}
338
+#define PHY_INT_FAULT (1 << 5)
1895
-
339
+#define PHY_INT_DOWN (1 << 4)
1896
-/* PXA Fast Infra-red Communications Port */
340
+#define PHY_INT_AUTONEG_LP (1 << 3)
1897
-struct PXA2xxFIrState {
341
+#define PHY_INT_PARFAULT (1 << 2)
1898
- /*< private >*/
342
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
1899
- SysBusDevice parent_obj;
343
+
1900
- /*< public >*/
344
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
1901
-
345
+{
1902
- MemoryRegion iomem;
346
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
1903
- qemu_irq irq;
347
+}
1904
- qemu_irq rx_dma;
348
+
1905
- qemu_irq tx_dma;
349
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
1906
- uint32_t enable;
350
+{
1907
- CharBackend chr;
351
+ uint16_t val;
1908
-
352
+
1909
- uint8_t control[3];
353
+ switch (reg) {
1910
- uint8_t status[2];
354
+ case 0: /* Basic Control */
1911
-
355
+ return s->control;
1912
- uint32_t rx_len;
356
+ case 1: /* Basic Status */
1913
- uint32_t rx_start;
357
+ return s->status;
1914
- uint8_t rx_fifo[64];
358
+ case 2: /* ID1 */
1915
-};
359
+ return 0x0007;
1916
-
360
+ case 3: /* ID2 */
1917
-static void pxa2xx_fir_reset(DeviceState *d)
361
+ return 0xc0d1;
1918
-{
362
+ case 4: /* Auto-neg advertisement */
1919
- PXA2xxFIrState *s = PXA2XX_FIR(d);
363
+ return s->advertise;
1920
-
364
+ case 5: /* Auto-neg Link Partner Ability */
1921
- s->control[0] = 0x00;
365
+ return 0x0f71;
1922
- s->control[1] = 0x00;
366
+ case 6: /* Auto-neg Expansion */
1923
- s->control[2] = 0x00;
367
+ return 1;
1924
- s->status[0] = 0x00;
368
+ /* TODO 17, 18, 27, 29, 30, 31 */
1925
- s->status[1] = 0x00;
369
+ case 29: /* Interrupt source. */
1926
- s->enable = 0;
370
+ val = s->ints;
1927
-}
371
+ s->ints = 0;
1928
-
372
+ lan9118_phy_update_irq(s);
1929
-static inline void pxa2xx_fir_update(PXA2xxFIrState *s)
373
+ return val;
1930
-{
374
+ case 30: /* Interrupt mask */
1931
- static const int tresh[4] = { 8, 16, 32, 0 };
375
+ return s->int_mask;
1932
- int intr = 0;
376
+ default:
1933
- if ((s->control[0] & (1 << 4)) &&            /* RXE */
377
+ qemu_log_mask(LOG_GUEST_ERROR,
1934
- s->rx_len >= tresh[s->control[2] & 3])    /* TRIG */
378
+ "lan9118_phy_read: PHY read reg %d\n", reg);
1935
- s->status[0] |= 1 << 4;                /* RFS */
379
+ return 0;
1936
- else
380
+ }
1937
- s->status[0] &= ~(1 << 4);            /* RFS */
381
+}
1938
- if (s->control[0] & (1 << 3))            /* TXE */
382
+
1939
- s->status[0] |= 1 << 3;                /* TFS */
383
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
1940
- else
384
+{
1941
- s->status[0] &= ~(1 << 3);            /* TFS */
385
+ switch (reg) {
1942
- if (s->rx_len)
386
+ case 0: /* Basic Control */
1943
- s->status[1] |= 1 << 2;                /* RNE */
387
+ if (val & 0x8000) {
1944
- else
388
+ lan9118_phy_reset(s);
1945
- s->status[1] &= ~(1 << 2);            /* RNE */
389
+ break;
1946
- if (s->control[0] & (1 << 4))            /* RXE */
390
+ }
1947
- s->status[1] |= 1 << 0;                /* RSY */
391
+ s->control = val & 0x7980;
1948
- else
392
+ /* Complete autonegotiation immediately. */
1949
- s->status[1] &= ~(1 << 0);            /* RSY */
393
+ if (val & 0x1000) {
1950
-
394
+ s->status |= 0x0020;
1951
- intr |= (s->control[0] & (1 << 5)) &&        /* RIE */
395
+ }
1952
- (s->status[0] & (1 << 4));            /* RFS */
396
+ break;
1953
- intr |= (s->control[0] & (1 << 6)) &&        /* TIE */
397
+ case 4: /* Auto-neg advertisement */
1954
- (s->status[0] & (1 << 3));            /* TFS */
398
+ s->advertise = (val & 0x2d7f) | 0x80;
1955
- intr |= (s->control[2] & (1 << 4)) &&        /* TRAIL */
399
+ break;
1956
- (s->status[0] & (1 << 6));            /* EOC */
400
+ /* TODO 17, 18, 27, 31 */
1957
- intr |= (s->control[0] & (1 << 2)) &&        /* TUS */
401
+ case 30: /* Interrupt mask */
1958
- (s->status[0] & (1 << 1));            /* TUR */
402
+ s->int_mask = val & 0xff;
1959
- intr |= s->status[0] & 0x25;            /* FRE, RAB, EIF */
403
+ lan9118_phy_update_irq(s);
1960
-
404
+ break;
1961
- qemu_set_irq(s->rx_dma, (s->status[0] >> 4) & 1);
405
+ default:
1962
- qemu_set_irq(s->tx_dma, (s->status[0] >> 3) & 1);
406
+ qemu_log_mask(LOG_GUEST_ERROR,
1963
-
407
+ "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
1964
- qemu_set_irq(s->irq, intr && s->enable);
408
+ }
1965
-}
409
+}
1966
-
410
+
1967
-#define ICCR0    0x00    /* FICP Control register 0 */
411
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
1968
-#define ICCR1    0x04    /* FICP Control register 1 */
412
+{
1969
-#define ICCR2    0x08    /* FICP Control register 2 */
413
+ s->link_down = link_down;
1970
-#define ICDR    0x0c    /* FICP Data register */
414
+
1971
-#define ICSR0    0x14    /* FICP Status register 0 */
415
+ /* Autonegotiation status mirrors link status. */
1972
-#define ICSR1    0x18    /* FICP Status register 1 */
416
+ if (link_down) {
1973
-#define ICFOR    0x1c    /* FICP FIFO Occupancy Status register */
417
+ s->status &= ~0x0024;
1974
-
418
+ s->ints |= PHY_INT_DOWN;
1975
-static uint64_t pxa2xx_fir_read(void *opaque, hwaddr addr,
419
+ } else {
1976
- unsigned size)
420
+ s->status |= 0x0024;
1977
-{
421
+ s->ints |= PHY_INT_ENERGYON;
1978
- PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
422
+ s->ints |= PHY_INT_AUTONEG_COMPLETE;
1979
- uint8_t ret;
423
+ }
1980
-
424
+ lan9118_phy_update_irq(s);
1981
- switch (addr) {
425
+}
1982
- case ICCR0:
426
+
1983
- return s->control[0];
427
+void lan9118_phy_reset(Lan9118PhyState *s)
1984
- case ICCR1:
428
+{
1985
- return s->control[1];
429
+ s->control = 0x3000;
1986
- case ICCR2:
430
+ s->status = 0x7809;
1987
- return s->control[2];
431
+ s->advertise = 0x01e1;
1988
- case ICDR:
432
+ s->int_mask = 0;
1989
- s->status[0] &= ~0x01;
433
+ s->ints = 0;
1990
- s->status[1] &= ~0x72;
434
+ lan9118_phy_update_link(s, s->link_down);
1991
- if (s->rx_len) {
435
+}
1992
- s->rx_len --;
436
+
1993
- ret = s->rx_fifo[s->rx_start ++];
437
+static void lan9118_phy_reset_hold(Object *obj, ResetType type)
1994
- s->rx_start &= 63;
438
+{
1995
- pxa2xx_fir_update(s);
439
+ Lan9118PhyState *s = LAN9118_PHY(obj);
1996
- return ret;
440
+
1997
- }
441
+ lan9118_phy_reset(s);
1998
- printf("%s: Rx FIFO underrun.\n", __func__);
442
+}
1999
- break;
443
+
2000
- case ICSR0:
444
+static void lan9118_phy_init(Object *obj)
2001
- return s->status[0];
445
+{
2002
- case ICSR1:
446
+ Lan9118PhyState *s = LAN9118_PHY(obj);
2003
- return s->status[1] | (1 << 3);            /* TNF */
447
+
2004
- case ICFOR:
448
+ qdev_init_gpio_out(DEVICE(s), &s->irq, 1);
2005
- return s->rx_len;
449
+}
2006
- default:
450
+
2007
- qemu_log_mask(LOG_GUEST_ERROR,
451
+static const VMStateDescription vmstate_lan9118_phy = {
2008
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
452
+ .name = "lan9118-phy",
2009
- __func__, addr);
453
+ .version_id = 1,
2010
- break;
454
+ .minimum_version_id = 1,
2011
- }
455
+ .fields = (const VMStateField[]) {
2012
- return 0;
456
+ VMSTATE_UINT16(control, Lan9118PhyState),
2013
-}
457
+ VMSTATE_UINT16(status, Lan9118PhyState),
2014
-
458
+ VMSTATE_UINT16(advertise, Lan9118PhyState),
2015
-static void pxa2xx_fir_write(void *opaque, hwaddr addr,
459
+ VMSTATE_UINT16(ints, Lan9118PhyState),
2016
- uint64_t value64, unsigned size)
460
+ VMSTATE_UINT16(int_mask, Lan9118PhyState),
2017
-{
461
+ VMSTATE_BOOL(link_down, Lan9118PhyState),
2018
- PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
462
+ VMSTATE_END_OF_LIST()
2019
- uint32_t value = value64;
463
+ }
2020
- uint8_t ch;
464
+};
2021
-
465
+
2022
- switch (addr) {
466
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
2023
- case ICCR0:
467
+{
2024
- s->control[0] = value;
468
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
2025
- if (!(value & (1 << 4)))            /* RXE */
469
+ DeviceClass *dc = DEVICE_CLASS(klass);
2026
- s->rx_len = s->rx_start = 0;
470
+
2027
- if (!(value & (1 << 3))) { /* TXE */
471
+ rc->phases.hold = lan9118_phy_reset_hold;
2028
- /* Nop */
472
+ dc->vmsd = &vmstate_lan9118_phy;
2029
- }
473
+}
2030
- s->enable = value & 1;                /* ITR */
474
+
2031
- if (!s->enable)
475
+static const TypeInfo types[] = {
2032
- s->status[0] = 0;
476
+ {
2033
- pxa2xx_fir_update(s);
477
+ .name = TYPE_LAN9118_PHY,
2034
- break;
478
+ .parent = TYPE_SYS_BUS_DEVICE,
2035
- case ICCR1:
479
+ .instance_size = sizeof(Lan9118PhyState),
2036
- s->control[1] = value;
480
+ .instance_init = lan9118_phy_init,
2037
- break;
481
+ .class_init = lan9118_phy_class_init,
2038
- case ICCR2:
482
+ }
2039
- s->control[2] = value & 0x3f;
483
+};
2040
- pxa2xx_fir_update(s);
484
+
2041
- break;
485
+DEFINE_TYPES(types)
2042
- case ICDR:
486
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
2043
- if (s->control[2] & (1 << 2)) { /* TXP */
2044
- ch = value;
2045
- } else {
2046
- ch = ~value;
2047
- }
2048
- if (s->enable && (s->control[0] & (1 << 3))) { /* TXE */
2049
- /* XXX this blocks entire thread. Rewrite to use
2050
- * qemu_chr_fe_write and background I/O callbacks */
2051
- qemu_chr_fe_write_all(&s->chr, &ch, 1);
2052
- }
2053
- break;
2054
- case ICSR0:
2055
- s->status[0] &= ~(value & 0x66);
2056
- pxa2xx_fir_update(s);
2057
- break;
2058
- case ICFOR:
2059
- break;
2060
- default:
2061
- qemu_log_mask(LOG_GUEST_ERROR,
2062
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
2063
- __func__, addr);
2064
- }
2065
-}
2066
-
2067
-static const MemoryRegionOps pxa2xx_fir_ops = {
2068
- .read = pxa2xx_fir_read,
2069
- .write = pxa2xx_fir_write,
2070
- .endianness = DEVICE_NATIVE_ENDIAN,
2071
-};
2072
-
2073
-static int pxa2xx_fir_is_empty(void *opaque)
2074
-{
2075
- PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
2076
- return (s->rx_len < 64);
2077
-}
2078
-
2079
-static void pxa2xx_fir_rx(void *opaque, const uint8_t *buf, int size)
2080
-{
2081
- PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
2082
- if (!(s->control[0] & (1 << 4)))            /* RXE */
2083
- return;
2084
-
2085
- while (size --) {
2086
- s->status[1] |= 1 << 4;                /* EOF */
2087
- if (s->rx_len >= 64) {
2088
- s->status[1] |= 1 << 6;            /* ROR */
2089
- break;
2090
- }
2091
-
2092
- if (s->control[2] & (1 << 3))            /* RXP */
2093
- s->rx_fifo[(s->rx_start + s->rx_len ++) & 63] = *(buf ++);
2094
- else
2095
- s->rx_fifo[(s->rx_start + s->rx_len ++) & 63] = ~*(buf ++);
2096
- }
2097
-
2098
- pxa2xx_fir_update(s);
2099
-}
2100
-
2101
-static void pxa2xx_fir_event(void *opaque, QEMUChrEvent event)
2102
-{
2103
-}
2104
-
2105
-static void pxa2xx_fir_instance_init(Object *obj)
2106
-{
2107
- PXA2xxFIrState *s = PXA2XX_FIR(obj);
2108
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
2109
-
2110
- memory_region_init_io(&s->iomem, obj, &pxa2xx_fir_ops, s,
2111
- "pxa2xx-fir", 0x1000);
2112
- sysbus_init_mmio(sbd, &s->iomem);
2113
- sysbus_init_irq(sbd, &s->irq);
2114
- sysbus_init_irq(sbd, &s->rx_dma);
2115
- sysbus_init_irq(sbd, &s->tx_dma);
2116
-}
2117
-
2118
-static void pxa2xx_fir_realize(DeviceState *dev, Error **errp)
2119
-{
2120
- PXA2xxFIrState *s = PXA2XX_FIR(dev);
2121
-
2122
- qemu_chr_fe_set_handlers(&s->chr, pxa2xx_fir_is_empty,
2123
- pxa2xx_fir_rx, pxa2xx_fir_event, NULL, s, NULL,
2124
- true);
2125
-}
2126
-
2127
-static bool pxa2xx_fir_vmstate_validate(void *opaque, int version_id)
2128
-{
2129
- PXA2xxFIrState *s = opaque;
2130
-
2131
- return s->rx_start < ARRAY_SIZE(s->rx_fifo);
2132
-}
2133
-
2134
-static const VMStateDescription pxa2xx_fir_vmsd = {
2135
- .name = "pxa2xx-fir",
2136
- .version_id = 1,
2137
- .minimum_version_id = 1,
2138
- .fields = (const VMStateField[]) {
2139
- VMSTATE_UINT32(enable, PXA2xxFIrState),
2140
- VMSTATE_UINT8_ARRAY(control, PXA2xxFIrState, 3),
2141
- VMSTATE_UINT8_ARRAY(status, PXA2xxFIrState, 2),
2142
- VMSTATE_UINT32(rx_len, PXA2xxFIrState),
2143
- VMSTATE_UINT32(rx_start, PXA2xxFIrState),
2144
- VMSTATE_VALIDATE("fifo is 64 bytes", pxa2xx_fir_vmstate_validate),
2145
- VMSTATE_UINT8_ARRAY(rx_fifo, PXA2xxFIrState, 64),
2146
- VMSTATE_END_OF_LIST()
2147
- }
2148
-};
2149
-
2150
-static Property pxa2xx_fir_properties[] = {
2151
- DEFINE_PROP_CHR("chardev", PXA2xxFIrState, chr),
2152
- DEFINE_PROP_END_OF_LIST(),
2153
-};
2154
-
2155
-static void pxa2xx_fir_class_init(ObjectClass *klass, void *data)
2156
-{
2157
- DeviceClass *dc = DEVICE_CLASS(klass);
2158
-
2159
- dc->realize = pxa2xx_fir_realize;
2160
- dc->vmsd = &pxa2xx_fir_vmsd;
2161
- device_class_set_props(dc, pxa2xx_fir_properties);
2162
- device_class_set_legacy_reset(dc, pxa2xx_fir_reset);
2163
-}
2164
-
2165
-static const TypeInfo pxa2xx_fir_info = {
2166
- .name = TYPE_PXA2XX_FIR,
2167
- .parent = TYPE_SYS_BUS_DEVICE,
2168
- .instance_size = sizeof(PXA2xxFIrState),
2169
- .class_init = pxa2xx_fir_class_init,
2170
- .instance_init = pxa2xx_fir_instance_init,
2171
-};
2172
-
2173
-static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
2174
- hwaddr base,
2175
- qemu_irq irq, qemu_irq rx_dma,
2176
- qemu_irq tx_dma,
2177
- Chardev *chr)
2178
-{
2179
- DeviceState *dev;
2180
- SysBusDevice *sbd;
2181
-
2182
- dev = qdev_new(TYPE_PXA2XX_FIR);
2183
- qdev_prop_set_chr(dev, "chardev", chr);
2184
- sbd = SYS_BUS_DEVICE(dev);
2185
- sysbus_realize_and_unref(sbd, &error_fatal);
2186
- sysbus_mmio_map(sbd, 0, base);
2187
- sysbus_connect_irq(sbd, 0, irq);
2188
- sysbus_connect_irq(sbd, 1, rx_dma);
2189
- sysbus_connect_irq(sbd, 2, tx_dma);
2190
- return PXA2XX_FIR(dev);
2191
-}
2192
-
2193
-static void pxa2xx_reset(void *opaque, int line, int level)
2194
-{
2195
- PXA2xxState *s = (PXA2xxState *) opaque;
2196
-
2197
- if (level && (s->pm_regs[PCFR >> 2] & 0x10)) {    /* GPR_EN */
2198
- cpu_reset(CPU(s->cpu));
2199
- /* TODO: reset peripherals */
2200
- }
2201
-}
2202
-
2203
-/* Initialise a PXA270 integrated chip (ARM based core). */
2204
-PXA2xxState *pxa270_init(unsigned int sdram_size, const char *cpu_type)
2205
-{
2206
- MemoryRegion *address_space = get_system_memory();
2207
- PXA2xxState *s;
2208
- int i;
2209
- DriveInfo *dinfo;
2210
- s = g_new0(PXA2xxState, 1);
2211
-
2212
- if (strncmp(cpu_type, "pxa27", 5)) {
2213
- error_report("Machine requires a PXA27x processor");
2214
- exit(1);
2215
- }
2216
-
2217
- s->cpu = ARM_CPU(cpu_create(cpu_type));
2218
- s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0);
2219
-
2220
- /* SDRAM & Internal Memory Storage */
2221
- memory_region_init_ram(&s->sdram, NULL, "pxa270.sdram", sdram_size,
2222
- &error_fatal);
2223
- memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
2224
- memory_region_init_ram(&s->internal, NULL, "pxa270.internal", 0x40000,
2225
- &error_fatal);
2226
- memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE,
2227
- &s->internal);
2228
-
2229
- s->pic = pxa2xx_pic_init(0x40d00000, s->cpu);
2230
-
2231
- s->dma = pxa27x_dma_init(0x40000000,
2232
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA));
2233
-
2234
- sysbus_create_varargs("pxa27x-timer", 0x40a00000,
2235
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0),
2236
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1),
2237
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2),
2238
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3),
2239
- qdev_get_gpio_in(s->pic, PXA27X_PIC_OST_4_11),
2240
- NULL);
2241
-
2242
- s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 121);
2243
-
2244
- s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
2245
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
2246
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
2247
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
2248
- dinfo = drive_get(IF_SD, 0, 0);
2249
- if (dinfo) {
2250
- DeviceState *carddev;
2251
-
2252
- /* Create and plug in the sd card */
2253
- carddev = qdev_new(TYPE_SD_CARD);
2254
- qdev_prop_set_drive_err(carddev, "drive",
2255
- blk_by_legacy_dinfo(dinfo), &error_fatal);
2256
- qdev_realize_and_unref(carddev, qdev_get_child_bus(DEVICE(s->mmc),
2257
- "sd-bus"),
2258
- &error_fatal);
2259
- } else if (!qtest_enabled()) {
2260
- warn_report("missing SecureDigital device");
2261
- }
2262
-
2263
- for (i = 0; pxa270_serial[i].io_base; i++) {
2264
- if (serial_hd(i)) {
2265
- serial_mm_init(address_space, pxa270_serial[i].io_base, 2,
2266
- qdev_get_gpio_in(s->pic, pxa270_serial[i].irqn),
2267
- 14857000 / 16, serial_hd(i),
2268
- DEVICE_NATIVE_ENDIAN);
2269
- } else {
2270
- break;
2271
- }
2272
- }
2273
- if (serial_hd(i))
2274
- s->fir = pxa2xx_fir_init(address_space, 0x40800000,
2275
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP),
2276
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP),
2277
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP),
2278
- serial_hd(i));
2279
-
2280
- s->lcd = pxa2xx_lcdc_init(address_space, 0x44000000,
2281
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
2282
-
2283
- s->cm_base = 0x41300000;
2284
- s->cm_regs[CCCR >> 2] = 0x02000210;    /* 416.0 MHz */
2285
- s->clkcfg = 0x00000009;        /* Turbo mode active */
2286
- memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000);
2287
- memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem);
2288
- vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
2289
-
2290
- pxa2xx_setup_cp14(s);
2291
-
2292
- s->mm_base = 0x48000000;
2293
- s->mm_regs[MDMRS >> 2] = 0x00020002;
2294
- s->mm_regs[MDREFR >> 2] = 0x03ca4000;
2295
- s->mm_regs[MECR >> 2] = 0x00000001;    /* Two PC Card sockets */
2296
- memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000);
2297
- memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem);
2298
- vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
2299
-
2300
- s->pm_base = 0x40f00000;
2301
- memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100);
2302
- memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem);
2303
- vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
2304
-
2305
- for (i = 0; pxa27x_ssp[i].io_base; i ++);
2306
- s->ssp = g_new0(SSIBus *, i);
2307
- for (i = 0; pxa27x_ssp[i].io_base; i ++) {
2308
- DeviceState *dev;
2309
- dev = sysbus_create_simple(TYPE_PXA2XX_SSP, pxa27x_ssp[i].io_base,
2310
- qdev_get_gpio_in(s->pic, pxa27x_ssp[i].irqn));
2311
- s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
2312
- }
2313
-
2314
- sysbus_create_simple("sysbus-ohci", 0x4c000000,
2315
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
2316
-
2317
- s->pcmcia[0] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
2318
- 0x20000000, NULL));
2319
- s->pcmcia[1] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
2320
- 0x30000000, NULL));
2321
-
2322
- sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000,
2323
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM));
2324
-
2325
- s->i2c[0] = pxa2xx_i2c_init(0x40301600,
2326
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff);
2327
- s->i2c[1] = pxa2xx_i2c_init(0x40f00100,
2328
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff);
2329
-
2330
- s->i2s = pxa2xx_i2s_init(address_space, 0x40400000,
2331
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S),
2332
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S),
2333
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S));
2334
-
2335
- s->kp = pxa27x_keypad_init(address_space, 0x41500000,
2336
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_KEYPAD));
2337
-
2338
- /* GPIO1 resets the processor */
2339
- /* The handler can be overridden by board-specific code */
2340
- qdev_connect_gpio_out(s->gpio, 1, s->reset);
2341
- return s;
2342
-}
2343
-
2344
-/* Initialise a PXA255 integrated chip (ARM based core). */
2345
-PXA2xxState *pxa255_init(unsigned int sdram_size)
2346
-{
2347
- MemoryRegion *address_space = get_system_memory();
2348
- PXA2xxState *s;
2349
- int i;
2350
- DriveInfo *dinfo;
2351
-
2352
- s = g_new0(PXA2xxState, 1);
2353
-
2354
- s->cpu = ARM_CPU(cpu_create(ARM_CPU_TYPE_NAME("pxa255")));
2355
- s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0);
2356
-
2357
- /* SDRAM & Internal Memory Storage */
2358
- memory_region_init_ram(&s->sdram, NULL, "pxa255.sdram", sdram_size,
2359
- &error_fatal);
2360
- memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
2361
- memory_region_init_ram(&s->internal, NULL, "pxa255.internal",
2362
- PXA2XX_INTERNAL_SIZE, &error_fatal);
2363
- memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE,
2364
- &s->internal);
2365
-
2366
- s->pic = pxa2xx_pic_init(0x40d00000, s->cpu);
2367
-
2368
- s->dma = pxa255_dma_init(0x40000000,
2369
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA));
2370
-
2371
- sysbus_create_varargs("pxa25x-timer", 0x40a00000,
2372
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0),
2373
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1),
2374
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2),
2375
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3),
2376
- NULL);
2377
-
2378
- s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 85);
2379
-
2380
- s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
2381
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
2382
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
2383
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
2384
- dinfo = drive_get(IF_SD, 0, 0);
2385
- if (dinfo) {
2386
- DeviceState *carddev;
2387
-
2388
- /* Create and plug in the sd card */
2389
- carddev = qdev_new(TYPE_SD_CARD);
2390
- qdev_prop_set_drive_err(carddev, "drive",
2391
- blk_by_legacy_dinfo(dinfo), &error_fatal);
2392
- qdev_realize_and_unref(carddev, qdev_get_child_bus(DEVICE(s->mmc),
2393
- "sd-bus"),
2394
- &error_fatal);
2395
- } else if (!qtest_enabled()) {
2396
- warn_report("missing SecureDigital device");
2397
- }
2398
-
2399
- for (i = 0; pxa255_serial[i].io_base; i++) {
2400
- if (serial_hd(i)) {
2401
- serial_mm_init(address_space, pxa255_serial[i].io_base, 2,
2402
- qdev_get_gpio_in(s->pic, pxa255_serial[i].irqn),
2403
- 14745600 / 16, serial_hd(i),
2404
- DEVICE_NATIVE_ENDIAN);
2405
- } else {
2406
- break;
2407
- }
2408
- }
2409
- if (serial_hd(i))
2410
- s->fir = pxa2xx_fir_init(address_space, 0x40800000,
2411
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP),
2412
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP),
2413
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP),
2414
- serial_hd(i));
2415
-
2416
- s->lcd = pxa2xx_lcdc_init(address_space, 0x44000000,
2417
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
2418
-
2419
- s->cm_base = 0x41300000;
2420
- s->cm_regs[CCCR >> 2] = 0x00000121; /* from datasheet */
2421
- s->cm_regs[CKEN >> 2] = 0x00017def; /* from datasheet */
2422
-
2423
- s->clkcfg = 0x00000009;        /* Turbo mode active */
2424
- memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000);
2425
- memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem);
2426
- vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
2427
-
2428
- pxa2xx_setup_cp14(s);
2429
-
2430
- s->mm_base = 0x48000000;
2431
- s->mm_regs[MDMRS >> 2] = 0x00020002;
2432
- s->mm_regs[MDREFR >> 2] = 0x03ca4000;
2433
- s->mm_regs[MECR >> 2] = 0x00000001;    /* Two PC Card sockets */
2434
- memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000);
2435
- memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem);
2436
- vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
2437
-
2438
- s->pm_base = 0x40f00000;
2439
- memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100);
2440
- memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem);
2441
- vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
2442
-
2443
- for (i = 0; pxa255_ssp[i].io_base; i ++);
2444
- s->ssp = g_new0(SSIBus *, i);
2445
- for (i = 0; pxa255_ssp[i].io_base; i ++) {
2446
- DeviceState *dev;
2447
- dev = sysbus_create_simple(TYPE_PXA2XX_SSP, pxa255_ssp[i].io_base,
2448
- qdev_get_gpio_in(s->pic, pxa255_ssp[i].irqn));
2449
- s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
2450
- }
2451
-
2452
- s->pcmcia[0] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
2453
- 0x20000000, NULL));
2454
- s->pcmcia[1] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
2455
- 0x30000000, NULL));
2456
-
2457
- sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000,
2458
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM));
2459
-
2460
- s->i2c[0] = pxa2xx_i2c_init(0x40301600,
2461
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff);
2462
- s->i2c[1] = pxa2xx_i2c_init(0x40f00100,
2463
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff);
2464
-
2465
- s->i2s = pxa2xx_i2s_init(address_space, 0x40400000,
2466
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S),
2467
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S),
2468
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S));
2469
-
2470
- /* GPIO1 resets the processor */
2471
- /* The handler can be overridden by board-specific code */
2472
- qdev_connect_gpio_out(s->gpio, 1, s->reset);
2473
- return s;
2474
-}
2475
-
2476
-static void pxa2xx_ssp_class_init(ObjectClass *klass, void *data)
2477
-{
2478
- DeviceClass *dc = DEVICE_CLASS(klass);
2479
-
2480
- device_class_set_legacy_reset(dc, pxa2xx_ssp_reset);
2481
- dc->vmsd = &vmstate_pxa2xx_ssp;
2482
-}
2483
-
2484
-static const TypeInfo pxa2xx_ssp_info = {
2485
- .name = TYPE_PXA2XX_SSP,
2486
- .parent = TYPE_SYS_BUS_DEVICE,
2487
- .instance_size = sizeof(PXA2xxSSPState),
2488
- .instance_init = pxa2xx_ssp_init,
2489
- .class_init = pxa2xx_ssp_class_init,
2490
-};
2491
-
2492
-static void pxa2xx_register_types(void)
2493
-{
2494
- type_register_static(&pxa2xx_i2c_slave_info);
2495
- type_register_static(&pxa2xx_ssp_info);
2496
- type_register_static(&pxa2xx_i2c_info);
2497
- type_register_static(&pxa2xx_rtc_sysbus_info);
2498
- type_register_static(&pxa2xx_fir_info);
2499
-}
2500
-
2501
-type_init(pxa2xx_register_types)
2502
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
2503
index XXXXXXX..XXXXXXX 100644
487
index XXXXXXX..XXXXXXX 100644
2504
--- a/hw/arm/meson.build
488
--- a/hw/net/Kconfig
2505
+++ b/hw/arm/meson.build
489
+++ b/hw/net/Kconfig
2506
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_SABRELITE', if_true: files('sabrelite.c'))
490
@@ -XXX,XX +XXX,XX @@ config VMXNET3_PCI
2507
491
config SMC91C111
2508
arm_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m.c'))
492
bool
2509
arm_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210.c'))
493
2510
-arm_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx.c', 'pxa2xx_gpio.c', 'pxa2xx_pic.c'))
494
+config LAN9118_PHY
2511
+arm_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_gpio.c', 'pxa2xx_pic.c'))
495
+ bool
2512
arm_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic.c'))
496
+
2513
arm_ss.add(when: 'CONFIG_OMAP', if_true: files('omap1.c'))
497
config LAN9118
2514
arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubieboard.c'))
498
bool
499
+ select LAN9118_PHY
500
select PTIMER
501
502
config NE2000_ISA
503
diff --git a/hw/net/meson.build b/hw/net/meson.build
504
index XXXXXXX..XXXXXXX 100644
505
--- a/hw/net/meson.build
506
+++ b/hw/net/meson.build
507
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('vmxnet3.c'))
508
509
system_ss.add(when: 'CONFIG_SMC91C111', if_true: files('smc91c111.c'))
510
system_ss.add(when: 'CONFIG_LAN9118', if_true: files('lan9118.c'))
511
+system_ss.add(when: 'CONFIG_LAN9118_PHY', if_true: files('lan9118_phy.c'))
512
system_ss.add(when: 'CONFIG_NE2000_ISA', if_true: files('ne2000-isa.c'))
513
system_ss.add(when: 'CONFIG_OPENCORES_ETH', if_true: files('opencores_eth.c'))
514
system_ss.add(when: 'CONFIG_XGMAC', if_true: files('xgmac.c'))
2515
--
515
--
2516
2.34.1
516
2.34.1
2517
2518
diff view generated by jsdifflib
1
The OneNAND devices were only used by n800/n810, so they
1
From: Bernhard Beschow <shentey@gmail.com>
2
can be removed now.
3
2
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>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20241102125724.532843-3-shentey@gmail.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Message-id: 20240903160751.4100218-33-peter.maydell@linaro.org
7
---
19
---
8
include/hw/block/flash.h | 3 -
20
include/hw/net/imx_fec.h | 9 ++-
9
hw/block/onenand.c | 872 ---------------------------------------
21
hw/net/imx_fec.c | 146 ++++-----------------------------------
10
hw/block/Kconfig | 3 -
22
hw/net/lan9118_phy.c | 82 ++++++++++++++++------
11
hw/block/meson.build | 1 -
23
hw/net/Kconfig | 1 +
12
4 files changed, 879 deletions(-)
24
hw/net/trace-events | 10 +--
13
delete mode 100644 hw/block/onenand.c
25
5 files changed, 85 insertions(+), 163 deletions(-)
14
26
15
diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h
27
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
16
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/block/flash.h
29
--- a/include/hw/net/imx_fec.h
18
+++ b/include/hw/block/flash.h
30
+++ b/include/hw/net/imx_fec.h
19
@@ -XXX,XX +XXX,XX @@ uint32_t nand_getbuswidth(DeviceState *dev);
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
20
#define NAND_MFR_HYNIX 0xad
32
#define TYPE_IMX_ENET "imx.enet"
21
#define NAND_MFR_MICRON 0x2c
33
22
34
#include "hw/sysbus.h"
23
-/* onenand.c */
35
+#include "hw/net/lan9118_phy.h"
24
-void *onenand_raw_otp(DeviceState *onenand_device);
36
+#include "hw/irq.h"
25
-
37
#include "net/net.h"
26
/* ecc.c */
38
27
typedef struct {
39
#define ENET_EIR 1
28
uint8_t cp; /* Column parity */
40
@@ -XXX,XX +XXX,XX @@ struct IMXFECState {
29
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
41
uint32_t tx_descriptor[ENET_TX_RING_NUM];
30
deleted file mode 100644
42
uint32_t tx_ring_num;
31
index XXXXXXX..XXXXXXX
43
32
--- a/hw/block/onenand.c
44
- uint32_t phy_status;
33
+++ /dev/null
45
- uint32_t phy_control;
34
@@ -XXX,XX +XXX,XX @@
46
- uint32_t phy_advertise;
35
-/*
47
- uint32_t phy_int;
36
- * OneNAND flash memories emulation.
48
- uint32_t phy_int_mask;
37
- *
49
+ Lan9118PhyState mii;
38
- * Copyright (C) 2008 Nokia Corporation
50
+ IRQState mii_irq;
39
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
51
uint32_t phy_num;
40
- *
52
bool phy_connected;
41
- * This program is free software; you can redistribute it and/or
53
struct IMXFECState *phy_consumer;
42
- * modify it under the terms of the GNU General Public License as
54
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
43
- * published by the Free Software Foundation; either version 2 or
55
index XXXXXXX..XXXXXXX 100644
44
- * (at your option) version 3 of the License.
56
--- a/hw/net/imx_fec.c
45
- *
57
+++ b/hw/net/imx_fec.c
46
- * This program is distributed in the hope that it will be useful,
58
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth_txdescs = {
47
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
59
48
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60
static const VMStateDescription vmstate_imx_eth = {
49
- * GNU General Public License for more details.
61
.name = TYPE_IMX_FEC,
50
- *
62
- .version_id = 2,
51
- * You should have received a copy of the GNU General Public License along
63
- .minimum_version_id = 2,
52
- * with this program; if not, see <http://www.gnu.org/licenses/>.
64
+ .version_id = 3,
53
- */
65
+ .minimum_version_id = 3,
54
-
66
.fields = (const VMStateField[]) {
55
-#include "qemu/osdep.h"
67
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
56
-#include "qapi/error.h"
68
VMSTATE_UINT32(rx_descriptor, IMXFECState),
57
-#include "hw/hw.h"
69
VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
58
-#include "hw/block/flash.h"
70
- VMSTATE_UINT32(phy_status, IMXFECState),
59
-#include "hw/irq.h"
71
- VMSTATE_UINT32(phy_control, IMXFECState),
60
-#include "hw/qdev-properties.h"
72
- VMSTATE_UINT32(phy_advertise, IMXFECState),
61
-#include "hw/qdev-properties-system.h"
73
- VMSTATE_UINT32(phy_int, IMXFECState),
62
-#include "sysemu/block-backend.h"
74
- VMSTATE_UINT32(phy_int_mask, IMXFECState),
63
-#include "exec/memory.h"
75
VMSTATE_END_OF_LIST()
64
-#include "hw/sysbus.h"
76
},
65
-#include "migration/vmstate.h"
77
.subsections = (const VMStateDescription * const []) {
66
-#include "qemu/error-report.h"
78
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth = {
67
-#include "qemu/log.h"
79
},
68
-#include "qemu/module.h"
80
};
69
-#include "qom/object.h"
81
70
-
82
-#define PHY_INT_ENERGYON (1 << 7)
71
-/* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
83
-#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
72
-#define PAGE_SHIFT 11
84
-#define PHY_INT_FAULT (1 << 5)
73
-
85
-#define PHY_INT_DOWN (1 << 4)
74
-/* Fixed */
86
-#define PHY_INT_AUTONEG_LP (1 << 3)
75
-#define BLOCK_SHIFT (PAGE_SHIFT + 6)
87
-#define PHY_INT_PARFAULT (1 << 2)
76
-
88
-#define PHY_INT_AUTONEG_PAGE (1 << 1)
77
-#define TYPE_ONE_NAND "onenand"
89
-
78
-OBJECT_DECLARE_SIMPLE_TYPE(OneNANDState, ONE_NAND)
90
static void imx_eth_update(IMXFECState *s);
79
-
91
80
-struct OneNANDState {
92
/*
81
- SysBusDevice parent_obj;
93
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s);
82
-
94
* For now we don't handle any GPIO/interrupt line, so the OS will
83
- struct {
95
* have to poll for the PHY status.
84
- uint16_t man;
96
*/
85
- uint16_t dev;
97
-static void imx_phy_update_irq(IMXFECState *s)
86
- uint16_t ver;
98
+static void imx_phy_update_irq(void *opaque, int n, int level)
87
- } id;
99
{
88
- int shift;
100
- imx_eth_update(s);
89
- hwaddr base;
101
-}
90
- qemu_irq intr;
102
-
91
- qemu_irq rdy;
103
-static void imx_phy_update_link(IMXFECState *s)
92
- BlockBackend *blk;
93
- BlockBackend *blk_cur;
94
- uint8_t *image;
95
- uint8_t *otp;
96
- uint8_t *current;
97
- MemoryRegion ram;
98
- MemoryRegion mapped_ram;
99
- uint8_t current_direction;
100
- uint8_t *boot[2];
101
- uint8_t *data[2][2];
102
- MemoryRegion iomem;
103
- MemoryRegion container;
104
- int cycle;
105
- int otpmode;
106
-
107
- uint16_t addr[8];
108
- uint16_t unladdr[8];
109
- int bufaddr;
110
- int count;
111
- uint16_t command;
112
- uint16_t config[2];
113
- uint16_t status;
114
- uint16_t intstatus;
115
- uint16_t wpstatus;
116
-
117
- ECCState ecc;
118
-
119
- int density_mask;
120
- int secs;
121
- int secs_cur;
122
- int blocks;
123
- uint8_t *blockwp;
124
-};
125
-
126
-enum {
127
- ONEN_BUF_BLOCK = 0,
128
- ONEN_BUF_BLOCK2 = 1,
129
- ONEN_BUF_DEST_BLOCK = 2,
130
- ONEN_BUF_DEST_PAGE = 3,
131
- ONEN_BUF_PAGE = 7,
132
-};
133
-
134
-enum {
135
- ONEN_ERR_CMD = 1 << 10,
136
- ONEN_ERR_ERASE = 1 << 11,
137
- ONEN_ERR_PROG = 1 << 12,
138
- ONEN_ERR_LOAD = 1 << 13,
139
-};
140
-
141
-enum {
142
- ONEN_INT_RESET = 1 << 4,
143
- ONEN_INT_ERASE = 1 << 5,
144
- ONEN_INT_PROG = 1 << 6,
145
- ONEN_INT_LOAD = 1 << 7,
146
- ONEN_INT = 1 << 15,
147
-};
148
-
149
-enum {
150
- ONEN_LOCK_LOCKTIGHTEN = 1 << 0,
151
- ONEN_LOCK_LOCKED = 1 << 1,
152
- ONEN_LOCK_UNLOCKED = 1 << 2,
153
-};
154
-
155
-static void onenand_mem_setup(OneNANDState *s)
156
-{
104
-{
157
- /* XXX: We should use IO_MEM_ROMD but we broke it earlier...
105
- /* Autonegotiation status mirrors link status. */
158
- * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to
106
- if (qemu_get_queue(s->nic)->link_down) {
159
- * write boot commands. Also take note of the BWPS bit. */
107
- trace_imx_phy_update_link("down");
160
- memory_region_init(&s->container, OBJECT(s), "onenand",
108
- s->phy_status &= ~0x0024;
161
- 0x10000 << s->shift);
109
- s->phy_int |= PHY_INT_DOWN;
162
- memory_region_add_subregion(&s->container, 0, &s->iomem);
110
- } else {
163
- memory_region_init_alias(&s->mapped_ram, OBJECT(s), "onenand-mapped-ram",
111
- trace_imx_phy_update_link("up");
164
- &s->ram, 0x0200 << s->shift,
112
- s->phy_status |= 0x0024;
165
- 0xbe00 << s->shift);
113
- s->phy_int |= PHY_INT_ENERGYON;
166
- memory_region_add_subregion_overlap(&s->container,
114
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
167
- 0x0200 << s->shift,
115
- }
168
- &s->mapped_ram,
116
- imx_phy_update_irq(s);
169
- 1);
117
+ imx_eth_update(opaque);
118
}
119
120
static void imx_eth_set_link(NetClientState *nc)
121
{
122
- imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
170
-}
123
-}
171
-
124
-
172
-static void onenand_intr_update(OneNANDState *s)
125
-static void imx_phy_reset(IMXFECState *s)
173
-{
126
-{
174
- qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
127
- trace_imx_phy_reset();
175
-}
128
-
176
-
129
- s->phy_status = 0x7809;
177
-static int onenand_pre_save(void *opaque)
130
- s->phy_control = 0x3000;
178
-{
131
- s->phy_advertise = 0x01e1;
179
- OneNANDState *s = opaque;
132
- s->phy_int_mask = 0;
180
- if (s->current == s->otp) {
133
- s->phy_int = 0;
181
- s->current_direction = 1;
134
- imx_phy_update_link(s);
182
- } else if (s->current == s->image) {
135
+ lan9118_phy_update_link(&IMX_FEC(qemu_get_nic_opaque(nc))->mii,
183
- s->current_direction = 2;
136
+ nc->link_down);
184
- } else {
137
}
185
- s->current_direction = 0;
138
139
static uint32_t imx_phy_read(IMXFECState *s, int reg)
140
{
141
- uint32_t val;
142
uint32_t phy = reg / 32;
143
144
if (!s->phy_connected) {
145
@@ -XXX,XX +XXX,XX @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
146
147
reg %= 32;
148
149
- switch (reg) {
150
- case 0: /* Basic Control */
151
- val = s->phy_control;
152
- break;
153
- case 1: /* Basic Status */
154
- val = s->phy_status;
155
- break;
156
- case 2: /* ID1 */
157
- val = 0x0007;
158
- break;
159
- case 3: /* ID2 */
160
- val = 0xc0d1;
161
- break;
162
- case 4: /* Auto-neg advertisement */
163
- val = s->phy_advertise;
164
- break;
165
- case 5: /* Auto-neg Link Partner Ability */
166
- val = 0x0f71;
167
- break;
168
- case 6: /* Auto-neg Expansion */
169
- val = 1;
170
- break;
171
- case 29: /* Interrupt source. */
172
- val = s->phy_int;
173
- s->phy_int = 0;
174
- imx_phy_update_irq(s);
175
- break;
176
- case 30: /* Interrupt mask */
177
- val = s->phy_int_mask;
178
- break;
179
- case 17:
180
- case 18:
181
- case 27:
182
- case 31:
183
- qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
184
- TYPE_IMX_FEC, __func__, reg);
185
- val = 0;
186
- break;
187
- default:
188
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
189
- TYPE_IMX_FEC, __func__, reg);
190
- val = 0;
191
- break;
186
- }
192
- }
187
-
193
-
188
- return 0;
194
- trace_imx_phy_read(val, phy, reg);
189
-}
195
-
190
-
196
- return val;
191
-static int onenand_post_load(void *opaque, int version_id)
197
+ return lan9118_phy_read(&s->mii, reg);
192
-{
198
}
193
- OneNANDState *s = opaque;
199
194
- switch (s->current_direction) {
200
static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
195
- case 0:
201
@@ -XXX,XX +XXX,XX @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
196
- break;
202
197
- case 1:
203
reg %= 32;
198
- s->current = s->otp;
204
199
- break;
205
- trace_imx_phy_write(val, phy, reg);
200
- case 2:
206
-
201
- s->current = s->image;
207
- switch (reg) {
202
- break;
208
- case 0: /* Basic Control */
203
- default:
209
- if (val & 0x8000) {
204
- return -1;
210
- imx_phy_reset(s);
205
- }
206
- onenand_intr_update(s);
207
- return 0;
208
-}
209
-
210
-static const VMStateDescription vmstate_onenand = {
211
- .name = "onenand",
212
- .version_id = 1,
213
- .minimum_version_id = 1,
214
- .pre_save = onenand_pre_save,
215
- .post_load = onenand_post_load,
216
- .fields = (const VMStateField[]) {
217
- VMSTATE_UINT8(current_direction, OneNANDState),
218
- VMSTATE_INT32(cycle, OneNANDState),
219
- VMSTATE_INT32(otpmode, OneNANDState),
220
- VMSTATE_UINT16_ARRAY(addr, OneNANDState, 8),
221
- VMSTATE_UINT16_ARRAY(unladdr, OneNANDState, 8),
222
- VMSTATE_INT32(bufaddr, OneNANDState),
223
- VMSTATE_INT32(count, OneNANDState),
224
- VMSTATE_UINT16(command, OneNANDState),
225
- VMSTATE_UINT16_ARRAY(config, OneNANDState, 2),
226
- VMSTATE_UINT16(status, OneNANDState),
227
- VMSTATE_UINT16(intstatus, OneNANDState),
228
- VMSTATE_UINT16(wpstatus, OneNANDState),
229
- VMSTATE_INT32(secs_cur, OneNANDState),
230
- VMSTATE_PARTIAL_VBUFFER(blockwp, OneNANDState, blocks),
231
- VMSTATE_UINT8(ecc.cp, OneNANDState),
232
- VMSTATE_UINT16_ARRAY(ecc.lp, OneNANDState, 2),
233
- VMSTATE_UINT16(ecc.count, OneNANDState),
234
- VMSTATE_BUFFER_POINTER_UNSAFE(otp, OneNANDState, 0,
235
- ((64 + 2) << PAGE_SHIFT)),
236
- VMSTATE_END_OF_LIST()
237
- }
238
-};
239
-
240
-/* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
241
-static void onenand_reset(OneNANDState *s, int cold)
242
-{
243
- memset(&s->addr, 0, sizeof(s->addr));
244
- s->command = 0;
245
- s->count = 1;
246
- s->bufaddr = 0;
247
- s->config[0] = 0x40c0;
248
- s->config[1] = 0x0000;
249
- onenand_intr_update(s);
250
- qemu_irq_raise(s->rdy);
251
- s->status = 0x0000;
252
- s->intstatus = cold ? 0x8080 : 0x8010;
253
- s->unladdr[0] = 0;
254
- s->unladdr[1] = 0;
255
- s->wpstatus = 0x0002;
256
- s->cycle = 0;
257
- s->otpmode = 0;
258
- s->blk_cur = s->blk;
259
- s->current = s->image;
260
- s->secs_cur = s->secs;
261
-
262
- if (cold) {
263
- /* Lock the whole flash */
264
- memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
265
-
266
- if (s->blk_cur && blk_pread(s->blk_cur, 0, 8 << BDRV_SECTOR_BITS,
267
- s->boot[0], 0) < 0) {
268
- hw_error("%s: Loading the BootRAM failed.\n", __func__);
269
- }
270
- }
271
-}
272
-
273
-static void onenand_system_reset(DeviceState *dev)
274
-{
275
- OneNANDState *s = ONE_NAND(dev);
276
-
277
- onenand_reset(s, 1);
278
-}
279
-
280
-static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
281
- void *dest)
282
-{
283
- assert(UINT32_MAX >> BDRV_SECTOR_BITS > sec);
284
- assert(UINT32_MAX >> BDRV_SECTOR_BITS > secn);
285
- if (s->blk_cur) {
286
- return blk_pread(s->blk_cur, sec << BDRV_SECTOR_BITS,
287
- secn << BDRV_SECTOR_BITS, dest, 0) < 0;
288
- } else if (sec + secn > s->secs_cur) {
289
- return 1;
290
- }
291
-
292
- memcpy(dest, s->current + (sec << 9), secn << 9);
293
-
294
- return 0;
295
-}
296
-
297
-static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
298
- void *src)
299
-{
300
- int result = 0;
301
-
302
- if (secn > 0) {
303
- uint32_t size = secn << BDRV_SECTOR_BITS;
304
- uint32_t offset = sec << BDRV_SECTOR_BITS;
305
- assert(UINT32_MAX >> BDRV_SECTOR_BITS > sec);
306
- assert(UINT32_MAX >> BDRV_SECTOR_BITS > secn);
307
- const uint8_t *sp = (const uint8_t *)src;
308
- uint8_t *dp = 0;
309
- if (s->blk_cur) {
310
- dp = g_malloc(size);
311
- if (!dp || blk_pread(s->blk_cur, offset, size, dp, 0) < 0) {
312
- result = 1;
313
- }
314
- } else {
211
- } else {
315
- if (sec + secn > s->secs_cur) {
212
- s->phy_control = val & 0x7980;
316
- result = 1;
213
- /* Complete autonegotiation immediately. */
317
- } else {
214
- if (val & 0x1000) {
318
- dp = (uint8_t *)s->current + offset;
215
- s->phy_status |= 0x0020;
319
- }
216
- }
320
- }
217
- }
321
- if (!result) {
218
- break;
322
- uint32_t i;
219
- case 4: /* Auto-neg advertisement */
323
- for (i = 0; i < size; i++) {
220
- s->phy_advertise = (val & 0x2d7f) | 0x80;
324
- dp[i] &= sp[i];
221
- break;
325
- }
222
- case 30: /* Interrupt mask */
326
- if (s->blk_cur) {
223
- s->phy_int_mask = val & 0xff;
327
- result = blk_pwrite(s->blk_cur, offset, size, dp, 0) < 0;
224
- imx_phy_update_irq(s);
328
- }
225
- break;
329
- }
226
- case 17:
330
- if (dp && s->blk_cur) {
227
- case 18:
331
- g_free(dp);
228
- case 27:
332
- }
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;
333
- }
237
- }
334
-
238
+ lan9118_phy_write(&s->mii, reg, val);
335
- return result;
239
}
336
-}
240
337
-
241
static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
338
-static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
242
@@ -XXX,XX +XXX,XX @@ static void imx_eth_reset(DeviceState *d)
339
- void *dest)
243
340
-{
244
s->rx_descriptor = 0;
341
- uint8_t buf[512];
245
memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
342
-
246
-
343
- if (s->blk_cur) {
247
- /* We also reset the PHY */
344
- uint32_t offset = (s->secs_cur + (sec >> 5)) << BDRV_SECTOR_BITS;
248
- imx_phy_reset(s);
345
- if (blk_pread(s->blk_cur, offset, BDRV_SECTOR_SIZE, buf, 0) < 0) {
249
}
346
- return 1;
250
347
- }
251
static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
348
- memcpy(dest, buf + ((sec & 31) << 4), secn << 4);
252
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
349
- } else if (sec + secn > s->secs_cur) {
253
sysbus_init_irq(sbd, &s->irq[0]);
254
sysbus_init_irq(sbd, &s->irq[1]);
255
256
+ qemu_init_irq(&s->mii_irq, imx_phy_update_irq, s, 0);
257
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
258
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
259
+ return;
260
+ }
261
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
262
+
263
qemu_macaddr_default_if_unset(&s->conf.macaddr);
264
265
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
266
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
267
index XXXXXXX..XXXXXXX 100644
268
--- a/hw/net/lan9118_phy.c
269
+++ b/hw/net/lan9118_phy.c
270
@@ -XXX,XX +XXX,XX @@
271
* Copyright (c) 2009 CodeSourcery, LLC.
272
* Written by Paul Brook
273
*
274
+ * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
275
+ *
276
* This code is licensed under the GNU GPL v2
277
*
278
* Contributions after 2012-01-13 are licensed under the terms of the
279
@@ -XXX,XX +XXX,XX @@
280
#include "hw/resettable.h"
281
#include "migration/vmstate.h"
282
#include "qemu/log.h"
283
+#include "trace.h"
284
285
#define PHY_INT_ENERGYON (1 << 7)
286
#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
287
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
288
289
switch (reg) {
290
case 0: /* Basic Control */
291
- return s->control;
292
+ val = s->control;
293
+ break;
294
case 1: /* Basic Status */
295
- return s->status;
296
+ val = s->status;
297
+ break;
298
case 2: /* ID1 */
299
- return 0x0007;
300
+ val = 0x0007;
301
+ break;
302
case 3: /* ID2 */
303
- return 0xc0d1;
304
+ val = 0xc0d1;
305
+ break;
306
case 4: /* Auto-neg advertisement */
307
- return s->advertise;
308
+ val = s->advertise;
309
+ break;
310
case 5: /* Auto-neg Link Partner Ability */
311
- return 0x0f71;
312
+ val = 0x0f71;
313
+ break;
314
case 6: /* Auto-neg Expansion */
350
- return 1;
315
- return 1;
351
- } else {
316
- /* TODO 17, 18, 27, 29, 30, 31 */
352
- memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);
317
+ val = 1;
353
- }
318
+ break;
354
-
319
case 29: /* Interrupt source. */
355
- return 0;
320
val = s->ints;
356
-}
321
s->ints = 0;
357
-
322
lan9118_phy_update_irq(s);
358
-static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
323
- return val;
359
- void *src)
324
+ break;
360
-{
325
case 30: /* Interrupt mask */
361
- int result = 0;
326
- return s->int_mask;
362
- if (secn > 0) {
327
+ val = s->int_mask;
363
- const uint8_t *sp = (const uint8_t *)src;
328
+ break;
364
- uint8_t *dp = 0, *dpp = 0;
329
+ case 17:
365
- uint32_t offset = (s->secs_cur + (sec >> 5)) << BDRV_SECTOR_BITS;
330
+ case 18:
366
- assert(UINT32_MAX >> BDRV_SECTOR_BITS > s->secs_cur + (sec >> 5));
331
+ case 27:
367
- if (s->blk_cur) {
332
+ case 31:
368
- dp = g_malloc(512);
333
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
369
- if (!dp
334
+ __func__, reg);
370
- || blk_pread(s->blk_cur, offset, BDRV_SECTOR_SIZE, dp, 0) < 0) {
335
+ val = 0;
371
- result = 1;
336
+ break;
372
- } else {
337
default:
373
- dpp = dp + ((sec & 31) << 4);
338
- qemu_log_mask(LOG_GUEST_ERROR,
374
- }
339
- "lan9118_phy_read: PHY read reg %d\n", reg);
375
- } else {
376
- if (sec + secn > s->secs_cur) {
377
- result = 1;
378
- } else {
379
- dpp = s->current + (s->secs_cur << 9) + (sec << 4);
380
- }
381
- }
382
- if (!result) {
383
- uint32_t i;
384
- for (i = 0; i < (secn << 4); i++) {
385
- dpp[i] &= sp[i];
386
- }
387
- if (s->blk_cur) {
388
- result = blk_pwrite(s->blk_cur, offset, BDRV_SECTOR_SIZE, dp,
389
- 0) < 0;
390
- }
391
- }
392
- g_free(dp);
393
- }
394
- return result;
395
-}
396
-
397
-static inline int onenand_erase(OneNANDState *s, int sec, int num)
398
-{
399
- uint8_t *blankbuf, *tmpbuf;
400
-
401
- blankbuf = g_malloc(512);
402
- tmpbuf = g_malloc(512);
403
- memset(blankbuf, 0xff, 512);
404
- for (; num > 0; num--, sec++) {
405
- if (s->blk_cur) {
406
- int erasesec = s->secs_cur + (sec >> 5);
407
- if (blk_pwrite(s->blk_cur, sec << BDRV_SECTOR_BITS,
408
- BDRV_SECTOR_SIZE, blankbuf, 0) < 0) {
409
- goto fail;
410
- }
411
- if (blk_pread(s->blk_cur, erasesec << BDRV_SECTOR_BITS,
412
- BDRV_SECTOR_SIZE, tmpbuf, 0) < 0) {
413
- goto fail;
414
- }
415
- memcpy(tmpbuf + ((sec & 31) << 4), blankbuf, 1 << 4);
416
- if (blk_pwrite(s->blk_cur, erasesec << BDRV_SECTOR_BITS,
417
- BDRV_SECTOR_SIZE, tmpbuf, 0) < 0) {
418
- goto fail;
419
- }
420
- } else {
421
- if (sec + 1 > s->secs_cur) {
422
- goto fail;
423
- }
424
- memcpy(s->current + (sec << 9), blankbuf, 512);
425
- memcpy(s->current + (s->secs_cur << 9) + (sec << 4),
426
- blankbuf, 1 << 4);
427
- }
428
- }
429
-
430
- g_free(tmpbuf);
431
- g_free(blankbuf);
432
- return 0;
433
-
434
-fail:
435
- g_free(tmpbuf);
436
- g_free(blankbuf);
437
- return 1;
438
-}
439
-
440
-static void onenand_command(OneNANDState *s)
441
-{
442
- int b;
443
- int sec;
444
- void *buf;
445
-#define SETADDR(block, page) \
446
- sec = (s->addr[page] & 3) + \
447
- ((((s->addr[page] >> 2) & 0x3f) + \
448
- (((s->addr[block] & 0xfff) | \
449
- (s->addr[block] >> 15 ? s->density_mask : 0)) \
450
- << 6)) \
451
- << (PAGE_SHIFT - 9));
452
-#define SETBUF_M() \
453
- buf = (s->bufaddr & 8) ? s->data[(s->bufaddr >> 2) & 1][0] : s->boot[0]; \
454
- buf += (s->bufaddr & 3) << 9;
455
-#define SETBUF_S() \
456
- buf = (s->bufaddr & 8) ? \
457
- s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1]; \
458
- buf += (s->bufaddr & 3) << 4;
459
-
460
- switch (s->command) {
461
- case 0x00: /* Load single/multiple sector data unit into buffer */
462
- SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
463
-
464
- SETBUF_M()
465
- if (onenand_load_main(s, sec, s->count, buf))
466
- s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
467
-
468
-#if 0
469
- SETBUF_S()
470
- if (onenand_load_spare(s, sec, s->count, buf))
471
- s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
472
-#endif
473
-
474
- /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
475
- * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
476
- * then we need two split the read/write into two chunks.
477
- */
478
- s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
479
- break;
480
- case 0x13: /* Load single/multiple spare sector into buffer */
481
- SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
482
-
483
- SETBUF_S()
484
- if (onenand_load_spare(s, sec, s->count, buf))
485
- s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD;
486
-
487
- /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
488
- * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
489
- * then we need two split the read/write into two chunks.
490
- */
491
- s->intstatus |= ONEN_INT | ONEN_INT_LOAD;
492
- break;
493
- case 0x80: /* Program single/multiple sector data unit from buffer */
494
- SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
495
-
496
- SETBUF_M()
497
- if (onenand_prog_main(s, sec, s->count, buf))
498
- s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
499
-
500
-#if 0
501
- SETBUF_S()
502
- if (onenand_prog_spare(s, sec, s->count, buf))
503
- s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
504
-#endif
505
-
506
- /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
507
- * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
508
- * then we need two split the read/write into two chunks.
509
- */
510
- s->intstatus |= ONEN_INT | ONEN_INT_PROG;
511
- break;
512
- case 0x1a: /* Program single/multiple spare area sector from buffer */
513
- SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
514
-
515
- SETBUF_S()
516
- if (onenand_prog_spare(s, sec, s->count, buf))
517
- s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
518
-
519
- /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages)
520
- * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages)
521
- * then we need two split the read/write into two chunks.
522
- */
523
- s->intstatus |= ONEN_INT | ONEN_INT_PROG;
524
- break;
525
- case 0x1b: /* Copy-back program */
526
- SETBUF_S()
527
-
528
- SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
529
- if (onenand_load_main(s, sec, s->count, buf))
530
- s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
531
-
532
- SETADDR(ONEN_BUF_DEST_BLOCK, ONEN_BUF_DEST_PAGE)
533
- if (onenand_prog_main(s, sec, s->count, buf))
534
- s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG;
535
-
536
- /* TODO: spare areas */
537
-
538
- s->intstatus |= ONEN_INT | ONEN_INT_PROG;
539
- break;
540
-
541
- case 0x23: /* Unlock NAND array block(s) */
542
- s->intstatus |= ONEN_INT;
543
-
544
- /* XXX the previous (?) area should be locked automatically */
545
- for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
546
- if (b >= s->blocks) {
547
- s->status |= ONEN_ERR_CMD;
548
- break;
549
- }
550
- if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
551
- break;
552
-
553
- s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
554
- }
555
- break;
556
- case 0x27: /* Unlock All NAND array blocks */
557
- s->intstatus |= ONEN_INT;
558
-
559
- for (b = 0; b < s->blocks; b ++) {
560
- if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
561
- break;
562
-
563
- s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED;
564
- }
565
- break;
566
-
567
- case 0x2a: /* Lock NAND array block(s) */
568
- s->intstatus |= ONEN_INT;
569
-
570
- for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
571
- if (b >= s->blocks) {
572
- s->status |= ONEN_ERR_CMD;
573
- break;
574
- }
575
- if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN)
576
- break;
577
-
578
- s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKED;
579
- }
580
- break;
581
- case 0x2c: /* Lock-tight NAND array block(s) */
582
- s->intstatus |= ONEN_INT;
583
-
584
- for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) {
585
- if (b >= s->blocks) {
586
- s->status |= ONEN_ERR_CMD;
587
- break;
588
- }
589
- if (s->blockwp[b] == ONEN_LOCK_UNLOCKED)
590
- continue;
591
-
592
- s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKTIGHTEN;
593
- }
594
- break;
595
-
596
- case 0x71: /* Erase-Verify-Read */
597
- s->intstatus |= ONEN_INT;
598
- break;
599
- case 0x95: /* Multi-block erase */
600
- qemu_irq_pulse(s->intr);
601
- /* Fall through. */
602
- case 0x94: /* Block erase */
603
- sec = ((s->addr[ONEN_BUF_BLOCK] & 0xfff) |
604
- (s->addr[ONEN_BUF_BLOCK] >> 15 ? s->density_mask : 0))
605
- << (BLOCK_SHIFT - 9);
606
- if (onenand_erase(s, sec, 1 << (BLOCK_SHIFT - 9)))
607
- s->status |= ONEN_ERR_CMD | ONEN_ERR_ERASE;
608
-
609
- s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
610
- break;
611
- case 0xb0: /* Erase suspend */
612
- break;
613
- case 0x30: /* Erase resume */
614
- s->intstatus |= ONEN_INT | ONEN_INT_ERASE;
615
- break;
616
-
617
- case 0xf0: /* Reset NAND Flash core */
618
- onenand_reset(s, 0);
619
- break;
620
- case 0xf3: /* Reset OneNAND */
621
- onenand_reset(s, 0);
622
- break;
623
-
624
- case 0x65: /* OTP Access */
625
- s->intstatus |= ONEN_INT;
626
- s->blk_cur = NULL;
627
- s->current = s->otp;
628
- s->secs_cur = 1 << (BLOCK_SHIFT - 9);
629
- s->addr[ONEN_BUF_BLOCK] = 0;
630
- s->otpmode = 1;
631
- break;
632
-
633
- default:
634
- s->status |= ONEN_ERR_CMD;
635
- s->intstatus |= ONEN_INT;
636
- qemu_log_mask(LOG_GUEST_ERROR, "unknown OneNAND command %x\n",
637
- s->command);
638
- }
639
-
640
- onenand_intr_update(s);
641
-}
642
-
643
-static uint64_t onenand_read(void *opaque, hwaddr addr,
644
- unsigned size)
645
-{
646
- OneNANDState *s = (OneNANDState *) opaque;
647
- int offset = addr >> s->shift;
648
-
649
- switch (offset) {
650
- case 0x0000 ... 0xbffe:
651
- return lduw_le_p(s->boot[0] + addr);
652
-
653
- case 0xf000: /* Manufacturer ID */
654
- return s->id.man;
655
- case 0xf001: /* Device ID */
656
- return s->id.dev;
657
- case 0xf002: /* Version ID */
658
- return s->id.ver;
659
- /* TODO: get the following values from a real chip! */
660
- case 0xf003: /* Data Buffer size */
661
- return 1 << PAGE_SHIFT;
662
- case 0xf004: /* Boot Buffer size */
663
- return 0x200;
664
- case 0xf005: /* Amount of buffers */
665
- return 1 | (2 << 8);
666
- case 0xf006: /* Technology */
667
- return 0;
340
- return 0;
668
-
341
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
669
- case 0xf100 ... 0xf107: /* Start addresses */
342
+ __func__, reg);
670
- return s->addr[offset - 0xf100];
343
+ val = 0;
671
-
344
+ break;
672
- case 0xf200: /* Start buffer */
345
}
673
- return (s->bufaddr << 8) | ((s->count - 1) & (1 << (PAGE_SHIFT - 10)));
346
+
674
-
347
+ trace_lan9118_phy_read(val, reg);
675
- case 0xf220: /* Command */
348
+
676
- return s->command;
349
+ return val;
677
- case 0xf221: /* System Configuration 1 */
350
}
678
- return s->config[0] & 0xffe0;
351
679
- case 0xf222: /* System Configuration 2 */
352
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
680
- return s->config[1];
353
{
681
-
354
+ trace_lan9118_phy_write(val, reg);
682
- case 0xf240: /* Controller Status */
355
+
683
- return s->status;
356
switch (reg) {
684
- case 0xf241: /* Interrupt */
357
case 0: /* Basic Control */
685
- return s->intstatus;
358
if (val & 0x8000) {
686
- case 0xf24c: /* Unlock Start Block Address */
359
lan9118_phy_reset(s);
687
- return s->unladdr[0];
688
- case 0xf24d: /* Unlock End Block Address */
689
- return s->unladdr[1];
690
- case 0xf24e: /* Write Protection Status */
691
- return s->wpstatus;
692
-
693
- case 0xff00: /* ECC Status */
694
- return 0x00;
695
- case 0xff01: /* ECC Result of main area data */
696
- case 0xff02: /* ECC Result of spare area data */
697
- case 0xff03: /* ECC Result of main area data */
698
- case 0xff04: /* ECC Result of spare area data */
699
- qemu_log_mask(LOG_UNIMP,
700
- "onenand: ECC result registers unimplemented\n");
701
- return 0x0000;
702
- }
703
-
704
- qemu_log_mask(LOG_GUEST_ERROR, "read of unknown OneNAND register 0x%x\n",
705
- offset);
706
- return 0;
707
-}
708
-
709
-static void onenand_write(void *opaque, hwaddr addr,
710
- uint64_t value, unsigned size)
711
-{
712
- OneNANDState *s = (OneNANDState *) opaque;
713
- int offset = addr >> s->shift;
714
- int sec;
715
-
716
- switch (offset) {
717
- case 0x0000 ... 0x01ff:
718
- case 0x8000 ... 0x800f:
719
- if (s->cycle) {
720
- s->cycle = 0;
721
-
722
- if (value == 0x0000) {
723
- SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
724
- onenand_load_main(s, sec,
725
- 1 << (PAGE_SHIFT - 9), s->data[0][0]);
726
- s->addr[ONEN_BUF_PAGE] += 4;
727
- s->addr[ONEN_BUF_PAGE] &= 0xff;
728
- }
729
- break;
360
- break;
730
- }
361
- }
731
-
362
- s->control = val & 0x7980;
732
- switch (value) {
363
- /* Complete autonegotiation immediately. */
733
- case 0x00f0: /* Reset OneNAND */
364
- if (val & 0x1000) {
734
- onenand_reset(s, 0);
365
- s->status |= 0x0020;
735
- break;
366
+ } else {
736
-
367
+ s->control = val & 0x7980;
737
- case 0x00e0: /* Load Data into Buffer */
368
+ /* Complete autonegotiation immediately. */
738
- s->cycle = 1;
369
+ if (val & 0x1000) {
739
- break;
370
+ s->status |= 0x0020;
740
-
371
+ }
741
- case 0x0090: /* Read Identification Data */
372
}
742
- memset(s->boot[0], 0, 3 << s->shift);
373
break;
743
- s->boot[0][0 << s->shift] = s->id.man & 0xff;
374
case 4: /* Auto-neg advertisement */
744
- s->boot[0][1 << s->shift] = s->id.dev & 0xff;
375
s->advertise = (val & 0x2d7f) | 0x80;
745
- s->boot[0][2 << s->shift] = s->wpstatus & 0xff;
376
break;
746
- break;
377
- /* TODO 17, 18, 27, 31 */
747
-
378
case 30: /* Interrupt mask */
748
- default:
379
s->int_mask = val & 0xff;
749
- qemu_log_mask(LOG_GUEST_ERROR,
380
lan9118_phy_update_irq(s);
750
- "unknown OneNAND boot command %" PRIx64 "\n",
381
break;
751
- value);
382
+ case 17:
752
- }
383
+ case 18:
753
- break;
384
+ case 27:
754
-
385
+ case 31:
755
- case 0xf100 ... 0xf107: /* Start addresses */
386
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
756
- s->addr[offset - 0xf100] = value;
387
+ __func__, reg);
757
- break;
388
+ break;
758
-
389
default:
759
- case 0xf200: /* Start buffer */
760
- s->bufaddr = (value >> 8) & 0xf;
761
- if (PAGE_SHIFT == 11)
762
- s->count = (value & 3) ?: 4;
763
- else if (PAGE_SHIFT == 10)
764
- s->count = (value & 1) ?: 2;
765
- break;
766
-
767
- case 0xf220: /* Command */
768
- if (s->intstatus & (1 << 15))
769
- break;
770
- s->command = value;
771
- onenand_command(s);
772
- break;
773
- case 0xf221: /* System Configuration 1 */
774
- s->config[0] = value;
775
- onenand_intr_update(s);
776
- qemu_set_irq(s->rdy, (s->config[0] >> 7) & 1);
777
- break;
778
- case 0xf222: /* System Configuration 2 */
779
- s->config[1] = value;
780
- break;
781
-
782
- case 0xf241: /* Interrupt */
783
- s->intstatus &= value;
784
- if ((1 << 15) & ~s->intstatus)
785
- s->status &= ~(ONEN_ERR_CMD | ONEN_ERR_ERASE |
786
- ONEN_ERR_PROG | ONEN_ERR_LOAD);
787
- onenand_intr_update(s);
788
- break;
789
- case 0xf24c: /* Unlock Start Block Address */
790
- s->unladdr[0] = value & (s->blocks - 1);
791
- /* For some reason we have to set the end address to by default
792
- * be same as start because the software forgets to write anything
793
- * in there. */
794
- s->unladdr[1] = value & (s->blocks - 1);
795
- break;
796
- case 0xf24d: /* Unlock End Block Address */
797
- s->unladdr[1] = value & (s->blocks - 1);
798
- break;
799
-
800
- default:
801
- qemu_log_mask(LOG_GUEST_ERROR,
390
- qemu_log_mask(LOG_GUEST_ERROR,
802
- "write to unknown OneNAND register 0x%x\n",
391
- "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
803
- offset);
392
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
804
- }
393
+ __func__, reg);
805
-}
394
+ break;
806
-
395
}
807
-static const MemoryRegionOps onenand_ops = {
396
}
808
- .read = onenand_read,
397
809
- .write = onenand_write,
398
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
810
- .endianness = DEVICE_NATIVE_ENDIAN,
399
811
-};
400
/* Autonegotiation status mirrors link status. */
812
-
401
if (link_down) {
813
-static void onenand_realize(DeviceState *dev, Error **errp)
402
+ trace_lan9118_phy_update_link("down");
814
-{
403
s->status &= ~0x0024;
815
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
404
s->ints |= PHY_INT_DOWN;
816
- OneNANDState *s = ONE_NAND(dev);
405
} else {
817
- uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7));
406
+ trace_lan9118_phy_update_link("up");
818
- void *ram;
407
s->status |= 0x0024;
819
- Error *local_err = NULL;
408
s->ints |= PHY_INT_ENERGYON;
820
-
409
s->ints |= PHY_INT_AUTONEG_COMPLETE;
821
- s->base = (hwaddr)-1;
410
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
822
- s->rdy = NULL;
411
823
- s->blocks = size >> BLOCK_SHIFT;
412
void lan9118_phy_reset(Lan9118PhyState *s)
824
- s->secs = size >> 9;
413
{
825
- s->blockwp = g_malloc(s->blocks);
414
+ trace_lan9118_phy_reset();
826
- s->density_mask = (s->id.dev & 0x08)
415
+
827
- ? (1 << (6 + ((s->id.dev >> 4) & 7))) : 0;
416
s->control = 0x3000;
828
- memory_region_init_io(&s->iomem, OBJECT(s), &onenand_ops, s, "onenand",
417
s->status = 0x7809;
829
- 0x10000 << s->shift);
418
s->advertise = 0x01e1;
830
- if (!s->blk) {
419
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_phy = {
831
- s->image = memset(g_malloc(size + (size >> 5)),
420
.version_id = 1,
832
- 0xff, size + (size >> 5));
421
.minimum_version_id = 1,
833
- } else {
422
.fields = (const VMStateField[]) {
834
- if (!blk_supports_write_perm(s->blk)) {
423
- VMSTATE_UINT16(control, Lan9118PhyState),
835
- error_setg(errp, "Can't use a read-only drive");
424
VMSTATE_UINT16(status, Lan9118PhyState),
836
- return;
425
+ VMSTATE_UINT16(control, Lan9118PhyState),
837
- }
426
VMSTATE_UINT16(advertise, Lan9118PhyState),
838
- blk_set_perm(s->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE,
427
VMSTATE_UINT16(ints, Lan9118PhyState),
839
- BLK_PERM_ALL, &local_err);
428
VMSTATE_UINT16(int_mask, Lan9118PhyState),
840
- if (local_err) {
429
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
841
- error_propagate(errp, local_err);
842
- return;
843
- }
844
- s->blk_cur = s->blk;
845
- }
846
- s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
847
- 0xff, (64 + 2) << PAGE_SHIFT);
848
- memory_region_init_ram_nomigrate(&s->ram, OBJECT(s), "onenand.ram",
849
- 0xc000 << s->shift, &error_fatal);
850
- vmstate_register_ram_global(&s->ram);
851
- ram = memory_region_get_ram_ptr(&s->ram);
852
- s->boot[0] = ram + (0x0000 << s->shift);
853
- s->boot[1] = ram + (0x8000 << s->shift);
854
- s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift);
855
- s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift);
856
- s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
857
- s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
858
- onenand_mem_setup(s);
859
- sysbus_init_irq(sbd, &s->intr);
860
- sysbus_init_mmio(sbd, &s->container);
861
- vmstate_register(VMSTATE_IF(dev),
862
- ((s->shift & 0x7f) << 24)
863
- | ((s->id.man & 0xff) << 16)
864
- | ((s->id.dev & 0xff) << 8)
865
- | (s->id.ver & 0xff),
866
- &vmstate_onenand, s);
867
-}
868
-
869
-static Property onenand_properties[] = {
870
- DEFINE_PROP_UINT16("manufacturer_id", OneNANDState, id.man, 0),
871
- DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0),
872
- DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0),
873
- DEFINE_PROP_INT32("shift", OneNANDState, shift, 0),
874
- DEFINE_PROP_DRIVE("drive", OneNANDState, blk),
875
- DEFINE_PROP_END_OF_LIST(),
876
-};
877
-
878
-static void onenand_class_init(ObjectClass *klass, void *data)
879
-{
880
- DeviceClass *dc = DEVICE_CLASS(klass);
881
-
882
- dc->realize = onenand_realize;
883
- device_class_set_legacy_reset(dc, onenand_system_reset);
884
- device_class_set_props(dc, onenand_properties);
885
-}
886
-
887
-static const TypeInfo onenand_info = {
888
- .name = TYPE_ONE_NAND,
889
- .parent = TYPE_SYS_BUS_DEVICE,
890
- .instance_size = sizeof(OneNANDState),
891
- .class_init = onenand_class_init,
892
-};
893
-
894
-static void onenand_register_types(void)
895
-{
896
- type_register_static(&onenand_info);
897
-}
898
-
899
-void *onenand_raw_otp(DeviceState *onenand_device)
900
-{
901
- OneNANDState *s = ONE_NAND(onenand_device);
902
-
903
- return s->otp;
904
-}
905
-
906
-type_init(onenand_register_types)
907
diff --git a/hw/block/Kconfig b/hw/block/Kconfig
908
index XXXXXXX..XXXXXXX 100644
430
index XXXXXXX..XXXXXXX 100644
909
--- a/hw/block/Kconfig
431
--- a/hw/net/Kconfig
910
+++ b/hw/block/Kconfig
432
+++ b/hw/net/Kconfig
911
@@ -XXX,XX +XXX,XX @@ config PFLASH_CFI02
433
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_SUN8I_EMAC
912
config ECC
434
435
config IMX_FEC
913
bool
436
bool
914
437
+ select LAN9118_PHY
915
-config ONENAND
438
916
- bool
439
config CADENCE
917
-
918
config VIRTIO_BLK
919
bool
440
bool
920
default y
441
diff --git a/hw/net/trace-events b/hw/net/trace-events
921
diff --git a/hw/block/meson.build b/hw/block/meson.build
922
index XXXXXXX..XXXXXXX 100644
442
index XXXXXXX..XXXXXXX 100644
923
--- a/hw/block/meson.build
443
--- a/hw/net/trace-events
924
+++ b/hw/block/meson.build
444
+++ b/hw/net/trace-events
925
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_FDC', if_true: files('fdc.c'))
445
@@ -XXX,XX +XXX,XX @@ allwinner_sun8i_emac_set_link(bool active) "Set link: active=%u"
926
system_ss.add(when: 'CONFIG_FDC_ISA', if_true: files('fdc-isa.c'))
446
allwinner_sun8i_emac_read(uint64_t offset, uint64_t val) "MMIO read: offset=0x%" PRIx64 " value=0x%" PRIx64
927
system_ss.add(when: 'CONFIG_FDC_SYSBUS', if_true: files('fdc-sysbus.c'))
447
allwinner_sun8i_emac_write(uint64_t offset, uint64_t val) "MMIO write: offset=0x%" PRIx64 " value=0x%" PRIx64
928
system_ss.add(when: 'CONFIG_NAND', if_true: files('nand.c'))
448
929
-system_ss.add(when: 'CONFIG_ONENAND', if_true: files('onenand.c'))
449
+# lan9118_phy.c
930
system_ss.add(when: 'CONFIG_PFLASH_CFI01', if_true: files('pflash_cfi01.c'))
450
+lan9118_phy_read(uint16_t val, int reg) "[0x%02x] -> 0x%04" PRIx16
931
system_ss.add(when: 'CONFIG_PFLASH_CFI02', if_true: files('pflash_cfi02.c'))
451
+lan9118_phy_write(uint16_t val, int reg) "[0x%02x] <- 0x%04" PRIx16
932
system_ss.add(when: 'CONFIG_SSI_M25P80', if_true: files('m25p80.c'))
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"
933
--
471
--
934
2.34.1
472
2.34.1
diff view generated by jsdifflib
New patch
1
From: Bernhard Beschow <shentey@gmail.com>
1
2
3
Turns 0x70 into 0xe0 (== 0x70 << 1) which adds the missing MII_ANLPAR_TX and
4
fixes the MSB of selector field to be zero, as specified in the datasheet.
5
6
Fixes: 2a424990170b "LAN9118 emulation"
7
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
8
Tested-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20241102125724.532843-4-shentey@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/net/lan9118_phy.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/lan9118_phy.c
19
+++ b/hw/net/lan9118_phy.c
20
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
21
val = s->advertise;
22
break;
23
case 5: /* Auto-neg Link Partner Ability */
24
- val = 0x0f71;
25
+ val = 0x0fe1;
26
break;
27
case 6: /* Auto-neg Expansion */
28
val = 1;
29
--
30
2.34.1
diff view generated by jsdifflib
New patch
1
From: Bernhard Beschow <shentey@gmail.com>
1
2
3
Prefer named constants over magic values for better readability.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
7
Tested-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20241102125724.532843-5-shentey@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/net/mii.h | 6 +++++
12
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
13
2 files changed, 46 insertions(+), 23 deletions(-)
14
15
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/net/mii.h
18
+++ b/include/hw/net/mii.h
19
@@ -XXX,XX +XXX,XX @@
20
#define MII_BMSR_JABBER (1 << 1) /* Jabber detected */
21
#define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */
22
23
+#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */
24
#define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */
25
#define MII_ANAR_PAUSE (1 << 10) /* Try for pause */
26
#define MII_ANAR_TXFD (1 << 8)
27
@@ -XXX,XX +XXX,XX @@
28
#define MII_ANAR_10FD (1 << 6)
29
#define MII_ANAR_10 (1 << 5)
30
#define MII_ANAR_CSMACD (1 << 0)
31
+#define MII_ANAR_SELECT (0x001f) /* Selector bits */
32
33
#define MII_ANLPAR_ACK (1 << 14)
34
#define MII_ANLPAR_PAUSEASY (1 << 11) /* can pause asymmetrically */
35
@@ -XXX,XX +XXX,XX @@
36
#define RTL8201CP_PHYID1 0x0000
37
#define RTL8201CP_PHYID2 0x8201
38
39
+/* SMSC LAN9118 */
40
+#define SMSCLAN9118_PHYID1 0x0007
41
+#define SMSCLAN9118_PHYID2 0xc0d1
42
+
43
/* RealTek 8211E */
44
#define RTL8211E_PHYID1 0x001c
45
#define RTL8211E_PHYID2 0xc915
46
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/net/lan9118_phy.c
49
+++ b/hw/net/lan9118_phy.c
50
@@ -XXX,XX +XXX,XX @@
51
52
#include "qemu/osdep.h"
53
#include "hw/net/lan9118_phy.h"
54
+#include "hw/net/mii.h"
55
#include "hw/irq.h"
56
#include "hw/resettable.h"
57
#include "migration/vmstate.h"
58
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
59
uint16_t val;
60
61
switch (reg) {
62
- case 0: /* Basic Control */
63
+ case MII_BMCR:
64
val = s->control;
65
break;
66
- case 1: /* Basic Status */
67
+ case MII_BMSR:
68
val = s->status;
69
break;
70
- case 2: /* ID1 */
71
- val = 0x0007;
72
+ case MII_PHYID1:
73
+ val = SMSCLAN9118_PHYID1;
74
break;
75
- case 3: /* ID2 */
76
- val = 0xc0d1;
77
+ case MII_PHYID2:
78
+ val = SMSCLAN9118_PHYID2;
79
break;
80
- case 4: /* Auto-neg advertisement */
81
+ case MII_ANAR:
82
val = s->advertise;
83
break;
84
- case 5: /* Auto-neg Link Partner Ability */
85
- val = 0x0fe1;
86
+ case MII_ANLPAR:
87
+ val = MII_ANLPAR_PAUSEASY | MII_ANLPAR_PAUSE | MII_ANLPAR_T4 |
88
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
89
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
90
break;
91
- case 6: /* Auto-neg Expansion */
92
- val = 1;
93
+ case MII_ANER:
94
+ val = MII_ANER_NWAY;
95
break;
96
case 29: /* Interrupt source. */
97
val = s->ints;
98
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
99
trace_lan9118_phy_write(val, reg);
100
101
switch (reg) {
102
- case 0: /* Basic Control */
103
- if (val & 0x8000) {
104
+ case MII_BMCR:
105
+ if (val & MII_BMCR_RESET) {
106
lan9118_phy_reset(s);
107
} else {
108
- s->control = val & 0x7980;
109
+ s->control = val & (MII_BMCR_LOOPBACK | MII_BMCR_SPEED100 |
110
+ MII_BMCR_AUTOEN | MII_BMCR_PDOWN | MII_BMCR_FD |
111
+ MII_BMCR_CTST);
112
/* Complete autonegotiation immediately. */
113
- if (val & 0x1000) {
114
- s->status |= 0x0020;
115
+ if (val & MII_BMCR_AUTOEN) {
116
+ s->status |= MII_BMSR_AN_COMP;
117
}
118
}
119
break;
120
- case 4: /* Auto-neg advertisement */
121
- s->advertise = (val & 0x2d7f) | 0x80;
122
+ case MII_ANAR:
123
+ s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
124
+ MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
125
+ MII_ANAR_SELECT))
126
+ | MII_ANAR_TX;
127
break;
128
case 30: /* Interrupt mask */
129
s->int_mask = val & 0xff;
130
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
131
/* Autonegotiation status mirrors link status. */
132
if (link_down) {
133
trace_lan9118_phy_update_link("down");
134
- s->status &= ~0x0024;
135
+ s->status &= ~(MII_BMSR_AN_COMP | MII_BMSR_LINK_ST);
136
s->ints |= PHY_INT_DOWN;
137
} else {
138
trace_lan9118_phy_update_link("up");
139
- s->status |= 0x0024;
140
+ s->status |= MII_BMSR_AN_COMP | MII_BMSR_LINK_ST;
141
s->ints |= PHY_INT_ENERGYON;
142
s->ints |= PHY_INT_AUTONEG_COMPLETE;
143
}
144
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_reset(Lan9118PhyState *s)
145
{
146
trace_lan9118_phy_reset();
147
148
- s->control = 0x3000;
149
- s->status = 0x7809;
150
- s->advertise = 0x01e1;
151
+ s->control = MII_BMCR_AUTOEN | MII_BMCR_SPEED100;
152
+ s->status = MII_BMSR_100TX_FD
153
+ | MII_BMSR_100TX_HD
154
+ | MII_BMSR_10T_FD
155
+ | MII_BMSR_10T_HD
156
+ | MII_BMSR_AUTONEG
157
+ | MII_BMSR_EXTCAP;
158
+ s->advertise = MII_ANAR_TXFD
159
+ | MII_ANAR_TX
160
+ | MII_ANAR_10FD
161
+ | MII_ANAR_10
162
+ | MII_ANAR_CSMACD;
163
s->int_mask = 0;
164
s->ints = 0;
165
lan9118_phy_update_link(s, s->link_down);
166
--
167
2.34.1
diff view generated by jsdifflib
1
From: Shiva sagar Myana <Shivasagar.Myana@amd.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Ensure that the FIFO is checked for emptiness before popping data
3
The real device advertises this mode and the device model already advertises
4
from it. Previously, the code directly popped the data from the FIFO
4
100 mbps half duplex and 10 mbps full+half duplex. So advertise this mode to
5
without checking, which could cause an assertion failure:
5
make the model more realistic.
6
6
7
../util/fifo8.c:67: fifo8_pop: Assertion `fifo->num > 0' failed.
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
8
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
9
Signed-off-by: Shiva sagar Myana <Shivasagar.Myana@amd.com>
9
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
Message-id: 20240924112035.1320865-1-Shivasagar.Myana@amd.com
10
Message-id: 20241102125724.532843-6-shentey@gmail.com
11
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
12
[PMM: tweaked commit message]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
12
---
15
hw/ssi/xilinx_spips.c | 4 +++-
13
hw/net/lan9118_phy.c | 4 ++--
16
1 file changed, 3 insertions(+), 1 deletion(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
17
15
18
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.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/ssi/xilinx_spips.c
18
--- a/hw/net/lan9118_phy.c
21
+++ b/hw/ssi/xilinx_spips.c
19
+++ b/hw/net/lan9118_phy.c
22
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
20
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
23
} else if (s->snoop_state == SNOOP_STRIPING ||
21
break;
24
s->snoop_state == SNOOP_NONE) {
22
case MII_ANAR:
25
for (i = 0; i < num_effective_busses(s); ++i) {
23
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
26
- tx_rx[i] = fifo8_pop(&s->tx_fifo);
24
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
27
+ if (!fifo8_is_empty(&s->tx_fifo)) {
25
- MII_ANAR_SELECT))
28
+ tx_rx[i] = fifo8_pop(&s->tx_fifo);
26
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
29
+ }
27
+ MII_ANAR_10 | MII_ANAR_SELECT))
30
}
28
| MII_ANAR_TX;
31
stripe8(tx_rx, num_effective_busses(s), false);
29
break;
32
} else if (s->snoop_state >= SNOOP_ADDR) {
30
case 30: /* Interrupt mask */
33
--
31
--
34
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
The omap_dss device is OMAP2 only, and we are removing it.
1
IEEE 758 does not define a fixed rule for what NaN to return in
2
the case of a fused multiply-add of inf * 0 + NaN. Different
3
architectures thus do different things:
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.
2
29
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Message-id: 20240903160751.4100218-50-peter.maydell@linaro.org
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
5
---
33
---
6
include/hw/arm/omap.h | 19 -
34
include/fpu/softfloat-helpers.h | 11 ++++
7
hw/display/omap_dss.c | 1093 ----------------------------------------
35
include/fpu/softfloat-types.h | 23 +++++++++
8
hw/display/meson.build | 1 -
36
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
9
3 files changed, 1113 deletions(-)
37
3 files changed, 95 insertions(+), 30 deletions(-)
10
delete mode 100644 hw/display/omap_dss.c
38
11
39
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
12
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
13
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/omap.h
41
--- a/include/fpu/softfloat-helpers.h
15
+++ b/include/hw/arm/omap.h
42
+++ b/include/fpu/softfloat-helpers.h
16
@@ -XXX,XX +XXX,XX @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
43
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
17
struct omap_dma_lcd_channel_s *dma,
44
status->float_2nan_prop_rule = rule;
18
omap_clk clk);
45
}
19
46
20
-/* omap_dss.c */
47
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
21
-struct rfbi_chip_s {
48
+ float_status *status)
22
- void *opaque;
49
+{
23
- void (*write)(void *opaque, int dc, uint16_t value);
50
+ status->float_infzeronan_rule = rule;
24
- void (*block)(void *opaque, int dc, void *buf, size_t len, int pitch);
51
+}
25
- uint16_t (*read)(void *opaque, int dc);
52
+
26
-};
53
static inline void set_flush_to_zero(bool val, float_status *status)
27
-struct omap_dss_s;
54
{
28
-void omap_dss_reset(struct omap_dss_s *s);
55
status->flush_to_zero = val;
29
-struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
56
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
30
- MemoryRegion *sysmem,
57
return status->float_2nan_prop_rule;
31
- hwaddr l3_base,
58
}
32
- qemu_irq irq, qemu_irq drq,
59
33
- omap_clk fck1, omap_clk fck2, omap_clk ck54m,
60
+static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
34
- omap_clk ick1, omap_clk ick2);
61
+{
35
-void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip);
62
+ return status->float_infzeronan_rule;
63
+}
64
+
65
static inline bool get_flush_to_zero(float_status *status)
66
{
67
return status->flush_to_zero;
68
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
69
index XXXXXXX..XXXXXXX 100644
70
--- a/include/fpu/softfloat-types.h
71
+++ b/include/fpu/softfloat-types.h
72
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
73
float_2nan_prop_x87,
74
} Float2NaNPropRule;
75
76
+/*
77
+ * Rule for result of fused multiply-add 0 * Inf + NaN.
78
+ * This must be a NaN, but implementations differ on whether this
79
+ * is the input NaN or the default NaN.
80
+ *
81
+ * You don't need to set this if default_nan_mode is enabled.
82
+ * When not in default-NaN mode, it is an error for the target
83
+ * not to set the rule in float_status if it uses muladd, and we
84
+ * will assert if we need to handle an input NaN and no rule was
85
+ * selected.
86
+ */
87
+typedef enum __attribute__((__packed__)) {
88
+ /* No propagation rule specified */
89
+ float_infzeronan_none = 0,
90
+ /* Result is never the default NaN (so always the input NaN) */
91
+ float_infzeronan_dnan_never,
92
+ /* Result is always the default NaN */
93
+ float_infzeronan_dnan_always,
94
+ /* Result is the default NaN if the input NaN is quiet */
95
+ float_infzeronan_dnan_if_qnan,
96
+} FloatInfZeroNaNRule;
97
+
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
- */
36
-
229
-
37
/* omap_mmc.c */
230
/* Prefer sNaN over qNaN, in the c, a, b order. */
38
struct omap_mmc_s;
231
if (is_snan(c_cls)) {
39
struct omap_mmc_s *omap_mmc_init(hwaddr base,
232
return 2;
40
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s {
233
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
41
234
return 1;
42
/* OMAP2-only peripherals */
235
}
43
struct omap_l4_s *l4;
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
- */
44
-
241
-
45
- struct omap_dss_s *dss;
242
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
46
};
243
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
47
244
*/
48
/* omap1.c */
245
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
49
diff --git a/hw/display/omap_dss.c b/hw/display/omap_dss.c
246
return 1;
50
deleted file mode 100644
247
}
51
index XXXXXXX..XXXXXXX
248
#elif defined(TARGET_S390X)
52
--- a/hw/display/omap_dss.c
249
- if (infzero) {
53
+++ /dev/null
250
- return 3;
54
@@ -XXX,XX +XXX,XX @@
55
-/*
56
- * OMAP2 Display Subsystem.
57
- *
58
- * Copyright (C) 2008 Nokia Corporation
59
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
60
- *
61
- * This program is free software; you can redistribute it and/or
62
- * modify it under the terms of the GNU General Public License as
63
- * published by the Free Software Foundation; either version 2 or
64
- * (at your option) version 3 of the License.
65
- *
66
- * This program is distributed in the hope that it will be useful,
67
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
68
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
69
- * GNU General Public License for more details.
70
- *
71
- * You should have received a copy of the GNU General Public License along
72
- * with this program; if not, see <http://www.gnu.org/licenses/>.
73
- */
74
-
75
-#include "qemu/osdep.h"
76
-#include "qemu/log.h"
77
-#include "hw/hw.h"
78
-#include "hw/irq.h"
79
-#include "ui/console.h"
80
-#include "hw/arm/omap.h"
81
-
82
-struct omap_dss_s {
83
- qemu_irq irq;
84
- qemu_irq drq;
85
- DisplayState *state;
86
- MemoryRegion iomem_diss1, iomem_disc1, iomem_rfbi1, iomem_venc1, iomem_im3;
87
-
88
- int autoidle;
89
- int control;
90
- int enable;
91
-
92
- struct omap_dss_panel_s {
93
- int enable;
94
- int nx;
95
- int ny;
96
-
97
- int x;
98
- int y;
99
- } dig, lcd;
100
-
101
- struct {
102
- uint32_t idlemode;
103
- uint32_t irqst;
104
- uint32_t irqen;
105
- uint32_t control;
106
- uint32_t config;
107
- uint32_t capable;
108
- uint32_t timing[4];
109
- int line;
110
- uint32_t bg[2];
111
- uint32_t trans[2];
112
-
113
- struct omap_dss_plane_s {
114
- int enable;
115
- int bpp;
116
- int posx;
117
- int posy;
118
- int nx;
119
- int ny;
120
-
121
- hwaddr addr[3];
122
-
123
- uint32_t attr;
124
- uint32_t tresh;
125
- int rowinc;
126
- int colinc;
127
- int wininc;
128
- } l[3];
129
-
130
- int invalidate;
131
- uint16_t palette[256];
132
- } dispc;
133
-
134
- struct {
135
- int idlemode;
136
- uint32_t control;
137
- int enable;
138
- int pixels;
139
- int busy;
140
- int skiplines;
141
- uint16_t rxbuf;
142
- uint32_t config[2];
143
- uint32_t time[4];
144
- uint32_t data[6];
145
- uint16_t vsync;
146
- uint16_t hsync;
147
- struct rfbi_chip_s *chip[2];
148
- } rfbi;
149
-};
150
-
151
-static void omap_dispc_interrupt_update(struct omap_dss_s *s)
152
-{
153
- qemu_set_irq(s->irq, s->dispc.irqst & s->dispc.irqen);
154
-}
155
-
156
-static void omap_rfbi_reset(struct omap_dss_s *s)
157
-{
158
- s->rfbi.idlemode = 0;
159
- s->rfbi.control = 2;
160
- s->rfbi.enable = 0;
161
- s->rfbi.pixels = 0;
162
- s->rfbi.skiplines = 0;
163
- s->rfbi.busy = 0;
164
- s->rfbi.config[0] = 0x00310000;
165
- s->rfbi.config[1] = 0x00310000;
166
- s->rfbi.time[0] = 0;
167
- s->rfbi.time[1] = 0;
168
- s->rfbi.time[2] = 0;
169
- s->rfbi.time[3] = 0;
170
- s->rfbi.data[0] = 0;
171
- s->rfbi.data[1] = 0;
172
- s->rfbi.data[2] = 0;
173
- s->rfbi.data[3] = 0;
174
- s->rfbi.data[4] = 0;
175
- s->rfbi.data[5] = 0;
176
- s->rfbi.vsync = 0;
177
- s->rfbi.hsync = 0;
178
-}
179
-
180
-void omap_dss_reset(struct omap_dss_s *s)
181
-{
182
- s->autoidle = 0;
183
- s->control = 0;
184
- s->enable = 0;
185
-
186
- s->dig.enable = 0;
187
- s->dig.nx = 1;
188
- s->dig.ny = 1;
189
-
190
- s->lcd.enable = 0;
191
- s->lcd.nx = 1;
192
- s->lcd.ny = 1;
193
-
194
- s->dispc.idlemode = 0;
195
- s->dispc.irqst = 0;
196
- s->dispc.irqen = 0;
197
- s->dispc.control = 0;
198
- s->dispc.config = 0;
199
- s->dispc.capable = 0x161;
200
- s->dispc.timing[0] = 0;
201
- s->dispc.timing[1] = 0;
202
- s->dispc.timing[2] = 0;
203
- s->dispc.timing[3] = 0;
204
- s->dispc.line = 0;
205
- s->dispc.bg[0] = 0;
206
- s->dispc.bg[1] = 0;
207
- s->dispc.trans[0] = 0;
208
- s->dispc.trans[1] = 0;
209
-
210
- s->dispc.l[0].enable = 0;
211
- s->dispc.l[0].bpp = 0;
212
- s->dispc.l[0].addr[0] = 0;
213
- s->dispc.l[0].addr[1] = 0;
214
- s->dispc.l[0].addr[2] = 0;
215
- s->dispc.l[0].posx = 0;
216
- s->dispc.l[0].posy = 0;
217
- s->dispc.l[0].nx = 1;
218
- s->dispc.l[0].ny = 1;
219
- s->dispc.l[0].attr = 0;
220
- s->dispc.l[0].tresh = 0;
221
- s->dispc.l[0].rowinc = 1;
222
- s->dispc.l[0].colinc = 1;
223
- s->dispc.l[0].wininc = 0;
224
-
225
- omap_rfbi_reset(s);
226
- omap_dispc_interrupt_update(s);
227
-}
228
-
229
-static uint64_t omap_diss_read(void *opaque, hwaddr addr,
230
- unsigned size)
231
-{
232
- struct omap_dss_s *s = opaque;
233
-
234
- if (size != 4) {
235
- return omap_badwidth_read32(opaque, addr);
236
- }
251
- }
237
-
252
-
238
- switch (addr) {
253
if (is_snan(a_cls)) {
239
- case 0x00: /* DSS_REVISIONNUMBER */
254
return 0;
240
- return 0x20;
255
} else if (is_snan(b_cls)) {
241
-
242
- case 0x10: /* DSS_SYSCONFIG */
243
- return s->autoidle;
244
-
245
- case 0x14: /* DSS_SYSSTATUS */
246
- return 1; /* RESETDONE */
247
-
248
- case 0x40: /* DSS_CONTROL */
249
- return s->control;
250
-
251
- case 0x50: /* DSS_PSA_LCD_REG_1 */
252
- case 0x54: /* DSS_PSA_LCD_REG_2 */
253
- case 0x58: /* DSS_PSA_VIDEO_REG */
254
- /* TODO: fake some values when appropriate s->control bits are set */
255
- return 0;
256
-
257
- case 0x5c: /* DSS_STATUS */
258
- return 1 + (s->control & 1);
259
-
260
- default:
261
- break;
262
- }
263
- OMAP_BAD_REG(addr);
264
- return 0;
265
-}
266
-
267
-static void omap_diss_write(void *opaque, hwaddr addr,
268
- uint64_t value, unsigned size)
269
-{
270
- struct omap_dss_s *s = opaque;
271
-
272
- if (size != 4) {
273
- omap_badwidth_write32(opaque, addr, value);
274
- return;
275
- }
276
-
277
- switch (addr) {
278
- case 0x00: /* DSS_REVISIONNUMBER */
279
- case 0x14: /* DSS_SYSSTATUS */
280
- case 0x50: /* DSS_PSA_LCD_REG_1 */
281
- case 0x54: /* DSS_PSA_LCD_REG_2 */
282
- case 0x58: /* DSS_PSA_VIDEO_REG */
283
- case 0x5c: /* DSS_STATUS */
284
- OMAP_RO_REG(addr);
285
- break;
286
-
287
- case 0x10: /* DSS_SYSCONFIG */
288
- if (value & 2) /* SOFTRESET */
289
- omap_dss_reset(s);
290
- s->autoidle = value & 1;
291
- break;
292
-
293
- case 0x40: /* DSS_CONTROL */
294
- s->control = value & 0x3dd;
295
- break;
296
-
297
- default:
298
- OMAP_BAD_REG(addr);
299
- }
300
-}
301
-
302
-static const MemoryRegionOps omap_diss_ops = {
303
- .read = omap_diss_read,
304
- .write = omap_diss_write,
305
- .endianness = DEVICE_NATIVE_ENDIAN,
306
-};
307
-
308
-static uint64_t omap_disc_read(void *opaque, hwaddr addr,
309
- unsigned size)
310
-{
311
- struct omap_dss_s *s = opaque;
312
-
313
- if (size != 4) {
314
- return omap_badwidth_read32(opaque, addr);
315
- }
316
-
317
- switch (addr) {
318
- case 0x000: /* DISPC_REVISION */
319
- return 0x20;
320
-
321
- case 0x010: /* DISPC_SYSCONFIG */
322
- return s->dispc.idlemode;
323
-
324
- case 0x014: /* DISPC_SYSSTATUS */
325
- return 1; /* RESETDONE */
326
-
327
- case 0x018: /* DISPC_IRQSTATUS */
328
- return s->dispc.irqst;
329
-
330
- case 0x01c: /* DISPC_IRQENABLE */
331
- return s->dispc.irqen;
332
-
333
- case 0x040: /* DISPC_CONTROL */
334
- return s->dispc.control;
335
-
336
- case 0x044: /* DISPC_CONFIG */
337
- return s->dispc.config;
338
-
339
- case 0x048: /* DISPC_CAPABLE */
340
- return s->dispc.capable;
341
-
342
- case 0x04c: /* DISPC_DEFAULT_COLOR0 */
343
- return s->dispc.bg[0];
344
- case 0x050: /* DISPC_DEFAULT_COLOR1 */
345
- return s->dispc.bg[1];
346
- case 0x054: /* DISPC_TRANS_COLOR0 */
347
- return s->dispc.trans[0];
348
- case 0x058: /* DISPC_TRANS_COLOR1 */
349
- return s->dispc.trans[1];
350
-
351
- case 0x05c: /* DISPC_LINE_STATUS */
352
- return 0x7ff;
353
- case 0x060: /* DISPC_LINE_NUMBER */
354
- return s->dispc.line;
355
-
356
- case 0x064: /* DISPC_TIMING_H */
357
- return s->dispc.timing[0];
358
- case 0x068: /* DISPC_TIMING_V */
359
- return s->dispc.timing[1];
360
- case 0x06c: /* DISPC_POL_FREQ */
361
- return s->dispc.timing[2];
362
- case 0x070: /* DISPC_DIVISOR */
363
- return s->dispc.timing[3];
364
-
365
- case 0x078: /* DISPC_SIZE_DIG */
366
- return ((s->dig.ny - 1) << 16) | (s->dig.nx - 1);
367
- case 0x07c: /* DISPC_SIZE_LCD */
368
- return ((s->lcd.ny - 1) << 16) | (s->lcd.nx - 1);
369
-
370
- case 0x080: /* DISPC_GFX_BA0 */
371
- return s->dispc.l[0].addr[0];
372
- case 0x084: /* DISPC_GFX_BA1 */
373
- return s->dispc.l[0].addr[1];
374
- case 0x088: /* DISPC_GFX_POSITION */
375
- return (s->dispc.l[0].posy << 16) | s->dispc.l[0].posx;
376
- case 0x08c: /* DISPC_GFX_SIZE */
377
- return ((s->dispc.l[0].ny - 1) << 16) | (s->dispc.l[0].nx - 1);
378
- case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
379
- return s->dispc.l[0].attr;
380
- case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */
381
- return s->dispc.l[0].tresh;
382
- case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */
383
- return 256;
384
- case 0x0ac: /* DISPC_GFX_ROW_INC */
385
- return s->dispc.l[0].rowinc;
386
- case 0x0b0: /* DISPC_GFX_PIXEL_INC */
387
- return s->dispc.l[0].colinc;
388
- case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
389
- return s->dispc.l[0].wininc;
390
- case 0x0b8: /* DISPC_GFX_TABLE_BA */
391
- return s->dispc.l[0].addr[2];
392
-
393
- case 0x0bc: /* DISPC_VID1_BA0 */
394
- case 0x0c0: /* DISPC_VID1_BA1 */
395
- case 0x0c4: /* DISPC_VID1_POSITION */
396
- case 0x0c8: /* DISPC_VID1_SIZE */
397
- case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
398
- case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */
399
- case 0x0d4: /* DISPC_VID1_FIFO_SIZE_STATUS */
400
- case 0x0d8: /* DISPC_VID1_ROW_INC */
401
- case 0x0dc: /* DISPC_VID1_PIXEL_INC */
402
- case 0x0e0: /* DISPC_VID1_FIR */
403
- case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
404
- case 0x0e8: /* DISPC_VID1_ACCU0 */
405
- case 0x0ec: /* DISPC_VID1_ACCU1 */
406
- case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */
407
- case 0x14c: /* DISPC_VID2_BA0 */
408
- case 0x150: /* DISPC_VID2_BA1 */
409
- case 0x154: /* DISPC_VID2_POSITION */
410
- case 0x158: /* DISPC_VID2_SIZE */
411
- case 0x15c: /* DISPC_VID2_ATTRIBUTES */
412
- case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */
413
- case 0x164: /* DISPC_VID2_FIFO_SIZE_STATUS */
414
- case 0x168: /* DISPC_VID2_ROW_INC */
415
- case 0x16c: /* DISPC_VID2_PIXEL_INC */
416
- case 0x170: /* DISPC_VID2_FIR */
417
- case 0x174: /* DISPC_VID2_PICTURE_SIZE */
418
- case 0x178: /* DISPC_VID2_ACCU0 */
419
- case 0x17c: /* DISPC_VID2_ACCU1 */
420
- case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */
421
- case 0x1d4: /* DISPC_DATA_CYCLE1 */
422
- case 0x1d8: /* DISPC_DATA_CYCLE2 */
423
- case 0x1dc: /* DISPC_DATA_CYCLE3 */
424
- return 0;
425
-
426
- default:
427
- break;
428
- }
429
- OMAP_BAD_REG(addr);
430
- return 0;
431
-}
432
-
433
-static void omap_disc_write(void *opaque, hwaddr addr,
434
- uint64_t value, unsigned size)
435
-{
436
- struct omap_dss_s *s = opaque;
437
-
438
- if (size != 4) {
439
- omap_badwidth_write32(opaque, addr, value);
440
- return;
441
- }
442
-
443
- switch (addr) {
444
- case 0x010: /* DISPC_SYSCONFIG */
445
- if (value & 2) /* SOFTRESET */
446
- omap_dss_reset(s);
447
- s->dispc.idlemode = value & 0x301b;
448
- break;
449
-
450
- case 0x018: /* DISPC_IRQSTATUS */
451
- s->dispc.irqst &= ~value;
452
- omap_dispc_interrupt_update(s);
453
- break;
454
-
455
- case 0x01c: /* DISPC_IRQENABLE */
456
- s->dispc.irqen = value & 0xffff;
457
- omap_dispc_interrupt_update(s);
458
- break;
459
-
460
- case 0x040: /* DISPC_CONTROL */
461
- s->dispc.control = value & 0x07ff9fff;
462
- s->dig.enable = (value >> 1) & 1;
463
- s->lcd.enable = (value >> 0) & 1;
464
- if (value & (1 << 12)) /* OVERLAY_OPTIMIZATION */
465
- if (!((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1)) {
466
- fprintf(stderr, "%s: Overlay Optimization when no overlay "
467
- "region effectively exists leads to "
468
- "unpredictable behaviour!\n", __func__);
469
- }
470
- if (value & (1 << 6)) { /* GODIGITAL */
471
- /* XXX: Shadowed fields are:
472
- * s->dispc.config
473
- * s->dispc.capable
474
- * s->dispc.bg[0]
475
- * s->dispc.bg[1]
476
- * s->dispc.trans[0]
477
- * s->dispc.trans[1]
478
- * s->dispc.line
479
- * s->dispc.timing[0]
480
- * s->dispc.timing[1]
481
- * s->dispc.timing[2]
482
- * s->dispc.timing[3]
483
- * s->lcd.nx
484
- * s->lcd.ny
485
- * s->dig.nx
486
- * s->dig.ny
487
- * s->dispc.l[0].addr[0]
488
- * s->dispc.l[0].addr[1]
489
- * s->dispc.l[0].addr[2]
490
- * s->dispc.l[0].posx
491
- * s->dispc.l[0].posy
492
- * s->dispc.l[0].nx
493
- * s->dispc.l[0].ny
494
- * s->dispc.l[0].tresh
495
- * s->dispc.l[0].rowinc
496
- * s->dispc.l[0].colinc
497
- * s->dispc.l[0].wininc
498
- * All they need to be loaded here from their shadow registers.
499
- */
500
- }
501
- if (value & (1 << 5)) { /* GOLCD */
502
- /* XXX: Likewise for LCD here. */
503
- }
504
- s->dispc.invalidate = 1;
505
- break;
506
-
507
- case 0x044: /* DISPC_CONFIG */
508
- s->dispc.config = value & 0x3fff;
509
- /* XXX:
510
- * bits 2:1 (LOADMODE) reset to 0 after set to 1 and palette loaded
511
- * bits 2:1 (LOADMODE) reset to 2 after set to 3 and palette loaded
512
- */
513
- s->dispc.invalidate = 1;
514
- break;
515
-
516
- case 0x048: /* DISPC_CAPABLE */
517
- s->dispc.capable = value & 0x3ff;
518
- break;
519
-
520
- case 0x04c: /* DISPC_DEFAULT_COLOR0 */
521
- s->dispc.bg[0] = value & 0xffffff;
522
- s->dispc.invalidate = 1;
523
- break;
524
- case 0x050: /* DISPC_DEFAULT_COLOR1 */
525
- s->dispc.bg[1] = value & 0xffffff;
526
- s->dispc.invalidate = 1;
527
- break;
528
- case 0x054: /* DISPC_TRANS_COLOR0 */
529
- s->dispc.trans[0] = value & 0xffffff;
530
- s->dispc.invalidate = 1;
531
- break;
532
- case 0x058: /* DISPC_TRANS_COLOR1 */
533
- s->dispc.trans[1] = value & 0xffffff;
534
- s->dispc.invalidate = 1;
535
- break;
536
-
537
- case 0x060: /* DISPC_LINE_NUMBER */
538
- s->dispc.line = value & 0x7ff;
539
- break;
540
-
541
- case 0x064: /* DISPC_TIMING_H */
542
- s->dispc.timing[0] = value & 0x0ff0ff3f;
543
- break;
544
- case 0x068: /* DISPC_TIMING_V */
545
- s->dispc.timing[1] = value & 0x0ff0ff3f;
546
- break;
547
- case 0x06c: /* DISPC_POL_FREQ */
548
- s->dispc.timing[2] = value & 0x0003ffff;
549
- break;
550
- case 0x070: /* DISPC_DIVISOR */
551
- s->dispc.timing[3] = value & 0x00ff00ff;
552
- break;
553
-
554
- case 0x078: /* DISPC_SIZE_DIG */
555
- s->dig.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */
556
- s->dig.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */
557
- s->dispc.invalidate = 1;
558
- break;
559
- case 0x07c: /* DISPC_SIZE_LCD */
560
- s->lcd.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */
561
- s->lcd.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */
562
- s->dispc.invalidate = 1;
563
- break;
564
- case 0x080: /* DISPC_GFX_BA0 */
565
- s->dispc.l[0].addr[0] = (hwaddr) value;
566
- s->dispc.invalidate = 1;
567
- break;
568
- case 0x084: /* DISPC_GFX_BA1 */
569
- s->dispc.l[0].addr[1] = (hwaddr) value;
570
- s->dispc.invalidate = 1;
571
- break;
572
- case 0x088: /* DISPC_GFX_POSITION */
573
- s->dispc.l[0].posx = ((value >> 0) & 0x7ff); /* GFXPOSX */
574
- s->dispc.l[0].posy = ((value >> 16) & 0x7ff); /* GFXPOSY */
575
- s->dispc.invalidate = 1;
576
- break;
577
- case 0x08c: /* DISPC_GFX_SIZE */
578
- s->dispc.l[0].nx = ((value >> 0) & 0x7ff) + 1; /* GFXSIZEX */
579
- s->dispc.l[0].ny = ((value >> 16) & 0x7ff) + 1; /* GFXSIZEY */
580
- s->dispc.invalidate = 1;
581
- break;
582
- case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
583
- s->dispc.l[0].attr = value & 0x7ff;
584
- if (value & (3 << 9))
585
- fprintf(stderr, "%s: Big-endian pixel format not supported\n",
586
- __func__);
587
- s->dispc.l[0].enable = value & 1;
588
- s->dispc.l[0].bpp = (value >> 1) & 0xf;
589
- s->dispc.invalidate = 1;
590
- break;
591
- case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */
592
- s->dispc.l[0].tresh = value & 0x01ff01ff;
593
- break;
594
- case 0x0ac: /* DISPC_GFX_ROW_INC */
595
- s->dispc.l[0].rowinc = value;
596
- s->dispc.invalidate = 1;
597
- break;
598
- case 0x0b0: /* DISPC_GFX_PIXEL_INC */
599
- s->dispc.l[0].colinc = value;
600
- s->dispc.invalidate = 1;
601
- break;
602
- case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
603
- s->dispc.l[0].wininc = value;
604
- break;
605
- case 0x0b8: /* DISPC_GFX_TABLE_BA */
606
- s->dispc.l[0].addr[2] = (hwaddr) value;
607
- s->dispc.invalidate = 1;
608
- break;
609
-
610
- case 0x0bc: /* DISPC_VID1_BA0 */
611
- case 0x0c0: /* DISPC_VID1_BA1 */
612
- case 0x0c4: /* DISPC_VID1_POSITION */
613
- case 0x0c8: /* DISPC_VID1_SIZE */
614
- case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
615
- case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */
616
- case 0x0d8: /* DISPC_VID1_ROW_INC */
617
- case 0x0dc: /* DISPC_VID1_PIXEL_INC */
618
- case 0x0e0: /* DISPC_VID1_FIR */
619
- case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
620
- case 0x0e8: /* DISPC_VID1_ACCU0 */
621
- case 0x0ec: /* DISPC_VID1_ACCU1 */
622
- case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */
623
- case 0x14c: /* DISPC_VID2_BA0 */
624
- case 0x150: /* DISPC_VID2_BA1 */
625
- case 0x154: /* DISPC_VID2_POSITION */
626
- case 0x158: /* DISPC_VID2_SIZE */
627
- case 0x15c: /* DISPC_VID2_ATTRIBUTES */
628
- case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */
629
- case 0x168: /* DISPC_VID2_ROW_INC */
630
- case 0x16c: /* DISPC_VID2_PIXEL_INC */
631
- case 0x170: /* DISPC_VID2_FIR */
632
- case 0x174: /* DISPC_VID2_PICTURE_SIZE */
633
- case 0x178: /* DISPC_VID2_ACCU0 */
634
- case 0x17c: /* DISPC_VID2_ACCU1 */
635
- case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */
636
- case 0x1d4: /* DISPC_DATA_CYCLE1 */
637
- case 0x1d8: /* DISPC_DATA_CYCLE2 */
638
- case 0x1dc: /* DISPC_DATA_CYCLE3 */
639
- break;
640
-
641
- default:
642
- OMAP_BAD_REG(addr);
643
- }
644
-}
645
-
646
-static const MemoryRegionOps omap_disc_ops = {
647
- .read = omap_disc_read,
648
- .write = omap_disc_write,
649
- .endianness = DEVICE_NATIVE_ENDIAN,
650
-};
651
-
652
-static void omap_rfbi_transfer_stop(struct omap_dss_s *s)
653
-{
654
- if (!s->rfbi.busy)
655
- return;
656
-
657
- /* TODO: in non-Bypass mode we probably need to just deassert the DRQ. */
658
-
659
- s->rfbi.busy = 0;
660
-}
661
-
662
-static void omap_rfbi_transfer_start(struct omap_dss_s *s)
663
-{
664
- void *data;
665
- hwaddr len;
666
- hwaddr data_addr;
667
- int pitch;
668
- static void *bounce_buffer;
669
- static hwaddr bounce_len;
670
-
671
- if (!s->rfbi.enable || s->rfbi.busy)
672
- return;
673
-
674
- if (s->rfbi.control & (1 << 1)) { /* BYPASS */
675
- /* TODO: in non-Bypass mode we probably need to just assert the
676
- * DRQ and wait for DMA to write the pixels. */
677
- qemu_log_mask(LOG_UNIMP, "%s: Bypass mode unimplemented\n", __func__);
678
- return;
679
- }
680
-
681
- if (!(s->dispc.control & (1 << 11))) /* RFBIMODE */
682
- return;
683
- /* TODO: check that LCD output is enabled in DISPC. */
684
-
685
- s->rfbi.busy = 1;
686
-
687
- len = s->rfbi.pixels * 2;
688
-
689
- data_addr = s->dispc.l[0].addr[0];
690
- data = cpu_physical_memory_map(data_addr, &len, false);
691
- if (data && len != s->rfbi.pixels * 2) {
692
- cpu_physical_memory_unmap(data, len, 0, 0);
693
- data = NULL;
694
- len = s->rfbi.pixels * 2;
695
- }
696
- if (!data) {
697
- if (len > bounce_len) {
698
- bounce_buffer = g_realloc(bounce_buffer, len);
699
- }
700
- data = bounce_buffer;
701
- cpu_physical_memory_read(data_addr, data, len);
702
- }
703
-
704
- /* TODO bpp */
705
- s->rfbi.pixels = 0;
706
-
707
- /* TODO: negative values */
708
- pitch = s->dispc.l[0].nx + (s->dispc.l[0].rowinc - 1) / 2;
709
-
710
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
711
- s->rfbi.chip[0]->block(s->rfbi.chip[0]->opaque, 1, data, len, pitch);
712
- if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
713
- s->rfbi.chip[1]->block(s->rfbi.chip[1]->opaque, 1, data, len, pitch);
714
-
715
- if (data != bounce_buffer) {
716
- cpu_physical_memory_unmap(data, len, 0, len);
717
- }
718
-
719
- omap_rfbi_transfer_stop(s);
720
-
721
- /* TODO */
722
- s->dispc.irqst |= 1; /* FRAMEDONE */
723
- omap_dispc_interrupt_update(s);
724
-}
725
-
726
-static uint64_t omap_rfbi_read(void *opaque, hwaddr addr, unsigned size)
727
-{
728
- struct omap_dss_s *s = opaque;
729
-
730
- if (size != 4) {
731
- return omap_badwidth_read32(opaque, addr);
732
- }
733
-
734
- switch (addr) {
735
- case 0x00: /* RFBI_REVISION */
736
- return 0x10;
737
-
738
- case 0x10: /* RFBI_SYSCONFIG */
739
- return s->rfbi.idlemode;
740
-
741
- case 0x14: /* RFBI_SYSSTATUS */
742
- return 1 | (s->rfbi.busy << 8); /* RESETDONE */
743
-
744
- case 0x40: /* RFBI_CONTROL */
745
- return s->rfbi.control;
746
-
747
- case 0x44: /* RFBI_PIXELCNT */
748
- return s->rfbi.pixels;
749
-
750
- case 0x48: /* RFBI_LINE_NUMBER */
751
- return s->rfbi.skiplines;
752
-
753
- case 0x58: /* RFBI_READ */
754
- case 0x5c: /* RFBI_STATUS */
755
- return s->rfbi.rxbuf;
756
-
757
- case 0x60: /* RFBI_CONFIG0 */
758
- return s->rfbi.config[0];
759
- case 0x64: /* RFBI_ONOFF_TIME0 */
760
- return s->rfbi.time[0];
761
- case 0x68: /* RFBI_CYCLE_TIME0 */
762
- return s->rfbi.time[1];
763
- case 0x6c: /* RFBI_DATA_CYCLE1_0 */
764
- return s->rfbi.data[0];
765
- case 0x70: /* RFBI_DATA_CYCLE2_0 */
766
- return s->rfbi.data[1];
767
- case 0x74: /* RFBI_DATA_CYCLE3_0 */
768
- return s->rfbi.data[2];
769
-
770
- case 0x78: /* RFBI_CONFIG1 */
771
- return s->rfbi.config[1];
772
- case 0x7c: /* RFBI_ONOFF_TIME1 */
773
- return s->rfbi.time[2];
774
- case 0x80: /* RFBI_CYCLE_TIME1 */
775
- return s->rfbi.time[3];
776
- case 0x84: /* RFBI_DATA_CYCLE1_1 */
777
- return s->rfbi.data[3];
778
- case 0x88: /* RFBI_DATA_CYCLE2_1 */
779
- return s->rfbi.data[4];
780
- case 0x8c: /* RFBI_DATA_CYCLE3_1 */
781
- return s->rfbi.data[5];
782
-
783
- case 0x90: /* RFBI_VSYNC_WIDTH */
784
- return s->rfbi.vsync;
785
- case 0x94: /* RFBI_HSYNC_WIDTH */
786
- return s->rfbi.hsync;
787
- }
788
- OMAP_BAD_REG(addr);
789
- return 0;
790
-}
791
-
792
-static void omap_rfbi_write(void *opaque, hwaddr addr,
793
- uint64_t value, unsigned size)
794
-{
795
- struct omap_dss_s *s = opaque;
796
-
797
- if (size != 4) {
798
- omap_badwidth_write32(opaque, addr, value);
799
- return;
800
- }
801
-
802
- switch (addr) {
803
- case 0x10: /* RFBI_SYSCONFIG */
804
- if (value & 2) /* SOFTRESET */
805
- omap_rfbi_reset(s);
806
- s->rfbi.idlemode = value & 0x19;
807
- break;
808
-
809
- case 0x40: /* RFBI_CONTROL */
810
- s->rfbi.control = value & 0xf;
811
- s->rfbi.enable = value & 1;
812
- if (value & (1 << 4) && /* ITE */
813
- !(s->rfbi.config[0] & s->rfbi.config[1] & 0xc))
814
- omap_rfbi_transfer_start(s);
815
- break;
816
-
817
- case 0x44: /* RFBI_PIXELCNT */
818
- s->rfbi.pixels = value;
819
- break;
820
-
821
- case 0x48: /* RFBI_LINE_NUMBER */
822
- s->rfbi.skiplines = value & 0x7ff;
823
- break;
824
-
825
- case 0x4c: /* RFBI_CMD */
826
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
827
- s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 0, value & 0xffff);
828
- if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
829
- s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 0, value & 0xffff);
830
- break;
831
- case 0x50: /* RFBI_PARAM */
832
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
833
- s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
834
- if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
835
- s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
836
- break;
837
- case 0x54: /* RFBI_DATA */
838
- /* TODO: take into account the format set up in s->rfbi.config[?] and
839
- * s->rfbi.data[?], but special-case the most usual scenario so that
840
- * speed doesn't suffer. */
841
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) {
842
- s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
843
- s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value >> 16);
844
- }
845
- if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) {
846
- s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
847
- s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value >> 16);
848
- }
849
- if (!-- s->rfbi.pixels)
850
- omap_rfbi_transfer_stop(s);
851
- break;
852
- case 0x58: /* RFBI_READ */
853
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
854
- s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1);
855
- else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
856
- s->rfbi.rxbuf = s->rfbi.chip[1]->read(s->rfbi.chip[1]->opaque, 1);
857
- if (!-- s->rfbi.pixels)
858
- omap_rfbi_transfer_stop(s);
859
- break;
860
-
861
- case 0x5c: /* RFBI_STATUS */
862
- if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
863
- s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0);
864
- else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
865
- s->rfbi.rxbuf = s->rfbi.chip[1]->read(s->rfbi.chip[1]->opaque, 0);
866
- if (!-- s->rfbi.pixels)
867
- omap_rfbi_transfer_stop(s);
868
- break;
869
-
870
- case 0x60: /* RFBI_CONFIG0 */
871
- s->rfbi.config[0] = value & 0x003f1fff;
872
- break;
873
-
874
- case 0x64: /* RFBI_ONOFF_TIME0 */
875
- s->rfbi.time[0] = value & 0x3fffffff;
876
- break;
877
- case 0x68: /* RFBI_CYCLE_TIME0 */
878
- s->rfbi.time[1] = value & 0x0fffffff;
879
- break;
880
- case 0x6c: /* RFBI_DATA_CYCLE1_0 */
881
- s->rfbi.data[0] = value & 0x0f1f0f1f;
882
- break;
883
- case 0x70: /* RFBI_DATA_CYCLE2_0 */
884
- s->rfbi.data[1] = value & 0x0f1f0f1f;
885
- break;
886
- case 0x74: /* RFBI_DATA_CYCLE3_0 */
887
- s->rfbi.data[2] = value & 0x0f1f0f1f;
888
- break;
889
- case 0x78: /* RFBI_CONFIG1 */
890
- s->rfbi.config[1] = value & 0x003f1fff;
891
- break;
892
-
893
- case 0x7c: /* RFBI_ONOFF_TIME1 */
894
- s->rfbi.time[2] = value & 0x3fffffff;
895
- break;
896
- case 0x80: /* RFBI_CYCLE_TIME1 */
897
- s->rfbi.time[3] = value & 0x0fffffff;
898
- break;
899
- case 0x84: /* RFBI_DATA_CYCLE1_1 */
900
- s->rfbi.data[3] = value & 0x0f1f0f1f;
901
- break;
902
- case 0x88: /* RFBI_DATA_CYCLE2_1 */
903
- s->rfbi.data[4] = value & 0x0f1f0f1f;
904
- break;
905
- case 0x8c: /* RFBI_DATA_CYCLE3_1 */
906
- s->rfbi.data[5] = value & 0x0f1f0f1f;
907
- break;
908
-
909
- case 0x90: /* RFBI_VSYNC_WIDTH */
910
- s->rfbi.vsync = value & 0xffff;
911
- break;
912
- case 0x94: /* RFBI_HSYNC_WIDTH */
913
- s->rfbi.hsync = value & 0xffff;
914
- break;
915
-
916
- default:
917
- OMAP_BAD_REG(addr);
918
- }
919
-}
920
-
921
-static const MemoryRegionOps omap_rfbi_ops = {
922
- .read = omap_rfbi_read,
923
- .write = omap_rfbi_write,
924
- .endianness = DEVICE_NATIVE_ENDIAN,
925
-};
926
-
927
-static uint64_t omap_venc_read(void *opaque, hwaddr addr,
928
- unsigned size)
929
-{
930
- if (size != 4) {
931
- return omap_badwidth_read32(opaque, addr);
932
- }
933
-
934
- switch (addr) {
935
- case 0x00: /* REV_ID */
936
- case 0x04: /* STATUS */
937
- case 0x08: /* F_CONTROL */
938
- case 0x10: /* VIDOUT_CTRL */
939
- case 0x14: /* SYNC_CTRL */
940
- case 0x1c: /* LLEN */
941
- case 0x20: /* FLENS */
942
- case 0x24: /* HFLTR_CTRL */
943
- case 0x28: /* CC_CARR_WSS_CARR */
944
- case 0x2c: /* C_PHASE */
945
- case 0x30: /* GAIN_U */
946
- case 0x34: /* GAIN_V */
947
- case 0x38: /* GAIN_Y */
948
- case 0x3c: /* BLACK_LEVEL */
949
- case 0x40: /* BLANK_LEVEL */
950
- case 0x44: /* X_COLOR */
951
- case 0x48: /* M_CONTROL */
952
- case 0x4c: /* BSTAMP_WSS_DATA */
953
- case 0x50: /* S_CARR */
954
- case 0x54: /* LINE21 */
955
- case 0x58: /* LN_SEL */
956
- case 0x5c: /* L21__WC_CTL */
957
- case 0x60: /* HTRIGGER_VTRIGGER */
958
- case 0x64: /* SAVID__EAVID */
959
- case 0x68: /* FLEN__FAL */
960
- case 0x6c: /* LAL__PHASE_RESET */
961
- case 0x70: /* HS_INT_START_STOP_X */
962
- case 0x74: /* HS_EXT_START_STOP_X */
963
- case 0x78: /* VS_INT_START_X */
964
- case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */
965
- case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */
966
- case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */
967
- case 0x88: /* VS_EXT_STOP_Y */
968
- case 0x90: /* AVID_START_STOP_X */
969
- case 0x94: /* AVID_START_STOP_Y */
970
- case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */
971
- case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */
972
- case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
973
- case 0xb0: /* TVDETGP_INT_START_STOP_X */
974
- case 0xb4: /* TVDETGP_INT_START_STOP_Y */
975
- case 0xb8: /* GEN_CTRL */
976
- case 0xc4: /* DAC_TST__DAC_A */
977
- case 0xc8: /* DAC_B__DAC_C */
978
- return 0;
979
-
980
- default:
981
- break;
982
- }
983
- OMAP_BAD_REG(addr);
984
- return 0;
985
-}
986
-
987
-static void omap_venc_write(void *opaque, hwaddr addr,
988
- uint64_t value, unsigned size)
989
-{
990
- if (size != 4) {
991
- omap_badwidth_write32(opaque, addr, size);
992
- return;
993
- }
994
-
995
- switch (addr) {
996
- case 0x08: /* F_CONTROL */
997
- case 0x10: /* VIDOUT_CTRL */
998
- case 0x14: /* SYNC_CTRL */
999
- case 0x1c: /* LLEN */
1000
- case 0x20: /* FLENS */
1001
- case 0x24: /* HFLTR_CTRL */
1002
- case 0x28: /* CC_CARR_WSS_CARR */
1003
- case 0x2c: /* C_PHASE */
1004
- case 0x30: /* GAIN_U */
1005
- case 0x34: /* GAIN_V */
1006
- case 0x38: /* GAIN_Y */
1007
- case 0x3c: /* BLACK_LEVEL */
1008
- case 0x40: /* BLANK_LEVEL */
1009
- case 0x44: /* X_COLOR */
1010
- case 0x48: /* M_CONTROL */
1011
- case 0x4c: /* BSTAMP_WSS_DATA */
1012
- case 0x50: /* S_CARR */
1013
- case 0x54: /* LINE21 */
1014
- case 0x58: /* LN_SEL */
1015
- case 0x5c: /* L21__WC_CTL */
1016
- case 0x60: /* HTRIGGER_VTRIGGER */
1017
- case 0x64: /* SAVID__EAVID */
1018
- case 0x68: /* FLEN__FAL */
1019
- case 0x6c: /* LAL__PHASE_RESET */
1020
- case 0x70: /* HS_INT_START_STOP_X */
1021
- case 0x74: /* HS_EXT_START_STOP_X */
1022
- case 0x78: /* VS_INT_START_X */
1023
- case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */
1024
- case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */
1025
- case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */
1026
- case 0x88: /* VS_EXT_STOP_Y */
1027
- case 0x90: /* AVID_START_STOP_X */
1028
- case 0x94: /* AVID_START_STOP_Y */
1029
- case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */
1030
- case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */
1031
- case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
1032
- case 0xb0: /* TVDETGP_INT_START_STOP_X */
1033
- case 0xb4: /* TVDETGP_INT_START_STOP_Y */
1034
- case 0xb8: /* GEN_CTRL */
1035
- case 0xc4: /* DAC_TST__DAC_A */
1036
- case 0xc8: /* DAC_B__DAC_C */
1037
- break;
1038
-
1039
- default:
1040
- OMAP_BAD_REG(addr);
1041
- }
1042
-}
1043
-
1044
-static const MemoryRegionOps omap_venc_ops = {
1045
- .read = omap_venc_read,
1046
- .write = omap_venc_write,
1047
- .endianness = DEVICE_NATIVE_ENDIAN,
1048
-};
1049
-
1050
-static uint64_t omap_im3_read(void *opaque, hwaddr addr,
1051
- unsigned size)
1052
-{
1053
- if (size != 4) {
1054
- return omap_badwidth_read32(opaque, addr);
1055
- }
1056
-
1057
- switch (addr) {
1058
- case 0x0a8: /* SBIMERRLOGA */
1059
- case 0x0b0: /* SBIMERRLOG */
1060
- case 0x190: /* SBIMSTATE */
1061
- case 0x198: /* SBTMSTATE_L */
1062
- case 0x19c: /* SBTMSTATE_H */
1063
- case 0x1a8: /* SBIMCONFIG_L */
1064
- case 0x1ac: /* SBIMCONFIG_H */
1065
- case 0x1f8: /* SBID_L */
1066
- case 0x1fc: /* SBID_H */
1067
- return 0;
1068
-
1069
- default:
1070
- break;
1071
- }
1072
- OMAP_BAD_REG(addr);
1073
- return 0;
1074
-}
1075
-
1076
-static void omap_im3_write(void *opaque, hwaddr addr,
1077
- uint64_t value, unsigned size)
1078
-{
1079
- if (size != 4) {
1080
- omap_badwidth_write32(opaque, addr, value);
1081
- return;
1082
- }
1083
-
1084
- switch (addr) {
1085
- case 0x0b0: /* SBIMERRLOG */
1086
- case 0x190: /* SBIMSTATE */
1087
- case 0x198: /* SBTMSTATE_L */
1088
- case 0x19c: /* SBTMSTATE_H */
1089
- case 0x1a8: /* SBIMCONFIG_L */
1090
- case 0x1ac: /* SBIMCONFIG_H */
1091
- break;
1092
-
1093
- default:
1094
- OMAP_BAD_REG(addr);
1095
- }
1096
-}
1097
-
1098
-static const MemoryRegionOps omap_im3_ops = {
1099
- .read = omap_im3_read,
1100
- .write = omap_im3_write,
1101
- .endianness = DEVICE_NATIVE_ENDIAN,
1102
-};
1103
-
1104
-struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
1105
- MemoryRegion *sysmem,
1106
- hwaddr l3_base,
1107
- qemu_irq irq, qemu_irq drq,
1108
- omap_clk fck1, omap_clk fck2, omap_clk ck54m,
1109
- omap_clk ick1, omap_clk ick2)
1110
-{
1111
- struct omap_dss_s *s = g_new0(struct omap_dss_s, 1);
1112
-
1113
- s->irq = irq;
1114
- s->drq = drq;
1115
- omap_dss_reset(s);
1116
-
1117
- memory_region_init_io(&s->iomem_diss1, NULL, &omap_diss_ops, s, "omap.diss1",
1118
- omap_l4_region_size(ta, 0));
1119
- memory_region_init_io(&s->iomem_disc1, NULL, &omap_disc_ops, s, "omap.disc1",
1120
- omap_l4_region_size(ta, 1));
1121
- memory_region_init_io(&s->iomem_rfbi1, NULL, &omap_rfbi_ops, s, "omap.rfbi1",
1122
- omap_l4_region_size(ta, 2));
1123
- memory_region_init_io(&s->iomem_venc1, NULL, &omap_venc_ops, s, "omap.venc1",
1124
- omap_l4_region_size(ta, 3));
1125
- memory_region_init_io(&s->iomem_im3, NULL, &omap_im3_ops, s,
1126
- "omap.im3", 0x1000);
1127
-
1128
- omap_l4_attach(ta, 0, &s->iomem_diss1);
1129
- omap_l4_attach(ta, 1, &s->iomem_disc1);
1130
- omap_l4_attach(ta, 2, &s->iomem_rfbi1);
1131
- omap_l4_attach(ta, 3, &s->iomem_venc1);
1132
- memory_region_add_subregion(sysmem, l3_base, &s->iomem_im3);
1133
-
1134
-#if 0
1135
- s->state = graphic_console_init(omap_update_display,
1136
- omap_invalidate_display, omap_screen_dump, s);
1137
-#endif
1138
-
1139
- return s;
1140
-}
1141
-
1142
-void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip)
1143
-{
1144
- if (cs < 0 || cs > 1)
1145
- hw_error("%s: wrong CS %i\n", __func__, cs);
1146
- s->rfbi.chip[cs] = chip;
1147
-}
1148
diff --git a/hw/display/meson.build b/hw/display/meson.build
1149
index XXXXXXX..XXXXXXX 100644
1150
--- a/hw/display/meson.build
1151
+++ b/hw/display/meson.build
1152
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_BOCHS_DISPLAY', if_true: files('bochs-display.c'))
1153
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_fimd.c'))
1154
system_ss.add(when: 'CONFIG_FRAMEBUFFER', if_true: files('framebuffer.c'))
1155
1156
-system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_dss.c'))
1157
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_fb.c'))
1158
system_ss.add(when: 'CONFIG_SM501', if_true: files('sm501.c'))
1159
system_ss.add(when: 'CONFIG_TCX', if_true: files('tcx.c'))
1160
--
256
--
1161
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
1
Remove the handling for all non-OMAP1 SoCs.
1
Set the FloatInfZeroNaNRule explicitly for s390, so we
2
can remove the ifdef from pickNaNMulAdd().
2
3
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Message-id: 20240903160751.4100218-52-peter.maydell@linaro.org
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-7-peter.maydell@linaro.org
5
---
7
---
6
hw/misc/omap_clk.c | 527 +--------------------------------------------
8
target/s390x/cpu.c | 2 ++
7
1 file changed, 2 insertions(+), 525 deletions(-)
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
8
11
9
diff --git a/hw/misc/omap_clk.c b/hw/misc/omap_clk.c
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
10
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/misc/omap_clk.c
14
--- a/target/s390x/cpu.c
12
+++ b/hw/misc/omap_clk.c
15
+++ b/target/s390x/cpu.c
13
@@ -XXX,XX +XXX,XX @@ struct clk {
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
14
#define CLOCK_IN_OMAP730    (1 << 11)
17
set_float_detect_tininess(float_tininess_before_rounding,
15
#define CLOCK_IN_OMAP1510    (1 << 12)
18
&env->fpu_status);
16
#define CLOCK_IN_OMAP16XX    (1 << 13)
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
17
-#define CLOCK_IN_OMAP242X    (1 << 14)
20
+ set_float_infzeronan_rule(float_infzeronan_dnan_always,
18
-#define CLOCK_IN_OMAP243X    (1 << 15)
21
+ &env->fpu_status);
19
-#define CLOCK_IN_OMAP343X    (1 << 16)
22
/* fall through */
20
uint32_t flags;
23
case RESET_TYPE_S390_CPU_NORMAL:
21
int id;
24
env->psw.mask &= ~PSW_MASK_RI;
22
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
23
@@ -XXX,XX +XXX,XX @@ static struct clk xtal_osc12m = {
26
index XXXXXXX..XXXXXXX 100644
24
static struct clk xtal_osc32k = {
27
--- a/fpu/softfloat-specialize.c.inc
25
.name    = "xtal_osc_32k",
28
+++ b/fpu/softfloat-specialize.c.inc
26
.rate    = 32768,
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
27
- .flags    = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
30
* a default NaN
28
- CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
31
*/
29
+ .flags    = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
32
rule = float_infzeronan_dnan_never;
30
};
33
-#elif defined(TARGET_S390X)
31
34
- rule = float_infzeronan_dnan_always;
32
static struct clk ck_ref = {
35
#endif
33
@@ -XXX,XX +XXX,XX @@ static struct clk i2c_ick = {
36
}
34
static struct clk clk32k = {
35
.name    = "clk32-kHz",
36
.flags    = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
37
- CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
38
+ ALWAYS_ENABLED,
39
.parent    = &xtal_osc32k,
40
};
41
42
-static struct clk ref_clk = {
43
- .name    = "ref_clk",
44
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
45
- .rate    = 12000000,    /* 12 MHz or 13 MHz or 19.2 MHz */
46
- /*.parent    = sys.xtalin */
47
-};
48
-
49
-static struct clk apll_96m = {
50
- .name    = "apll_96m",
51
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
52
- .rate    = 96000000,
53
- /*.parent    = ref_clk */
54
-};
55
-
56
-static struct clk apll_54m = {
57
- .name    = "apll_54m",
58
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
59
- .rate    = 54000000,
60
- /*.parent    = ref_clk */
61
-};
62
-
63
-static struct clk sys_clk = {
64
- .name    = "sys_clk",
65
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
66
- .rate    = 32768,
67
- /*.parent    = sys.xtalin */
68
-};
69
-
70
-static struct clk sleep_clk = {
71
- .name    = "sleep_clk",
72
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
73
- .rate    = 32768,
74
- /*.parent    = sys.xtalin */
75
-};
76
-
77
-static struct clk dpll_ck = {
78
- .name    = "dpll",
79
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
80
- .parent    = &ref_clk,
81
-};
82
-
83
-static struct clk dpll_x2_ck = {
84
- .name    = "dpll_x2",
85
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
86
- .parent    = &ref_clk,
87
-};
88
-
89
-static struct clk wdt1_sys_clk = {
90
- .name    = "wdt1_sys_clk",
91
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
92
- .rate    = 32768,
93
- /*.parent    = sys.xtalin */
94
-};
95
-
96
-static struct clk func_96m_clk = {
97
- .name    = "func_96m_clk",
98
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
99
- .divisor    = 1,
100
- .parent    = &apll_96m,
101
-};
102
-
103
-static struct clk func_48m_clk = {
104
- .name    = "func_48m_clk",
105
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
106
- .divisor    = 2,
107
- .parent    = &apll_96m,
108
-};
109
-
110
-static struct clk func_12m_clk = {
111
- .name    = "func_12m_clk",
112
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
113
- .divisor    = 8,
114
- .parent    = &apll_96m,
115
-};
116
-
117
-static struct clk func_54m_clk = {
118
- .name    = "func_54m_clk",
119
- .flags    = CLOCK_IN_OMAP242X,
120
- .divisor    = 1,
121
- .parent    = &apll_54m,
122
-};
123
-
124
-static struct clk sys_clkout = {
125
- .name    = "clkout",
126
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
127
- .parent    = &sys_clk,
128
-};
129
-
130
-static struct clk sys_clkout2 = {
131
- .name    = "clkout2",
132
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
133
- .parent    = &sys_clk,
134
-};
135
-
136
-static struct clk core_clk = {
137
- .name    = "core_clk",
138
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
139
- .parent    = &dpll_x2_ck,    /* Switchable between dpll_ck and clk32k */
140
-};
141
-
142
-static struct clk l3_clk = {
143
- .name    = "l3_clk",
144
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
145
- .parent    = &core_clk,
146
-};
147
-
148
-static struct clk core_l4_iclk = {
149
- .name    = "core_l4_iclk",
150
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
151
- .parent    = &l3_clk,
152
-};
153
-
154
-static struct clk wu_l4_iclk = {
155
- .name    = "wu_l4_iclk",
156
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
157
- .parent    = &l3_clk,
158
-};
159
-
160
-static struct clk core_l3_iclk = {
161
- .name    = "core_l3_iclk",
162
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
163
- .parent    = &core_clk,
164
-};
165
-
166
-static struct clk core_l4_usb_clk = {
167
- .name    = "core_l4_usb_clk",
168
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
169
- .parent    = &l3_clk,
170
-};
171
-
172
-static struct clk wu_gpt1_clk = {
173
- .name    = "wu_gpt1_clk",
174
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
175
- .parent    = &sys_clk,
176
-};
177
-
178
-static struct clk wu_32k_clk = {
179
- .name    = "wu_32k_clk",
180
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
181
- .parent    = &sys_clk,
182
-};
183
-
184
-static struct clk uart1_fclk = {
185
- .name    = "uart1_fclk",
186
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
187
- .parent    = &func_48m_clk,
188
-};
189
-
190
-static struct clk uart1_iclk = {
191
- .name    = "uart1_iclk",
192
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
193
- .parent    = &core_l4_iclk,
194
-};
195
-
196
-static struct clk uart2_fclk = {
197
- .name    = "uart2_fclk",
198
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
199
- .parent    = &func_48m_clk,
200
-};
201
-
202
-static struct clk uart2_iclk = {
203
- .name    = "uart2_iclk",
204
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
205
- .parent    = &core_l4_iclk,
206
-};
207
-
208
-static struct clk uart3_fclk = {
209
- .name    = "uart3_fclk",
210
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
211
- .parent    = &func_48m_clk,
212
-};
213
-
214
-static struct clk uart3_iclk = {
215
- .name    = "uart3_iclk",
216
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
217
- .parent    = &core_l4_iclk,
218
-};
219
-
220
-static struct clk mpu_fclk = {
221
- .name    = "mpu_fclk",
222
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
223
- .parent    = &core_clk,
224
-};
225
-
226
-static struct clk mpu_iclk = {
227
- .name    = "mpu_iclk",
228
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
229
- .parent    = &core_clk,
230
-};
231
-
232
-static struct clk int_m_fclk = {
233
- .name    = "int_m_fclk",
234
- .alias    = "mpu_intc_fclk",
235
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
236
- .parent    = &core_clk,
237
-};
238
-
239
-static struct clk int_m_iclk = {
240
- .name    = "int_m_iclk",
241
- .alias    = "mpu_intc_iclk",
242
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
243
- .parent    = &core_clk,
244
-};
245
-
246
-static struct clk core_gpt2_clk = {
247
- .name    = "core_gpt2_clk",
248
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
249
- .parent    = &sys_clk,
250
-};
251
-
252
-static struct clk core_gpt3_clk = {
253
- .name    = "core_gpt3_clk",
254
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
255
- .parent    = &sys_clk,
256
-};
257
-
258
-static struct clk core_gpt4_clk = {
259
- .name    = "core_gpt4_clk",
260
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
261
- .parent    = &sys_clk,
262
-};
263
-
264
-static struct clk core_gpt5_clk = {
265
- .name    = "core_gpt5_clk",
266
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
267
- .parent    = &sys_clk,
268
-};
269
-
270
-static struct clk core_gpt6_clk = {
271
- .name    = "core_gpt6_clk",
272
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
273
- .parent    = &sys_clk,
274
-};
275
-
276
-static struct clk core_gpt7_clk = {
277
- .name    = "core_gpt7_clk",
278
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
279
- .parent    = &sys_clk,
280
-};
281
-
282
-static struct clk core_gpt8_clk = {
283
- .name    = "core_gpt8_clk",
284
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
285
- .parent    = &sys_clk,
286
-};
287
-
288
-static struct clk core_gpt9_clk = {
289
- .name    = "core_gpt9_clk",
290
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
291
- .parent    = &sys_clk,
292
-};
293
-
294
-static struct clk core_gpt10_clk = {
295
- .name    = "core_gpt10_clk",
296
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
297
- .parent    = &sys_clk,
298
-};
299
-
300
-static struct clk core_gpt11_clk = {
301
- .name    = "core_gpt11_clk",
302
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
303
- .parent    = &sys_clk,
304
-};
305
-
306
-static struct clk core_gpt12_clk = {
307
- .name    = "core_gpt12_clk",
308
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
309
- .parent    = &sys_clk,
310
-};
311
-
312
-static struct clk mcbsp1_clk = {
313
- .name    = "mcbsp1_cg",
314
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
315
- .divisor    = 2,
316
- .parent    = &func_96m_clk,
317
-};
318
-
319
-static struct clk mcbsp2_clk = {
320
- .name    = "mcbsp2_cg",
321
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
322
- .divisor    = 2,
323
- .parent    = &func_96m_clk,
324
-};
325
-
326
-static struct clk emul_clk = {
327
- .name    = "emul_ck",
328
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
329
- .parent    = &func_54m_clk,
330
-};
331
-
332
-static struct clk sdma_fclk = {
333
- .name    = "sdma_fclk",
334
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
335
- .parent    = &l3_clk,
336
-};
337
-
338
-static struct clk sdma_iclk = {
339
- .name    = "sdma_iclk",
340
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
341
- .parent    = &core_l3_iclk, /* core_l4_iclk for the configuration port */
342
-};
343
-
344
-static struct clk i2c1_fclk = {
345
- .name    = "i2c1.fclk",
346
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
347
- .parent    = &func_12m_clk,
348
- .divisor    = 1,
349
-};
350
-
351
-static struct clk i2c1_iclk = {
352
- .name    = "i2c1.iclk",
353
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
354
- .parent    = &core_l4_iclk,
355
-};
356
-
357
-static struct clk i2c2_fclk = {
358
- .name    = "i2c2.fclk",
359
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
360
- .parent    = &func_12m_clk,
361
- .divisor    = 1,
362
-};
363
-
364
-static struct clk i2c2_iclk = {
365
- .name    = "i2c2.iclk",
366
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
367
- .parent    = &core_l4_iclk,
368
-};
369
-
370
-static struct clk gpio_dbclk[5] = {
371
- {
372
- .name    = "gpio1_dbclk",
373
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
374
- .parent    = &wu_32k_clk,
375
- }, {
376
- .name    = "gpio2_dbclk",
377
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
378
- .parent    = &wu_32k_clk,
379
- }, {
380
- .name    = "gpio3_dbclk",
381
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
382
- .parent    = &wu_32k_clk,
383
- }, {
384
- .name    = "gpio4_dbclk",
385
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
386
- .parent    = &wu_32k_clk,
387
- }, {
388
- .name = "gpio5_dbclk",
389
- .flags = CLOCK_IN_OMAP243X,
390
- .parent = &wu_32k_clk,
391
- },
392
-};
393
-
394
-static struct clk gpio_iclk = {
395
- .name    = "gpio_iclk",
396
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
397
- .parent    = &wu_l4_iclk,
398
-};
399
-
400
-static struct clk mmc_fck = {
401
- .name    = "mmc_fclk",
402
- .flags    = CLOCK_IN_OMAP242X,
403
- .parent    = &func_96m_clk,
404
-};
405
-
406
-static struct clk mmc_ick = {
407
- .name    = "mmc_iclk",
408
- .flags    = CLOCK_IN_OMAP242X,
409
- .parent    = &core_l4_iclk,
410
-};
411
-
412
-static struct clk spi_fclk[3] = {
413
- {
414
- .name    = "spi1_fclk",
415
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
416
- .parent    = &func_48m_clk,
417
- }, {
418
- .name    = "spi2_fclk",
419
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
420
- .parent    = &func_48m_clk,
421
- }, {
422
- .name    = "spi3_fclk",
423
- .flags    = CLOCK_IN_OMAP243X,
424
- .parent    = &func_48m_clk,
425
- },
426
-};
427
-
428
-static struct clk dss_clk[2] = {
429
- {
430
- .name    = "dss_clk1",
431
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
432
- .parent    = &core_clk,
433
- }, {
434
- .name    = "dss_clk2",
435
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
436
- .parent    = &sys_clk,
437
- },
438
-};
439
-
440
-static struct clk dss_54m_clk = {
441
- .name    = "dss_54m_clk",
442
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
443
- .parent    = &func_54m_clk,
444
-};
445
-
446
-static struct clk dss_l3_iclk = {
447
- .name    = "dss_l3_iclk",
448
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
449
- .parent    = &core_l3_iclk,
450
-};
451
-
452
-static struct clk dss_l4_iclk = {
453
- .name    = "dss_l4_iclk",
454
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
455
- .parent    = &core_l4_iclk,
456
-};
457
-
458
-static struct clk spi_iclk[3] = {
459
- {
460
- .name    = "spi1_iclk",
461
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
462
- .parent    = &core_l4_iclk,
463
- }, {
464
- .name    = "spi2_iclk",
465
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
466
- .parent    = &core_l4_iclk,
467
- }, {
468
- .name    = "spi3_iclk",
469
- .flags    = CLOCK_IN_OMAP243X,
470
- .parent    = &core_l4_iclk,
471
- },
472
-};
473
-
474
-static struct clk omapctrl_clk = {
475
- .name    = "omapctrl_iclk",
476
- .flags    = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
477
- /* XXX Should be in WKUP domain */
478
- .parent    = &core_l4_iclk,
479
-};
480
-
481
static struct clk *onchip_clks[] = {
482
/* OMAP 1 */
483
484
@@ -XXX,XX +XXX,XX @@ static struct clk *onchip_clks[] = {
485
&i2c_fck,
486
&i2c_ick,
487
488
- /* OMAP 2 */
489
-
490
- &ref_clk,
491
- &apll_96m,
492
- &apll_54m,
493
- &sys_clk,
494
- &sleep_clk,
495
- &dpll_ck,
496
- &dpll_x2_ck,
497
- &wdt1_sys_clk,
498
- &func_96m_clk,
499
- &func_48m_clk,
500
- &func_12m_clk,
501
- &func_54m_clk,
502
- &sys_clkout,
503
- &sys_clkout2,
504
- &core_clk,
505
- &l3_clk,
506
- &core_l4_iclk,
507
- &wu_l4_iclk,
508
- &core_l3_iclk,
509
- &core_l4_usb_clk,
510
- &wu_gpt1_clk,
511
- &wu_32k_clk,
512
- &uart1_fclk,
513
- &uart1_iclk,
514
- &uart2_fclk,
515
- &uart2_iclk,
516
- &uart3_fclk,
517
- &uart3_iclk,
518
- &mpu_fclk,
519
- &mpu_iclk,
520
- &int_m_fclk,
521
- &int_m_iclk,
522
- &core_gpt2_clk,
523
- &core_gpt3_clk,
524
- &core_gpt4_clk,
525
- &core_gpt5_clk,
526
- &core_gpt6_clk,
527
- &core_gpt7_clk,
528
- &core_gpt8_clk,
529
- &core_gpt9_clk,
530
- &core_gpt10_clk,
531
- &core_gpt11_clk,
532
- &core_gpt12_clk,
533
- &mcbsp1_clk,
534
- &mcbsp2_clk,
535
- &emul_clk,
536
- &sdma_fclk,
537
- &sdma_iclk,
538
- &i2c1_fclk,
539
- &i2c1_iclk,
540
- &i2c2_fclk,
541
- &i2c2_iclk,
542
- &gpio_dbclk[0],
543
- &gpio_dbclk[1],
544
- &gpio_dbclk[2],
545
- &gpio_dbclk[3],
546
- &gpio_iclk,
547
- &mmc_fck,
548
- &mmc_ick,
549
- &spi_fclk[0],
550
- &spi_iclk[0],
551
- &spi_fclk[1],
552
- &spi_iclk[1],
553
- &spi_fclk[2],
554
- &spi_iclk[2],
555
- &dss_clk[0],
556
- &dss_clk[1],
557
- &dss_54m_clk,
558
- &dss_l3_iclk,
559
- &dss_l4_iclk,
560
- &omapctrl_clk,
561
-
562
NULL
563
};
564
565
@@ -XXX,XX +XXX,XX @@ void omap_clk_init(struct omap_mpu_state_s *mpu)
566
flag = CLOCK_IN_OMAP310;
567
else if (cpu_is_omap1510(mpu))
568
flag = CLOCK_IN_OMAP1510;
569
- else if (cpu_is_omap2410(mpu) || cpu_is_omap2420(mpu))
570
- flag = CLOCK_IN_OMAP242X;
571
- else if (cpu_is_omap2430(mpu))
572
- flag = CLOCK_IN_OMAP243X;
573
- else if (cpu_is_omap3430(mpu))
574
- flag = CLOCK_IN_OMAP243X;
575
else
576
return;
577
37
578
--
38
--
579
2.34.1
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
1
The omap_l4 device is OMAP2 only, so we can remove it.
1
Set the FloatInfZeroNaNRule explicitly for the HPPA target,
2
so we can remove the ifdef from pickNaNMulAdd().
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.
2
7
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20241202131347.498124-14-peter.maydell@linaro.org
6
Message-id: 20240903160751.4100218-51-peter.maydell@linaro.org
7
---
11
---
8
include/hw/arm/omap.h | 42 -----------
12
target/hppa/fpu_helper.c | 2 ++
9
hw/misc/omap_l4.c | 162 ------------------------------------------
13
fpu/softfloat-specialize.c.inc | 13 +------------
10
hw/misc/meson.build | 1 -
14
2 files changed, 3 insertions(+), 12 deletions(-)
11
3 files changed, 205 deletions(-)
12
delete mode 100644 hw/misc/omap_l4.c
13
15
14
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
16
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/omap.h
18
--- a/target/hppa/fpu_helper.c
17
+++ b/include/hw/arm/omap.h
19
+++ b/target/hppa/fpu_helper.c
18
@@ -XXX,XX +XXX,XX @@ DECLARE_INSTANCE_CHECKER(Omap1GpioState, OMAP1_GPIO,
20
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
19
/* TODO: clock framework (see above) */
21
* HPPA does note implement a CPU reset method at all...
20
void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk);
22
*/
21
23
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
22
-/* OMAP2 l4 Interconnect */
24
+ /* For inf * 0 + NaN, return the input NaN */
23
-struct omap_l4_s;
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
-struct omap_l4_region_s {
26
}
25
- hwaddr offset;
27
26
- size_t size;
28
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
27
- int access;
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
-};
30
index XXXXXXX..XXXXXXX 100644
29
-struct omap_l4_agent_info_s {
31
--- a/fpu/softfloat-specialize.c.inc
30
- int ta;
32
+++ b/fpu/softfloat-specialize.c.inc
31
- int region;
33
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
32
- int regions;
34
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
33
- int ta_region;
35
bool infzero, float_status *status)
34
-};
36
{
35
-struct omap_target_agent_s {
37
- FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
36
- MemoryRegion iomem;
37
- struct omap_l4_s *bus;
38
- int regions;
39
- const struct omap_l4_region_s *start;
40
- hwaddr base;
41
- uint32_t component;
42
- uint32_t control;
43
- uint32_t status;
44
-};
45
-struct omap_l4_s *omap_l4_init(MemoryRegion *address_space,
46
- hwaddr base, int ta_num);
47
-
38
-
48
-struct omap_target_agent_s;
39
/*
49
-struct omap_target_agent_s *omap_l4ta_get(
40
* We guarantee not to require the target to tell us how to
50
- struct omap_l4_s *bus,
41
* pick a NaN if we're always returning the default NaN.
51
- const struct omap_l4_region_s *regions,
42
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
52
- const struct omap_l4_agent_info_s *agents,
43
*/
53
- int cs);
44
assert(!status->default_nan_mode);
54
-hwaddr omap_l4_attach(struct omap_target_agent_s *ta,
45
55
- int region, MemoryRegion *mr);
46
- if (rule == float_infzeronan_none) {
56
-hwaddr omap_l4_region_base(struct omap_target_agent_s *ta,
47
- /*
57
- int region);
48
- * Temporarily fall back to ifdef ladder
58
-hwaddr omap_l4_region_size(struct omap_target_agent_s *ta,
49
- */
59
- int region);
50
-#if defined(TARGET_HPPA)
60
-
51
- rule = float_infzeronan_dnan_never;
61
/*
52
-#endif
62
* Common IRQ numbers for level 1 interrupt handler
63
* See /usr/include/asm-arm/arch-omap/irqs.h in Linux.
64
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s {
65
uint16_t dsp_idlect2;
66
uint16_t dsp_rstct2;
67
} clkm;
68
-
69
- /* OMAP2-only peripherals */
70
- struct omap_l4_s *l4;
71
};
72
73
/* omap1.c */
74
diff --git a/hw/misc/omap_l4.c b/hw/misc/omap_l4.c
75
deleted file mode 100644
76
index XXXXXXX..XXXXXXX
77
--- a/hw/misc/omap_l4.c
78
+++ /dev/null
79
@@ -XXX,XX +XXX,XX @@
80
-/*
81
- * TI OMAP L4 interconnect emulation.
82
- *
83
- * Copyright (C) 2007-2009 Nokia Corporation
84
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
85
- *
86
- * This program is free software; you can redistribute it and/or
87
- * modify it under the terms of the GNU General Public License as
88
- * published by the Free Software Foundation; either version 2 or
89
- * (at your option) any later version of the License.
90
- *
91
- * This program is distributed in the hope that it will be useful,
92
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
93
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
94
- * GNU General Public License for more details.
95
- *
96
- * You should have received a copy of the GNU General Public License along
97
- * with this program; if not, see <http://www.gnu.org/licenses/>.
98
- */
99
-#include "qemu/osdep.h"
100
-#include "hw/arm/omap.h"
101
-
102
-struct omap_l4_s {
103
- MemoryRegion *address_space;
104
- hwaddr base;
105
- int ta_num;
106
- struct omap_target_agent_s ta[];
107
-};
108
-
109
-struct omap_l4_s *omap_l4_init(MemoryRegion *address_space,
110
- hwaddr base, int ta_num)
111
-{
112
- struct omap_l4_s *bus = g_malloc0(
113
- sizeof(*bus) + ta_num * sizeof(*bus->ta));
114
-
115
- bus->address_space = address_space;
116
- bus->ta_num = ta_num;
117
- bus->base = base;
118
-
119
- return bus;
120
-}
121
-
122
-hwaddr omap_l4_region_base(struct omap_target_agent_s *ta,
123
- int region)
124
-{
125
- return ta->bus->base + ta->start[region].offset;
126
-}
127
-
128
-hwaddr omap_l4_region_size(struct omap_target_agent_s *ta,
129
- int region)
130
-{
131
- return ta->start[region].size;
132
-}
133
-
134
-static uint64_t omap_l4ta_read(void *opaque, hwaddr addr, unsigned size)
135
-{
136
- struct omap_target_agent_s *s = opaque;
137
-
138
- if (size != 2) {
139
- return omap_badwidth_read16(opaque, addr);
140
- }
53
- }
141
-
54
-
142
- switch (addr) {
55
if (infzero) {
143
- case 0x00:    /* COMPONENT */
56
/*
144
- return s->component;
57
* Inf * 0 + NaN -- some implementations return the default NaN here,
145
-
58
* and some return the input NaN.
146
- case 0x20:    /* AGENT_CONTROL */
59
*/
147
- return s->control;
60
- switch (rule) {
148
-
61
+ switch (status->float_infzeronan_rule) {
149
- case 0x28:    /* AGENT_STATUS */
62
case float_infzeronan_dnan_never:
150
- return s->status;
63
return 2;
151
- }
64
case float_infzeronan_dnan_always:
152
-
153
- OMAP_BAD_REG(addr);
154
- return 0;
155
-}
156
-
157
-static void omap_l4ta_write(void *opaque, hwaddr addr,
158
- uint64_t value, unsigned size)
159
-{
160
- struct omap_target_agent_s *s = opaque;
161
-
162
- if (size != 4) {
163
- omap_badwidth_write32(opaque, addr, value);
164
- return;
165
- }
166
-
167
- switch (addr) {
168
- case 0x00:    /* COMPONENT */
169
- case 0x28:    /* AGENT_STATUS */
170
- OMAP_RO_REG(addr);
171
- break;
172
-
173
- case 0x20:    /* AGENT_CONTROL */
174
- s->control = value & 0x01000700;
175
- if (value & 1)                    /* OCP_RESET */
176
- s->status &= ~1;                /* REQ_TIMEOUT */
177
- break;
178
-
179
- default:
180
- OMAP_BAD_REG(addr);
181
- }
182
-}
183
-
184
-static const MemoryRegionOps omap_l4ta_ops = {
185
- .read = omap_l4ta_read,
186
- .write = omap_l4ta_write,
187
- .endianness = DEVICE_NATIVE_ENDIAN,
188
-};
189
-
190
-struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus,
191
- const struct omap_l4_region_s *regions,
192
- const struct omap_l4_agent_info_s *agents,
193
- int cs)
194
-{
195
- int i;
196
- struct omap_target_agent_s *ta = NULL;
197
- const struct omap_l4_agent_info_s *info = NULL;
198
-
199
- for (i = 0; i < bus->ta_num; i ++)
200
- if (agents[i].ta == cs) {
201
- ta = &bus->ta[i];
202
- info = &agents[i];
203
- break;
204
- }
205
- if (!ta) {
206
- fprintf(stderr, "%s: bad target agent (%i)\n", __func__, cs);
207
- exit(-1);
208
- }
209
-
210
- ta->bus = bus;
211
- ta->start = &regions[info->region];
212
- ta->regions = info->regions;
213
-
214
- ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
215
- ta->status = 0x00000000;
216
- ta->control = 0x00000200;    /* XXX 01000200 for L4TAO */
217
-
218
- memory_region_init_io(&ta->iomem, NULL, &omap_l4ta_ops, ta, "omap.l4ta",
219
- omap_l4_region_size(ta, info->ta_region));
220
- omap_l4_attach(ta, info->ta_region, &ta->iomem);
221
-
222
- return ta;
223
-}
224
-
225
-hwaddr omap_l4_attach(struct omap_target_agent_s *ta,
226
- int region, MemoryRegion *mr)
227
-{
228
- hwaddr base;
229
-
230
- if (region < 0 || region >= ta->regions) {
231
- fprintf(stderr, "%s: bad io region (%i)\n", __func__, region);
232
- exit(-1);
233
- }
234
-
235
- base = ta->bus->base + ta->start[region].offset;
236
- if (mr) {
237
- memory_region_add_subregion(ta->bus->address_space, base, mr);
238
- }
239
-
240
- return base;
241
-}
242
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
243
index XXXXXXX..XXXXXXX 100644
244
--- a/hw/misc/meson.build
245
+++ b/hw/misc/meson.build
246
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
247
))
248
system_ss.add(when: 'CONFIG_OMAP', if_true: files(
249
'omap_clk.c',
250
- 'omap_l4.c',
251
))
252
system_ss.add(when: 'CONFIG_RASPI', if_true: files(
253
'bcm2835_mbox.c',
254
--
65
--
255
2.34.1
66
2.34.1
256
257
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
Remove the pxa2xx-specific interrupt controller device.
1
IEEE 758 does not define a fixed rule for which NaN to pick as the
2
As this is the last user of the pxa.h header file and the
2
result if both operands of a 3-operand fused multiply-add operation
3
CONFIG_PXA2XX define we can remove those too.
3
are NaNs. As a result different architectures have ended up with
4
4
different rules for propagating NaNs.
5
This completes the removal of the pxa2xx specific code. We leave:
5
6
* pxa2xx_timer -- still used by the Collie board (strongarm)
6
QEMU currently hardcodes the NaN propagation logic into the binary
7
* the definitions of the CPUs themselves in target/arm
7
because pickNaNMulAdd() has an ifdef ladder for different targets.
8
(still usable by linux-user mode)
8
We want to make the propagation rule instead be selectable at
9
runtime, because:
10
* this will let us have multiple targets in one QEMU binary
11
* the Arm FEAT_AFP architectural feature includes letting
12
the guest select a NaN propagation rule at runtime
13
14
In this commit we add an enum for the propagation rule, the field in
15
float_status, and the corresponding getters and setters. We change
16
pickNaNMulAdd to honour this, but because all targets still leave
17
this field at its default 0 value, the fallback logic will pick the
18
rule type with the old ifdef ladder.
19
20
It's valid not to set a propagation rule if default_nan_mode is
21
enabled, because in that case there's no need to pick a NaN; all the
22
callers of pickNaNMulAdd() catch this case and skip calling it.
9
23
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240903160751.4100218-23-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
MAINTAINERS | 10 --
28
include/fpu/softfloat-helpers.h | 11 +++
14
include/hw/arm/pxa.h | 74 ---------
29
include/fpu/softfloat-types.h | 55 +++++++++++
15
hw/arm/pxa2xx_pic.c | 359 -------------------------------------------
30
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
16
hw/arm/Kconfig | 11 --
31
3 files changed, 107 insertions(+), 126 deletions(-)
17
hw/arm/meson.build | 1 -
32
18
5 files changed, 455 deletions(-)
33
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
19
delete mode 100644 include/hw/arm/pxa.h
20
delete mode 100644 hw/arm/pxa2xx_pic.c
21
22
diff --git a/MAINTAINERS b/MAINTAINERS
23
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
24
--- a/MAINTAINERS
35
--- a/include/fpu/softfloat-helpers.h
25
+++ b/MAINTAINERS
36
+++ b/include/fpu/softfloat-helpers.h
26
@@ -XXX,XX +XXX,XX @@ F: hw/intc/realview_gic.c
37
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
27
F: include/hw/intc/realview_gic.h
38
status->float_2nan_prop_rule = rule;
28
F: docs/system/arm/realview.rst
39
}
29
40
30
-PXA2XX
41
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
31
-M: Peter Maydell <peter.maydell@linaro.org>
42
+ float_status *status)
32
-L: qemu-arm@nongnu.org
43
+{
33
-S: Odd Fixes
44
+ status->float_3nan_prop_rule = rule;
34
-F: hw/*/pxa2xx*
45
+}
35
-F: hw/gpio/max7310.c
46
+
36
-F: hw/adc/max111x.c
47
static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
37
-F: include/hw/adc/max111x.h
48
float_status *status)
38
-F: include/hw/arm/pxa.h
49
{
50
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
51
return status->float_2nan_prop_rule;
52
}
53
54
+static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
55
+{
56
+ return status->float_3nan_prop_rule;
57
+}
58
+
59
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
60
{
61
return status->float_infzeronan_rule;
62
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
63
index XXXXXXX..XXXXXXX 100644
64
--- a/include/fpu/softfloat-types.h
65
+++ b/include/fpu/softfloat-types.h
66
@@ -XXX,XX +XXX,XX @@ this code that are retained.
67
#ifndef SOFTFLOAT_TYPES_H
68
#define SOFTFLOAT_TYPES_H
69
70
+#include "hw/registerfields.h"
71
+
72
/*
73
* Software IEC/IEEE floating-point types.
74
*/
75
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
76
float_2nan_prop_x87,
77
} Float2NaNPropRule;
78
79
+/*
80
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
81
+ * architectures have different rules for which input NaN is
82
+ * propagated to the output when there is more than one NaN on the
83
+ * input.
84
+ *
85
+ * If default_nan_mode is enabled then it is valid not to set a NaN
86
+ * propagation rule, because the softfloat code guarantees not to try
87
+ * to pick a NaN to propagate in default NaN mode. When not in
88
+ * default-NaN mode, it is an error for the target not to set the rule
89
+ * in float_status if it uses a muladd, and we will assert if we need
90
+ * to handle an input NaN and no rule was selected.
91
+ *
92
+ * The naming scheme for Float3NaNPropRule values is:
93
+ * float_3nan_prop_s_abc:
94
+ * = "Prefer SNaN over QNaN, then operand A over B over C"
95
+ * float_3nan_prop_abc:
96
+ * = "Prefer A over B over C regardless of SNaN vs QNAN"
97
+ *
98
+ * For QEMU, the multiply-add operation is A * B + C.
99
+ */
100
+
101
+/*
102
+ * We set the Float3NaNPropRule enum values up so we can select the
103
+ * right value in pickNaNMulAdd in a data driven way.
104
+ */
105
+FIELD(3NAN, 1ST, 0, 2) /* which operand is most preferred ? */
106
+FIELD(3NAN, 2ND, 2, 2) /* which operand is next most preferred ? */
107
+FIELD(3NAN, 3RD, 4, 2) /* which operand is least preferred ? */
108
+FIELD(3NAN, SNAN, 6, 1) /* do we prefer SNaN over QNaN ? */
109
+
110
+#define PROPRULE(X, Y, Z) \
111
+ ((X << R_3NAN_1ST_SHIFT) | (Y << R_3NAN_2ND_SHIFT) | (Z << R_3NAN_3RD_SHIFT))
112
+
113
+typedef enum __attribute__((__packed__)) {
114
+ float_3nan_prop_none = 0, /* No propagation rule specified */
115
+ float_3nan_prop_abc = PROPRULE(0, 1, 2),
116
+ float_3nan_prop_acb = PROPRULE(0, 2, 1),
117
+ float_3nan_prop_bac = PROPRULE(1, 0, 2),
118
+ float_3nan_prop_bca = PROPRULE(1, 2, 0),
119
+ float_3nan_prop_cab = PROPRULE(2, 0, 1),
120
+ float_3nan_prop_cba = PROPRULE(2, 1, 0),
121
+ float_3nan_prop_s_abc = float_3nan_prop_abc | R_3NAN_SNAN_MASK,
122
+ float_3nan_prop_s_acb = float_3nan_prop_acb | R_3NAN_SNAN_MASK,
123
+ float_3nan_prop_s_bac = float_3nan_prop_bac | R_3NAN_SNAN_MASK,
124
+ float_3nan_prop_s_bca = float_3nan_prop_bca | R_3NAN_SNAN_MASK,
125
+ float_3nan_prop_s_cab = float_3nan_prop_cab | R_3NAN_SNAN_MASK,
126
+ float_3nan_prop_s_cba = float_3nan_prop_cba | R_3NAN_SNAN_MASK,
127
+} Float3NaNPropRule;
128
+
129
+#undef PROPRULE
130
+
131
/*
132
* Rule for result of fused multiply-add 0 * Inf + NaN.
133
* This must be a NaN, but implementations differ on whether this
134
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
135
FloatRoundMode float_rounding_mode;
136
FloatX80RoundPrec floatx80_rounding_precision;
137
Float2NaNPropRule float_2nan_prop_rule;
138
+ Float3NaNPropRule float_3nan_prop_rule;
139
FloatInfZeroNaNRule float_infzeronan_rule;
140
bool tininess_before_rounding;
141
/* should denormalised results go to zero and set the inexact flag? */
142
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
143
index XXXXXXX..XXXXXXX 100644
144
--- a/fpu/softfloat-specialize.c.inc
145
+++ b/fpu/softfloat-specialize.c.inc
146
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
147
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
148
bool infzero, bool have_snan, float_status *status)
149
{
150
+ FloatClass cls[3] = { a_cls, b_cls, c_cls };
151
+ Float3NaNPropRule rule = status->float_3nan_prop_rule;
152
+ int which;
153
+
154
/*
155
* We guarantee not to require the target to tell us how to
156
* pick a NaN if we're always returning the default NaN.
157
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
158
}
159
}
160
161
+ if (rule == float_3nan_prop_none) {
162
#if defined(TARGET_ARM)
39
-
163
-
40
SABRELITE / i.MX6
164
- /* This looks different from the ARM ARM pseudocode, because the ARM ARM
41
M: Peter Maydell <peter.maydell@linaro.org>
165
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
42
R: Jean-Christophe Dubois <jcd@tribudubois.net>
166
- */
43
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
167
- if (is_snan(c_cls)) {
44
deleted file mode 100644
168
- return 2;
45
index XXXXXXX..XXXXXXX
169
- } else if (is_snan(a_cls)) {
46
--- a/include/hw/arm/pxa.h
170
- return 0;
47
+++ /dev/null
171
- } else if (is_snan(b_cls)) {
48
@@ -XXX,XX +XXX,XX @@
172
- return 1;
49
-/*
173
- } else if (is_qnan(c_cls)) {
50
- * Intel XScale PXA255/270 processor support.
174
- return 2;
51
- *
175
- } else if (is_qnan(a_cls)) {
52
- * Copyright (c) 2006 Openedhand Ltd.
176
- return 0;
53
- * Written by Andrzej Zaborowski <balrog@zabor.org>
177
- } else {
54
- *
178
- return 1;
55
- * This code is licensed under the GNU GPL v2.
179
- }
56
- */
180
+ /*
57
-
181
+ * This looks different from the ARM ARM pseudocode, because the ARM ARM
58
-#ifndef PXA_H
182
+ * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
59
-#define PXA_H
183
+ */
60
-
184
+ rule = float_3nan_prop_s_cab;
61
-#include "exec/memory.h"
185
#elif defined(TARGET_MIPS)
62
-#include "target/arm/cpu-qom.h"
186
- if (snan_bit_is_one(status)) {
63
-#include "hw/pcmcia.h"
187
- /* Prefer sNaN over qNaN, in the a, b, c order. */
64
-#include "qom/object.h"
188
- if (is_snan(a_cls)) {
65
-
189
- return 0;
66
-/* Interrupt numbers */
190
- } else if (is_snan(b_cls)) {
67
-# define PXA2XX_PIC_SSP3    0
191
- return 1;
68
-# define PXA2XX_PIC_USBH2    2
192
- } else if (is_snan(c_cls)) {
69
-# define PXA2XX_PIC_USBH1    3
193
- return 2;
70
-# define PXA2XX_PIC_KEYPAD    4
194
- } else if (is_qnan(a_cls)) {
71
-# define PXA2XX_PIC_PWRI2C    6
195
- return 0;
72
-# define PXA25X_PIC_HWUART    7
196
- } else if (is_qnan(b_cls)) {
73
-# define PXA27X_PIC_OST_4_11    7
197
- return 1;
74
-# define PXA2XX_PIC_GPIO_0    8
198
+ if (snan_bit_is_one(status)) {
75
-# define PXA2XX_PIC_GPIO_1    9
199
+ rule = float_3nan_prop_s_abc;
76
-# define PXA2XX_PIC_GPIO_X    10
200
} else {
77
-# define PXA2XX_PIC_I2S     13
201
- return 2;
78
-# define PXA26X_PIC_ASSP    15
202
+ rule = float_3nan_prop_s_cab;
79
-# define PXA25X_PIC_NSSP    16
203
}
80
-# define PXA27X_PIC_SSP2    16
204
- } else {
81
-# define PXA2XX_PIC_LCD        17
205
- /* Prefer sNaN over qNaN, in the c, a, b order. */
82
-# define PXA2XX_PIC_I2C        18
206
- if (is_snan(c_cls)) {
83
-# define PXA2XX_PIC_ICP        19
207
- return 2;
84
-# define PXA2XX_PIC_STUART    20
208
- } else if (is_snan(a_cls)) {
85
-# define PXA2XX_PIC_BTUART    21
209
- return 0;
86
-# define PXA2XX_PIC_FFUART    22
210
- } else if (is_snan(b_cls)) {
87
-# define PXA2XX_PIC_MMC        23
211
- return 1;
88
-# define PXA2XX_PIC_SSP        24
212
- } else if (is_qnan(c_cls)) {
89
-# define PXA2XX_PIC_DMA        25
213
- return 2;
90
-# define PXA2XX_PIC_OST_0    26
214
- } else if (is_qnan(a_cls)) {
91
-# define PXA2XX_PIC_RTC1HZ    30
215
- return 0;
92
-# define PXA2XX_PIC_RTCALARM    31
216
- } else {
93
-
217
- return 1;
94
-/* DMA requests */
95
-# define PXA2XX_RX_RQ_I2S    2
96
-# define PXA2XX_TX_RQ_I2S    3
97
-# define PXA2XX_RX_RQ_BTUART    4
98
-# define PXA2XX_TX_RQ_BTUART    5
99
-# define PXA2XX_RX_RQ_FFUART    6
100
-# define PXA2XX_TX_RQ_FFUART    7
101
-# define PXA2XX_RX_RQ_SSP1    13
102
-# define PXA2XX_TX_RQ_SSP1    14
103
-# define PXA2XX_RX_RQ_SSP2    15
104
-# define PXA2XX_TX_RQ_SSP2    16
105
-# define PXA2XX_RX_RQ_ICP    17
106
-# define PXA2XX_TX_RQ_ICP    18
107
-# define PXA2XX_RX_RQ_STUART    19
108
-# define PXA2XX_TX_RQ_STUART    20
109
-# define PXA2XX_RX_RQ_MMCI    21
110
-# define PXA2XX_TX_RQ_MMCI    22
111
-# define PXA2XX_USB_RQ(x)    ((x) + 24)
112
-# define PXA2XX_RX_RQ_SSP3    66
113
-# define PXA2XX_TX_RQ_SSP3    67
114
-
115
-# define PXA2XX_SDRAM_BASE    0xa0000000
116
-# define PXA2XX_INTERNAL_BASE    0x5c000000
117
-# define PXA2XX_INTERNAL_SIZE    0x40000
118
-
119
-/* pxa2xx_pic.c */
120
-DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu);
121
-
122
-#endif /* PXA_H */
123
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
124
deleted file mode 100644
125
index XXXXXXX..XXXXXXX
126
--- a/hw/arm/pxa2xx_pic.c
127
+++ /dev/null
128
@@ -XXX,XX +XXX,XX @@
129
-/*
130
- * Intel XScale PXA Programmable Interrupt Controller.
131
- *
132
- * Copyright (c) 2006 Openedhand Ltd.
133
- * Copyright (c) 2006 Thorsten Zitterell
134
- * Written by Andrzej Zaborowski <balrog@zabor.org>
135
- *
136
- * This code is licensed under the GPL.
137
- */
138
-
139
-#include "qemu/osdep.h"
140
-#include "qapi/error.h"
141
-#include "qemu/module.h"
142
-#include "qemu/log.h"
143
-#include "cpu.h"
144
-#include "hw/arm/pxa.h"
145
-#include "hw/sysbus.h"
146
-#include "hw/qdev-properties.h"
147
-#include "migration/vmstate.h"
148
-#include "qom/object.h"
149
-#include "target/arm/cpregs.h"
150
-
151
-#define ICIP    0x00    /* Interrupt Controller IRQ Pending register */
152
-#define ICMR    0x04    /* Interrupt Controller Mask register */
153
-#define ICLR    0x08    /* Interrupt Controller Level register */
154
-#define ICFP    0x0c    /* Interrupt Controller FIQ Pending register */
155
-#define ICPR    0x10    /* Interrupt Controller Pending register */
156
-#define ICCR    0x14    /* Interrupt Controller Control register */
157
-#define ICHP    0x18    /* Interrupt Controller Highest Priority register */
158
-#define IPR0    0x1c    /* Interrupt Controller Priority register 0 */
159
-#define IPR31    0x98    /* Interrupt Controller Priority register 31 */
160
-#define ICIP2    0x9c    /* Interrupt Controller IRQ Pending register 2 */
161
-#define ICMR2    0xa0    /* Interrupt Controller Mask register 2 */
162
-#define ICLR2    0xa4    /* Interrupt Controller Level register 2 */
163
-#define ICFP2    0xa8    /* Interrupt Controller FIQ Pending register 2 */
164
-#define ICPR2    0xac    /* Interrupt Controller Pending register 2 */
165
-#define IPR32    0xb0    /* Interrupt Controller Priority register 32 */
166
-#define IPR39    0xcc    /* Interrupt Controller Priority register 39 */
167
-
168
-#define PXA2XX_PIC_SRCS    40
169
-
170
-#define TYPE_PXA2XX_PIC "pxa2xx_pic"
171
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxPICState, PXA2XX_PIC)
172
-
173
-struct PXA2xxPICState {
174
- /*< private >*/
175
- SysBusDevice parent_obj;
176
- /*< public >*/
177
-
178
- MemoryRegion iomem;
179
- ARMCPU *cpu;
180
- uint32_t int_enabled[2];
181
- uint32_t int_pending[2];
182
- uint32_t is_fiq[2];
183
- uint32_t int_idle;
184
- uint32_t priority[PXA2XX_PIC_SRCS];
185
-};
186
-
187
-static void pxa2xx_pic_update(void *opaque)
188
-{
189
- uint32_t mask[2];
190
- PXA2xxPICState *s = (PXA2xxPICState *) opaque;
191
- CPUState *cpu = CPU(s->cpu);
192
-
193
- if (cpu->halted) {
194
- mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle);
195
- mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle);
196
- if (mask[0] || mask[1]) {
197
- cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
198
- }
218
- }
199
- }
219
- }
200
-
220
#elif defined(TARGET_LOONGARCH64)
201
- mask[0] = s->int_pending[0] & s->int_enabled[0];
221
- /* Prefer sNaN over qNaN, in the c, a, b order. */
202
- mask[1] = s->int_pending[1] & s->int_enabled[1];
222
- if (is_snan(c_cls)) {
203
-
223
- return 2;
204
- if ((mask[0] & s->is_fiq[0]) || (mask[1] & s->is_fiq[1])) {
224
- } else if (is_snan(a_cls)) {
205
- cpu_interrupt(cpu, CPU_INTERRUPT_FIQ);
225
- return 0;
206
- } else {
226
- } else if (is_snan(b_cls)) {
207
- cpu_reset_interrupt(cpu, CPU_INTERRUPT_FIQ);
227
- return 1;
208
- }
228
- } else if (is_qnan(c_cls)) {
209
-
229
- return 2;
210
- if ((mask[0] & ~s->is_fiq[0]) || (mask[1] & ~s->is_fiq[1])) {
230
- } else if (is_qnan(a_cls)) {
211
- cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
231
- return 0;
212
- } else {
232
- } else {
213
- cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
233
- return 1;
214
- }
234
- }
215
-}
235
+ rule = float_3nan_prop_s_cab;
216
-
236
#elif defined(TARGET_PPC)
217
-/* Note: Here level means state of the signal on a pin, not
237
- /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
218
- * IRQ/FIQ distinction as in PXA Developer Manual. */
238
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
219
-static void pxa2xx_pic_set_irq(void *opaque, int irq, int level)
239
- */
220
-{
240
- if (is_nan(a_cls)) {
221
- PXA2xxPICState *s = (PXA2xxPICState *) opaque;
241
- return 0;
222
- int int_set = (irq >= 32);
242
- } else if (is_nan(c_cls)) {
223
- irq &= 31;
243
- return 2;
224
-
244
- } else {
225
- if (level)
245
- return 1;
226
- s->int_pending[int_set] |= 1 << irq;
246
- }
227
- else
247
+ /*
228
- s->int_pending[int_set] &= ~(1 << irq);
248
+ * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
229
-
249
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
230
- pxa2xx_pic_update(opaque);
250
+ */
231
-}
251
+ rule = float_3nan_prop_acb;
232
-
252
#elif defined(TARGET_S390X)
233
-static inline uint32_t pxa2xx_pic_highest(PXA2xxPICState *s) {
253
- if (is_snan(a_cls)) {
234
- int i, int_set, irq;
254
- return 0;
235
- uint32_t bit, mask[2];
255
- } else if (is_snan(b_cls)) {
236
- uint32_t ichp = 0x003f003f;    /* Both IDs invalid */
256
- return 1;
237
-
257
- } else if (is_snan(c_cls)) {
238
- mask[0] = s->int_pending[0] & s->int_enabled[0];
258
- return 2;
239
- mask[1] = s->int_pending[1] & s->int_enabled[1];
259
- } else if (is_qnan(a_cls)) {
240
-
260
- return 0;
241
- for (i = PXA2XX_PIC_SRCS - 1; i >= 0; i --) {
261
- } else if (is_qnan(b_cls)) {
242
- irq = s->priority[i] & 0x3f;
262
- return 1;
243
- if ((s->priority[i] & (1U << 31)) && irq < PXA2XX_PIC_SRCS) {
263
- } else {
244
- /* Source peripheral ID is valid. */
264
- return 2;
245
- bit = 1 << (irq & 31);
265
- }
246
- int_set = (irq >= 32);
266
+ rule = float_3nan_prop_s_abc;
247
-
267
#elif defined(TARGET_SPARC)
248
- if (mask[int_set] & bit & s->is_fiq[int_set]) {
268
- /* Prefer SNaN over QNaN, order C, B, A. */
249
- /* FIQ asserted */
269
- if (is_snan(c_cls)) {
250
- ichp &= 0xffff0000;
270
- return 2;
251
- ichp |= (1 << 15) | irq;
271
- } else if (is_snan(b_cls)) {
252
- }
272
- return 1;
253
-
273
- } else if (is_snan(a_cls)) {
254
- if (mask[int_set] & bit & ~s->is_fiq[int_set]) {
274
- return 0;
255
- /* IRQ asserted */
275
- } else if (is_qnan(c_cls)) {
256
- ichp &= 0x0000ffff;
276
- return 2;
257
- ichp |= (1U << 31) | (irq << 16);
277
- } else if (is_qnan(b_cls)) {
258
- }
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;
259
- }
306
- }
260
- }
307
- }
261
-
308
#else
262
- return ichp;
309
- /* A default implementation: prefer a to b to c.
263
-}
310
- * This is unlikely to actually match any real implementation.
264
-
311
- */
265
-static uint64_t pxa2xx_pic_mem_read(void *opaque, hwaddr offset,
312
- if (is_nan(a_cls)) {
266
- unsigned size)
313
- return 0;
267
-{
314
- } else if (is_nan(b_cls)) {
268
- PXA2xxPICState *s = (PXA2xxPICState *) opaque;
315
- return 1;
269
-
316
- } else {
270
- switch (offset) {
317
- return 2;
271
- case ICIP:    /* IRQ Pending register */
318
- }
272
- return s->int_pending[0] & ~s->is_fiq[0] & s->int_enabled[0];
319
+ rule = float_3nan_prop_abc;
273
- case ICIP2:    /* IRQ Pending register 2 */
320
#endif
274
- return s->int_pending[1] & ~s->is_fiq[1] & s->int_enabled[1];
321
+ }
275
- case ICMR:    /* Mask register */
322
+
276
- return s->int_enabled[0];
323
+ assert(rule != float_3nan_prop_none);
277
- case ICMR2:    /* Mask register 2 */
324
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
278
- return s->int_enabled[1];
325
+ /* We have at least one SNaN input and should prefer it */
279
- case ICLR:    /* Level register */
326
+ do {
280
- return s->is_fiq[0];
327
+ which = rule & R_3NAN_1ST_MASK;
281
- case ICLR2:    /* Level register 2 */
328
+ rule >>= R_3NAN_1ST_LENGTH;
282
- return s->is_fiq[1];
329
+ } while (!is_snan(cls[which]));
283
- case ICCR:    /* Idle mask */
330
+ } else {
284
- return (s->int_idle == 0);
331
+ do {
285
- case ICFP:    /* FIQ Pending register */
332
+ which = rule & R_3NAN_1ST_MASK;
286
- return s->int_pending[0] & s->is_fiq[0] & s->int_enabled[0];
333
+ rule >>= R_3NAN_1ST_LENGTH;
287
- case ICFP2:    /* FIQ Pending register 2 */
334
+ } while (!is_nan(cls[which]));
288
- return s->int_pending[1] & s->is_fiq[1] & s->int_enabled[1];
335
+ }
289
- case ICPR:    /* Pending register */
336
+ return which;
290
- return s->int_pending[0];
337
}
291
- case ICPR2:    /* Pending register 2 */
338
292
- return s->int_pending[1];
339
/*----------------------------------------------------------------------------
293
- case IPR0 ... IPR31:
294
- return s->priority[0 + ((offset - IPR0 ) >> 2)];
295
- case IPR32 ... IPR39:
296
- return s->priority[32 + ((offset - IPR32) >> 2)];
297
- case ICHP:    /* Highest Priority register */
298
- return pxa2xx_pic_highest(s);
299
- default:
300
- qemu_log_mask(LOG_GUEST_ERROR,
301
- "pxa2xx_pic_mem_read: bad register offset 0x%" HWADDR_PRIx
302
- "\n", offset);
303
- return 0;
304
- }
305
-}
306
-
307
-static void pxa2xx_pic_mem_write(void *opaque, hwaddr offset,
308
- uint64_t value, unsigned size)
309
-{
310
- PXA2xxPICState *s = (PXA2xxPICState *) opaque;
311
-
312
- switch (offset) {
313
- case ICMR:    /* Mask register */
314
- s->int_enabled[0] = value;
315
- break;
316
- case ICMR2:    /* Mask register 2 */
317
- s->int_enabled[1] = value;
318
- break;
319
- case ICLR:    /* Level register */
320
- s->is_fiq[0] = value;
321
- break;
322
- case ICLR2:    /* Level register 2 */
323
- s->is_fiq[1] = value;
324
- break;
325
- case ICCR:    /* Idle mask */
326
- s->int_idle = (value & 1) ? 0 : ~0;
327
- break;
328
- case IPR0 ... IPR31:
329
- s->priority[0 + ((offset - IPR0 ) >> 2)] = value & 0x8000003f;
330
- break;
331
- case IPR32 ... IPR39:
332
- s->priority[32 + ((offset - IPR32) >> 2)] = value & 0x8000003f;
333
- break;
334
- default:
335
- qemu_log_mask(LOG_GUEST_ERROR,
336
- "pxa2xx_pic_mem_write: bad register offset 0x%"
337
- HWADDR_PRIx "\n", offset);
338
- return;
339
- }
340
- pxa2xx_pic_update(opaque);
341
-}
342
-
343
-/* Interrupt Controller Coprocessor Space Register Mapping */
344
-static const int pxa2xx_cp_reg_map[0x10] = {
345
- [0x0 ... 0xf] = -1,
346
- [0x0] = ICIP,
347
- [0x1] = ICMR,
348
- [0x2] = ICLR,
349
- [0x3] = ICFP,
350
- [0x4] = ICPR,
351
- [0x5] = ICHP,
352
- [0x6] = ICIP2,
353
- [0x7] = ICMR2,
354
- [0x8] = ICLR2,
355
- [0x9] = ICFP2,
356
- [0xa] = ICPR2,
357
-};
358
-
359
-static uint64_t pxa2xx_pic_cp_read(CPUARMState *env, const ARMCPRegInfo *ri)
360
-{
361
- int offset = pxa2xx_cp_reg_map[ri->crn];
362
- return pxa2xx_pic_mem_read(ri->opaque, offset, 4);
363
-}
364
-
365
-static void pxa2xx_pic_cp_write(CPUARMState *env, const ARMCPRegInfo *ri,
366
- uint64_t value)
367
-{
368
- int offset = pxa2xx_cp_reg_map[ri->crn];
369
- pxa2xx_pic_mem_write(ri->opaque, offset, value, 4);
370
-}
371
-
372
-#define REGINFO_FOR_PIC_CP(NAME, CRN) \
373
- { .name = NAME, .cp = 6, .crn = CRN, .crm = 0, .opc1 = 0, .opc2 = 0, \
374
- .access = PL1_RW, .type = ARM_CP_IO, \
375
- .readfn = pxa2xx_pic_cp_read, .writefn = pxa2xx_pic_cp_write }
376
-
377
-static const ARMCPRegInfo pxa_pic_cp_reginfo[] = {
378
- REGINFO_FOR_PIC_CP("ICIP", 0),
379
- REGINFO_FOR_PIC_CP("ICMR", 1),
380
- REGINFO_FOR_PIC_CP("ICLR", 2),
381
- REGINFO_FOR_PIC_CP("ICFP", 3),
382
- REGINFO_FOR_PIC_CP("ICPR", 4),
383
- REGINFO_FOR_PIC_CP("ICHP", 5),
384
- REGINFO_FOR_PIC_CP("ICIP2", 6),
385
- REGINFO_FOR_PIC_CP("ICMR2", 7),
386
- REGINFO_FOR_PIC_CP("ICLR2", 8),
387
- REGINFO_FOR_PIC_CP("ICFP2", 9),
388
- REGINFO_FOR_PIC_CP("ICPR2", 0xa),
389
-};
390
-
391
-static const MemoryRegionOps pxa2xx_pic_ops = {
392
- .read = pxa2xx_pic_mem_read,
393
- .write = pxa2xx_pic_mem_write,
394
- .endianness = DEVICE_NATIVE_ENDIAN,
395
-};
396
-
397
-static int pxa2xx_pic_post_load(void *opaque, int version_id)
398
-{
399
- pxa2xx_pic_update(opaque);
400
- return 0;
401
-}
402
-
403
-static void pxa2xx_pic_reset_hold(Object *obj, ResetType type)
404
-{
405
- PXA2xxPICState *s = PXA2XX_PIC(obj);
406
-
407
- s->int_pending[0] = 0;
408
- s->int_pending[1] = 0;
409
- s->int_enabled[0] = 0;
410
- s->int_enabled[1] = 0;
411
- s->is_fiq[0] = 0;
412
- s->is_fiq[1] = 0;
413
-}
414
-
415
-DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
416
-{
417
- DeviceState *dev = qdev_new(TYPE_PXA2XX_PIC);
418
-
419
- object_property_set_link(OBJECT(dev), "arm-cpu",
420
- OBJECT(cpu), &error_abort);
421
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
422
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
423
-
424
- return dev;
425
-}
426
-
427
-static void pxa2xx_pic_realize(DeviceState *dev, Error **errp)
428
-{
429
- PXA2xxPICState *s = PXA2XX_PIC(dev);
430
-
431
- qdev_init_gpio_in(dev, pxa2xx_pic_set_irq, PXA2XX_PIC_SRCS);
432
-
433
- /* Enable IC memory-mapped registers access. */
434
- memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_pic_ops, s,
435
- "pxa2xx-pic", 0x00100000);
436
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
437
-
438
- /* Enable IC coprocessor access. */
439
- define_arm_cp_regs_with_opaque(s->cpu, pxa_pic_cp_reginfo, s);
440
-}
441
-
442
-static const VMStateDescription vmstate_pxa2xx_pic_regs = {
443
- .name = "pxa2xx_pic",
444
- .version_id = 0,
445
- .minimum_version_id = 0,
446
- .post_load = pxa2xx_pic_post_load,
447
- .fields = (const VMStateField[]) {
448
- VMSTATE_UINT32_ARRAY(int_enabled, PXA2xxPICState, 2),
449
- VMSTATE_UINT32_ARRAY(int_pending, PXA2xxPICState, 2),
450
- VMSTATE_UINT32_ARRAY(is_fiq, PXA2xxPICState, 2),
451
- VMSTATE_UINT32(int_idle, PXA2xxPICState),
452
- VMSTATE_UINT32_ARRAY(priority, PXA2xxPICState, PXA2XX_PIC_SRCS),
453
- VMSTATE_END_OF_LIST(),
454
- },
455
-};
456
-
457
-static Property pxa2xx_pic_properties[] = {
458
- DEFINE_PROP_LINK("arm-cpu", PXA2xxPICState, cpu,
459
- TYPE_ARM_CPU, ARMCPU *),
460
- DEFINE_PROP_END_OF_LIST(),
461
-};
462
-
463
-static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
464
-{
465
- DeviceClass *dc = DEVICE_CLASS(klass);
466
- ResettableClass *rc = RESETTABLE_CLASS(klass);
467
-
468
- device_class_set_props(dc, pxa2xx_pic_properties);
469
- dc->realize = pxa2xx_pic_realize;
470
- dc->desc = "PXA2xx PIC";
471
- dc->vmsd = &vmstate_pxa2xx_pic_regs;
472
- rc->phases.hold = pxa2xx_pic_reset_hold;
473
-}
474
-
475
-static const TypeInfo pxa2xx_pic_info = {
476
- .name = TYPE_PXA2XX_PIC,
477
- .parent = TYPE_SYS_BUS_DEVICE,
478
- .instance_size = sizeof(PXA2xxPICState),
479
- .class_init = pxa2xx_pic_class_init,
480
-};
481
-
482
-static void pxa2xx_pic_register_types(void)
483
-{
484
- type_register_static(&pxa2xx_pic_info);
485
-}
486
-
487
-type_init(pxa2xx_pic_register_types)
488
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
489
index XXXXXXX..XXXXXXX 100644
490
--- a/hw/arm/Kconfig
491
+++ b/hw/arm/Kconfig
492
@@ -XXX,XX +XXX,XX @@ config OMAP
493
select SD
494
select SERIAL
495
496
-config PXA2XX
497
- bool
498
- select FRAMEBUFFER
499
- select I2C
500
- select SERIAL
501
- select SD
502
- select SSI
503
- select USB_OHCI_SYSBUS
504
- select PCMCIA
505
- select PXA2XX_TIMER
506
-
507
config REALVIEW
508
bool
509
default y
510
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
511
index XXXXXXX..XXXXXXX 100644
512
--- a/hw/arm/meson.build
513
+++ b/hw/arm/meson.build
514
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_SABRELITE', if_true: files('sabrelite.c'))
515
516
arm_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m.c'))
517
arm_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210.c'))
518
-arm_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_pic.c'))
519
arm_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic.c'))
520
arm_ss.add(when: 'CONFIG_OMAP', if_true: files('omap1.c'))
521
arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubieboard.c'))
522
--
340
--
523
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
1
Remove some defines and enums that are OMAP2 specific and
1
Set the Float3NaNPropRule explicitly for SPARC, and remove the
2
no longer used anywhere.
2
ifdef from pickNaNMulAdd().
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20241202131347.498124-22-peter.maydell@linaro.org
7
Message-id: 20240903160751.4100218-54-peter.maydell@linaro.org
8
---
7
---
9
include/hw/arm/omap.h | 207 ------------------------------------------
8
target/sparc/cpu.c | 2 ++
10
1 file changed, 207 deletions(-)
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
11
12
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/omap.h
14
--- a/target/sparc/cpu.c
15
+++ b/include/hw/arm/omap.h
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
#include "qom/object.h"
17
* the CPU state struct so it won't get zeroed on reset.
18
18
*/
19
# define OMAP_EMIFS_BASE    0x00000000
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
-# define OMAP2_Q0_BASE        0x00000000
20
+ /* For fused-multiply add, prefer SNaN over QNaN, then C->B->A */
21
# define OMAP_CS0_BASE        0x00000000
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
22
# define OMAP_CS1_BASE        0x04000000
22
/* For inf * 0 + NaN, return the input NaN */
23
# define OMAP_CS2_BASE        0x08000000
23
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
@@ -XXX,XX +XXX,XX @@
24
25
# define OMAP_EMIFF_BASE    0x10000000
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
# define OMAP_IMIF_BASE        0x20000000
26
index XXXXXXX..XXXXXXX 100644
27
# define OMAP_LOCALBUS_BASE    0x30000000
27
--- a/fpu/softfloat-specialize.c.inc
28
-# define OMAP2_Q1_BASE        0x40000000
28
+++ b/fpu/softfloat-specialize.c.inc
29
-# define OMAP2_L4_BASE        0x48000000
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
-# define OMAP2_SRAM_BASE    0x40200000
30
} else {
31
-# define OMAP2_L3_BASE        0x68000000
31
rule = float_3nan_prop_s_cab;
32
-# define OMAP2_Q2_BASE        0x80000000
32
}
33
-# define OMAP2_Q3_BASE        0xc0000000
33
-#elif defined(TARGET_SPARC)
34
# define OMAP_MPUI_BASE        0xe1000000
34
- rule = float_3nan_prop_s_cba;
35
35
#elif defined(TARGET_XTENSA)
36
# define OMAP730_SRAM_SIZE    0x00032000
36
if (status->use_first_nan) {
37
# define OMAP15XX_SRAM_SIZE    0x00030000
37
rule = float_3nan_prop_abc;
38
# define OMAP16XX_SRAM_SIZE    0x00004000
39
# define OMAP1611_SRAM_SIZE    0x0003e800
40
-# define OMAP242X_SRAM_SIZE    0x000a0000
41
-# define OMAP243X_SRAM_SIZE    0x00010000
42
# define OMAP_CS0_SIZE        0x04000000
43
# define OMAP_CS1_SIZE        0x04000000
44
# define OMAP_CS2_SIZE        0x04000000
45
@@ -XXX,XX +XXX,XX @@ void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk);
46
# define OMAP_INT_730_DMA_CH15        62
47
# define OMAP_INT_730_NAND        63
48
49
-/*
50
- * OMAP-24xx common IRQ numbers
51
- */
52
-# define OMAP_INT_24XX_STI        4
53
-# define OMAP_INT_24XX_SYS_NIRQ        7
54
-# define OMAP_INT_24XX_L3_IRQ        10
55
-# define OMAP_INT_24XX_PRCM_MPU_IRQ    11
56
-# define OMAP_INT_24XX_SDMA_IRQ0    12
57
-# define OMAP_INT_24XX_SDMA_IRQ1    13
58
-# define OMAP_INT_24XX_SDMA_IRQ2    14
59
-# define OMAP_INT_24XX_SDMA_IRQ3    15
60
-# define OMAP_INT_243X_MCBSP2_IRQ    16
61
-# define OMAP_INT_243X_MCBSP3_IRQ    17
62
-# define OMAP_INT_243X_MCBSP4_IRQ    18
63
-# define OMAP_INT_243X_MCBSP5_IRQ    19
64
-# define OMAP_INT_24XX_GPMC_IRQ        20
65
-# define OMAP_INT_24XX_GUFFAW_IRQ    21
66
-# define OMAP_INT_24XX_IVA_IRQ        22
67
-# define OMAP_INT_24XX_EAC_IRQ        23
68
-# define OMAP_INT_24XX_CAM_IRQ        24
69
-# define OMAP_INT_24XX_DSS_IRQ        25
70
-# define OMAP_INT_24XX_MAIL_U0_MPU    26
71
-# define OMAP_INT_24XX_DSP_UMA        27
72
-# define OMAP_INT_24XX_DSP_MMU        28
73
-# define OMAP_INT_24XX_GPIO_BANK1    29
74
-# define OMAP_INT_24XX_GPIO_BANK2    30
75
-# define OMAP_INT_24XX_GPIO_BANK3    31
76
-# define OMAP_INT_24XX_GPIO_BANK4    32
77
-# define OMAP_INT_243X_GPIO_BANK5    33
78
-# define OMAP_INT_24XX_MAIL_U3_MPU    34
79
-# define OMAP_INT_24XX_WDT3        35
80
-# define OMAP_INT_24XX_WDT4        36
81
-# define OMAP_INT_24XX_GPTIMER1        37
82
-# define OMAP_INT_24XX_GPTIMER2        38
83
-# define OMAP_INT_24XX_GPTIMER3        39
84
-# define OMAP_INT_24XX_GPTIMER4        40
85
-# define OMAP_INT_24XX_GPTIMER5        41
86
-# define OMAP_INT_24XX_GPTIMER6        42
87
-# define OMAP_INT_24XX_GPTIMER7        43
88
-# define OMAP_INT_24XX_GPTIMER8        44
89
-# define OMAP_INT_24XX_GPTIMER9        45
90
-# define OMAP_INT_24XX_GPTIMER10    46
91
-# define OMAP_INT_24XX_GPTIMER11    47
92
-# define OMAP_INT_24XX_GPTIMER12    48
93
-# define OMAP_INT_24XX_PKA_IRQ        50
94
-# define OMAP_INT_24XX_SHA1MD5_IRQ    51
95
-# define OMAP_INT_24XX_RNG_IRQ        52
96
-# define OMAP_INT_24XX_MG_IRQ        53
97
-# define OMAP_INT_24XX_I2C1_IRQ        56
98
-# define OMAP_INT_24XX_I2C2_IRQ        57
99
-# define OMAP_INT_24XX_MCBSP1_IRQ_TX    59
100
-# define OMAP_INT_24XX_MCBSP1_IRQ_RX    60
101
-# define OMAP_INT_24XX_MCBSP2_IRQ_TX    62
102
-# define OMAP_INT_24XX_MCBSP2_IRQ_RX    63
103
-# define OMAP_INT_243X_MCBSP1_IRQ    64
104
-# define OMAP_INT_24XX_MCSPI1_IRQ    65
105
-# define OMAP_INT_24XX_MCSPI2_IRQ    66
106
-# define OMAP_INT_24XX_SSI1_IRQ0    67
107
-# define OMAP_INT_24XX_SSI1_IRQ1    68
108
-# define OMAP_INT_24XX_SSI2_IRQ0    69
109
-# define OMAP_INT_24XX_SSI2_IRQ1    70
110
-# define OMAP_INT_24XX_SSI_GDD_IRQ    71
111
-# define OMAP_INT_24XX_UART1_IRQ    72
112
-# define OMAP_INT_24XX_UART2_IRQ    73
113
-# define OMAP_INT_24XX_UART3_IRQ    74
114
-# define OMAP_INT_24XX_USB_IRQ_GEN    75
115
-# define OMAP_INT_24XX_USB_IRQ_NISO    76
116
-# define OMAP_INT_24XX_USB_IRQ_ISO    77
117
-# define OMAP_INT_24XX_USB_IRQ_HGEN    78
118
-# define OMAP_INT_24XX_USB_IRQ_HSOF    79
119
-# define OMAP_INT_24XX_USB_IRQ_OTG    80
120
-# define OMAP_INT_24XX_VLYNQ_IRQ    81
121
-# define OMAP_INT_24XX_MMC_IRQ        83
122
-# define OMAP_INT_24XX_MS_IRQ        84
123
-# define OMAP_INT_24XX_FAC_IRQ        85
124
-# define OMAP_INT_24XX_MCSPI3_IRQ    91
125
-# define OMAP_INT_243X_HS_USB_MC    92
126
-# define OMAP_INT_243X_HS_USB_DMA    93
127
-# define OMAP_INT_243X_CARKIT        94
128
-# define OMAP_INT_34XX_GPTIMER12    95
129
-
130
/* omap_dma.c */
131
enum omap_dma_model {
132
omap_dma_3_0,
133
@@ -XXX,XX +XXX,XX @@ struct omap_dma_lcd_channel_s {
134
# define OMAP_DMA_MMC2_RX        55
135
# define OMAP_DMA_CRYPTO_DES_OUT    56
136
137
-/*
138
- * DMA request numbers for the OMAP2
139
- */
140
-# define OMAP24XX_DMA_NO_DEVICE        0
141
-# define OMAP24XX_DMA_XTI_DMA        1    /* Not in OMAP2420 */
142
-# define OMAP24XX_DMA_EXT_DMAREQ0    2
143
-# define OMAP24XX_DMA_EXT_DMAREQ1    3
144
-# define OMAP24XX_DMA_GPMC        4
145
-# define OMAP24XX_DMA_GFX        5    /* Not in OMAP2420 */
146
-# define OMAP24XX_DMA_DSS        6
147
-# define OMAP24XX_DMA_VLYNQ_TX        7    /* Not in OMAP2420 */
148
-# define OMAP24XX_DMA_CWT        8    /* Not in OMAP2420 */
149
-# define OMAP24XX_DMA_AES_TX        9    /* Not in OMAP2420 */
150
-# define OMAP24XX_DMA_AES_RX        10    /* Not in OMAP2420 */
151
-# define OMAP24XX_DMA_DES_TX        11    /* Not in OMAP2420 */
152
-# define OMAP24XX_DMA_DES_RX        12    /* Not in OMAP2420 */
153
-# define OMAP24XX_DMA_SHA1MD5_RX    13    /* Not in OMAP2420 */
154
-# define OMAP24XX_DMA_EXT_DMAREQ2    14
155
-# define OMAP24XX_DMA_EXT_DMAREQ3    15
156
-# define OMAP24XX_DMA_EXT_DMAREQ4    16
157
-# define OMAP24XX_DMA_EAC_AC_RD        17
158
-# define OMAP24XX_DMA_EAC_AC_WR        18
159
-# define OMAP24XX_DMA_EAC_MD_UL_RD    19
160
-# define OMAP24XX_DMA_EAC_MD_UL_WR    20
161
-# define OMAP24XX_DMA_EAC_MD_DL_RD    21
162
-# define OMAP24XX_DMA_EAC_MD_DL_WR    22
163
-# define OMAP24XX_DMA_EAC_BT_UL_RD    23
164
-# define OMAP24XX_DMA_EAC_BT_UL_WR    24
165
-# define OMAP24XX_DMA_EAC_BT_DL_RD    25
166
-# define OMAP24XX_DMA_EAC_BT_DL_WR    26
167
-# define OMAP24XX_DMA_I2C1_TX        27
168
-# define OMAP24XX_DMA_I2C1_RX        28
169
-# define OMAP24XX_DMA_I2C2_TX        29
170
-# define OMAP24XX_DMA_I2C2_RX        30
171
-# define OMAP24XX_DMA_MCBSP1_TX        31
172
-# define OMAP24XX_DMA_MCBSP1_RX        32
173
-# define OMAP24XX_DMA_MCBSP2_TX        33
174
-# define OMAP24XX_DMA_MCBSP2_RX        34
175
-# define OMAP24XX_DMA_SPI1_TX0        35
176
-# define OMAP24XX_DMA_SPI1_RX0        36
177
-# define OMAP24XX_DMA_SPI1_TX1        37
178
-# define OMAP24XX_DMA_SPI1_RX1        38
179
-# define OMAP24XX_DMA_SPI1_TX2        39
180
-# define OMAP24XX_DMA_SPI1_RX2        40
181
-# define OMAP24XX_DMA_SPI1_TX3        41
182
-# define OMAP24XX_DMA_SPI1_RX3        42
183
-# define OMAP24XX_DMA_SPI2_TX0        43
184
-# define OMAP24XX_DMA_SPI2_RX0        44
185
-# define OMAP24XX_DMA_SPI2_TX1        45
186
-# define OMAP24XX_DMA_SPI2_RX1        46
187
-
188
-# define OMAP24XX_DMA_UART1_TX        49
189
-# define OMAP24XX_DMA_UART1_RX        50
190
-# define OMAP24XX_DMA_UART2_TX        51
191
-# define OMAP24XX_DMA_UART2_RX        52
192
-# define OMAP24XX_DMA_UART3_TX        53
193
-# define OMAP24XX_DMA_UART3_RX        54
194
-# define OMAP24XX_DMA_USB_W2FC_TX0    55
195
-# define OMAP24XX_DMA_USB_W2FC_RX0    56
196
-# define OMAP24XX_DMA_USB_W2FC_TX1    57
197
-# define OMAP24XX_DMA_USB_W2FC_RX1    58
198
-# define OMAP24XX_DMA_USB_W2FC_TX2    59
199
-# define OMAP24XX_DMA_USB_W2FC_RX2    60
200
-# define OMAP24XX_DMA_MMC1_TX        61
201
-# define OMAP24XX_DMA_MMC1_RX        62
202
-# define OMAP24XX_DMA_MS        63    /* Not in OMAP2420 */
203
-# define OMAP24XX_DMA_EXT_DMAREQ5    64
204
-
205
struct omap_uart_s;
206
struct omap_uart_s *omap_uart_init(hwaddr base,
207
qemu_irq irq, omap_clk fclk, omap_clk iclk,
208
@@ -XXX,XX +XXX,XX @@ I2CBus *omap_i2c_bus(DeviceState *omap_i2c);
209
# define cpu_is_omap1510(cpu)        (cpu->mpu_model == omap1510)
210
# define cpu_is_omap1610(cpu)        (cpu->mpu_model == omap1610)
211
# define cpu_is_omap1710(cpu)        (cpu->mpu_model == omap1710)
212
-# define cpu_is_omap2410(cpu)        (cpu->mpu_model == omap2410)
213
-# define cpu_is_omap2420(cpu)        (cpu->mpu_model == omap2420)
214
-# define cpu_is_omap2430(cpu)        (cpu->mpu_model == omap2430)
215
-# define cpu_is_omap3430(cpu)        (cpu->mpu_model == omap3430)
216
-# define cpu_is_omap3630(cpu) (cpu->mpu_model == omap3630)
217
218
# define cpu_is_omap15xx(cpu)        \
219
(cpu_is_omap310(cpu) || cpu_is_omap1510(cpu))
220
# define cpu_is_omap16xx(cpu)        \
221
(cpu_is_omap1610(cpu) || cpu_is_omap1710(cpu))
222
-# define cpu_is_omap24xx(cpu)        \
223
- (cpu_is_omap2410(cpu) || cpu_is_omap2420(cpu) || cpu_is_omap2430(cpu))
224
-
225
-# define cpu_class_omap1(cpu)        \
226
- (cpu_is_omap15xx(cpu) || cpu_is_omap16xx(cpu))
227
-# define cpu_class_omap2(cpu)        cpu_is_omap24xx(cpu)
228
-# define cpu_class_omap3(cpu) \
229
- (cpu_is_omap3430(cpu) || cpu_is_omap3630(cpu))
230
231
struct omap_mpu_state_s {
232
enum omap_mpu_model {
233
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s {
234
omap1510,
235
omap1610,
236
omap1710,
237
- omap2410,
238
- omap2420,
239
- omap2422,
240
- omap2423,
241
- omap2430,
242
- omap3430,
243
- omap3630,
244
} mpu_model;
245
246
ARMCPU *cpu;
247
@@ -XXX,XX +XXX,XX @@ void omap_mpu_wakeup(void *opaque, int irq, int req);
248
HWADDR_PRIx "\n", \
249
__func__, paddr)
250
251
-/* OMAP-specific Linux bootloader tags for the ATAG_BOARD area
252
- * (Board-specific tags are not here)
253
- */
254
-#define OMAP_TAG_CLOCK        0x4f01
255
-#define OMAP_TAG_MMC        0x4f02
256
-#define OMAP_TAG_SERIAL_CONSOLE    0x4f03
257
-#define OMAP_TAG_USB        0x4f04
258
-#define OMAP_TAG_LCD        0x4f05
259
-#define OMAP_TAG_GPIO_SWITCH    0x4f06
260
-#define OMAP_TAG_UART        0x4f07
261
-#define OMAP_TAG_FBMEM        0x4f08
262
-#define OMAP_TAG_STI_CONSOLE    0x4f09
263
-#define OMAP_TAG_CAMERA_SENSOR    0x4f0a
264
-#define OMAP_TAG_PARTITION    0x4f0b
265
-#define OMAP_TAG_TEA5761    0x4f10
266
-#define OMAP_TAG_TMP105        0x4f11
267
-#define OMAP_TAG_BOOT_REASON    0x4f80
268
-#define OMAP_TAG_FLASH_PART_STR    0x4f81
269
-#define OMAP_TAG_VERSION_STR    0x4f82
270
-
271
-enum {
272
- OMAP_GPIOSW_TYPE_COVER    = 0 << 4,
273
- OMAP_GPIOSW_TYPE_CONNECTION    = 1 << 4,
274
- OMAP_GPIOSW_TYPE_ACTIVITY    = 2 << 4,
275
-};
276
-
277
-#define OMAP_GPIOSW_INVERTED    0x0001
278
-#define OMAP_GPIOSW_OUTPUT    0x0002
279
-
280
# define OMAP_MPUI_REG_MASK        0x000007ff
281
282
#endif
283
--
38
--
284
2.34.1
39
2.34.1
285
286
diff view generated by jsdifflib
1
The omap_tap device is OMAP2 only, and we are removing it.
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
ifdef from pickNaNMulAdd().
2
3
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20241202131347.498124-23-peter.maydell@linaro.org
6
Message-id: 20240903160751.4100218-49-peter.maydell@linaro.org
7
---
7
---
8
include/hw/arm/omap.h | 3 --
8
target/mips/fpu_helper.h | 4 ++++
9
hw/misc/omap_tap.c | 117 ------------------------------------------
9
target/mips/msa.c | 3 +++
10
hw/misc/meson.build | 1 -
10
fpu/softfloat-specialize.c.inc | 8 +-------
11
3 files changed, 121 deletions(-)
11
3 files changed, 8 insertions(+), 7 deletions(-)
12
delete mode 100644 hw/misc/omap_tap.c
13
12
14
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/omap.h
15
--- a/target/mips/fpu_helper.h
17
+++ b/include/hw/arm/omap.h
16
+++ b/target/mips/fpu_helper.h
18
@@ -XXX,XX +XXX,XX @@ struct I2SCodec {
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
19
struct omap_mcbsp_s;
18
{
20
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave);
19
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
21
20
FloatInfZeroNaNRule izn_rule;
22
-void omap_tap_init(struct omap_target_agent_s *ta,
21
+ Float3NaNPropRule nan3_rule;
23
- struct omap_mpu_state_s *mpu);
22
24
-
23
/*
25
/* omap_lcdc.c */
24
* With nan2008, SNaNs are silenced in the usual way.
26
struct omap_lcd_panel_s;
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
27
void omap_lcdc_reset(struct omap_lcd_panel_s *s);
26
*/
28
diff --git a/hw/misc/omap_tap.c b/hw/misc/omap_tap.c
27
izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
29
deleted file mode 100644
28
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
30
index XXXXXXX..XXXXXXX
29
+ nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
31
--- a/hw/misc/omap_tap.c
30
+ set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
32
+++ /dev/null
31
+
33
@@ -XXX,XX +XXX,XX @@
32
}
34
-/*
33
35
- * TI OMAP TEST-Chip-level TAP emulation.
34
static inline void restore_fp_status(CPUMIPSState *env)
36
- *
35
diff --git a/target/mips/msa.c b/target/mips/msa.c
37
- * Copyright (C) 2007-2008 Nokia Corporation
36
index XXXXXXX..XXXXXXX 100644
38
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
37
--- a/target/mips/msa.c
39
- *
38
+++ b/target/mips/msa.c
40
- * This program is free software; you can redistribute it and/or
39
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
41
- * modify it under the terms of the GNU General Public License as
40
set_float_2nan_prop_rule(float_2nan_prop_s_ab,
42
- * published by the Free Software Foundation; either version 2 or
41
&env->active_tc.msa_fp_status);
43
- * (at your option) any later version of the License.
42
44
- *
43
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab,
45
- * This program is distributed in the hope that it will be useful,
44
+ &env->active_tc.msa_fp_status);
46
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
45
+
47
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46
/* clear float_status exception flags */
48
- * GNU General Public License for more details.
47
set_float_exception_flags(0, &env->active_tc.msa_fp_status);
49
- *
48
50
- * You should have received a copy of the GNU General Public License along
49
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
51
- * with this program; if not, see <http://www.gnu.org/licenses/>.
50
index XXXXXXX..XXXXXXX 100644
52
- */
51
--- a/fpu/softfloat-specialize.c.inc
53
-
52
+++ b/fpu/softfloat-specialize.c.inc
54
-#include "qemu/osdep.h"
53
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
55
-#include "hw/hw.h"
54
}
56
-#include "hw/arm/omap.h"
55
57
-
56
if (rule == float_3nan_prop_none) {
58
-/* TEST-Chip-level TAP */
57
-#if defined(TARGET_MIPS)
59
-static uint64_t omap_tap_read(void *opaque, hwaddr addr, unsigned size)
58
- if (snan_bit_is_one(status)) {
60
-{
59
- rule = float_3nan_prop_s_abc;
61
- struct omap_mpu_state_s *s = opaque;
60
- } else {
62
-
61
- rule = float_3nan_prop_s_cab;
63
- if (size != 4) {
64
- return omap_badwidth_read32(opaque, addr);
65
- }
66
-
67
- switch (addr) {
68
- case 0x204:    /* IDCODE_reg */
69
- switch (s->mpu_model) {
70
- case omap2420:
71
- case omap2422:
72
- case omap2423:
73
- return 0x5b5d902f;    /* ES 2.2 */
74
- case omap2430:
75
- return 0x5b68a02f;    /* ES 2.2 */
76
- case omap3430:
77
- return 0x1b7ae02f;    /* ES 2 */
78
- default:
79
- hw_error("%s: Bad mpu model\n", __func__);
80
- }
62
- }
81
-
63
-#elif defined(TARGET_XTENSA)
82
- case 0x208:    /* PRODUCTION_ID_reg for OMAP2 */
64
+#if defined(TARGET_XTENSA)
83
- case 0x210:    /* PRODUCTION_ID_reg for OMAP3 */
65
if (status->use_first_nan) {
84
- switch (s->mpu_model) {
66
rule = float_3nan_prop_abc;
85
- case omap2420:
67
} else {
86
- return 0x000254f0;    /* POP ESHS2.1.1 in N91/93/95, ES2 in N800 */
87
- case omap2422:
88
- return 0x000400f0;
89
- case omap2423:
90
- return 0x000800f0;
91
- case omap2430:
92
- return 0x000000f0;
93
- case omap3430:
94
- return 0x000000f0;
95
- default:
96
- hw_error("%s: Bad mpu model\n", __func__);
97
- }
98
-
99
- case 0x20c:
100
- switch (s->mpu_model) {
101
- case omap2420:
102
- case omap2422:
103
- case omap2423:
104
- return 0xcafeb5d9;    /* ES 2.2 */
105
- case omap2430:
106
- return 0xcafeb68a;    /* ES 2.2 */
107
- case omap3430:
108
- return 0xcafeb7ae;    /* ES 2 */
109
- default:
110
- hw_error("%s: Bad mpu model\n", __func__);
111
- }
112
-
113
- case 0x218:    /* DIE_ID_reg */
114
- return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
115
- case 0x21c:    /* DIE_ID_reg */
116
- return 0x54 << 24;
117
- case 0x220:    /* DIE_ID_reg */
118
- return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
119
- case 0x224:    /* DIE_ID_reg */
120
- return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
121
- }
122
-
123
- OMAP_BAD_REG(addr);
124
- return 0;
125
-}
126
-
127
-static void omap_tap_write(void *opaque, hwaddr addr,
128
- uint64_t value, unsigned size)
129
-{
130
- if (size != 4) {
131
- omap_badwidth_write32(opaque, addr, value);
132
- return;
133
- }
134
-
135
- OMAP_BAD_REG(addr);
136
-}
137
-
138
-static const MemoryRegionOps omap_tap_ops = {
139
- .read = omap_tap_read,
140
- .write = omap_tap_write,
141
- .endianness = DEVICE_NATIVE_ENDIAN,
142
-};
143
-
144
-void omap_tap_init(struct omap_target_agent_s *ta,
145
- struct omap_mpu_state_s *mpu)
146
-{
147
- memory_region_init_io(&mpu->tap_iomem, NULL, &omap_tap_ops, mpu, "omap.tap",
148
- omap_l4_region_size(ta, 0));
149
- omap_l4_attach(ta, 0, &mpu->tap_iomem);
150
-}
151
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
152
index XXXXXXX..XXXXXXX 100644
153
--- a/hw/misc/meson.build
154
+++ b/hw/misc/meson.build
155
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
156
system_ss.add(when: 'CONFIG_OMAP', if_true: files(
157
'omap_clk.c',
158
'omap_l4.c',
159
- 'omap_tap.c',
160
))
161
system_ss.add(when: 'CONFIG_RASPI', if_true: files(
162
'bcm2835_mbox.c',
163
--
68
--
164
2.34.1
69
2.34.1
165
166
diff view generated by jsdifflib
1
The Sharp XScale-based PDA board models akita, borzoi, spitz,
1
Set the Float3NaNPropRule explicitly for xtensa, and remove the
2
terrier, and tosa were all deprecated in 9.0, so our deprecation
2
ifdef from pickNaNMulAdd().
3
cycle permits removing them for the 9.2 release.
4
5
Remove the source files for the board models themselves, and their
6
documentation. There were no tests for these boards.
7
8
We will move the text describing the dropped boards from
9
deprecated.rst to removed-features.rst when we've cleaned up all the
10
boards it lists. Device models used only by removed board models
11
will be removed in separate commits.
12
3
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20241202131347.498124-24-peter.maydell@linaro.org
16
Message-id: 20240903160751.4100218-2-peter.maydell@linaro.org
17
---
7
---
18
MAINTAINERS | 3 -
8
target/xtensa/fpu_helper.c | 2 ++
19
docs/system/arm/xscale.rst | 35 -
9
fpu/softfloat-specialize.c.inc | 8 --------
20
docs/system/target-arm.rst | 1 -
10
2 files changed, 2 insertions(+), 8 deletions(-)
21
configs/devices/arm-softmmu/default.mak | 2 -
22
hw/arm/spitz.c | 1284 -----------------------
23
hw/arm/tosa.c | 327 ------
24
hw/arm/Kconfig | 23 -
25
hw/arm/meson.build | 2 -
26
8 files changed, 1677 deletions(-)
27
delete mode 100644 docs/system/arm/xscale.rst
28
delete mode 100644 hw/arm/spitz.c
29
delete mode 100644 hw/arm/tosa.c
30
11
31
diff --git a/MAINTAINERS b/MAINTAINERS
12
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
32
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
33
--- a/MAINTAINERS
14
--- a/target/xtensa/fpu_helper.c
34
+++ b/MAINTAINERS
15
+++ b/target/xtensa/fpu_helper.c
35
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
16
@@ -XXX,XX +XXX,XX @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
36
L: qemu-arm@nongnu.org
17
set_use_first_nan(use_first, &env->fp_status);
37
S: Odd Fixes
18
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
38
F: hw/arm/mainstone.c
19
&env->fp_status);
39
-F: hw/arm/spitz.c
20
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
40
-F: hw/arm/tosa.c
21
+ &env->fp_status);
41
F: hw/arm/z2.c
22
}
42
F: hw/*/pxa2xx*
23
43
F: hw/display/tc6393xb.c
24
void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
44
@@ -XXX,XX +XXX,XX @@ F: include/hw/adc/max111x.h
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
45
F: include/hw/arm/pxa.h
46
F: include/hw/arm/sharpsl.h
47
F: include/hw/display/tc6393xb.h
48
-F: docs/system/arm/xscale.rst
49
F: docs/system/arm/mainstone.rst
50
51
SABRELITE / i.MX6
52
diff --git a/docs/system/arm/xscale.rst b/docs/system/arm/xscale.rst
53
deleted file mode 100644
54
index XXXXXXX..XXXXXXX
55
--- a/docs/system/arm/xscale.rst
56
+++ /dev/null
57
@@ -XXX,XX +XXX,XX @@
58
-Sharp XScale-based PDA models (``akita``, ``borzoi``, ``spitz``, ``terrier``, ``tosa``)
59
-=======================================================================================
60
-
61
-The Sharp Zaurus are PDAs based on XScale, able to run Linux ('SL series').
62
-
63
-The SL-6000 (\"Tosa\"), released in 2005, uses a PXA255 System-on-chip.
64
-
65
-The SL-C3000 (\"Spitz\"), SL-C1000 (\"Akita\"), SL-C3100 (\"Borzoi\") and
66
-SL-C3200 (\"Terrier\") use a PXA270.
67
-
68
-The clamshell PDA models emulation includes the following peripherals:
69
-
70
-- Intel PXA255/PXA270 System-on-chip (ARMv5TE core)
71
-
72
-- NAND Flash memory - not in \"Tosa\"
73
-
74
-- IBM/Hitachi DSCM microdrive in a PXA PCMCIA slot - not in \"Akita\"
75
-
76
-- On-chip OHCI USB controller - not in \"Tosa\"
77
-
78
-- On-chip LCD controller
79
-
80
-- On-chip Real Time Clock
81
-
82
-- TI ADS7846 touchscreen controller on SSP bus
83
-
84
-- Maxim MAX1111 analog-digital converter on |I2C| bus
85
-
86
-- GPIO-connected keyboard controller and LEDs
87
-
88
-- Secure Digital card connected to PXA MMC/SD host
89
-
90
-- Three on-chip UARTs
91
-
92
-- WM8750 audio CODEC on |I2C| and |I2S| buses
93
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
94
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
95
--- a/docs/system/target-arm.rst
27
--- a/fpu/softfloat-specialize.c.inc
96
+++ b/docs/system/target-arm.rst
28
+++ b/fpu/softfloat-specialize.c.inc
97
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
98
arm/orangepi
30
}
99
arm/palm
31
100
arm/raspi
32
if (rule == float_3nan_prop_none) {
101
- arm/xscale
33
-#if defined(TARGET_XTENSA)
102
arm/collie
34
- if (status->use_first_nan) {
103
arm/sx1
35
- rule = float_3nan_prop_abc;
104
arm/stellaris
36
- } else {
105
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
37
- rule = float_3nan_prop_cba;
106
index XXXXXXX..XXXXXXX 100644
107
--- a/configs/devices/arm-softmmu/default.mak
108
+++ b/configs/devices/arm-softmmu/default.mak
109
@@ -XXX,XX +XXX,XX @@
110
# CONFIG_ZYNQ=n
111
# CONFIG_MAINSTONE=n
112
# CONFIG_GUMSTIX=n
113
-# CONFIG_SPITZ=n
114
-# CONFIG_TOSA=n
115
# CONFIG_Z2=n
116
# CONFIG_NPCM7XX=n
117
# CONFIG_COLLIE=n
118
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
119
deleted file mode 100644
120
index XXXXXXX..XXXXXXX
121
--- a/hw/arm/spitz.c
122
+++ /dev/null
123
@@ -XXX,XX +XXX,XX @@
124
-/*
125
- * PXA270-based Clamshell PDA platforms.
126
- *
127
- * Copyright (c) 2006 Openedhand Ltd.
128
- * Written by Andrzej Zaborowski <balrog@zabor.org>
129
- *
130
- * This code is licensed under the GNU GPL v2.
131
- *
132
- * Contributions after 2012-01-13 are licensed under the terms of the
133
- * GNU GPL, version 2 or (at your option) any later version.
134
- */
135
-
136
-#include "qemu/osdep.h"
137
-#include "qapi/error.h"
138
-#include "hw/arm/pxa.h"
139
-#include "hw/arm/boot.h"
140
-#include "sysemu/runstate.h"
141
-#include "sysemu/sysemu.h"
142
-#include "hw/pcmcia.h"
143
-#include "hw/qdev-properties.h"
144
-#include "hw/i2c/i2c.h"
145
-#include "hw/irq.h"
146
-#include "hw/ssi/ssi.h"
147
-#include "hw/block/flash.h"
148
-#include "qemu/timer.h"
149
-#include "qemu/log.h"
150
-#include "hw/arm/sharpsl.h"
151
-#include "ui/console.h"
152
-#include "hw/audio/wm8750.h"
153
-#include "audio/audio.h"
154
-#include "hw/boards.h"
155
-#include "hw/sysbus.h"
156
-#include "hw/adc/max111x.h"
157
-#include "migration/vmstate.h"
158
-#include "exec/address-spaces.h"
159
-#include "qom/object.h"
160
-#include "audio/audio.h"
161
-
162
-enum spitz_model_e { spitz, akita, borzoi, terrier };
163
-
164
-struct SpitzMachineClass {
165
- MachineClass parent;
166
- enum spitz_model_e model;
167
- int arm_id;
168
-};
169
-
170
-struct SpitzMachineState {
171
- MachineState parent;
172
- PXA2xxState *mpu;
173
- DeviceState *mux;
174
- DeviceState *lcdtg;
175
- DeviceState *ads7846;
176
- DeviceState *max1111;
177
- DeviceState *scp0;
178
- DeviceState *scp1;
179
- DeviceState *misc_gpio;
180
-};
181
-
182
-#define TYPE_SPITZ_MACHINE "spitz-common"
183
-OBJECT_DECLARE_TYPE(SpitzMachineState, SpitzMachineClass, SPITZ_MACHINE)
184
-
185
-#define zaurus_printf(format, ...) \
186
- fprintf(stderr, "%s: " format, __func__, ##__VA_ARGS__)
187
-
188
-/* Spitz Flash */
189
-#define FLASH_BASE 0x0c000000
190
-#define FLASH_ECCLPLB 0x00 /* Line parity 7 - 0 bit */
191
-#define FLASH_ECCLPUB 0x04 /* Line parity 15 - 8 bit */
192
-#define FLASH_ECCCP 0x08 /* Column parity 5 - 0 bit */
193
-#define FLASH_ECCCNTR 0x0c /* ECC byte counter */
194
-#define FLASH_ECCCLRR 0x10 /* Clear ECC */
195
-#define FLASH_FLASHIO 0x14 /* Flash I/O */
196
-#define FLASH_FLASHCTL 0x18 /* Flash Control */
197
-
198
-#define FLASHCTL_CE0 (1 << 0)
199
-#define FLASHCTL_CLE (1 << 1)
200
-#define FLASHCTL_ALE (1 << 2)
201
-#define FLASHCTL_WP (1 << 3)
202
-#define FLASHCTL_CE1 (1 << 4)
203
-#define FLASHCTL_RYBY (1 << 5)
204
-#define FLASHCTL_NCE (FLASHCTL_CE0 | FLASHCTL_CE1)
205
-
206
-#define TYPE_SL_NAND "sl-nand"
207
-OBJECT_DECLARE_SIMPLE_TYPE(SLNANDState, SL_NAND)
208
-
209
-struct SLNANDState {
210
- SysBusDevice parent_obj;
211
-
212
- MemoryRegion iomem;
213
- DeviceState *nand;
214
- uint8_t ctl;
215
- uint8_t manf_id;
216
- uint8_t chip_id;
217
- ECCState ecc;
218
-};
219
-
220
-static uint64_t sl_read(void *opaque, hwaddr addr, unsigned size)
221
-{
222
- SLNANDState *s = (SLNANDState *) opaque;
223
- int ryby;
224
-
225
- switch (addr) {
226
-#define BSHR(byte, from, to) ((s->ecc.lp[byte] >> (from - to)) & (1 << to))
227
- case FLASH_ECCLPLB:
228
- return BSHR(0, 4, 0) | BSHR(0, 5, 2) | BSHR(0, 6, 4) | BSHR(0, 7, 6) |
229
- BSHR(1, 4, 1) | BSHR(1, 5, 3) | BSHR(1, 6, 5) | BSHR(1, 7, 7);
230
-
231
-#define BSHL(byte, from, to) ((s->ecc.lp[byte] << (to - from)) & (1 << to))
232
- case FLASH_ECCLPUB:
233
- return BSHL(0, 0, 0) | BSHL(0, 1, 2) | BSHL(0, 2, 4) | BSHL(0, 3, 6) |
234
- BSHL(1, 0, 1) | BSHL(1, 1, 3) | BSHL(1, 2, 5) | BSHL(1, 3, 7);
235
-
236
- case FLASH_ECCCP:
237
- return s->ecc.cp;
238
-
239
- case FLASH_ECCCNTR:
240
- return s->ecc.count & 0xff;
241
-
242
- case FLASH_FLASHCTL:
243
- nand_getpins(s->nand, &ryby);
244
- if (ryby)
245
- return s->ctl | FLASHCTL_RYBY;
246
- else
247
- return s->ctl;
248
-
249
- case FLASH_FLASHIO:
250
- if (size == 4) {
251
- return ecc_digest(&s->ecc, nand_getio(s->nand)) |
252
- (ecc_digest(&s->ecc, nand_getio(s->nand)) << 16);
253
- }
254
- return ecc_digest(&s->ecc, nand_getio(s->nand));
255
-
256
- default:
257
- qemu_log_mask(LOG_GUEST_ERROR,
258
- "sl_read: bad register offset 0x%02" HWADDR_PRIx "\n",
259
- addr);
260
- }
261
- return 0;
262
-}
263
-
264
-static void sl_write(void *opaque, hwaddr addr,
265
- uint64_t value, unsigned size)
266
-{
267
- SLNANDState *s = (SLNANDState *) opaque;
268
-
269
- switch (addr) {
270
- case FLASH_ECCCLRR:
271
- /* Value is ignored. */
272
- ecc_reset(&s->ecc);
273
- break;
274
-
275
- case FLASH_FLASHCTL:
276
- s->ctl = value & 0xff & ~FLASHCTL_RYBY;
277
- nand_setpins(s->nand,
278
- s->ctl & FLASHCTL_CLE,
279
- s->ctl & FLASHCTL_ALE,
280
- s->ctl & FLASHCTL_NCE,
281
- s->ctl & FLASHCTL_WP,
282
- 0);
283
- break;
284
-
285
- case FLASH_FLASHIO:
286
- nand_setio(s->nand, ecc_digest(&s->ecc, value & 0xff));
287
- break;
288
-
289
- default:
290
- qemu_log_mask(LOG_GUEST_ERROR,
291
- "sl_write: bad register offset 0x%02" HWADDR_PRIx "\n",
292
- addr);
293
- }
294
-}
295
-
296
-enum {
297
- FLASH_128M,
298
- FLASH_1024M,
299
-};
300
-
301
-static const MemoryRegionOps sl_ops = {
302
- .read = sl_read,
303
- .write = sl_write,
304
- .endianness = DEVICE_NATIVE_ENDIAN,
305
-};
306
-
307
-static void sl_flash_register(PXA2xxState *cpu, int size)
308
-{
309
- DeviceState *dev;
310
-
311
- dev = qdev_new(TYPE_SL_NAND);
312
-
313
- qdev_prop_set_uint8(dev, "manf_id", NAND_MFR_SAMSUNG);
314
- if (size == FLASH_128M)
315
- qdev_prop_set_uint8(dev, "chip_id", 0x73);
316
- else if (size == FLASH_1024M)
317
- qdev_prop_set_uint8(dev, "chip_id", 0xf1);
318
-
319
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
320
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, FLASH_BASE);
321
-}
322
-
323
-static void sl_nand_init(Object *obj)
324
-{
325
- SLNANDState *s = SL_NAND(obj);
326
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
327
-
328
- s->ctl = 0;
329
-
330
- memory_region_init_io(&s->iomem, obj, &sl_ops, s, "sl", 0x40);
331
- sysbus_init_mmio(dev, &s->iomem);
332
-}
333
-
334
-static void sl_nand_realize(DeviceState *dev, Error **errp)
335
-{
336
- SLNANDState *s = SL_NAND(dev);
337
- DriveInfo *nand;
338
-
339
- /* FIXME use a qdev drive property instead of drive_get() */
340
- nand = drive_get(IF_MTD, 0, 0);
341
- s->nand = nand_init(nand ? blk_by_legacy_dinfo(nand) : NULL,
342
- s->manf_id, s->chip_id);
343
-}
344
-
345
-/* Spitz Keyboard */
346
-
347
-#define SPITZ_KEY_STROBE_NUM 11
348
-#define SPITZ_KEY_SENSE_NUM 7
349
-
350
-static const int spitz_gpio_key_sense[SPITZ_KEY_SENSE_NUM] = {
351
- 12, 17, 91, 34, 36, 38, 39
352
-};
353
-
354
-static const int spitz_gpio_key_strobe[SPITZ_KEY_STROBE_NUM] = {
355
- 88, 23, 24, 25, 26, 27, 52, 103, 107, 108, 114
356
-};
357
-
358
-/* Eighth additional row maps the special keys */
359
-static int spitz_keymap[SPITZ_KEY_SENSE_NUM + 1][SPITZ_KEY_STROBE_NUM] = {
360
- { 0x1d, 0x02, 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0e, 0x3f, 0x40 },
361
- { -1 , 0x03, 0x05, 0x13, 0x15, 0x09, 0x17, 0x18, 0x19, 0x41, 0x42 },
362
- { 0x0f, 0x10, 0x12, 0x14, 0x22, 0x16, 0x24, 0x25, -1 , -1 , -1 },
363
- { 0x3c, 0x11, 0x1f, 0x21, 0x2f, 0x23, 0x32, 0x26, -1 , 0x36, -1 },
364
- { 0x3b, 0x1e, 0x20, 0x2e, 0x30, 0x31, 0x34, -1 , 0x1c, 0x2a, -1 },
365
- { 0x44, 0x2c, 0x2d, 0x0c, 0x39, 0x33, -1 , 0x48, -1 , -1 , 0x38 },
366
- { 0x37, 0x3d, -1 , 0x45, 0x57, 0x58, 0x4b, 0x50, 0x4d, -1 , -1 },
367
- { 0x52, 0x43, 0x01, 0x47, 0x49, -1 , -1 , -1 , -1 , -1 , -1 },
368
-};
369
-
370
-#define SPITZ_GPIO_AK_INT 13 /* Remote control */
371
-#define SPITZ_GPIO_SYNC 16 /* Sync button */
372
-#define SPITZ_GPIO_ON_KEY 95 /* Power button */
373
-#define SPITZ_GPIO_SWA 97 /* Lid */
374
-#define SPITZ_GPIO_SWB 96 /* Tablet mode */
375
-
376
-/* The special buttons are mapped to unused keys */
377
-static const int spitz_gpiomap[5] = {
378
- SPITZ_GPIO_AK_INT, SPITZ_GPIO_SYNC, SPITZ_GPIO_ON_KEY,
379
- SPITZ_GPIO_SWA, SPITZ_GPIO_SWB,
380
-};
381
-
382
-#define TYPE_SPITZ_KEYBOARD "spitz-keyboard"
383
-OBJECT_DECLARE_SIMPLE_TYPE(SpitzKeyboardState, SPITZ_KEYBOARD)
384
-
385
-struct SpitzKeyboardState {
386
- SysBusDevice parent_obj;
387
-
388
- qemu_irq sense[SPITZ_KEY_SENSE_NUM];
389
- qemu_irq gpiomap[5];
390
- int keymap[0x80];
391
- uint16_t keyrow[SPITZ_KEY_SENSE_NUM];
392
- uint16_t strobe_state;
393
- uint16_t sense_state;
394
-
395
- uint16_t pre_map[0x100];
396
- uint16_t modifiers;
397
- uint16_t imodifiers;
398
- uint8_t fifo[16];
399
- int fifopos, fifolen;
400
- QEMUTimer *kbdtimer;
401
-};
402
-
403
-static void spitz_keyboard_sense_update(SpitzKeyboardState *s)
404
-{
405
- int i;
406
- uint16_t strobe, sense = 0;
407
- for (i = 0; i < SPITZ_KEY_SENSE_NUM; i ++) {
408
- strobe = s->keyrow[i] & s->strobe_state;
409
- if (strobe) {
410
- sense |= 1 << i;
411
- if (!(s->sense_state & (1 << i)))
412
- qemu_irq_raise(s->sense[i]);
413
- } else if (s->sense_state & (1 << i))
414
- qemu_irq_lower(s->sense[i]);
415
- }
416
-
417
- s->sense_state = sense;
418
-}
419
-
420
-static void spitz_keyboard_strobe(void *opaque, int line, int level)
421
-{
422
- SpitzKeyboardState *s = (SpitzKeyboardState *) opaque;
423
-
424
- if (level)
425
- s->strobe_state |= 1 << line;
426
- else
427
- s->strobe_state &= ~(1 << line);
428
- spitz_keyboard_sense_update(s);
429
-}
430
-
431
-static void spitz_keyboard_keydown(SpitzKeyboardState *s, int keycode)
432
-{
433
- int spitz_keycode = s->keymap[keycode & 0x7f];
434
- if (spitz_keycode == -1)
435
- return;
436
-
437
- /* Handle the additional keys */
438
- if ((spitz_keycode >> 4) == SPITZ_KEY_SENSE_NUM) {
439
- qemu_set_irq(s->gpiomap[spitz_keycode & 0xf], (keycode < 0x80));
440
- return;
441
- }
442
-
443
- if (keycode & 0x80)
444
- s->keyrow[spitz_keycode >> 4] &= ~(1 << (spitz_keycode & 0xf));
445
- else
446
- s->keyrow[spitz_keycode >> 4] |= 1 << (spitz_keycode & 0xf);
447
-
448
- spitz_keyboard_sense_update(s);
449
-}
450
-
451
-#define SPITZ_MOD_SHIFT (1 << 7)
452
-#define SPITZ_MOD_CTRL (1 << 8)
453
-#define SPITZ_MOD_FN (1 << 9)
454
-
455
-#define QUEUE_KEY(c) s->fifo[(s->fifopos + s->fifolen ++) & 0xf] = c
456
-
457
-static void spitz_keyboard_handler(void *opaque, int keycode)
458
-{
459
- SpitzKeyboardState *s = opaque;
460
- uint16_t code;
461
- int mapcode;
462
- switch (keycode) {
463
- case 0x2a: /* Left Shift */
464
- s->modifiers |= 1;
465
- break;
466
- case 0xaa:
467
- s->modifiers &= ~1;
468
- break;
469
- case 0x36: /* Right Shift */
470
- s->modifiers |= 2;
471
- break;
472
- case 0xb6:
473
- s->modifiers &= ~2;
474
- break;
475
- case 0x1d: /* Control */
476
- s->modifiers |= 4;
477
- break;
478
- case 0x9d:
479
- s->modifiers &= ~4;
480
- break;
481
- case 0x38: /* Alt */
482
- s->modifiers |= 8;
483
- break;
484
- case 0xb8:
485
- s->modifiers &= ~8;
486
- break;
487
- }
488
-
489
- code = s->pre_map[mapcode = ((s->modifiers & 3) ?
490
- (keycode | SPITZ_MOD_SHIFT) :
491
- (keycode & ~SPITZ_MOD_SHIFT))];
492
-
493
- if (code != mapcode) {
494
-#if 0
495
- if ((code & SPITZ_MOD_SHIFT) && !(s->modifiers & 1)) {
496
- QUEUE_KEY(0x2a | (keycode & 0x80));
497
- }
498
- if ((code & SPITZ_MOD_CTRL) && !(s->modifiers & 4)) {
499
- QUEUE_KEY(0x1d | (keycode & 0x80));
500
- }
501
- if ((code & SPITZ_MOD_FN) && !(s->modifiers & 8)) {
502
- QUEUE_KEY(0x38 | (keycode & 0x80));
503
- }
504
- if ((code & SPITZ_MOD_FN) && (s->modifiers & 1)) {
505
- QUEUE_KEY(0x2a | (~keycode & 0x80));
506
- }
507
- if ((code & SPITZ_MOD_FN) && (s->modifiers & 2)) {
508
- QUEUE_KEY(0x36 | (~keycode & 0x80));
509
- }
38
- }
510
-#else
39
-#else
511
- if (keycode & 0x80) {
40
rule = float_3nan_prop_abc;
512
- if ((s->imodifiers & 1 ) && !(s->modifiers & 1))
513
- QUEUE_KEY(0x2a | 0x80);
514
- if ((s->imodifiers & 4 ) && !(s->modifiers & 4))
515
- QUEUE_KEY(0x1d | 0x80);
516
- if ((s->imodifiers & 8 ) && !(s->modifiers & 8))
517
- QUEUE_KEY(0x38 | 0x80);
518
- if ((s->imodifiers & 0x10) && (s->modifiers & 1))
519
- QUEUE_KEY(0x2a);
520
- if ((s->imodifiers & 0x20) && (s->modifiers & 2))
521
- QUEUE_KEY(0x36);
522
- s->imodifiers = 0;
523
- } else {
524
- if ((code & SPITZ_MOD_SHIFT) &&
525
- !((s->modifiers | s->imodifiers) & 1)) {
526
- QUEUE_KEY(0x2a);
527
- s->imodifiers |= 1;
528
- }
529
- if ((code & SPITZ_MOD_CTRL) &&
530
- !((s->modifiers | s->imodifiers) & 4)) {
531
- QUEUE_KEY(0x1d);
532
- s->imodifiers |= 4;
533
- }
534
- if ((code & SPITZ_MOD_FN) &&
535
- !((s->modifiers | s->imodifiers) & 8)) {
536
- QUEUE_KEY(0x38);
537
- s->imodifiers |= 8;
538
- }
539
- if ((code & SPITZ_MOD_FN) && (s->modifiers & 1) &&
540
- !(s->imodifiers & 0x10)) {
541
- QUEUE_KEY(0x2a | 0x80);
542
- s->imodifiers |= 0x10;
543
- }
544
- if ((code & SPITZ_MOD_FN) && (s->modifiers & 2) &&
545
- !(s->imodifiers & 0x20)) {
546
- QUEUE_KEY(0x36 | 0x80);
547
- s->imodifiers |= 0x20;
548
- }
549
- }
550
-#endif
41
-#endif
551
- }
42
}
552
-
43
553
- QUEUE_KEY((code & 0x7f) | (keycode & 0x80));
44
assert(rule != float_3nan_prop_none);
554
-}
555
-
556
-static void spitz_keyboard_tick(void *opaque)
557
-{
558
- SpitzKeyboardState *s = (SpitzKeyboardState *) opaque;
559
-
560
- if (s->fifolen) {
561
- spitz_keyboard_keydown(s, s->fifo[s->fifopos ++]);
562
- s->fifolen --;
563
- if (s->fifopos >= 16)
564
- s->fifopos = 0;
565
- }
566
-
567
- timer_mod(s->kbdtimer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
568
- NANOSECONDS_PER_SECOND / 32);
569
-}
570
-
571
-static void spitz_keyboard_pre_map(SpitzKeyboardState *s)
572
-{
573
- int i;
574
- for (i = 0; i < 0x100; i ++)
575
- s->pre_map[i] = i;
576
- s->pre_map[0x02 | SPITZ_MOD_SHIFT] = 0x02 | SPITZ_MOD_SHIFT; /* exclam */
577
- s->pre_map[0x28 | SPITZ_MOD_SHIFT] = 0x03 | SPITZ_MOD_SHIFT; /* quotedbl */
578
- s->pre_map[0x04 | SPITZ_MOD_SHIFT] = 0x04 | SPITZ_MOD_SHIFT; /* # */
579
- s->pre_map[0x05 | SPITZ_MOD_SHIFT] = 0x05 | SPITZ_MOD_SHIFT; /* dollar */
580
- s->pre_map[0x06 | SPITZ_MOD_SHIFT] = 0x06 | SPITZ_MOD_SHIFT; /* percent */
581
- s->pre_map[0x08 | SPITZ_MOD_SHIFT] = 0x07 | SPITZ_MOD_SHIFT; /* ampersand */
582
- s->pre_map[0x28] = 0x08 | SPITZ_MOD_SHIFT; /* ' */
583
- s->pre_map[0x0a | SPITZ_MOD_SHIFT] = 0x09 | SPITZ_MOD_SHIFT; /* ( */
584
- s->pre_map[0x0b | SPITZ_MOD_SHIFT] = 0x0a | SPITZ_MOD_SHIFT; /* ) */
585
- s->pre_map[0x29 | SPITZ_MOD_SHIFT] = 0x0b | SPITZ_MOD_SHIFT; /* tilde */
586
- s->pre_map[0x03 | SPITZ_MOD_SHIFT] = 0x0c | SPITZ_MOD_SHIFT; /* at */
587
- s->pre_map[0xd3] = 0x0e | SPITZ_MOD_FN; /* Delete */
588
- s->pre_map[0x3a] = 0x0f | SPITZ_MOD_FN; /* Caps_Lock */
589
- s->pre_map[0x07 | SPITZ_MOD_SHIFT] = 0x11 | SPITZ_MOD_FN; /* ^ */
590
- s->pre_map[0x0d] = 0x12 | SPITZ_MOD_FN; /* equal */
591
- s->pre_map[0x0d | SPITZ_MOD_SHIFT] = 0x13 | SPITZ_MOD_FN; /* plus */
592
- s->pre_map[0x1a] = 0x14 | SPITZ_MOD_FN; /* [ */
593
- s->pre_map[0x1b] = 0x15 | SPITZ_MOD_FN; /* ] */
594
- s->pre_map[0x1a | SPITZ_MOD_SHIFT] = 0x16 | SPITZ_MOD_FN; /* { */
595
- s->pre_map[0x1b | SPITZ_MOD_SHIFT] = 0x17 | SPITZ_MOD_FN; /* } */
596
- s->pre_map[0x27] = 0x22 | SPITZ_MOD_FN; /* semicolon */
597
- s->pre_map[0x27 | SPITZ_MOD_SHIFT] = 0x23 | SPITZ_MOD_FN; /* colon */
598
- s->pre_map[0x09 | SPITZ_MOD_SHIFT] = 0x24 | SPITZ_MOD_FN; /* asterisk */
599
- s->pre_map[0x2b] = 0x25 | SPITZ_MOD_FN; /* backslash */
600
- s->pre_map[0x2b | SPITZ_MOD_SHIFT] = 0x26 | SPITZ_MOD_FN; /* bar */
601
- s->pre_map[0x0c | SPITZ_MOD_SHIFT] = 0x30 | SPITZ_MOD_FN; /* _ */
602
- s->pre_map[0x33 | SPITZ_MOD_SHIFT] = 0x33 | SPITZ_MOD_FN; /* less */
603
- s->pre_map[0x35] = 0x33 | SPITZ_MOD_SHIFT; /* slash */
604
- s->pre_map[0x34 | SPITZ_MOD_SHIFT] = 0x34 | SPITZ_MOD_FN; /* greater */
605
- s->pre_map[0x35 | SPITZ_MOD_SHIFT] = 0x34 | SPITZ_MOD_SHIFT; /* question */
606
- s->pre_map[0x49] = 0x48 | SPITZ_MOD_FN; /* Page_Up */
607
- s->pre_map[0x51] = 0x50 | SPITZ_MOD_FN; /* Page_Down */
608
-
609
- s->modifiers = 0;
610
- s->imodifiers = 0;
611
- s->fifopos = 0;
612
- s->fifolen = 0;
613
-}
614
-
615
-#undef SPITZ_MOD_SHIFT
616
-#undef SPITZ_MOD_CTRL
617
-#undef SPITZ_MOD_FN
618
-
619
-static int spitz_keyboard_post_load(void *opaque, int version_id)
620
-{
621
- SpitzKeyboardState *s = (SpitzKeyboardState *) opaque;
622
-
623
- /* Release all pressed keys */
624
- memset(s->keyrow, 0, sizeof(s->keyrow));
625
- spitz_keyboard_sense_update(s);
626
- s->modifiers = 0;
627
- s->imodifiers = 0;
628
- s->fifopos = 0;
629
- s->fifolen = 0;
630
-
631
- return 0;
632
-}
633
-
634
-static void spitz_keyboard_register(PXA2xxState *cpu)
635
-{
636
- int i;
637
- DeviceState *dev;
638
- SpitzKeyboardState *s;
639
-
640
- dev = sysbus_create_simple(TYPE_SPITZ_KEYBOARD, -1, NULL);
641
- s = SPITZ_KEYBOARD(dev);
642
-
643
- for (i = 0; i < SPITZ_KEY_SENSE_NUM; i ++)
644
- qdev_connect_gpio_out(dev, i, qdev_get_gpio_in(cpu->gpio, spitz_gpio_key_sense[i]));
645
-
646
- for (i = 0; i < 5; i ++)
647
- s->gpiomap[i] = qdev_get_gpio_in(cpu->gpio, spitz_gpiomap[i]);
648
-
649
- if (!graphic_rotate)
650
- s->gpiomap[4] = qemu_irq_invert(s->gpiomap[4]);
651
-
652
- for (i = 0; i < 5; i++)
653
- qemu_set_irq(s->gpiomap[i], 0);
654
-
655
- for (i = 0; i < SPITZ_KEY_STROBE_NUM; i ++)
656
- qdev_connect_gpio_out(cpu->gpio, spitz_gpio_key_strobe[i],
657
- qdev_get_gpio_in(dev, i));
658
-
659
- timer_mod(s->kbdtimer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
660
-
661
- qemu_add_kbd_event_handler(spitz_keyboard_handler, s);
662
-}
663
-
664
-static void spitz_keyboard_init(Object *obj)
665
-{
666
- DeviceState *dev = DEVICE(obj);
667
- SpitzKeyboardState *s = SPITZ_KEYBOARD(obj);
668
- int i, j;
669
-
670
- for (i = 0; i < 0x80; i ++)
671
- s->keymap[i] = -1;
672
- for (i = 0; i < SPITZ_KEY_SENSE_NUM + 1; i ++)
673
- for (j = 0; j < SPITZ_KEY_STROBE_NUM; j ++)
674
- if (spitz_keymap[i][j] != -1)
675
- s->keymap[spitz_keymap[i][j]] = (i << 4) | j;
676
-
677
- spitz_keyboard_pre_map(s);
678
-
679
- qdev_init_gpio_in(dev, spitz_keyboard_strobe, SPITZ_KEY_STROBE_NUM);
680
- qdev_init_gpio_out(dev, s->sense, SPITZ_KEY_SENSE_NUM);
681
-}
682
-
683
-static void spitz_keyboard_realize(DeviceState *dev, Error **errp)
684
-{
685
- SpitzKeyboardState *s = SPITZ_KEYBOARD(dev);
686
- s->kbdtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, spitz_keyboard_tick, s);
687
-}
688
-
689
-/* LCD backlight controller */
690
-
691
-#define LCDTG_RESCTL 0x00
692
-#define LCDTG_PHACTRL 0x01
693
-#define LCDTG_DUTYCTRL 0x02
694
-#define LCDTG_POWERREG0 0x03
695
-#define LCDTG_POWERREG1 0x04
696
-#define LCDTG_GPOR3 0x05
697
-#define LCDTG_PICTRL 0x06
698
-#define LCDTG_POLCTRL 0x07
699
-
700
-#define TYPE_SPITZ_LCDTG "spitz-lcdtg"
701
-OBJECT_DECLARE_SIMPLE_TYPE(SpitzLCDTG, SPITZ_LCDTG)
702
-
703
-struct SpitzLCDTG {
704
- SSIPeripheral ssidev;
705
- uint32_t bl_intensity;
706
- uint32_t bl_power;
707
-};
708
-
709
-static void spitz_bl_update(SpitzLCDTG *s)
710
-{
711
- if (s->bl_power && s->bl_intensity)
712
- zaurus_printf("LCD Backlight now at %u/63\n", s->bl_intensity);
713
- else
714
- zaurus_printf("LCD Backlight now off\n");
715
-}
716
-
717
-static inline void spitz_bl_bit5(void *opaque, int line, int level)
718
-{
719
- SpitzLCDTG *s = opaque;
720
- int prev = s->bl_intensity;
721
-
722
- if (level)
723
- s->bl_intensity &= ~0x20;
724
- else
725
- s->bl_intensity |= 0x20;
726
-
727
- if (s->bl_power && prev != s->bl_intensity)
728
- spitz_bl_update(s);
729
-}
730
-
731
-static inline void spitz_bl_power(void *opaque, int line, int level)
732
-{
733
- SpitzLCDTG *s = opaque;
734
- s->bl_power = !!level;
735
- spitz_bl_update(s);
736
-}
737
-
738
-static uint32_t spitz_lcdtg_transfer(SSIPeripheral *dev, uint32_t value)
739
-{
740
- SpitzLCDTG *s = SPITZ_LCDTG(dev);
741
- int addr;
742
- addr = value >> 5;
743
- value &= 0x1f;
744
-
745
- switch (addr) {
746
- case LCDTG_RESCTL:
747
- if (value)
748
- zaurus_printf("LCD in QVGA mode\n");
749
- else
750
- zaurus_printf("LCD in VGA mode\n");
751
- break;
752
-
753
- case LCDTG_DUTYCTRL:
754
- s->bl_intensity &= ~0x1f;
755
- s->bl_intensity |= value;
756
- if (s->bl_power)
757
- spitz_bl_update(s);
758
- break;
759
-
760
- case LCDTG_POWERREG0:
761
- /* Set common voltage to M62332FP */
762
- break;
763
- }
764
- return 0;
765
-}
766
-
767
-static void spitz_lcdtg_realize(SSIPeripheral *ssi, Error **errp)
768
-{
769
- SpitzLCDTG *s = SPITZ_LCDTG(ssi);
770
- DeviceState *dev = DEVICE(s);
771
-
772
- s->bl_power = 0;
773
- s->bl_intensity = 0x20;
774
-
775
- qdev_init_gpio_in_named(dev, spitz_bl_bit5, "bl_bit5", 1);
776
- qdev_init_gpio_in_named(dev, spitz_bl_power, "bl_power", 1);
777
-}
778
-
779
-/* SSP devices */
780
-
781
-#define CORGI_SSP_PORT 2
782
-
783
-#define SPITZ_GPIO_LCDCON_CS 53
784
-#define SPITZ_GPIO_ADS7846_CS 14
785
-#define SPITZ_GPIO_MAX1111_CS 20
786
-#define SPITZ_GPIO_TP_INT 11
787
-
788
-#define TYPE_CORGI_SSP "corgi-ssp"
789
-OBJECT_DECLARE_SIMPLE_TYPE(CorgiSSPState, CORGI_SSP)
790
-
791
-/* "Demux" the signal based on current chipselect */
792
-struct CorgiSSPState {
793
- SSIPeripheral ssidev;
794
- SSIBus *bus[3];
795
- uint32_t enable[3];
796
-};
797
-
798
-static uint32_t corgi_ssp_transfer(SSIPeripheral *dev, uint32_t value)
799
-{
800
- CorgiSSPState *s = CORGI_SSP(dev);
801
- int i;
802
-
803
- for (i = 0; i < 3; i++) {
804
- if (s->enable[i]) {
805
- return ssi_transfer(s->bus[i], value);
806
- }
807
- }
808
- return 0;
809
-}
810
-
811
-static void corgi_ssp_gpio_cs(void *opaque, int line, int level)
812
-{
813
- CorgiSSPState *s = (CorgiSSPState *)opaque;
814
- assert(line >= 0 && line < 3);
815
- s->enable[line] = !level;
816
-}
817
-
818
-#define MAX1111_BATT_VOLT 1
819
-#define MAX1111_BATT_TEMP 2
820
-#define MAX1111_ACIN_VOLT 3
821
-
822
-#define SPITZ_BATTERY_TEMP 0xe0 /* About 2.9V */
823
-#define SPITZ_BATTERY_VOLT 0xd0 /* About 4.0V */
824
-#define SPITZ_CHARGEON_ACIN 0x80 /* About 5.0V */
825
-
826
-static void corgi_ssp_realize(SSIPeripheral *d, Error **errp)
827
-{
828
- DeviceState *dev = DEVICE(d);
829
- CorgiSSPState *s = CORGI_SSP(d);
830
-
831
- qdev_init_gpio_in(dev, corgi_ssp_gpio_cs, 3);
832
- s->bus[0] = ssi_create_bus(dev, "ssi0");
833
- s->bus[1] = ssi_create_bus(dev, "ssi1");
834
- s->bus[2] = ssi_create_bus(dev, "ssi2");
835
-}
836
-
837
-static void spitz_ssp_attach(SpitzMachineState *sms)
838
-{
839
- void *bus;
840
-
841
- sms->mux = ssi_create_peripheral(sms->mpu->ssp[CORGI_SSP_PORT - 1],
842
- TYPE_CORGI_SSP);
843
-
844
- bus = qdev_get_child_bus(sms->mux, "ssi0");
845
- sms->lcdtg = ssi_create_peripheral(bus, TYPE_SPITZ_LCDTG);
846
-
847
- bus = qdev_get_child_bus(sms->mux, "ssi1");
848
- sms->ads7846 = ssi_create_peripheral(bus, "ads7846");
849
- qdev_connect_gpio_out(sms->ads7846, 0,
850
- qdev_get_gpio_in(sms->mpu->gpio, SPITZ_GPIO_TP_INT));
851
-
852
- bus = qdev_get_child_bus(sms->mux, "ssi2");
853
- sms->max1111 = qdev_new(TYPE_MAX_1111);
854
- qdev_prop_set_uint8(sms->max1111, "input1" /* BATT_VOLT */,
855
- SPITZ_BATTERY_VOLT);
856
- qdev_prop_set_uint8(sms->max1111, "input2" /* BATT_TEMP */, 0);
857
- qdev_prop_set_uint8(sms->max1111, "input3" /* ACIN_VOLT */,
858
- SPITZ_CHARGEON_ACIN);
859
- ssi_realize_and_unref(sms->max1111, bus, &error_fatal);
860
-
861
- qdev_connect_gpio_out(sms->mpu->gpio, SPITZ_GPIO_LCDCON_CS,
862
- qdev_get_gpio_in(sms->mux, 0));
863
- qdev_connect_gpio_out(sms->mpu->gpio, SPITZ_GPIO_ADS7846_CS,
864
- qdev_get_gpio_in(sms->mux, 1));
865
- qdev_connect_gpio_out(sms->mpu->gpio, SPITZ_GPIO_MAX1111_CS,
866
- qdev_get_gpio_in(sms->mux, 2));
867
-}
868
-
869
-/* CF Microdrive */
870
-
871
-static void spitz_microdrive_attach(PXA2xxState *cpu, int slot)
872
-{
873
- PCMCIACardState *md;
874
- DriveInfo *dinfo;
875
-
876
- dinfo = drive_get(IF_IDE, 0, 0);
877
- if (!dinfo || dinfo->media_cd)
878
- return;
879
- md = dscm1xxxx_init(dinfo);
880
- pxa2xx_pcmcia_attach(cpu->pcmcia[slot], md);
881
-}
882
-
883
-/* Wm8750 and Max7310 on I2C */
884
-
885
-#define AKITA_MAX_ADDR 0x18
886
-#define SPITZ_WM_ADDRL 0x1b
887
-#define SPITZ_WM_ADDRH 0x1a
888
-
889
-#define SPITZ_GPIO_WM 5
890
-
891
-static void spitz_wm8750_addr(void *opaque, int line, int level)
892
-{
893
- I2CSlave *wm = (I2CSlave *) opaque;
894
- if (level)
895
- i2c_slave_set_address(wm, SPITZ_WM_ADDRH);
896
- else
897
- i2c_slave_set_address(wm, SPITZ_WM_ADDRL);
898
-}
899
-
900
-static void spitz_i2c_setup(MachineState *machine, PXA2xxState *cpu)
901
-{
902
- /* Attach the CPU on one end of our I2C bus. */
903
- I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
904
-
905
- /* Attach a WM8750 to the bus */
906
- I2CSlave *i2c_dev = i2c_slave_new(TYPE_WM8750, 0);
907
- DeviceState *wm = DEVICE(i2c_dev);
908
-
909
- if (machine->audiodev) {
910
- qdev_prop_set_string(wm, "audiodev", machine->audiodev);
911
- }
912
- i2c_slave_realize_and_unref(i2c_dev, bus, &error_abort);
913
-
914
- spitz_wm8750_addr(wm, 0, 0);
915
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_WM,
916
- qemu_allocate_irq(spitz_wm8750_addr, wm, 0));
917
- /* .. and to the sound interface. */
918
- cpu->i2s->opaque = wm;
919
- cpu->i2s->codec_out = wm8750_dac_dat;
920
- cpu->i2s->codec_in = wm8750_adc_dat;
921
- wm8750_data_req_set(wm, cpu->i2s->data_req, cpu->i2s);
922
-}
923
-
924
-static void spitz_akita_i2c_setup(PXA2xxState *cpu)
925
-{
926
- /* Attach a Max7310 to Akita I2C bus. */
927
- i2c_slave_create_simple(pxa2xx_i2c_bus(cpu->i2c[0]), "max7310",
928
- AKITA_MAX_ADDR);
929
-}
930
-
931
-/* Other peripherals */
932
-
933
-/*
934
- * Encapsulation of some miscellaneous GPIO line behaviour for the Spitz boards.
935
- *
936
- * QEMU interface:
937
- * + named GPIO inputs "green-led", "orange-led", "charging", "discharging":
938
- * these currently just print messages that the line has been signalled
939
- * + named GPIO input "adc-temp-on": set to cause the battery-temperature
940
- * value to be passed to the max111x ADC
941
- * + named GPIO output "adc-temp": the ADC value, to be wired up to the max111x
942
- */
943
-#define TYPE_SPITZ_MISC_GPIO "spitz-misc-gpio"
944
-OBJECT_DECLARE_SIMPLE_TYPE(SpitzMiscGPIOState, SPITZ_MISC_GPIO)
945
-
946
-struct SpitzMiscGPIOState {
947
- SysBusDevice parent_obj;
948
-
949
- qemu_irq adc_value;
950
-};
951
-
952
-static void spitz_misc_charging(void *opaque, int n, int level)
953
-{
954
- zaurus_printf("Charging %s.\n", level ? "off" : "on");
955
-}
956
-
957
-static void spitz_misc_discharging(void *opaque, int n, int level)
958
-{
959
- zaurus_printf("Discharging %s.\n", level ? "off" : "on");
960
-}
961
-
962
-static void spitz_misc_green_led(void *opaque, int n, int level)
963
-{
964
- zaurus_printf("Green LED %s.\n", level ? "off" : "on");
965
-}
966
-
967
-static void spitz_misc_orange_led(void *opaque, int n, int level)
968
-{
969
- zaurus_printf("Orange LED %s.\n", level ? "off" : "on");
970
-}
971
-
972
-static void spitz_misc_adc_temp(void *opaque, int n, int level)
973
-{
974
- SpitzMiscGPIOState *s = SPITZ_MISC_GPIO(opaque);
975
- int batt_temp = level ? SPITZ_BATTERY_TEMP : 0;
976
-
977
- qemu_set_irq(s->adc_value, batt_temp);
978
-}
979
-
980
-static void spitz_misc_gpio_init(Object *obj)
981
-{
982
- SpitzMiscGPIOState *s = SPITZ_MISC_GPIO(obj);
983
- DeviceState *dev = DEVICE(obj);
984
-
985
- qdev_init_gpio_in_named(dev, spitz_misc_charging, "charging", 1);
986
- qdev_init_gpio_in_named(dev, spitz_misc_discharging, "discharging", 1);
987
- qdev_init_gpio_in_named(dev, spitz_misc_green_led, "green-led", 1);
988
- qdev_init_gpio_in_named(dev, spitz_misc_orange_led, "orange-led", 1);
989
- qdev_init_gpio_in_named(dev, spitz_misc_adc_temp, "adc-temp-on", 1);
990
-
991
- qdev_init_gpio_out_named(dev, &s->adc_value, "adc-temp", 1);
992
-}
993
-
994
-#define SPITZ_SCP_LED_GREEN 1
995
-#define SPITZ_SCP_JK_B 2
996
-#define SPITZ_SCP_CHRG_ON 3
997
-#define SPITZ_SCP_MUTE_L 4
998
-#define SPITZ_SCP_MUTE_R 5
999
-#define SPITZ_SCP_CF_POWER 6
1000
-#define SPITZ_SCP_LED_ORANGE 7
1001
-#define SPITZ_SCP_JK_A 8
1002
-#define SPITZ_SCP_ADC_TEMP_ON 9
1003
-#define SPITZ_SCP2_IR_ON 1
1004
-#define SPITZ_SCP2_AKIN_PULLUP 2
1005
-#define SPITZ_SCP2_BACKLIGHT_CONT 7
1006
-#define SPITZ_SCP2_BACKLIGHT_ON 8
1007
-#define SPITZ_SCP2_MIC_BIAS 9
1008
-
1009
-static void spitz_scoop_gpio_setup(SpitzMachineState *sms)
1010
-{
1011
- DeviceState *miscdev = sysbus_create_simple(TYPE_SPITZ_MISC_GPIO, -1, NULL);
1012
-
1013
- sms->misc_gpio = miscdev;
1014
-
1015
- qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_CHRG_ON,
1016
- qdev_get_gpio_in_named(miscdev, "charging", 0));
1017
- qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_JK_B,
1018
- qdev_get_gpio_in_named(miscdev, "discharging", 0));
1019
- qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_LED_GREEN,
1020
- qdev_get_gpio_in_named(miscdev, "green-led", 0));
1021
- qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_LED_ORANGE,
1022
- qdev_get_gpio_in_named(miscdev, "orange-led", 0));
1023
- qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_ADC_TEMP_ON,
1024
- qdev_get_gpio_in_named(miscdev, "adc-temp-on", 0));
1025
- qdev_connect_gpio_out_named(miscdev, "adc-temp", 0,
1026
- qdev_get_gpio_in(sms->max1111, MAX1111_BATT_TEMP));
1027
-
1028
- if (sms->scp1) {
1029
- qdev_connect_gpio_out(sms->scp1, SPITZ_SCP2_BACKLIGHT_CONT,
1030
- qdev_get_gpio_in_named(sms->lcdtg, "bl_bit5", 0));
1031
- qdev_connect_gpio_out(sms->scp1, SPITZ_SCP2_BACKLIGHT_ON,
1032
- qdev_get_gpio_in_named(sms->lcdtg, "bl_power", 0));
1033
- }
1034
-}
1035
-
1036
-#define SPITZ_GPIO_HSYNC 22
1037
-#define SPITZ_GPIO_SD_DETECT 9
1038
-#define SPITZ_GPIO_SD_WP 81
1039
-#define SPITZ_GPIO_ON_RESET 89
1040
-#define SPITZ_GPIO_BAT_COVER 90
1041
-#define SPITZ_GPIO_CF1_IRQ 105
1042
-#define SPITZ_GPIO_CF1_CD 94
1043
-#define SPITZ_GPIO_CF2_IRQ 106
1044
-#define SPITZ_GPIO_CF2_CD 93
1045
-
1046
-static int spitz_hsync;
1047
-
1048
-static void spitz_lcd_hsync_handler(void *opaque, int line, int level)
1049
-{
1050
- PXA2xxState *cpu = (PXA2xxState *) opaque;
1051
- qemu_set_irq(qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_HSYNC), spitz_hsync);
1052
- spitz_hsync ^= 1;
1053
-}
1054
-
1055
-static void spitz_reset(void *opaque, int line, int level)
1056
-{
1057
- if (level) {
1058
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
1059
- }
1060
-}
1061
-
1062
-static void spitz_gpio_setup(PXA2xxState *cpu, int slots)
1063
-{
1064
- qemu_irq lcd_hsync;
1065
- qemu_irq reset;
1066
-
1067
- /*
1068
- * Bad hack: We toggle the LCD hsync GPIO on every GPIO status
1069
- * read to satisfy broken guests that poll-wait for hsync.
1070
- * Simulating a real hsync event would be less practical and
1071
- * wouldn't guarantee that a guest ever exits the loop.
1072
- */
1073
- spitz_hsync = 0;
1074
- lcd_hsync = qemu_allocate_irq(spitz_lcd_hsync_handler, cpu, 0);
1075
- pxa2xx_gpio_read_notifier(cpu->gpio, lcd_hsync);
1076
- pxa2xx_lcd_vsync_notifier(cpu->lcd, lcd_hsync);
1077
-
1078
- /* MMC/SD host */
1079
- pxa2xx_mmci_handlers(cpu->mmc,
1080
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_SD_WP),
1081
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_SD_DETECT));
1082
-
1083
- /* Battery lock always closed */
1084
- qemu_irq_raise(qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_BAT_COVER));
1085
-
1086
- /* Handle reset */
1087
- reset = qemu_allocate_irq(spitz_reset, cpu, 0);
1088
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_ON_RESET, reset);
1089
-
1090
- /* PCMCIA signals: card's IRQ and Card-Detect */
1091
- if (slots >= 1)
1092
- pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0],
1093
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_CF1_IRQ),
1094
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_CF1_CD));
1095
- if (slots >= 2)
1096
- pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[1],
1097
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_CF2_IRQ),
1098
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_CF2_CD));
1099
-}
1100
-
1101
-/* Board init. */
1102
-#define SPITZ_RAM 0x04000000
1103
-#define SPITZ_ROM 0x00800000
1104
-
1105
-static struct arm_boot_info spitz_binfo = {
1106
- .loader_start = PXA2XX_SDRAM_BASE,
1107
- .ram_size = 0x04000000,
1108
-};
1109
-
1110
-static void spitz_common_init(MachineState *machine)
1111
-{
1112
- SpitzMachineClass *smc = SPITZ_MACHINE_GET_CLASS(machine);
1113
- SpitzMachineState *sms = SPITZ_MACHINE(machine);
1114
- enum spitz_model_e model = smc->model;
1115
- PXA2xxState *mpu;
1116
- MemoryRegion *rom = g_new(MemoryRegion, 1);
1117
-
1118
- /* Setup CPU & memory */
1119
- mpu = pxa270_init(spitz_binfo.ram_size, machine->cpu_type);
1120
- sms->mpu = mpu;
1121
-
1122
- sl_flash_register(mpu, (model == spitz) ? FLASH_128M : FLASH_1024M);
1123
-
1124
- memory_region_init_rom(rom, NULL, "spitz.rom", SPITZ_ROM, &error_fatal);
1125
- memory_region_add_subregion(get_system_memory(), 0, rom);
1126
-
1127
- /* Setup peripherals */
1128
- spitz_keyboard_register(mpu);
1129
-
1130
- spitz_ssp_attach(sms);
1131
-
1132
- sms->scp0 = sysbus_create_simple("scoop", 0x10800000, NULL);
1133
- if (model != akita) {
1134
- sms->scp1 = sysbus_create_simple("scoop", 0x08800040, NULL);
1135
- } else {
1136
- sms->scp1 = NULL;
1137
- }
1138
-
1139
- spitz_scoop_gpio_setup(sms);
1140
-
1141
- spitz_gpio_setup(mpu, (model == akita) ? 1 : 2);
1142
-
1143
- spitz_i2c_setup(machine, mpu);
1144
-
1145
- if (model == akita)
1146
- spitz_akita_i2c_setup(mpu);
1147
-
1148
- if (model == terrier)
1149
- /* A 6.0 GB microdrive is permanently sitting in CF slot 1. */
1150
- spitz_microdrive_attach(mpu, 1);
1151
- else if (model != akita)
1152
- /* A 4.0 GB microdrive is permanently sitting in CF slot 0. */
1153
- spitz_microdrive_attach(mpu, 0);
1154
-
1155
- spitz_binfo.board_id = smc->arm_id;
1156
- arm_load_kernel(mpu->cpu, machine, &spitz_binfo);
1157
- sl_bootparam_write(SL_PXA_PARAM_BASE);
1158
-}
1159
-
1160
-static void spitz_common_class_init(ObjectClass *oc, void *data)
1161
-{
1162
- MachineClass *mc = MACHINE_CLASS(oc);
1163
-
1164
- mc->block_default_type = IF_IDE;
1165
- mc->ignore_memory_transaction_failures = true;
1166
- mc->init = spitz_common_init;
1167
- mc->deprecation_reason = "machine is old and unmaintained";
1168
-
1169
- machine_add_audiodev_property(mc);
1170
-}
1171
-
1172
-static const TypeInfo spitz_common_info = {
1173
- .name = TYPE_SPITZ_MACHINE,
1174
- .parent = TYPE_MACHINE,
1175
- .abstract = true,
1176
- .instance_size = sizeof(SpitzMachineState),
1177
- .class_size = sizeof(SpitzMachineClass),
1178
- .class_init = spitz_common_class_init,
1179
-};
1180
-
1181
-static void akitapda_class_init(ObjectClass *oc, void *data)
1182
-{
1183
- MachineClass *mc = MACHINE_CLASS(oc);
1184
- SpitzMachineClass *smc = SPITZ_MACHINE_CLASS(oc);
1185
-
1186
- mc->desc = "Sharp SL-C1000 (Akita) PDA (PXA270)";
1187
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
1188
- smc->model = akita;
1189
- smc->arm_id = 0x2e8;
1190
-}
1191
-
1192
-static const TypeInfo akitapda_type = {
1193
- .name = MACHINE_TYPE_NAME("akita"),
1194
- .parent = TYPE_SPITZ_MACHINE,
1195
- .class_init = akitapda_class_init,
1196
-};
1197
-
1198
-static void spitzpda_class_init(ObjectClass *oc, void *data)
1199
-{
1200
- MachineClass *mc = MACHINE_CLASS(oc);
1201
- SpitzMachineClass *smc = SPITZ_MACHINE_CLASS(oc);
1202
-
1203
- mc->desc = "Sharp SL-C3000 (Spitz) PDA (PXA270)";
1204
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
1205
- smc->model = spitz;
1206
- smc->arm_id = 0x2c9;
1207
-}
1208
-
1209
-static const TypeInfo spitzpda_type = {
1210
- .name = MACHINE_TYPE_NAME("spitz"),
1211
- .parent = TYPE_SPITZ_MACHINE,
1212
- .class_init = spitzpda_class_init,
1213
-};
1214
-
1215
-static void borzoipda_class_init(ObjectClass *oc, void *data)
1216
-{
1217
- MachineClass *mc = MACHINE_CLASS(oc);
1218
- SpitzMachineClass *smc = SPITZ_MACHINE_CLASS(oc);
1219
-
1220
- mc->desc = "Sharp SL-C3100 (Borzoi) PDA (PXA270)";
1221
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
1222
- smc->model = borzoi;
1223
- smc->arm_id = 0x33f;
1224
-}
1225
-
1226
-static const TypeInfo borzoipda_type = {
1227
- .name = MACHINE_TYPE_NAME("borzoi"),
1228
- .parent = TYPE_SPITZ_MACHINE,
1229
- .class_init = borzoipda_class_init,
1230
-};
1231
-
1232
-static void terrierpda_class_init(ObjectClass *oc, void *data)
1233
-{
1234
- MachineClass *mc = MACHINE_CLASS(oc);
1235
- SpitzMachineClass *smc = SPITZ_MACHINE_CLASS(oc);
1236
-
1237
- mc->desc = "Sharp SL-C3200 (Terrier) PDA (PXA270)";
1238
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c5");
1239
- smc->model = terrier;
1240
- smc->arm_id = 0x33f;
1241
-}
1242
-
1243
-static const TypeInfo terrierpda_type = {
1244
- .name = MACHINE_TYPE_NAME("terrier"),
1245
- .parent = TYPE_SPITZ_MACHINE,
1246
- .class_init = terrierpda_class_init,
1247
-};
1248
-
1249
-static void spitz_machine_init(void)
1250
-{
1251
- type_register_static(&spitz_common_info);
1252
- type_register_static(&akitapda_type);
1253
- type_register_static(&spitzpda_type);
1254
- type_register_static(&borzoipda_type);
1255
- type_register_static(&terrierpda_type);
1256
-}
1257
-
1258
-type_init(spitz_machine_init)
1259
-
1260
-static bool is_version_0(void *opaque, int version_id)
1261
-{
1262
- return version_id == 0;
1263
-}
1264
-
1265
-static const VMStateDescription vmstate_sl_nand_info = {
1266
- .name = "sl-nand",
1267
- .version_id = 0,
1268
- .minimum_version_id = 0,
1269
- .fields = (const VMStateField[]) {
1270
- VMSTATE_UINT8(ctl, SLNANDState),
1271
- VMSTATE_STRUCT(ecc, SLNANDState, 0, vmstate_ecc_state, ECCState),
1272
- VMSTATE_END_OF_LIST(),
1273
- },
1274
-};
1275
-
1276
-static Property sl_nand_properties[] = {
1277
- DEFINE_PROP_UINT8("manf_id", SLNANDState, manf_id, NAND_MFR_SAMSUNG),
1278
- DEFINE_PROP_UINT8("chip_id", SLNANDState, chip_id, 0xf1),
1279
- DEFINE_PROP_END_OF_LIST(),
1280
-};
1281
-
1282
-static void sl_nand_class_init(ObjectClass *klass, void *data)
1283
-{
1284
- DeviceClass *dc = DEVICE_CLASS(klass);
1285
-
1286
- dc->vmsd = &vmstate_sl_nand_info;
1287
- device_class_set_props(dc, sl_nand_properties);
1288
- dc->realize = sl_nand_realize;
1289
- /* Reason: init() method uses drive_get() */
1290
- dc->user_creatable = false;
1291
-}
1292
-
1293
-static const TypeInfo sl_nand_info = {
1294
- .name = TYPE_SL_NAND,
1295
- .parent = TYPE_SYS_BUS_DEVICE,
1296
- .instance_size = sizeof(SLNANDState),
1297
- .instance_init = sl_nand_init,
1298
- .class_init = sl_nand_class_init,
1299
-};
1300
-
1301
-static const VMStateDescription vmstate_spitz_kbd = {
1302
- .name = "spitz-keyboard",
1303
- .version_id = 1,
1304
- .minimum_version_id = 0,
1305
- .post_load = spitz_keyboard_post_load,
1306
- .fields = (const VMStateField[]) {
1307
- VMSTATE_UINT16(sense_state, SpitzKeyboardState),
1308
- VMSTATE_UINT16(strobe_state, SpitzKeyboardState),
1309
- VMSTATE_UNUSED_TEST(is_version_0, 5),
1310
- VMSTATE_END_OF_LIST(),
1311
- },
1312
-};
1313
-
1314
-static void spitz_keyboard_class_init(ObjectClass *klass, void *data)
1315
-{
1316
- DeviceClass *dc = DEVICE_CLASS(klass);
1317
-
1318
- dc->vmsd = &vmstate_spitz_kbd;
1319
- dc->realize = spitz_keyboard_realize;
1320
-}
1321
-
1322
-static const TypeInfo spitz_keyboard_info = {
1323
- .name = TYPE_SPITZ_KEYBOARD,
1324
- .parent = TYPE_SYS_BUS_DEVICE,
1325
- .instance_size = sizeof(SpitzKeyboardState),
1326
- .instance_init = spitz_keyboard_init,
1327
- .class_init = spitz_keyboard_class_init,
1328
-};
1329
-
1330
-static const VMStateDescription vmstate_corgi_ssp_regs = {
1331
- .name = "corgi-ssp",
1332
- .version_id = 2,
1333
- .minimum_version_id = 2,
1334
- .fields = (const VMStateField[]) {
1335
- VMSTATE_SSI_PERIPHERAL(ssidev, CorgiSSPState),
1336
- VMSTATE_UINT32_ARRAY(enable, CorgiSSPState, 3),
1337
- VMSTATE_END_OF_LIST(),
1338
- }
1339
-};
1340
-
1341
-static void corgi_ssp_class_init(ObjectClass *klass, void *data)
1342
-{
1343
- DeviceClass *dc = DEVICE_CLASS(klass);
1344
- SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
1345
-
1346
- k->realize = corgi_ssp_realize;
1347
- k->transfer = corgi_ssp_transfer;
1348
- dc->vmsd = &vmstate_corgi_ssp_regs;
1349
-}
1350
-
1351
-static const TypeInfo corgi_ssp_info = {
1352
- .name = TYPE_CORGI_SSP,
1353
- .parent = TYPE_SSI_PERIPHERAL,
1354
- .instance_size = sizeof(CorgiSSPState),
1355
- .class_init = corgi_ssp_class_init,
1356
-};
1357
-
1358
-static const VMStateDescription vmstate_spitz_lcdtg_regs = {
1359
- .name = "spitz-lcdtg",
1360
- .version_id = 1,
1361
- .minimum_version_id = 1,
1362
- .fields = (const VMStateField[]) {
1363
- VMSTATE_SSI_PERIPHERAL(ssidev, SpitzLCDTG),
1364
- VMSTATE_UINT32(bl_intensity, SpitzLCDTG),
1365
- VMSTATE_UINT32(bl_power, SpitzLCDTG),
1366
- VMSTATE_END_OF_LIST(),
1367
- }
1368
-};
1369
-
1370
-static void spitz_lcdtg_class_init(ObjectClass *klass, void *data)
1371
-{
1372
- DeviceClass *dc = DEVICE_CLASS(klass);
1373
- SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
1374
-
1375
- k->realize = spitz_lcdtg_realize;
1376
- k->transfer = spitz_lcdtg_transfer;
1377
- dc->vmsd = &vmstate_spitz_lcdtg_regs;
1378
-}
1379
-
1380
-static const TypeInfo spitz_lcdtg_info = {
1381
- .name = TYPE_SPITZ_LCDTG,
1382
- .parent = TYPE_SSI_PERIPHERAL,
1383
- .instance_size = sizeof(SpitzLCDTG),
1384
- .class_init = spitz_lcdtg_class_init,
1385
-};
1386
-
1387
-static const TypeInfo spitz_misc_gpio_info = {
1388
- .name = TYPE_SPITZ_MISC_GPIO,
1389
- .parent = TYPE_SYS_BUS_DEVICE,
1390
- .instance_size = sizeof(SpitzMiscGPIOState),
1391
- .instance_init = spitz_misc_gpio_init,
1392
- /*
1393
- * No class_init required: device has no internal state so does not
1394
- * need to set up reset or vmstate, and does not have a realize method.
1395
- */
1396
-};
1397
-
1398
-static void spitz_register_types(void)
1399
-{
1400
- type_register_static(&corgi_ssp_info);
1401
- type_register_static(&spitz_lcdtg_info);
1402
- type_register_static(&spitz_keyboard_info);
1403
- type_register_static(&sl_nand_info);
1404
- type_register_static(&spitz_misc_gpio_info);
1405
-}
1406
-
1407
-type_init(spitz_register_types)
1408
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
1409
deleted file mode 100644
1410
index XXXXXXX..XXXXXXX
1411
--- a/hw/arm/tosa.c
1412
+++ /dev/null
1413
@@ -XXX,XX +XXX,XX @@
1414
-/* vim:set shiftwidth=4 ts=4 et: */
1415
-/*
1416
- * PXA255 Sharp Zaurus SL-6000 PDA platform
1417
- *
1418
- * Copyright (c) 2008 Dmitry Baryshkov
1419
- *
1420
- * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org>
1421
- * This code is licensed under the GNU GPL v2.
1422
- *
1423
- * Contributions after 2012-01-13 are licensed under the terms of the
1424
- * GNU GPL, version 2 or (at your option) any later version.
1425
- */
1426
-
1427
-#include "qemu/osdep.h"
1428
-#include "qapi/error.h"
1429
-#include "sysemu/runstate.h"
1430
-#include "hw/arm/pxa.h"
1431
-#include "hw/arm/boot.h"
1432
-#include "hw/arm/sharpsl.h"
1433
-#include "hw/pcmcia.h"
1434
-#include "hw/boards.h"
1435
-#include "hw/display/tc6393xb.h"
1436
-#include "hw/i2c/i2c.h"
1437
-#include "hw/irq.h"
1438
-#include "hw/ssi/ssi.h"
1439
-#include "hw/sysbus.h"
1440
-#include "hw/misc/led.h"
1441
-#include "exec/address-spaces.h"
1442
-#include "qom/object.h"
1443
-
1444
-#define TOSA_RAM 0x04000000
1445
-#define TOSA_ROM 0x00800000
1446
-
1447
-#define TOSA_GPIO_USB_IN (5)
1448
-#define TOSA_GPIO_nSD_DETECT (9)
1449
-#define TOSA_GPIO_ON_RESET (19)
1450
-#define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */
1451
-#define TOSA_GPIO_CF_CD (13)
1452
-#define TOSA_GPIO_TC6393XB_INT (15)
1453
-#define TOSA_GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */
1454
-
1455
-#define TOSA_SCOOP_GPIO_BASE 1
1456
-#define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2)
1457
-#define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3)
1458
-#define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4)
1459
-
1460
-#define TOSA_SCOOP_JC_GPIO_BASE 1
1461
-#define TOSA_GPIO_BT_LED (TOSA_SCOOP_JC_GPIO_BASE + 0)
1462
-#define TOSA_GPIO_NOTE_LED (TOSA_SCOOP_JC_GPIO_BASE + 1)
1463
-#define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2)
1464
-#define TOSA_GPIO_TC6393XB_L3V_ON (TOSA_SCOOP_JC_GPIO_BASE + 5)
1465
-#define TOSA_GPIO_WLAN_LED (TOSA_SCOOP_JC_GPIO_BASE + 7)
1466
-
1467
-#define DAC_BASE 0x4e
1468
-#define DAC_CH1 0
1469
-#define DAC_CH2 1
1470
-
1471
-static void tosa_microdrive_attach(PXA2xxState *cpu)
1472
-{
1473
- PCMCIACardState *md;
1474
- DriveInfo *dinfo;
1475
-
1476
- dinfo = drive_get(IF_IDE, 0, 0);
1477
- if (!dinfo || dinfo->media_cd)
1478
- return;
1479
- md = dscm1xxxx_init(dinfo);
1480
- pxa2xx_pcmcia_attach(cpu->pcmcia[0], md);
1481
-}
1482
-
1483
-/*
1484
- * Encapsulation of some GPIO line behaviour for the Tosa board
1485
- *
1486
- * QEMU interface:
1487
- * + named GPIO inputs "leds[0..3]": assert to light LEDs
1488
- * + named GPIO input "reset": when asserted, resets the system
1489
- */
1490
-
1491
-#define TYPE_TOSA_MISC_GPIO "tosa-misc-gpio"
1492
-OBJECT_DECLARE_SIMPLE_TYPE(TosaMiscGPIOState, TOSA_MISC_GPIO)
1493
-
1494
-struct TosaMiscGPIOState {
1495
- SysBusDevice parent_obj;
1496
-};
1497
-
1498
-static void tosa_reset(void *opaque, int line, int level)
1499
-{
1500
- if (level) {
1501
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
1502
- }
1503
-}
1504
-
1505
-static void tosa_misc_gpio_init(Object *obj)
1506
-{
1507
- DeviceState *dev = DEVICE(obj);
1508
-
1509
- qdev_init_gpio_in_named(dev, tosa_reset, "reset", 1);
1510
-}
1511
-
1512
-static void tosa_gpio_setup(PXA2xxState *cpu,
1513
- DeviceState *scp0,
1514
- DeviceState *scp1,
1515
- TC6393xbState *tmio)
1516
-{
1517
- DeviceState *misc_gpio;
1518
- LEDState *led[4];
1519
-
1520
- misc_gpio = sysbus_create_simple(TYPE_TOSA_MISC_GPIO, -1, NULL);
1521
-
1522
- /* MMC/SD host */
1523
- pxa2xx_mmci_handlers(cpu->mmc,
1524
- qdev_get_gpio_in(scp0, TOSA_GPIO_SD_WP),
1525
- qemu_irq_invert(qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_nSD_DETECT)));
1526
-
1527
- /* Handle reset */
1528
- qdev_connect_gpio_out(cpu->gpio, TOSA_GPIO_ON_RESET,
1529
- qdev_get_gpio_in_named(misc_gpio, "reset", 0));
1530
-
1531
- /* PCMCIA signals: card's IRQ and Card-Detect */
1532
- pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0],
1533
- qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_CF_IRQ),
1534
- qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_CF_CD));
1535
-
1536
- pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[1],
1537
- qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_JC_CF_IRQ),
1538
- NULL);
1539
-
1540
- led[0] = led_create_simple(OBJECT(misc_gpio), GPIO_POLARITY_ACTIVE_HIGH,
1541
- LED_COLOR_BLUE, "bluetooth");
1542
- led[1] = led_create_simple(OBJECT(misc_gpio), GPIO_POLARITY_ACTIVE_HIGH,
1543
- LED_COLOR_GREEN, "note");
1544
- led[2] = led_create_simple(OBJECT(misc_gpio), GPIO_POLARITY_ACTIVE_HIGH,
1545
- LED_COLOR_AMBER, "charger-error");
1546
- led[3] = led_create_simple(OBJECT(misc_gpio), GPIO_POLARITY_ACTIVE_HIGH,
1547
- LED_COLOR_GREEN, "wlan");
1548
-
1549
- qdev_connect_gpio_out(scp1, TOSA_GPIO_BT_LED,
1550
- qdev_get_gpio_in(DEVICE(led[0]), 0));
1551
- qdev_connect_gpio_out(scp1, TOSA_GPIO_NOTE_LED,
1552
- qdev_get_gpio_in(DEVICE(led[1]), 0));
1553
- qdev_connect_gpio_out(scp1, TOSA_GPIO_CHRG_ERR_LED,
1554
- qdev_get_gpio_in(DEVICE(led[2]), 0));
1555
- qdev_connect_gpio_out(scp1, TOSA_GPIO_WLAN_LED,
1556
- qdev_get_gpio_in(DEVICE(led[3]), 0));
1557
-
1558
- qdev_connect_gpio_out(scp1, TOSA_GPIO_TC6393XB_L3V_ON, tc6393xb_l3v_get(tmio));
1559
-
1560
- /* UDC Vbus */
1561
- qemu_irq_raise(qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_USB_IN));
1562
-}
1563
-
1564
-static uint32_t tosa_ssp_tansfer(SSIPeripheral *dev, uint32_t value)
1565
-{
1566
- fprintf(stderr, "TG: %u %02x\n", value >> 5, value & 0x1f);
1567
- return 0;
1568
-}
1569
-
1570
-static void tosa_ssp_realize(SSIPeripheral *dev, Error **errp)
1571
-{
1572
- /* Nothing to do. */
1573
-}
1574
-
1575
-#define TYPE_TOSA_DAC "tosa_dac"
1576
-OBJECT_DECLARE_SIMPLE_TYPE(TosaDACState, TOSA_DAC)
1577
-
1578
-struct TosaDACState {
1579
- I2CSlave parent_obj;
1580
-
1581
- int len;
1582
- char buf[3];
1583
-};
1584
-
1585
-static int tosa_dac_send(I2CSlave *i2c, uint8_t data)
1586
-{
1587
- TosaDACState *s = TOSA_DAC(i2c);
1588
-
1589
- s->buf[s->len] = data;
1590
- if (s->len ++ > 2) {
1591
-#ifdef VERBOSE
1592
- fprintf(stderr, "%s: message too long (%i bytes)\n", __func__, s->len);
1593
-#endif
1594
- return 1;
1595
- }
1596
-
1597
- if (s->len == 2) {
1598
- fprintf(stderr, "dac: channel %d value 0x%02x\n",
1599
- s->buf[0], s->buf[1]);
1600
- }
1601
-
1602
- return 0;
1603
-}
1604
-
1605
-static int tosa_dac_event(I2CSlave *i2c, enum i2c_event event)
1606
-{
1607
- TosaDACState *s = TOSA_DAC(i2c);
1608
-
1609
- s->len = 0;
1610
- switch (event) {
1611
- case I2C_START_SEND:
1612
- break;
1613
- case I2C_START_RECV:
1614
- printf("%s: recv not supported!!!\n", __func__);
1615
- break;
1616
- case I2C_FINISH:
1617
-#ifdef VERBOSE
1618
- if (s->len < 2)
1619
- printf("%s: message too short (%i bytes)\n", __func__, s->len);
1620
- if (s->len > 2)
1621
- printf("%s: message too long\n", __func__);
1622
-#endif
1623
- break;
1624
- default:
1625
- break;
1626
- }
1627
-
1628
- return 0;
1629
-}
1630
-
1631
-static uint8_t tosa_dac_recv(I2CSlave *s)
1632
-{
1633
- printf("%s: recv not supported!!!\n", __func__);
1634
- return 0xff;
1635
-}
1636
-
1637
-static void tosa_tg_init(PXA2xxState *cpu)
1638
-{
1639
- I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
1640
- i2c_slave_create_simple(bus, TYPE_TOSA_DAC, DAC_BASE);
1641
- ssi_create_peripheral(cpu->ssp[1], "tosa-ssp");
1642
-}
1643
-
1644
-
1645
-static struct arm_boot_info tosa_binfo = {
1646
- .loader_start = PXA2XX_SDRAM_BASE,
1647
- .ram_size = 0x04000000,
1648
-};
1649
-
1650
-static void tosa_init(MachineState *machine)
1651
-{
1652
- MemoryRegion *address_space_mem = get_system_memory();
1653
- MemoryRegion *rom = g_new(MemoryRegion, 1);
1654
- PXA2xxState *mpu;
1655
- TC6393xbState *tmio;
1656
- DeviceState *scp0, *scp1;
1657
-
1658
- mpu = pxa255_init(tosa_binfo.ram_size);
1659
-
1660
- memory_region_init_rom(rom, NULL, "tosa.rom", TOSA_ROM, &error_fatal);
1661
- memory_region_add_subregion(address_space_mem, 0, rom);
1662
-
1663
- tmio = tc6393xb_init(address_space_mem, 0x10000000,
1664
- qdev_get_gpio_in(mpu->gpio, TOSA_GPIO_TC6393XB_INT));
1665
-
1666
- scp0 = sysbus_create_simple("scoop", 0x08800000, NULL);
1667
- scp1 = sysbus_create_simple("scoop", 0x14800040, NULL);
1668
-
1669
- tosa_gpio_setup(mpu, scp0, scp1, tmio);
1670
-
1671
- tosa_microdrive_attach(mpu);
1672
-
1673
- tosa_tg_init(mpu);
1674
-
1675
- tosa_binfo.board_id = 0x208;
1676
- arm_load_kernel(mpu->cpu, machine, &tosa_binfo);
1677
- sl_bootparam_write(SL_PXA_PARAM_BASE);
1678
-}
1679
-
1680
-static void tosapda_machine_init(MachineClass *mc)
1681
-{
1682
- mc->desc = "Sharp SL-6000 (Tosa) PDA (PXA255)";
1683
- mc->init = tosa_init;
1684
- mc->block_default_type = IF_IDE;
1685
- mc->ignore_memory_transaction_failures = true;
1686
- mc->deprecation_reason = "machine is old and unmaintained";
1687
-}
1688
-
1689
-DEFINE_MACHINE("tosa", tosapda_machine_init)
1690
-
1691
-static void tosa_dac_class_init(ObjectClass *klass, void *data)
1692
-{
1693
- I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
1694
-
1695
- k->event = tosa_dac_event;
1696
- k->recv = tosa_dac_recv;
1697
- k->send = tosa_dac_send;
1698
-}
1699
-
1700
-static const TypeInfo tosa_dac_info = {
1701
- .name = TYPE_TOSA_DAC,
1702
- .parent = TYPE_I2C_SLAVE,
1703
- .instance_size = sizeof(TosaDACState),
1704
- .class_init = tosa_dac_class_init,
1705
-};
1706
-
1707
-static void tosa_ssp_class_init(ObjectClass *klass, void *data)
1708
-{
1709
- SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
1710
-
1711
- k->realize = tosa_ssp_realize;
1712
- k->transfer = tosa_ssp_tansfer;
1713
-}
1714
-
1715
-static const TypeInfo tosa_ssp_info = {
1716
- .name = "tosa-ssp",
1717
- .parent = TYPE_SSI_PERIPHERAL,
1718
- .instance_size = sizeof(SSIPeripheral),
1719
- .class_init = tosa_ssp_class_init,
1720
-};
1721
-
1722
-static const TypeInfo tosa_misc_gpio_info = {
1723
- .name = TYPE_TOSA_MISC_GPIO,
1724
- .parent = TYPE_SYS_BUS_DEVICE,
1725
- .instance_size = sizeof(TosaMiscGPIOState),
1726
- .instance_init = tosa_misc_gpio_init,
1727
- /*
1728
- * No class init required: device has no internal state so does not
1729
- * need to set up reset or vmstate, and has no realize method.
1730
- */
1731
-};
1732
-
1733
-static void tosa_register_types(void)
1734
-{
1735
- type_register_static(&tosa_dac_info);
1736
- type_register_static(&tosa_ssp_info);
1737
- type_register_static(&tosa_misc_gpio_info);
1738
-}
1739
-
1740
-type_init(tosa_register_types)
1741
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
1742
index XXXXXXX..XXXXXXX 100644
1743
--- a/hw/arm/Kconfig
1744
+++ b/hw/arm/Kconfig
1745
@@ -XXX,XX +XXX,XX @@ config GUMSTIX
1746
select SMC91C111
1747
select PXA2XX
1748
1749
-config TOSA
1750
- bool
1751
- default y
1752
- depends on TCG && ARM
1753
- select ZAURUS # scoop
1754
- select MICRODRIVE
1755
- select PXA2XX
1756
- select LED
1757
-
1758
-config SPITZ
1759
- bool
1760
- default y
1761
- depends on TCG && ARM
1762
- select ADS7846 # touch-screen controller
1763
- select MAX111X # A/D converter
1764
- select WM8750 # audio codec
1765
- select MAX7310 # GPIO expander
1766
- select ZAURUS # scoop
1767
- select NAND # memory
1768
- select ECC # Error-correcting for NAND
1769
- select MICRODRIVE
1770
- select PXA2XX
1771
-
1772
config Z2
1773
bool
1774
default y
1775
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
1776
index XXXXXXX..XXXXXXX 100644
1777
--- a/hw/arm/meson.build
1778
+++ b/hw/arm/meson.build
1779
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_NETDUINO2', if_true: files('netduino2.c'))
1780
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap2.c'))
1781
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_peripherals.c'))
1782
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2838_peripherals.c'))
1783
-system_ss.add(when: 'CONFIG_SPITZ', if_true: files('spitz.c'))
1784
system_ss.add(when: 'CONFIG_STRONGARM', if_true: files('strongarm.c'))
1785
system_ss.add(when: 'CONFIG_SX1', if_true: files('omap_sx1.c'))
1786
-system_ss.add(when: 'CONFIG_TOSA', if_true: files('tosa.c'))
1787
system_ss.add(when: 'CONFIG_VERSATILE', if_true: files('versatilepb.c'))
1788
system_ss.add(when: 'CONFIG_VEXPRESS', if_true: files('vexpress.c'))
1789
system_ss.add(when: 'CONFIG_Z2', if_true: files('z2.c'))
1790
--
45
--
1791
2.34.1
46
2.34.1
1792
1793
diff view generated by jsdifflib
1
The omap_dma4 device was only used in the OMAP2 SoC, which has
1
Set the Float3NaNPropRule explicitly for i386. We had no
2
been removed.
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.
3
5
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241202131347.498124-25-peter.maydell@linaro.org
7
Message-id: 20240903160751.4100218-53-peter.maydell@linaro.org
8
---
9
---
9
include/hw/arm/omap.h | 1 -
10
target/i386/tcg/fpu_helper.c | 1 +
10
hw/dma/omap_dma.c | 451 +-----------------------------------------
11
1 file changed, 1 insertion(+)
11
2 files changed, 3 insertions(+), 449 deletions(-)
12
12
13
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
13
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/omap.h
15
--- a/target/i386/tcg/fpu_helper.c
16
+++ b/include/hw/arm/omap.h
16
+++ b/target/i386/tcg/fpu_helper.c
17
@@ -XXX,XX +XXX,XX @@ enum omap_dma_model {
17
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
18
omap_dma_3_0,
18
* there are multiple input NaNs they are selected in the order a, b, c.
19
omap_dma_3_1,
19
*/
20
omap_dma_3_2,
20
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
21
- omap_dma_4,
21
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
22
};
23
24
struct soc_dma_s;
25
diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/dma/omap_dma.c
28
+++ b/hw/dma/omap_dma.c
29
@@ -XXX,XX +XXX,XX @@ void omap_dma_reset(struct soc_dma_s *dma)
30
struct omap_dma_s *s = dma->opaque;
31
32
soc_dma_reset(s->dma);
33
- if (s->model < omap_dma_4)
34
- s->gcr = 0x0004;
35
- else
36
- s->gcr = 0x00010010;
37
+ s->gcr = 0x0004;
38
s->ocp = 0x00000000;
39
memset(&s->irqstat, 0, sizeof(s->irqstat));
40
memset(&s->irqen, 0, sizeof(s->irqen));
41
@@ -XXX,XX +XXX,XX @@ void omap_dma_reset(struct soc_dma_s *dma)
42
s->lcd_ch.condition = 0;
43
s->lcd_ch.interrupts = 0;
44
s->lcd_ch.dual = 0;
45
- if (s->model < omap_dma_4)
46
- omap_dma_enable_3_1_mapping(s);
47
+ omap_dma_enable_3_1_mapping(s);
48
for (i = 0; i < s->chans; i ++) {
49
s->ch[i].suspend = 0;
50
s->ch[i].prefetch = 0;
51
@@ -XXX,XX +XXX,XX @@ void omap_dma_reset(struct soc_dma_s *dma)
52
s->ch[i].repeat = 0;
53
s->ch[i].auto_init = 0;
54
s->ch[i].link_enabled = 0;
55
- if (s->model < omap_dma_4)
56
- s->ch[i].interrupts = 0x0003;
57
- else
58
- s->ch[i].interrupts = 0x0000;
59
+ s->ch[i].interrupts = 0x0003;
60
s->ch[i].status = 0;
61
s->ch[i].cstatus = 0;
62
s->ch[i].active = 0;
63
@@ -XXX,XX +XXX,XX @@ static void omap_dma_setcaps(struct omap_dma_s *s)
64
case omap_dma_3_1:
65
break;
66
case omap_dma_3_2:
67
- case omap_dma_4:
68
/* XXX Only available for sDMA */
69
s->caps[0] =
70
(1 << 19) |    /* Constant Fill Capability */
71
@@ -XXX,XX +XXX,XX @@ struct soc_dma_s *omap_dma_init(hwaddr base, qemu_irq *irqs,
72
return s->dma;
73
}
22
}
74
23
75
-static void omap_dma_interrupts_4_update(struct omap_dma_s *s)
24
static inline uint8_t save_exception_flags(CPUX86State *env)
76
-{
77
- struct omap_dma_channel_s *ch = s->ch;
78
- uint32_t bmp, bit;
79
-
80
- for (bmp = 0, bit = 1; bit; ch ++, bit <<= 1)
81
- if (ch->status) {
82
- bmp |= bit;
83
- ch->cstatus |= ch->status;
84
- ch->status = 0;
85
- }
86
- if ((s->irqstat[0] |= s->irqen[0] & bmp))
87
- qemu_irq_raise(s->irq[0]);
88
- if ((s->irqstat[1] |= s->irqen[1] & bmp))
89
- qemu_irq_raise(s->irq[1]);
90
- if ((s->irqstat[2] |= s->irqen[2] & bmp))
91
- qemu_irq_raise(s->irq[2]);
92
- if ((s->irqstat[3] |= s->irqen[3] & bmp))
93
- qemu_irq_raise(s->irq[3]);
94
-}
95
-
96
-static uint64_t omap_dma4_read(void *opaque, hwaddr addr,
97
- unsigned size)
98
-{
99
- struct omap_dma_s *s = opaque;
100
- int irqn = 0, chnum;
101
- struct omap_dma_channel_s *ch;
102
-
103
- if (size == 1) {
104
- return omap_badwidth_read16(opaque, addr);
105
- }
106
-
107
- switch (addr) {
108
- case 0x00:    /* DMA4_REVISION */
109
- return 0x40;
110
-
111
- case 0x14:    /* DMA4_IRQSTATUS_L3 */
112
- irqn ++;
113
- /* fall through */
114
- case 0x10:    /* DMA4_IRQSTATUS_L2 */
115
- irqn ++;
116
- /* fall through */
117
- case 0x0c:    /* DMA4_IRQSTATUS_L1 */
118
- irqn ++;
119
- /* fall through */
120
- case 0x08:    /* DMA4_IRQSTATUS_L0 */
121
- return s->irqstat[irqn];
122
-
123
- case 0x24:    /* DMA4_IRQENABLE_L3 */
124
- irqn ++;
125
- /* fall through */
126
- case 0x20:    /* DMA4_IRQENABLE_L2 */
127
- irqn ++;
128
- /* fall through */
129
- case 0x1c:    /* DMA4_IRQENABLE_L1 */
130
- irqn ++;
131
- /* fall through */
132
- case 0x18:    /* DMA4_IRQENABLE_L0 */
133
- return s->irqen[irqn];
134
-
135
- case 0x28:    /* DMA4_SYSSTATUS */
136
- return 1;                        /* RESETDONE */
137
-
138
- case 0x2c:    /* DMA4_OCP_SYSCONFIG */
139
- return s->ocp;
140
-
141
- case 0x64:    /* DMA4_CAPS_0 */
142
- return s->caps[0];
143
- case 0x6c:    /* DMA4_CAPS_2 */
144
- return s->caps[2];
145
- case 0x70:    /* DMA4_CAPS_3 */
146
- return s->caps[3];
147
- case 0x74:    /* DMA4_CAPS_4 */
148
- return s->caps[4];
149
-
150
- case 0x78:    /* DMA4_GCR */
151
- return s->gcr;
152
-
153
- case 0x80 ... 0xfff:
154
- addr -= 0x80;
155
- chnum = addr / 0x60;
156
- ch = s->ch + chnum;
157
- addr -= chnum * 0x60;
158
- break;
159
-
160
- default:
161
- OMAP_BAD_REG(addr);
162
- return 0;
163
- }
164
-
165
- /* Per-channel registers */
166
- switch (addr) {
167
- case 0x00:    /* DMA4_CCR */
168
- return (ch->buf_disable << 25) |
169
- (ch->src_sync << 24) |
170
- (ch->prefetch << 23) |
171
- ((ch->sync & 0x60) << 14) |
172
- (ch->bs << 18) |
173
- (ch->transparent_copy << 17) |
174
- (ch->constant_fill << 16) |
175
- (ch->mode[1] << 14) |
176
- (ch->mode[0] << 12) |
177
- (0 << 10) | (0 << 9) |
178
- (ch->suspend << 8) |
179
- (ch->enable << 7) |
180
- (ch->priority << 6) |
181
- (ch->fs << 5) | (ch->sync & 0x1f);
182
-
183
- case 0x04:    /* DMA4_CLNK_CTRL */
184
- return (ch->link_enabled << 15) | ch->link_next_ch;
185
-
186
- case 0x08:    /* DMA4_CICR */
187
- return ch->interrupts;
188
-
189
- case 0x0c:    /* DMA4_CSR */
190
- return ch->cstatus;
191
-
192
- case 0x10:    /* DMA4_CSDP */
193
- return (ch->endian[0] << 21) |
194
- (ch->endian_lock[0] << 20) |
195
- (ch->endian[1] << 19) |
196
- (ch->endian_lock[1] << 18) |
197
- (ch->write_mode << 16) |
198
- (ch->burst[1] << 14) |
199
- (ch->pack[1] << 13) |
200
- (ch->translate[1] << 9) |
201
- (ch->burst[0] << 7) |
202
- (ch->pack[0] << 6) |
203
- (ch->translate[0] << 2) |
204
- (ch->data_type >> 1);
205
-
206
- case 0x14:    /* DMA4_CEN */
207
- return ch->elements;
208
-
209
- case 0x18:    /* DMA4_CFN */
210
- return ch->frames;
211
-
212
- case 0x1c:    /* DMA4_CSSA */
213
- return ch->addr[0];
214
-
215
- case 0x20:    /* DMA4_CDSA */
216
- return ch->addr[1];
217
-
218
- case 0x24:    /* DMA4_CSEI */
219
- return ch->element_index[0];
220
-
221
- case 0x28:    /* DMA4_CSFI */
222
- return ch->frame_index[0];
223
-
224
- case 0x2c:    /* DMA4_CDEI */
225
- return ch->element_index[1];
226
-
227
- case 0x30:    /* DMA4_CDFI */
228
- return ch->frame_index[1];
229
-
230
- case 0x34:    /* DMA4_CSAC */
231
- return ch->active_set.src & 0xffff;
232
-
233
- case 0x38:    /* DMA4_CDAC */
234
- return ch->active_set.dest & 0xffff;
235
-
236
- case 0x3c:    /* DMA4_CCEN */
237
- return ch->active_set.element;
238
-
239
- case 0x40:    /* DMA4_CCFN */
240
- return ch->active_set.frame;
241
-
242
- case 0x44:    /* DMA4_COLOR */
243
- /* XXX only in sDMA */
244
- return ch->color;
245
-
246
- default:
247
- OMAP_BAD_REG(addr);
248
- return 0;
249
- }
250
-}
251
-
252
-static void omap_dma4_write(void *opaque, hwaddr addr,
253
- uint64_t value, unsigned size)
254
-{
255
- struct omap_dma_s *s = opaque;
256
- int chnum, irqn = 0;
257
- struct omap_dma_channel_s *ch;
258
-
259
- if (size == 1) {
260
- omap_badwidth_write16(opaque, addr, value);
261
- return;
262
- }
263
-
264
- switch (addr) {
265
- case 0x14:    /* DMA4_IRQSTATUS_L3 */
266
- irqn ++;
267
- /* fall through */
268
- case 0x10:    /* DMA4_IRQSTATUS_L2 */
269
- irqn ++;
270
- /* fall through */
271
- case 0x0c:    /* DMA4_IRQSTATUS_L1 */
272
- irqn ++;
273
- /* fall through */
274
- case 0x08:    /* DMA4_IRQSTATUS_L0 */
275
- s->irqstat[irqn] &= ~value;
276
- if (!s->irqstat[irqn])
277
- qemu_irq_lower(s->irq[irqn]);
278
- return;
279
-
280
- case 0x24:    /* DMA4_IRQENABLE_L3 */
281
- irqn ++;
282
- /* fall through */
283
- case 0x20:    /* DMA4_IRQENABLE_L2 */
284
- irqn ++;
285
- /* fall through */
286
- case 0x1c:    /* DMA4_IRQENABLE_L1 */
287
- irqn ++;
288
- /* fall through */
289
- case 0x18:    /* DMA4_IRQENABLE_L0 */
290
- s->irqen[irqn] = value;
291
- return;
292
-
293
- case 0x2c:    /* DMA4_OCP_SYSCONFIG */
294
- if (value & 2)                        /* SOFTRESET */
295
- omap_dma_reset(s->dma);
296
- s->ocp = value & 0x3321;
297
- if (((s->ocp >> 12) & 3) == 3) { /* MIDLEMODE */
298
- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid DMA power mode\n",
299
- __func__);
300
- }
301
- return;
302
-
303
- case 0x78:    /* DMA4_GCR */
304
- s->gcr = value & 0x00ff00ff;
305
- if ((value & 0xff) == 0x00) { /* MAX_CHANNEL_FIFO_DEPTH */
306
- qemu_log_mask(LOG_GUEST_ERROR, "%s: wrong FIFO depth in GCR\n",
307
- __func__);
308
- }
309
- return;
310
-
311
- case 0x80 ... 0xfff:
312
- addr -= 0x80;
313
- chnum = addr / 0x60;
314
- ch = s->ch + chnum;
315
- addr -= chnum * 0x60;
316
- break;
317
-
318
- case 0x00:    /* DMA4_REVISION */
319
- case 0x28:    /* DMA4_SYSSTATUS */
320
- case 0x64:    /* DMA4_CAPS_0 */
321
- case 0x6c:    /* DMA4_CAPS_2 */
322
- case 0x70:    /* DMA4_CAPS_3 */
323
- case 0x74:    /* DMA4_CAPS_4 */
324
- OMAP_RO_REG(addr);
325
- return;
326
-
327
- default:
328
- OMAP_BAD_REG(addr);
329
- return;
330
- }
331
-
332
- /* Per-channel registers */
333
- switch (addr) {
334
- case 0x00:    /* DMA4_CCR */
335
- ch->buf_disable = (value >> 25) & 1;
336
- ch->src_sync = (value >> 24) & 1;    /* XXX For CamDMA must be 1 */
337
- if (ch->buf_disable && !ch->src_sync) {
338
- qemu_log_mask(LOG_GUEST_ERROR,
339
- "%s: Buffering disable is not allowed in "
340
- "destination synchronised mode\n", __func__);
341
- }
342
- ch->prefetch = (value >> 23) & 1;
343
- ch->bs = (value >> 18) & 1;
344
- ch->transparent_copy = (value >> 17) & 1;
345
- ch->constant_fill = (value >> 16) & 1;
346
- ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
347
- ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
348
- ch->suspend = (value & 0x0100) >> 8;
349
- ch->priority = (value & 0x0040) >> 6;
350
- ch->fs = (value & 0x0020) >> 5;
351
- if (ch->fs && ch->bs && ch->mode[0] && ch->mode[1]) {
352
- qemu_log_mask(LOG_GUEST_ERROR,
353
- "%s: For a packet transfer at least one port "
354
- "must be constant-addressed\n", __func__);
355
- }
356
- ch->sync = (value & 0x001f) | ((value >> 14) & 0x0060);
357
- /* XXX must be 0x01 for CamDMA */
358
-
359
- if (value & 0x0080)
360
- omap_dma_enable_channel(s, ch);
361
- else
362
- omap_dma_disable_channel(s, ch);
363
-
364
- break;
365
-
366
- case 0x04:    /* DMA4_CLNK_CTRL */
367
- ch->link_enabled = (value >> 15) & 0x1;
368
- ch->link_next_ch = value & 0x1f;
369
- break;
370
-
371
- case 0x08:    /* DMA4_CICR */
372
- ch->interrupts = value & 0x09be;
373
- break;
374
-
375
- case 0x0c:    /* DMA4_CSR */
376
- ch->cstatus &= ~value;
377
- break;
378
-
379
- case 0x10:    /* DMA4_CSDP */
380
- ch->endian[0] =(value >> 21) & 1;
381
- ch->endian_lock[0] =(value >> 20) & 1;
382
- ch->endian[1] =(value >> 19) & 1;
383
- ch->endian_lock[1] =(value >> 18) & 1;
384
- if (ch->endian[0] != ch->endian[1]) {
385
- qemu_log_mask(LOG_GUEST_ERROR,
386
- "%s: DMA endianness conversion enable attempt\n",
387
- __func__);
388
- }
389
- ch->write_mode = (value >> 16) & 3;
390
- ch->burst[1] = (value & 0xc000) >> 14;
391
- ch->pack[1] = (value & 0x2000) >> 13;
392
- ch->translate[1] = (value & 0x1e00) >> 9;
393
- ch->burst[0] = (value & 0x0180) >> 7;
394
- ch->pack[0] = (value & 0x0040) >> 6;
395
- ch->translate[0] = (value & 0x003c) >> 2;
396
- if (ch->translate[0] | ch->translate[1]) {
397
- qemu_log_mask(LOG_GUEST_ERROR,
398
- "%s: bad MReqAddressTranslate sideband signal\n",
399
- __func__);
400
- }
401
- ch->data_type = 1 << (value & 3);
402
- if ((value & 3) == 3) {
403
- qemu_log_mask(LOG_GUEST_ERROR,
404
- "%s: bad data_type for DMA channel\n", __func__);
405
- ch->data_type >>= 1;
406
- }
407
- break;
408
-
409
- case 0x14:    /* DMA4_CEN */
410
- ch->set_update = 1;
411
- ch->elements = value & 0xffffff;
412
- break;
413
-
414
- case 0x18:    /* DMA4_CFN */
415
- ch->frames = value & 0xffff;
416
- ch->set_update = 1;
417
- break;
418
-
419
- case 0x1c:    /* DMA4_CSSA */
420
- ch->addr[0] = (hwaddr) (uint32_t) value;
421
- ch->set_update = 1;
422
- break;
423
-
424
- case 0x20:    /* DMA4_CDSA */
425
- ch->addr[1] = (hwaddr) (uint32_t) value;
426
- ch->set_update = 1;
427
- break;
428
-
429
- case 0x24:    /* DMA4_CSEI */
430
- ch->element_index[0] = (int16_t) value;
431
- ch->set_update = 1;
432
- break;
433
-
434
- case 0x28:    /* DMA4_CSFI */
435
- ch->frame_index[0] = (int32_t) value;
436
- ch->set_update = 1;
437
- break;
438
-
439
- case 0x2c:    /* DMA4_CDEI */
440
- ch->element_index[1] = (int16_t) value;
441
- ch->set_update = 1;
442
- break;
443
-
444
- case 0x30:    /* DMA4_CDFI */
445
- ch->frame_index[1] = (int32_t) value;
446
- ch->set_update = 1;
447
- break;
448
-
449
- case 0x44:    /* DMA4_COLOR */
450
- /* XXX only in sDMA */
451
- ch->color = value;
452
- break;
453
-
454
- case 0x34:    /* DMA4_CSAC */
455
- case 0x38:    /* DMA4_CDAC */
456
- case 0x3c:    /* DMA4_CCEN */
457
- case 0x40:    /* DMA4_CCFN */
458
- OMAP_RO_REG(addr);
459
- break;
460
-
461
- default:
462
- OMAP_BAD_REG(addr);
463
- }
464
-}
465
-
466
-static const MemoryRegionOps omap_dma4_ops = {
467
- .read = omap_dma4_read,
468
- .write = omap_dma4_write,
469
- .endianness = DEVICE_NATIVE_ENDIAN,
470
-};
471
-
472
-struct soc_dma_s *omap_dma4_init(hwaddr base, qemu_irq *irqs,
473
- MemoryRegion *sysmem,
474
- struct omap_mpu_state_s *mpu, int fifo,
475
- int chans, omap_clk iclk, omap_clk fclk)
476
-{
477
- int i;
478
- struct omap_dma_s *s = g_new0(struct omap_dma_s, 1);
479
-
480
- s->model = omap_dma_4;
481
- s->chans = chans;
482
- s->mpu = mpu;
483
- s->clk = fclk;
484
-
485
- s->dma = soc_dma_init(s->chans);
486
- s->dma->freq = omap_clk_getrate(fclk);
487
- s->dma->transfer_fn = omap_dma_transfer_generic;
488
- s->dma->setup_fn = omap_dma_transfer_setup;
489
- s->dma->drq = qemu_allocate_irqs(omap_dma_request, s, 64);
490
- s->dma->opaque = s;
491
- for (i = 0; i < s->chans; i ++) {
492
- s->ch[i].dma = &s->dma->ch[i];
493
- s->dma->ch[i].opaque = &s->ch[i];
494
- }
495
-
496
- memcpy(&s->irq, irqs, sizeof(s->irq));
497
- s->intr_update = omap_dma_interrupts_4_update;
498
-
499
- omap_dma_setcaps(s);
500
- omap_clk_adduser(s->clk, qemu_allocate_irq(omap_dma_clk_update, s, 0));
501
- omap_dma_reset(s->dma);
502
- omap_dma_clk_update(s, 0, !!s->dma->freq);
503
-
504
- memory_region_init_io(&s->iomem, NULL, &omap_dma4_ops, s, "omap.dma4", 0x1000);
505
- memory_region_add_subregion(sysmem, base, &s->iomem);
506
-
507
- mpu->drq = s->dma->drq;
508
-
509
- return s->dma;
510
-}
511
-
512
struct omap_dma_lcd_channel_s *omap_dma_get_lcdch(struct soc_dma_s *dma)
513
{
514
struct omap_dma_s *s = dma->opaque;
515
--
25
--
516
2.34.1
26
2.34.1
517
518
diff view generated by jsdifflib
1
The omap_mcspi device is used only in the OMAP2 SoC, which we
1
Set the Float3NaNPropRule explicitly for HPPA, and remove the
2
are removing.
2
ifdef from pickNaNMulAdd().
3
4
HPPA is the only target that was using the default branch of the
5
ifdef ladder (other targets either do not use muladd or set
6
default_nan_mode), so we can remove the ifdef fallback entirely now
7
(allowing the "rule not set" case to fall into the default of the
8
switch statement and assert).
9
10
We add a TODO note that the HPPA rule is probably wrong; this is
11
not a behavioural change for this refactoring.
3
12
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240903160751.4100218-48-peter.maydell@linaro.org
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-26-peter.maydell@linaro.org
6
---
16
---
7
include/hw/arm/omap.h | 11 --
17
target/hppa/fpu_helper.c | 8 ++++++++
8
hw/ssi/omap_spi.c | 380 ------------------------------------------
18
fpu/softfloat-specialize.c.inc | 4 ----
9
hw/ssi/meson.build | 1 -
19
2 files changed, 8 insertions(+), 4 deletions(-)
10
3 files changed, 392 deletions(-)
11
delete mode 100644 hw/ssi/omap_spi.c
12
20
13
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
21
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/omap.h
23
--- a/target/hppa/fpu_helper.c
16
+++ b/include/hw/arm/omap.h
24
+++ b/target/hppa/fpu_helper.c
17
@@ -XXX,XX +XXX,XX @@ struct omap_uwire_s;
25
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
18
void omap_uwire_attach(struct omap_uwire_s *s,
26
* HPPA does note implement a CPU reset method at all...
19
uWireSlave *slave, int chipselect);
27
*/
20
28
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
21
-/* OMAP2 spi */
29
+ /*
22
-struct omap_mcspi_s;
30
+ * TODO: The HPPA architecture reference only documents its NaN
23
-struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
31
+ * propagation rule for 2-operand operations. Testing on real hardware
24
- qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk);
32
+ * might be necessary to confirm whether this order for muladd is correct.
25
-void omap_mcspi_attach(struct omap_mcspi_s *s,
33
+ * Not preferring the SNaN is almost certainly incorrect as it diverges
26
- uint32_t (*txrx)(void *opaque, uint32_t, int), void *opaque,
34
+ * from the documented rules for 2-operand operations.
27
- int chipselect);
35
+ */
28
-void omap_mcspi_reset(struct omap_mcspi_s *s);
36
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
29
-
37
/* For inf * 0 + NaN, return the input NaN */
30
struct I2SCodec {
38
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
31
void *opaque;
39
}
32
40
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s {
41
index XXXXXXX..XXXXXXX 100644
34
/* OMAP2-only peripherals */
42
--- a/fpu/softfloat-specialize.c.inc
35
struct omap_l4_s *l4;
43
+++ b/fpu/softfloat-specialize.c.inc
36
44
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
37
- struct omap_mcspi_s *mcspi[2];
45
}
38
-
46
}
39
struct omap_dss_s *dss;
47
40
};
48
- if (rule == float_3nan_prop_none) {
41
49
- rule = float_3nan_prop_abc;
42
diff --git a/hw/ssi/omap_spi.c b/hw/ssi/omap_spi.c
43
deleted file mode 100644
44
index XXXXXXX..XXXXXXX
45
--- a/hw/ssi/omap_spi.c
46
+++ /dev/null
47
@@ -XXX,XX +XXX,XX @@
48
-/*
49
- * TI OMAP processor's Multichannel SPI emulation.
50
- *
51
- * Copyright (C) 2007-2009 Nokia Corporation
52
- *
53
- * Original code for OMAP2 by Andrzej Zaborowski <andrew@openedhand.com>
54
- *
55
- * This program is free software; you can redistribute it and/or
56
- * modify it under the terms of the GNU General Public License as
57
- * published by the Free Software Foundation; either version 2 or
58
- * (at your option) any later version of the License.
59
- *
60
- * This program is distributed in the hope that it will be useful,
61
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
62
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63
- * GNU General Public License for more details.
64
- *
65
- * You should have received a copy of the GNU General Public License along
66
- * with this program; if not, write to the Free Software Foundation, Inc.,
67
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
68
- */
69
-
70
-#include "qemu/osdep.h"
71
-#include "qemu/log.h"
72
-#include "hw/hw.h"
73
-#include "hw/irq.h"
74
-#include "hw/arm/omap.h"
75
-
76
-/* Multichannel SPI */
77
-struct omap_mcspi_s {
78
- MemoryRegion iomem;
79
- qemu_irq irq;
80
- int chnum;
81
-
82
- uint32_t sysconfig;
83
- uint32_t systest;
84
- uint32_t irqst;
85
- uint32_t irqen;
86
- uint32_t wken;
87
- uint32_t control;
88
-
89
- struct omap_mcspi_ch_s {
90
- qemu_irq txdrq;
91
- qemu_irq rxdrq;
92
- uint32_t (*txrx)(void *opaque, uint32_t, int);
93
- void *opaque;
94
-
95
- uint32_t tx;
96
- uint32_t rx;
97
-
98
- uint32_t config;
99
- uint32_t status;
100
- uint32_t control;
101
- } ch[4];
102
-};
103
-
104
-static inline void omap_mcspi_interrupt_update(struct omap_mcspi_s *s)
105
-{
106
- qemu_set_irq(s->irq, s->irqst & s->irqen);
107
-}
108
-
109
-static inline void omap_mcspi_dmarequest_update(struct omap_mcspi_ch_s *ch)
110
-{
111
- qemu_set_irq(ch->txdrq,
112
- (ch->control & 1) &&        /* EN */
113
- (ch->config & (1 << 14)) &&        /* DMAW */
114
- (ch->status & (1 << 1)) &&        /* TXS */
115
- ((ch->config >> 12) & 3) != 1);    /* TRM */
116
- qemu_set_irq(ch->rxdrq,
117
- (ch->control & 1) &&        /* EN */
118
- (ch->config & (1 << 15)) &&        /* DMAW */
119
- (ch->status & (1 << 0)) &&        /* RXS */
120
- ((ch->config >> 12) & 3) != 2);    /* TRM */
121
-}
122
-
123
-static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum)
124
-{
125
- struct omap_mcspi_ch_s *ch = s->ch + chnum;
126
-
127
- if (!(ch->control & 1))                /* EN */
128
- return;
129
- if ((ch->status & (1 << 0)) &&            /* RXS */
130
- ((ch->config >> 12) & 3) != 2 &&    /* TRM */
131
- !(ch->config & (1 << 19)))        /* TURBO */
132
- goto intr_update;
133
- if ((ch->status & (1 << 1)) &&            /* TXS */
134
- ((ch->config >> 12) & 3) != 1)    /* TRM */
135
- goto intr_update;
136
-
137
- if (!(s->control & 1) ||                /* SINGLE */
138
- (ch->config & (1 << 20))) {        /* FORCE */
139
- if (ch->txrx)
140
- ch->rx = ch->txrx(ch->opaque, ch->tx,    /* WL */
141
- 1 + (0x1f & (ch->config >> 7)));
142
- }
50
- }
143
-
51
-
144
- ch->tx = 0;
52
assert(rule != float_3nan_prop_none);
145
- ch->status |= 1 << 2;                /* EOT */
53
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
146
- ch->status |= 1 << 1;                /* TXS */
54
/* We have at least one SNaN input and should prefer it */
147
- if (((ch->config >> 12) & 3) != 2)            /* TRM */
148
- ch->status |= 1 << 0;                /* RXS */
149
-
150
-intr_update:
151
- if ((ch->status & (1 << 0)) &&            /* RXS */
152
- ((ch->config >> 12) & 3) != 2 &&    /* TRM */
153
- !(ch->config & (1 << 19)))        /* TURBO */
154
- s->irqst |= 1 << (2 + 4 * chnum);        /* RX_FULL */
155
- if ((ch->status & (1 << 1)) &&            /* TXS */
156
- ((ch->config >> 12) & 3) != 1)    /* TRM */
157
- s->irqst |= 1 << (0 + 4 * chnum);        /* TX_EMPTY */
158
- omap_mcspi_interrupt_update(s);
159
- omap_mcspi_dmarequest_update(ch);
160
-}
161
-
162
-void omap_mcspi_reset(struct omap_mcspi_s *s)
163
-{
164
- int ch;
165
-
166
- s->sysconfig = 0;
167
- s->systest = 0;
168
- s->irqst = 0;
169
- s->irqen = 0;
170
- s->wken = 0;
171
- s->control = 4;
172
-
173
- for (ch = 0; ch < 4; ch ++) {
174
- s->ch[ch].config = 0x060000;
175
- s->ch[ch].status = 2;                /* TXS */
176
- s->ch[ch].control = 0;
177
-
178
- omap_mcspi_dmarequest_update(s->ch + ch);
179
- }
180
-
181
- omap_mcspi_interrupt_update(s);
182
-}
183
-
184
-static uint64_t omap_mcspi_read(void *opaque, hwaddr addr, unsigned size)
185
-{
186
- struct omap_mcspi_s *s = opaque;
187
- int ch = 0;
188
- uint32_t ret;
189
-
190
- if (size != 4) {
191
- return omap_badwidth_read32(opaque, addr);
192
- }
193
-
194
- switch (addr) {
195
- case 0x00:    /* MCSPI_REVISION */
196
- return 0x91;
197
-
198
- case 0x10:    /* MCSPI_SYSCONFIG */
199
- return s->sysconfig;
200
-
201
- case 0x14:    /* MCSPI_SYSSTATUS */
202
- return 1;                    /* RESETDONE */
203
-
204
- case 0x18:    /* MCSPI_IRQSTATUS */
205
- return s->irqst;
206
-
207
- case 0x1c:    /* MCSPI_IRQENABLE */
208
- return s->irqen;
209
-
210
- case 0x20:    /* MCSPI_WAKEUPENABLE */
211
- return s->wken;
212
-
213
- case 0x24:    /* MCSPI_SYST */
214
- return s->systest;
215
-
216
- case 0x28:    /* MCSPI_MODULCTRL */
217
- return s->control;
218
-
219
- case 0x68: ch ++;
220
- /* fall through */
221
- case 0x54: ch ++;
222
- /* fall through */
223
- case 0x40: ch ++;
224
- /* fall through */
225
- case 0x2c:    /* MCSPI_CHCONF */
226
- return s->ch[ch].config;
227
-
228
- case 0x6c: ch ++;
229
- /* fall through */
230
- case 0x58: ch ++;
231
- /* fall through */
232
- case 0x44: ch ++;
233
- /* fall through */
234
- case 0x30:    /* MCSPI_CHSTAT */
235
- return s->ch[ch].status;
236
-
237
- case 0x70: ch ++;
238
- /* fall through */
239
- case 0x5c: ch ++;
240
- /* fall through */
241
- case 0x48: ch ++;
242
- /* fall through */
243
- case 0x34:    /* MCSPI_CHCTRL */
244
- return s->ch[ch].control;
245
-
246
- case 0x74: ch ++;
247
- /* fall through */
248
- case 0x60: ch ++;
249
- /* fall through */
250
- case 0x4c: ch ++;
251
- /* fall through */
252
- case 0x38:    /* MCSPI_TX */
253
- return s->ch[ch].tx;
254
-
255
- case 0x78: ch ++;
256
- /* fall through */
257
- case 0x64: ch ++;
258
- /* fall through */
259
- case 0x50: ch ++;
260
- /* fall through */
261
- case 0x3c:    /* MCSPI_RX */
262
- s->ch[ch].status &= ~(1 << 0);            /* RXS */
263
- ret = s->ch[ch].rx;
264
- omap_mcspi_transfer_run(s, ch);
265
- return ret;
266
- }
267
-
268
- OMAP_BAD_REG(addr);
269
- return 0;
270
-}
271
-
272
-static void omap_mcspi_write(void *opaque, hwaddr addr,
273
- uint64_t value, unsigned size)
274
-{
275
- struct omap_mcspi_s *s = opaque;
276
- int ch = 0;
277
-
278
- if (size != 4) {
279
- omap_badwidth_write32(opaque, addr, value);
280
- return;
281
- }
282
-
283
- switch (addr) {
284
- case 0x00:    /* MCSPI_REVISION */
285
- case 0x14:    /* MCSPI_SYSSTATUS */
286
- case 0x30:    /* MCSPI_CHSTAT0 */
287
- case 0x3c:    /* MCSPI_RX0 */
288
- case 0x44:    /* MCSPI_CHSTAT1 */
289
- case 0x50:    /* MCSPI_RX1 */
290
- case 0x58:    /* MCSPI_CHSTAT2 */
291
- case 0x64:    /* MCSPI_RX2 */
292
- case 0x6c:    /* MCSPI_CHSTAT3 */
293
- case 0x78:    /* MCSPI_RX3 */
294
- OMAP_RO_REG(addr);
295
- return;
296
-
297
- case 0x10:    /* MCSPI_SYSCONFIG */
298
- if (value & (1 << 1))                /* SOFTRESET */
299
- omap_mcspi_reset(s);
300
- s->sysconfig = value & 0x31d;
301
- break;
302
-
303
- case 0x18:    /* MCSPI_IRQSTATUS */
304
- if (!((s->control & (1 << 3)) && (s->systest & (1 << 11)))) {
305
- s->irqst &= ~value;
306
- omap_mcspi_interrupt_update(s);
307
- }
308
- break;
309
-
310
- case 0x1c:    /* MCSPI_IRQENABLE */
311
- s->irqen = value & 0x1777f;
312
- omap_mcspi_interrupt_update(s);
313
- break;
314
-
315
- case 0x20:    /* MCSPI_WAKEUPENABLE */
316
- s->wken = value & 1;
317
- break;
318
-
319
- case 0x24:    /* MCSPI_SYST */
320
- if (s->control & (1 << 3))            /* SYSTEM_TEST */
321
- if (value & (1 << 11)) {            /* SSB */
322
- s->irqst |= 0x1777f;
323
- omap_mcspi_interrupt_update(s);
324
- }
325
- s->systest = value & 0xfff;
326
- break;
327
-
328
- case 0x28:    /* MCSPI_MODULCTRL */
329
- if (value & (1 << 3))                /* SYSTEM_TEST */
330
- if (s->systest & (1 << 11)) {        /* SSB */
331
- s->irqst |= 0x1777f;
332
- omap_mcspi_interrupt_update(s);
333
- }
334
- s->control = value & 0xf;
335
- break;
336
-
337
- case 0x68: ch ++;
338
- /* fall through */
339
- case 0x54: ch ++;
340
- /* fall through */
341
- case 0x40: ch ++;
342
- /* fall through */
343
- case 0x2c:    /* MCSPI_CHCONF */
344
- if ((value ^ s->ch[ch].config) & (3 << 14))    /* DMAR | DMAW */
345
- omap_mcspi_dmarequest_update(s->ch + ch);
346
- if (((value >> 12) & 3) == 3) { /* TRM */
347
- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid TRM value (3)\n",
348
- __func__);
349
- }
350
- if (((value >> 7) & 0x1f) < 3) { /* WL */
351
- qemu_log_mask(LOG_GUEST_ERROR,
352
- "%s: invalid WL value (%" PRIx64 ")\n",
353
- __func__, (value >> 7) & 0x1f);
354
- }
355
- s->ch[ch].config = value & 0x7fffff;
356
- break;
357
-
358
- case 0x70: ch ++;
359
- /* fall through */
360
- case 0x5c: ch ++;
361
- /* fall through */
362
- case 0x48: ch ++;
363
- /* fall through */
364
- case 0x34:    /* MCSPI_CHCTRL */
365
- if (value & ~s->ch[ch].control & 1) {        /* EN */
366
- s->ch[ch].control |= 1;
367
- omap_mcspi_transfer_run(s, ch);
368
- } else
369
- s->ch[ch].control = value & 1;
370
- break;
371
-
372
- case 0x74: ch ++;
373
- /* fall through */
374
- case 0x60: ch ++;
375
- /* fall through */
376
- case 0x4c: ch ++;
377
- /* fall through */
378
- case 0x38:    /* MCSPI_TX */
379
- s->ch[ch].tx = value;
380
- s->ch[ch].status &= ~(1 << 1);            /* TXS */
381
- omap_mcspi_transfer_run(s, ch);
382
- break;
383
-
384
- default:
385
- OMAP_BAD_REG(addr);
386
- return;
387
- }
388
-}
389
-
390
-static const MemoryRegionOps omap_mcspi_ops = {
391
- .read = omap_mcspi_read,
392
- .write = omap_mcspi_write,
393
- .endianness = DEVICE_NATIVE_ENDIAN,
394
-};
395
-
396
-struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
397
- qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
398
-{
399
- struct omap_mcspi_s *s = g_new0(struct omap_mcspi_s, 1);
400
- struct omap_mcspi_ch_s *ch = s->ch;
401
-
402
- s->irq = irq;
403
- s->chnum = chnum;
404
- while (chnum --) {
405
- ch->txdrq = *drq ++;
406
- ch->rxdrq = *drq ++;
407
- ch ++;
408
- }
409
- omap_mcspi_reset(s);
410
-
411
- memory_region_init_io(&s->iomem, NULL, &omap_mcspi_ops, s, "omap.mcspi",
412
- omap_l4_region_size(ta, 0));
413
- omap_l4_attach(ta, 0, &s->iomem);
414
-
415
- return s;
416
-}
417
-
418
-void omap_mcspi_attach(struct omap_mcspi_s *s,
419
- uint32_t (*txrx)(void *opaque, uint32_t, int), void *opaque,
420
- int chipselect)
421
-{
422
- if (chipselect < 0 || chipselect >= s->chnum)
423
- hw_error("%s: Bad chipselect %i\n", __func__, chipselect);
424
-
425
- s->ch[chipselect].txrx = txrx;
426
- s->ch[chipselect].opaque = opaque;
427
-}
428
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
429
index XXXXXXX..XXXXXXX 100644
430
--- a/hw/ssi/meson.build
431
+++ b/hw/ssi/meson.build
432
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_XILINX_SPI', if_true: files('xilinx_spi.c'))
433
system_ss.add(when: 'CONFIG_XILINX_SPIPS', if_true: files('xilinx_spips.c'))
434
system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-ospi.c'))
435
system_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
436
-system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
437
system_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_spi_host.c'))
438
system_ss.add(when: 'CONFIG_BCM2835_SPI', if_true: files('bcm2835_spi.c'))
439
system_ss.add(when: 'CONFIG_PNV_SPI', if_true: files('pnv_spi.c'))
440
--
55
--
441
2.34.1
56
2.34.1
diff view generated by jsdifflib
1
Remove the omap_synctimer device, which is only in the OMAP2 SoC.
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
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20241202131347.498124-27-peter.maydell@linaro.org
6
Message-id: 20240903160751.4100218-46-peter.maydell@linaro.org
7
---
10
---
8
include/hw/arm/omap.h | 8 ---
11
include/fpu/softfloat-helpers.h | 5 -----
9
hw/timer/omap_synctimer.c | 110 --------------------------------------
12
include/fpu/softfloat-types.h | 1 -
10
hw/timer/meson.build | 1 -
13
target/xtensa/fpu_helper.c | 1 -
11
3 files changed, 119 deletions(-)
14
3 files changed, 7 deletions(-)
12
delete mode 100644 hw/timer/omap_synctimer.c
13
15
14
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
16
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/omap.h
18
--- a/include/fpu/softfloat-helpers.h
17
+++ b/include/hw/arm/omap.h
19
+++ b/include/fpu/softfloat-helpers.h
18
@@ -XXX,XX +XXX,XX @@ struct omap_dma_lcd_channel_s {
20
@@ -XXX,XX +XXX,XX @@ static inline void set_snan_bit_is_one(bool val, float_status *status)
19
# define OMAP24XX_DMA_MS        63    /* Not in OMAP2420 */
21
status->snan_bit_is_one = val;
20
# define OMAP24XX_DMA_EXT_DMAREQ5    64
22
}
21
23
22
-/* OMAP2 sysctimer */
24
-static inline void set_use_first_nan(bool val, float_status *status)
23
-struct omap_synctimer_s;
25
-{
24
-struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta,
26
- status->use_first_nan = val;
25
- struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk);
26
-void omap_synctimer_reset(struct omap_synctimer_s *s);
27
-
28
struct omap_uart_s;
29
struct omap_uart_s *omap_uart_init(hwaddr base,
30
qemu_irq irq, omap_clk fclk, omap_clk iclk,
31
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s {
32
/* OMAP2-only peripherals */
33
struct omap_l4_s *l4;
34
35
- struct omap_synctimer_s *synctimer;
36
-
37
struct omap_mcspi_s *mcspi[2];
38
39
struct omap_dss_s *dss;
40
diff --git a/hw/timer/omap_synctimer.c b/hw/timer/omap_synctimer.c
41
deleted file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- a/hw/timer/omap_synctimer.c
44
+++ /dev/null
45
@@ -XXX,XX +XXX,XX @@
46
-/*
47
- * TI OMAP2 32kHz sync timer emulation.
48
- *
49
- * Copyright (C) 2007-2008 Nokia Corporation
50
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
51
- *
52
- * This program is free software; you can redistribute it and/or
53
- * modify it under the terms of the GNU General Public License as
54
- * published by the Free Software Foundation; either version 2 or
55
- * (at your option) any later version of the License.
56
- *
57
- * This program is distributed in the hope that it will be useful,
58
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
59
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60
- * GNU General Public License for more details.
61
- *
62
- * You should have received a copy of the GNU General Public License along
63
- * with this program; if not, see <http://www.gnu.org/licenses/>.
64
- */
65
-#include "qemu/osdep.h"
66
-#include "qemu/timer.h"
67
-#include "hw/arm/omap.h"
68
-struct omap_synctimer_s {
69
- MemoryRegion iomem;
70
- uint32_t val;
71
- uint16_t readh;
72
-};
73
-
74
-/* 32-kHz Sync Timer of the OMAP2 */
75
-static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) {
76
- return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 0x8000,
77
- NANOSECONDS_PER_SECOND);
78
-}
27
-}
79
-
28
-
80
-void omap_synctimer_reset(struct omap_synctimer_s *s)
29
static inline void set_no_signaling_nans(bool val, float_status *status)
81
-{
30
{
82
- s->val = omap_synctimer_read(s);
31
status->no_signaling_nans = val;
83
-}
32
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
84
-
85
-static uint32_t omap_synctimer_readw(void *opaque, hwaddr addr)
86
-{
87
- struct omap_synctimer_s *s = opaque;
88
-
89
- switch (addr) {
90
- case 0x00:    /* 32KSYNCNT_REV */
91
- return 0x21;
92
-
93
- case 0x10:    /* CR */
94
- return omap_synctimer_read(s) - s->val;
95
- }
96
-
97
- OMAP_BAD_REG(addr);
98
- return 0;
99
-}
100
-
101
-static uint32_t omap_synctimer_readh(void *opaque, hwaddr addr)
102
-{
103
- struct omap_synctimer_s *s = opaque;
104
- uint32_t ret;
105
-
106
- if (addr & 2)
107
- return s->readh;
108
- else {
109
- ret = omap_synctimer_readw(opaque, addr);
110
- s->readh = ret >> 16;
111
- return ret & 0xffff;
112
- }
113
-}
114
-
115
-static uint64_t omap_synctimer_readfn(void *opaque, hwaddr addr,
116
- unsigned size)
117
-{
118
- switch (size) {
119
- case 1:
120
- return omap_badwidth_read32(opaque, addr);
121
- case 2:
122
- return omap_synctimer_readh(opaque, addr);
123
- case 4:
124
- return omap_synctimer_readw(opaque, addr);
125
- default:
126
- g_assert_not_reached();
127
- }
128
-}
129
-
130
-static void omap_synctimer_writefn(void *opaque, hwaddr addr,
131
- uint64_t value, unsigned size)
132
-{
133
- OMAP_BAD_REG(addr);
134
-}
135
-
136
-static const MemoryRegionOps omap_synctimer_ops = {
137
- .read = omap_synctimer_readfn,
138
- .write = omap_synctimer_writefn,
139
- .valid.min_access_size = 1,
140
- .valid.max_access_size = 4,
141
- .endianness = DEVICE_NATIVE_ENDIAN,
142
-};
143
-
144
-struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta,
145
- struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk)
146
-{
147
- struct omap_synctimer_s *s = g_malloc0(sizeof(*s));
148
-
149
- omap_synctimer_reset(s);
150
- memory_region_init_io(&s->iomem, NULL, &omap_synctimer_ops, s, "omap.synctimer",
151
- omap_l4_region_size(ta, 0));
152
- omap_l4_attach(ta, 0, &s->iomem);
153
-
154
- return s;
155
-}
156
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
157
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
158
--- a/hw/timer/meson.build
34
--- a/include/fpu/softfloat-types.h
159
+++ b/hw/timer/meson.build
35
+++ b/include/fpu/softfloat-types.h
160
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gictimer.c'))
36
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
161
system_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-timer.c'))
37
* softfloat-specialize.inc.c)
162
system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_timer.c'))
38
*/
163
system_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_timer.c'))
39
bool snan_bit_is_one;
164
-system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_synctimer.c'))
40
- bool use_first_nan;
165
system_ss.add(when: 'CONFIG_PXA2XX_TIMER', if_true: files('pxa2xx_timer.c'))
41
bool no_signaling_nans;
166
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_systmr.c'))
42
/* should overflowed results subtract re_bias to its exponent? */
167
system_ss.add(when: 'CONFIG_SH_TIMER', if_true: files('sh_timer.c'))
43
bool rebias_overflow;
44
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/xtensa/fpu_helper.c
47
+++ b/target/xtensa/fpu_helper.c
48
@@ -XXX,XX +XXX,XX @@ static const struct {
49
50
void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
51
{
52
- set_use_first_nan(use_first, &env->fp_status);
53
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
54
&env->fp_status);
55
set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
168
--
56
--
169
2.34.1
57
2.34.1
170
171
diff view generated by jsdifflib
1
The omap_gpmc device is only in OMAP2, which we are removing.
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.
8
9
Rearrange m68k_cpu_reset_hold() so that we initialize env->fp_status
10
earlier, and thus can pass it to floatx80_default_nan().
2
11
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Message-id: 20241202131347.498124-28-peter.maydell@linaro.org
6
Message-id: 20240903160751.4100218-44-peter.maydell@linaro.org
7
---
15
---
8
include/hw/arm/omap.h | 11 -
16
target/m68k/cpu.c | 12 +++++++-----
9
hw/misc/omap_gpmc.c | 898 ------------------------------------------
17
1 file changed, 7 insertions(+), 5 deletions(-)
10
hw/misc/meson.build | 1 -
11
3 files changed, 910 deletions(-)
12
delete mode 100644 hw/misc/omap_gpmc.c
13
18
14
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
19
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/omap.h
21
--- a/target/m68k/cpu.c
17
+++ b/include/hw/arm/omap.h
22
+++ b/target/m68k/cpu.c
18
@@ -XXX,XX +XXX,XX @@ hwaddr omap_l4_region_base(struct omap_target_agent_s *ta,
23
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
19
hwaddr omap_l4_region_size(struct omap_target_agent_s *ta,
24
CPUState *cs = CPU(obj);
20
int region);
25
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(obj);
21
26
CPUM68KState *env = cpu_env(cs);
22
-/* OMAP2 general purpose memory controller */
27
- floatx80 nan = floatx80_default_nan(NULL);
23
-struct omap_gpmc_s;
28
+ floatx80 nan;
24
-struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
29
int i;
25
- hwaddr base,
30
26
- qemu_irq irq, qemu_irq drq);
31
if (mcc->parent_phases.hold) {
27
-void omap_gpmc_reset(struct omap_gpmc_s *s);
32
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
28
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem);
33
#else
29
-void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand);
34
cpu_m68k_set_sr(env, SR_S | SR_I);
30
-
35
#endif
31
/*
36
- for (i = 0; i < 8; i++) {
32
* Common IRQ numbers for level 1 interrupt handler
37
- env->fregs[i].d = nan;
33
* See /usr/include/asm-arm/arch-omap/irqs.h in Linux.
34
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s {
35
struct omap_gp_timer_s *gptimer[12];
36
struct omap_synctimer_s *synctimer;
37
38
- struct omap_gpmc_s *gpmc;
39
-
40
struct omap_mcspi_s *mcspi[2];
41
42
struct omap_dss_s *dss;
43
diff --git a/hw/misc/omap_gpmc.c b/hw/misc/omap_gpmc.c
44
deleted file mode 100644
45
index XXXXXXX..XXXXXXX
46
--- a/hw/misc/omap_gpmc.c
47
+++ /dev/null
48
@@ -XXX,XX +XXX,XX @@
49
-/*
50
- * TI OMAP general purpose memory controller emulation.
51
- *
52
- * Copyright (C) 2007-2009 Nokia Corporation
53
- * Original code written by Andrzej Zaborowski <andrew@openedhand.com>
54
- * Enhancements for OMAP3 and NAND support written by Juha Riihimäki
55
- *
56
- * This program is free software; you can redistribute it and/or
57
- * modify it under the terms of the GNU General Public License as
58
- * published by the Free Software Foundation; either version 2 or
59
- * (at your option) any later version of the License.
60
- *
61
- * This program is distributed in the hope that it will be useful,
62
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
63
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
64
- * GNU General Public License for more details.
65
- *
66
- * You should have received a copy of the GNU General Public License along
67
- * with this program; if not, see <http://www.gnu.org/licenses/>.
68
- */
69
-
70
-#include "qemu/osdep.h"
71
-#include "hw/irq.h"
72
-#include "hw/block/flash.h"
73
-#include "hw/arm/omap.h"
74
-#include "exec/memory.h"
75
-#include "exec/address-spaces.h"
76
-
77
-/* General-Purpose Memory Controller */
78
-struct omap_gpmc_s {
79
- qemu_irq irq;
80
- qemu_irq drq;
81
- MemoryRegion iomem;
82
- int accept_256;
83
-
84
- uint8_t revision;
85
- uint8_t sysconfig;
86
- uint16_t irqst;
87
- uint16_t irqen;
88
- uint16_t lastirq;
89
- uint16_t timeout;
90
- uint16_t config;
91
- struct omap_gpmc_cs_file_s {
92
- uint32_t config[7];
93
- MemoryRegion *iomem;
94
- MemoryRegion container;
95
- MemoryRegion nandiomem;
96
- DeviceState *dev;
97
- } cs_file[8];
98
- int ecc_cs;
99
- int ecc_ptr;
100
- uint32_t ecc_cfg;
101
- ECCState ecc[9];
102
- struct prefetch {
103
- uint32_t config1; /* GPMC_PREFETCH_CONFIG1 */
104
- uint32_t transfercount; /* GPMC_PREFETCH_CONFIG2:TRANSFERCOUNT */
105
- int startengine; /* GPMC_PREFETCH_CONTROL:STARTENGINE */
106
- int fifopointer; /* GPMC_PREFETCH_STATUS:FIFOPOINTER */
107
- int count; /* GPMC_PREFETCH_STATUS:COUNTVALUE */
108
- MemoryRegion iomem;
109
- uint8_t fifo[64];
110
- } prefetch;
111
-};
112
-
113
-#define OMAP_GPMC_8BIT 0
114
-#define OMAP_GPMC_16BIT 1
115
-#define OMAP_GPMC_NOR 0
116
-#define OMAP_GPMC_NAND 2
117
-
118
-static int omap_gpmc_devtype(struct omap_gpmc_cs_file_s *f)
119
-{
120
- return (f->config[0] >> 10) & 3;
121
-}
122
-
123
-static int omap_gpmc_devsize(struct omap_gpmc_cs_file_s *f)
124
-{
125
- /* devsize field is really 2 bits but we ignore the high
126
- * bit to ensure consistent behaviour if the guest sets
127
- * it (values 2 and 3 are reserved in the TRM)
128
- */
129
- return (f->config[0] >> 12) & 1;
130
-}
131
-
132
-/* Extract the chip-select value from the prefetch config1 register */
133
-static int prefetch_cs(uint32_t config1)
134
-{
135
- return (config1 >> 24) & 7;
136
-}
137
-
138
-static int prefetch_threshold(uint32_t config1)
139
-{
140
- return (config1 >> 8) & 0x7f;
141
-}
142
-
143
-static void omap_gpmc_int_update(struct omap_gpmc_s *s)
144
-{
145
- /* The TRM is a bit unclear, but it seems to say that
146
- * the TERMINALCOUNTSTATUS bit is set only on the
147
- * transition when the prefetch engine goes from
148
- * active to inactive, whereas the FIFOEVENTSTATUS
149
- * bit is held high as long as the fifo has at
150
- * least THRESHOLD bytes available.
151
- * So we do the latter here, but TERMINALCOUNTSTATUS
152
- * is set elsewhere.
153
- */
154
- if (s->prefetch.fifopointer >= prefetch_threshold(s->prefetch.config1)) {
155
- s->irqst |= 1;
156
- }
38
- }
157
- if ((s->irqen & s->irqst) != s->lastirq) {
39
- cpu_m68k_set_fpcr(env, 0);
158
- s->lastirq = s->irqen & s->irqst;
40
/*
159
- qemu_set_irq(s->irq, s->lastirq);
41
* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
160
- }
42
* 3.4 FLOATING-POINT INSTRUCTION DETAILS
161
-}
43
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
162
-
44
* preceding paragraph for nonsignaling NaNs.
163
-static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value)
45
*/
164
-{
46
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
165
- if (s->prefetch.config1 & 4) {
47
+
166
- qemu_set_irq(s->drq, value);
48
+ nan = floatx80_default_nan(&env->fp_status);
167
- }
49
+ for (i = 0; i < 8; i++) {
168
-}
50
+ env->fregs[i].d = nan;
169
-
51
+ }
170
-/* Access functions for when a NAND-like device is mapped into memory:
52
+ cpu_m68k_set_fpcr(env, 0);
171
- * all addresses in the region behave like accesses to the relevant
53
env->fpsr = 0;
172
- * GPMC_NAND_DATA_i register (which is actually implemented to call these)
54
173
- */
55
/* TODO: We should set PC from the interrupt vector. */
174
-static uint64_t omap_nand_read(void *opaque, hwaddr addr,
175
- unsigned size)
176
-{
177
- struct omap_gpmc_cs_file_s *f = opaque;
178
- uint64_t v;
179
- nand_setpins(f->dev, 0, 0, 0, 1, 0);
180
- switch (omap_gpmc_devsize(f)) {
181
- case OMAP_GPMC_8BIT:
182
- v = nand_getio(f->dev);
183
- if (size == 1) {
184
- return v;
185
- }
186
- v |= (nand_getio(f->dev) << 8);
187
- if (size == 2) {
188
- return v;
189
- }
190
- v |= (nand_getio(f->dev) << 16);
191
- v |= (nand_getio(f->dev) << 24);
192
- return v;
193
- case OMAP_GPMC_16BIT:
194
- v = nand_getio(f->dev);
195
- if (size == 1) {
196
- /* 8 bit read from 16 bit device : probably a guest bug */
197
- return v & 0xff;
198
- }
199
- if (size == 2) {
200
- return v;
201
- }
202
- v |= (nand_getio(f->dev) << 16);
203
- return v;
204
- default:
205
- abort();
206
- }
207
-}
208
-
209
-static void omap_nand_setio(DeviceState *dev, uint64_t value,
210
- int nandsize, int size)
211
-{
212
- /* Write the specified value to the NAND device, respecting
213
- * both size of the NAND device and size of the write access.
214
- */
215
- switch (nandsize) {
216
- case OMAP_GPMC_8BIT:
217
- switch (size) {
218
- case 1:
219
- nand_setio(dev, value & 0xff);
220
- break;
221
- case 2:
222
- nand_setio(dev, value & 0xff);
223
- nand_setio(dev, (value >> 8) & 0xff);
224
- break;
225
- case 4:
226
- default:
227
- nand_setio(dev, value & 0xff);
228
- nand_setio(dev, (value >> 8) & 0xff);
229
- nand_setio(dev, (value >> 16) & 0xff);
230
- nand_setio(dev, (value >> 24) & 0xff);
231
- break;
232
- }
233
- break;
234
- case OMAP_GPMC_16BIT:
235
- switch (size) {
236
- case 1:
237
- /* writing to a 16bit device with 8bit access is probably a guest
238
- * bug; pass the value through anyway.
239
- */
240
- case 2:
241
- nand_setio(dev, value & 0xffff);
242
- break;
243
- case 4:
244
- default:
245
- nand_setio(dev, value & 0xffff);
246
- nand_setio(dev, (value >> 16) & 0xffff);
247
- break;
248
- }
249
- break;
250
- }
251
-}
252
-
253
-static void omap_nand_write(void *opaque, hwaddr addr,
254
- uint64_t value, unsigned size)
255
-{
256
- struct omap_gpmc_cs_file_s *f = opaque;
257
- nand_setpins(f->dev, 0, 0, 0, 1, 0);
258
- omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
259
-}
260
-
261
-static const MemoryRegionOps omap_nand_ops = {
262
- .read = omap_nand_read,
263
- .write = omap_nand_write,
264
- .endianness = DEVICE_NATIVE_ENDIAN,
265
-};
266
-
267
-static void fill_prefetch_fifo(struct omap_gpmc_s *s)
268
-{
269
- /* Fill the prefetch FIFO by reading data from NAND.
270
- * We do this synchronously, unlike the hardware which
271
- * will do this asynchronously. We refill when the
272
- * FIFO has THRESHOLD bytes free, and we always refill
273
- * as much data as possible starting at the top end
274
- * of the FIFO.
275
- * (We have to refill at THRESHOLD rather than waiting
276
- * for the FIFO to empty to allow for the case where
277
- * the FIFO size isn't an exact multiple of THRESHOLD
278
- * and we're doing DMA transfers.)
279
- * This means we never need to handle wrap-around in
280
- * the fifo-reading code, and the next byte of data
281
- * to read is always fifo[63 - fifopointer].
282
- */
283
- int fptr;
284
- int cs = prefetch_cs(s->prefetch.config1);
285
- int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
286
- int bytes;
287
- /* Don't believe the bit of the OMAP TRM that says that COUNTVALUE
288
- * and TRANSFERCOUNT are in units of 16 bit words for 16 bit NAND.
289
- * Instead believe the bit that says it is always a byte count.
290
- */
291
- bytes = 64 - s->prefetch.fifopointer;
292
- if (bytes > s->prefetch.count) {
293
- bytes = s->prefetch.count;
294
- }
295
- if (is16bit) {
296
- bytes &= ~1;
297
- }
298
-
299
- s->prefetch.count -= bytes;
300
- s->prefetch.fifopointer += bytes;
301
- fptr = 64 - s->prefetch.fifopointer;
302
- /* Move the existing data in the FIFO so it sits just
303
- * before what we're about to read in
304
- */
305
- while (fptr < (64 - bytes)) {
306
- s->prefetch.fifo[fptr] = s->prefetch.fifo[fptr + bytes];
307
- fptr++;
308
- }
309
- while (fptr < 64) {
310
- if (is16bit) {
311
- uint32_t v = omap_nand_read(&s->cs_file[cs], 0, 2);
312
- s->prefetch.fifo[fptr++] = v & 0xff;
313
- s->prefetch.fifo[fptr++] = (v >> 8) & 0xff;
314
- } else {
315
- s->prefetch.fifo[fptr++] = omap_nand_read(&s->cs_file[cs], 0, 1);
316
- }
317
- }
318
- if (s->prefetch.startengine && (s->prefetch.count == 0)) {
319
- /* This was the final transfer: raise TERMINALCOUNTSTATUS */
320
- s->irqst |= 2;
321
- s->prefetch.startengine = 0;
322
- }
323
- /* If there are any bytes in the FIFO at this point then
324
- * we must raise a DMA request (either this is a final part
325
- * transfer, or we filled the FIFO in which case we certainly
326
- * have THRESHOLD bytes available)
327
- */
328
- if (s->prefetch.fifopointer != 0) {
329
- omap_gpmc_dma_update(s, 1);
330
- }
331
- omap_gpmc_int_update(s);
332
-}
333
-
334
-/* Access functions for a NAND-like device when the prefetch/postwrite
335
- * engine is enabled -- all addresses in the region behave alike:
336
- * data is read or written to the FIFO.
337
- */
338
-static uint64_t omap_gpmc_prefetch_read(void *opaque, hwaddr addr,
339
- unsigned size)
340
-{
341
- struct omap_gpmc_s *s = opaque;
342
- uint32_t data;
343
- if (s->prefetch.config1 & 1) {
344
- /* The TRM doesn't define the behaviour if you read from the
345
- * FIFO when the prefetch engine is in write mode. We choose
346
- * to always return zero.
347
- */
348
- return 0;
349
- }
350
- /* Note that trying to read an empty fifo repeats the last byte */
351
- if (s->prefetch.fifopointer) {
352
- s->prefetch.fifopointer--;
353
- }
354
- data = s->prefetch.fifo[63 - s->prefetch.fifopointer];
355
- if (s->prefetch.fifopointer ==
356
- (64 - prefetch_threshold(s->prefetch.config1))) {
357
- /* We've drained THRESHOLD bytes now. So deassert the
358
- * DMA request, then refill the FIFO (which will probably
359
- * assert it again.)
360
- */
361
- omap_gpmc_dma_update(s, 0);
362
- fill_prefetch_fifo(s);
363
- }
364
- omap_gpmc_int_update(s);
365
- return data;
366
-}
367
-
368
-static void omap_gpmc_prefetch_write(void *opaque, hwaddr addr,
369
- uint64_t value, unsigned size)
370
-{
371
- struct omap_gpmc_s *s = opaque;
372
- int cs = prefetch_cs(s->prefetch.config1);
373
- if ((s->prefetch.config1 & 1) == 0) {
374
- /* The TRM doesn't define the behaviour of writing to the
375
- * FIFO when the prefetch engine is in read mode. We
376
- * choose to ignore the write.
377
- */
378
- return;
379
- }
380
- if (s->prefetch.count == 0) {
381
- /* The TRM doesn't define the behaviour of writing to the
382
- * FIFO if the transfer is complete. We choose to ignore.
383
- */
384
- return;
385
- }
386
- /* The only reason we do any data buffering in postwrite
387
- * mode is if we are talking to a 16 bit NAND device, in
388
- * which case we need to buffer the first byte of the
389
- * 16 bit word until the other byte arrives.
390
- */
391
- int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
392
- if (is16bit) {
393
- /* fifopointer alternates between 64 (waiting for first
394
- * byte of word) and 63 (waiting for second byte)
395
- */
396
- if (s->prefetch.fifopointer == 64) {
397
- s->prefetch.fifo[0] = value;
398
- s->prefetch.fifopointer--;
399
- } else {
400
- value = (value << 8) | s->prefetch.fifo[0];
401
- omap_nand_write(&s->cs_file[cs], 0, value, 2);
402
- s->prefetch.count--;
403
- s->prefetch.fifopointer = 64;
404
- }
405
- } else {
406
- /* Just write the byte : fifopointer remains 64 at all times */
407
- omap_nand_write(&s->cs_file[cs], 0, value, 1);
408
- s->prefetch.count--;
409
- }
410
- if (s->prefetch.count == 0) {
411
- /* Final transfer: raise TERMINALCOUNTSTATUS */
412
- s->irqst |= 2;
413
- s->prefetch.startengine = 0;
414
- }
415
- omap_gpmc_int_update(s);
416
-}
417
-
418
-static const MemoryRegionOps omap_prefetch_ops = {
419
- .read = omap_gpmc_prefetch_read,
420
- .write = omap_gpmc_prefetch_write,
421
- .endianness = DEVICE_NATIVE_ENDIAN,
422
- .impl.min_access_size = 1,
423
- .impl.max_access_size = 1,
424
-};
425
-
426
-static MemoryRegion *omap_gpmc_cs_memregion(struct omap_gpmc_s *s, int cs)
427
-{
428
- /* Return the MemoryRegion* to map/unmap for this chipselect */
429
- struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
430
- if (omap_gpmc_devtype(f) == OMAP_GPMC_NOR) {
431
- return f->iomem;
432
- }
433
- if ((s->prefetch.config1 & 0x80) &&
434
- (prefetch_cs(s->prefetch.config1) == cs)) {
435
- /* The prefetch engine is enabled for this CS: map the FIFO */
436
- return &s->prefetch.iomem;
437
- }
438
- return &f->nandiomem;
439
-}
440
-
441
-static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
442
-{
443
- struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
444
- uint32_t mask = (f->config[6] >> 8) & 0xf;
445
- uint32_t base = f->config[6] & 0x3f;
446
- uint32_t size;
447
-
448
- if (!f->iomem && !f->dev) {
449
- return;
450
- }
451
-
452
- if (!(f->config[6] & (1 << 6))) {
453
- /* Do nothing unless CSVALID */
454
- return;
455
- }
456
-
457
- /* TODO: check for overlapping regions and report access errors */
458
- if (mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf
459
- && !(s->accept_256 && !mask)) {
460
- fprintf(stderr, "%s: invalid chip-select mask address (0x%x)\n",
461
- __func__, mask);
462
- }
463
-
464
- base <<= 24;
465
- size = (0x0fffffff & ~(mask << 24)) + 1;
466
- /* TODO: rather than setting the size of the mapping (which should be
467
- * constant), the mask should cause wrapping of the address space, so
468
- * that the same memory becomes accessible at every <i>size</i> bytes
469
- * starting from <i>base</i>. */
470
- memory_region_init(&f->container, NULL, "omap-gpmc-file", size);
471
- memory_region_add_subregion(&f->container, 0,
472
- omap_gpmc_cs_memregion(s, cs));
473
- memory_region_add_subregion(get_system_memory(), base,
474
- &f->container);
475
-}
476
-
477
-static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
478
-{
479
- struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
480
- if (!(f->config[6] & (1 << 6))) {
481
- /* Do nothing unless CSVALID */
482
- return;
483
- }
484
- if (!f->iomem && !f->dev) {
485
- return;
486
- }
487
- memory_region_del_subregion(get_system_memory(), &f->container);
488
- memory_region_del_subregion(&f->container, omap_gpmc_cs_memregion(s, cs));
489
- object_unparent(OBJECT(&f->container));
490
-}
491
-
492
-void omap_gpmc_reset(struct omap_gpmc_s *s)
493
-{
494
- int i;
495
-
496
- s->sysconfig = 0;
497
- s->irqst = 0;
498
- s->irqen = 0;
499
- omap_gpmc_int_update(s);
500
- for (i = 0; i < 8; i++) {
501
- /* This has to happen before we change any of the config
502
- * used to determine which memory regions are mapped or unmapped.
503
- */
504
- omap_gpmc_cs_unmap(s, i);
505
- }
506
- s->timeout = 0;
507
- s->config = 0xa00;
508
- s->prefetch.config1 = 0x00004000;
509
- s->prefetch.transfercount = 0x00000000;
510
- s->prefetch.startengine = 0;
511
- s->prefetch.fifopointer = 0;
512
- s->prefetch.count = 0;
513
- for (i = 0; i < 8; i ++) {
514
- s->cs_file[i].config[1] = 0x101001;
515
- s->cs_file[i].config[2] = 0x020201;
516
- s->cs_file[i].config[3] = 0x10031003;
517
- s->cs_file[i].config[4] = 0x10f1111;
518
- s->cs_file[i].config[5] = 0;
519
- s->cs_file[i].config[6] = 0xf00;
520
- /* In theory we could probe attached devices for some CFG1
521
- * bits here, but we just retain them across resets as they
522
- * were set initially by omap_gpmc_attach().
523
- */
524
- if (i == 0) {
525
- s->cs_file[i].config[0] &= 0x00433e00;
526
- s->cs_file[i].config[6] |= 1 << 6; /* CSVALID */
527
- omap_gpmc_cs_map(s, i);
528
- } else {
529
- s->cs_file[i].config[0] &= 0x00403c00;
530
- }
531
- }
532
- s->ecc_cs = 0;
533
- s->ecc_ptr = 0;
534
- s->ecc_cfg = 0x3fcff000;
535
- for (i = 0; i < 9; i ++)
536
- ecc_reset(&s->ecc[i]);
537
-}
538
-
539
-static int gpmc_wordaccess_only(hwaddr addr)
540
-{
541
- /* Return true if the register offset is to a register that
542
- * only permits word width accesses.
543
- * Non-word accesses are only OK for GPMC_NAND_DATA/ADDRESS/COMMAND
544
- * for any chipselect.
545
- */
546
- if (addr >= 0x60 && addr <= 0x1d4) {
547
- int cs = (addr - 0x60) / 0x30;
548
- addr -= cs * 0x30;
549
- if (addr >= 0x7c && addr < 0x88) {
550
- /* GPMC_NAND_COMMAND, GPMC_NAND_ADDRESS, GPMC_NAND_DATA */
551
- return 0;
552
- }
553
- }
554
- return 1;
555
-}
556
-
557
-static uint64_t omap_gpmc_read(void *opaque, hwaddr addr,
558
- unsigned size)
559
-{
560
- struct omap_gpmc_s *s = opaque;
561
- int cs;
562
- struct omap_gpmc_cs_file_s *f;
563
-
564
- if (size != 4 && gpmc_wordaccess_only(addr)) {
565
- return omap_badwidth_read32(opaque, addr);
566
- }
567
-
568
- switch (addr) {
569
- case 0x000:    /* GPMC_REVISION */
570
- return s->revision;
571
-
572
- case 0x010:    /* GPMC_SYSCONFIG */
573
- return s->sysconfig;
574
-
575
- case 0x014:    /* GPMC_SYSSTATUS */
576
- return 1;                        /* RESETDONE */
577
-
578
- case 0x018:    /* GPMC_IRQSTATUS */
579
- return s->irqst;
580
-
581
- case 0x01c:    /* GPMC_IRQENABLE */
582
- return s->irqen;
583
-
584
- case 0x040:    /* GPMC_TIMEOUT_CONTROL */
585
- return s->timeout;
586
-
587
- case 0x044:    /* GPMC_ERR_ADDRESS */
588
- case 0x048:    /* GPMC_ERR_TYPE */
589
- return 0;
590
-
591
- case 0x050:    /* GPMC_CONFIG */
592
- return s->config;
593
-
594
- case 0x054:    /* GPMC_STATUS */
595
- return 0x001;
596
-
597
- case 0x060 ... 0x1d4:
598
- cs = (addr - 0x060) / 0x30;
599
- addr -= cs * 0x30;
600
- f = s->cs_file + cs;
601
- switch (addr) {
602
- case 0x60: /* GPMC_CONFIG1 */
603
- return f->config[0];
604
- case 0x64: /* GPMC_CONFIG2 */
605
- return f->config[1];
606
- case 0x68: /* GPMC_CONFIG3 */
607
- return f->config[2];
608
- case 0x6c: /* GPMC_CONFIG4 */
609
- return f->config[3];
610
- case 0x70: /* GPMC_CONFIG5 */
611
- return f->config[4];
612
- case 0x74: /* GPMC_CONFIG6 */
613
- return f->config[5];
614
- case 0x78: /* GPMC_CONFIG7 */
615
- return f->config[6];
616
- case 0x84 ... 0x87: /* GPMC_NAND_DATA */
617
- if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
618
- return omap_nand_read(f, 0, size);
619
- }
620
- return 0;
621
- }
622
- break;
623
-
624
- case 0x1e0:    /* GPMC_PREFETCH_CONFIG1 */
625
- return s->prefetch.config1;
626
- case 0x1e4:    /* GPMC_PREFETCH_CONFIG2 */
627
- return s->prefetch.transfercount;
628
- case 0x1ec:    /* GPMC_PREFETCH_CONTROL */
629
- return s->prefetch.startengine;
630
- case 0x1f0:    /* GPMC_PREFETCH_STATUS */
631
- /* NB: The OMAP3 TRM is inconsistent about whether the GPMC
632
- * FIFOTHRESHOLDSTATUS bit should be set when
633
- * FIFOPOINTER > FIFOTHRESHOLD or when it is >= FIFOTHRESHOLD.
634
- * Apparently the underlying functional spec from which the TRM was
635
- * created states that the behaviour is ">=", and this also
636
- * makes more conceptual sense.
637
- */
638
- return (s->prefetch.fifopointer << 24) |
639
- ((s->prefetch.fifopointer >=
640
- ((s->prefetch.config1 >> 8) & 0x7f) ? 1 : 0) << 16) |
641
- s->prefetch.count;
642
-
643
- case 0x1f4:    /* GPMC_ECC_CONFIG */
644
- return s->ecc_cs;
645
- case 0x1f8:    /* GPMC_ECC_CONTROL */
646
- return s->ecc_ptr;
647
- case 0x1fc:    /* GPMC_ECC_SIZE_CONFIG */
648
- return s->ecc_cfg;
649
- case 0x200 ... 0x220:    /* GPMC_ECC_RESULT */
650
- cs = (addr & 0x1f) >> 2;
651
- /* TODO: check correctness */
652
- return
653
- ((s->ecc[cs].cp & 0x07) << 0) |
654
- ((s->ecc[cs].cp & 0x38) << 13) |
655
- ((s->ecc[cs].lp[0] & 0x1ff) << 3) |
656
- ((s->ecc[cs].lp[1] & 0x1ff) << 19);
657
-
658
- case 0x230:    /* GPMC_TESTMODE_CTRL */
659
- return 0;
660
- case 0x234:    /* GPMC_PSA_LSB */
661
- case 0x238:    /* GPMC_PSA_MSB */
662
- return 0x00000000;
663
- }
664
-
665
- OMAP_BAD_REG(addr);
666
- return 0;
667
-}
668
-
669
-static void omap_gpmc_write(void *opaque, hwaddr addr,
670
- uint64_t value, unsigned size)
671
-{
672
- struct omap_gpmc_s *s = opaque;
673
- int cs;
674
- struct omap_gpmc_cs_file_s *f;
675
-
676
- if (size != 4 && gpmc_wordaccess_only(addr)) {
677
- omap_badwidth_write32(opaque, addr, value);
678
- return;
679
- }
680
-
681
- switch (addr) {
682
- case 0x000:    /* GPMC_REVISION */
683
- case 0x014:    /* GPMC_SYSSTATUS */
684
- case 0x054:    /* GPMC_STATUS */
685
- case 0x1f0:    /* GPMC_PREFETCH_STATUS */
686
- case 0x200 ... 0x220:    /* GPMC_ECC_RESULT */
687
- case 0x234:    /* GPMC_PSA_LSB */
688
- case 0x238:    /* GPMC_PSA_MSB */
689
- OMAP_RO_REG(addr);
690
- break;
691
-
692
- case 0x010:    /* GPMC_SYSCONFIG */
693
- if ((value >> 3) == 0x3)
694
- fprintf(stderr, "%s: bad SDRAM idle mode %"PRIi64"\n",
695
- __func__, value >> 3);
696
- if (value & 2)
697
- omap_gpmc_reset(s);
698
- s->sysconfig = value & 0x19;
699
- break;
700
-
701
- case 0x018:    /* GPMC_IRQSTATUS */
702
- s->irqst &= ~value;
703
- omap_gpmc_int_update(s);
704
- break;
705
-
706
- case 0x01c:    /* GPMC_IRQENABLE */
707
- s->irqen = value & 0xf03;
708
- omap_gpmc_int_update(s);
709
- break;
710
-
711
- case 0x040:    /* GPMC_TIMEOUT_CONTROL */
712
- s->timeout = value & 0x1ff1;
713
- break;
714
-
715
- case 0x044:    /* GPMC_ERR_ADDRESS */
716
- case 0x048:    /* GPMC_ERR_TYPE */
717
- break;
718
-
719
- case 0x050:    /* GPMC_CONFIG */
720
- s->config = value & 0xf13;
721
- break;
722
-
723
- case 0x060 ... 0x1d4:
724
- cs = (addr - 0x060) / 0x30;
725
- addr -= cs * 0x30;
726
- f = s->cs_file + cs;
727
- switch (addr) {
728
- case 0x60: /* GPMC_CONFIG1 */
729
- f->config[0] = value & 0xffef3e13;
730
- break;
731
- case 0x64: /* GPMC_CONFIG2 */
732
- f->config[1] = value & 0x001f1f8f;
733
- break;
734
- case 0x68: /* GPMC_CONFIG3 */
735
- f->config[2] = value & 0x001f1f8f;
736
- break;
737
- case 0x6c: /* GPMC_CONFIG4 */
738
- f->config[3] = value & 0x1f8f1f8f;
739
- break;
740
- case 0x70: /* GPMC_CONFIG5 */
741
- f->config[4] = value & 0x0f1f1f1f;
742
- break;
743
- case 0x74: /* GPMC_CONFIG6 */
744
- f->config[5] = value & 0x00000fcf;
745
- break;
746
- case 0x78: /* GPMC_CONFIG7 */
747
- if ((f->config[6] ^ value) & 0xf7f) {
748
- omap_gpmc_cs_unmap(s, cs);
749
- f->config[6] = value & 0x00000f7f;
750
- omap_gpmc_cs_map(s, cs);
751
- }
752
- break;
753
- case 0x7c ... 0x7f: /* GPMC_NAND_COMMAND */
754
- if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
755
- nand_setpins(f->dev, 1, 0, 0, 1, 0); /* CLE */
756
- omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
757
- }
758
- break;
759
- case 0x80 ... 0x83: /* GPMC_NAND_ADDRESS */
760
- if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
761
- nand_setpins(f->dev, 0, 1, 0, 1, 0); /* ALE */
762
- omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
763
- }
764
- break;
765
- case 0x84 ... 0x87: /* GPMC_NAND_DATA */
766
- if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
767
- omap_nand_write(f, 0, value, size);
768
- }
769
- break;
770
- default:
771
- goto bad_reg;
772
- }
773
- break;
774
-
775
- case 0x1e0:    /* GPMC_PREFETCH_CONFIG1 */
776
- if (!s->prefetch.startengine) {
777
- uint32_t newconfig1 = value & 0x7f8f7fbf;
778
- uint32_t changed;
779
- changed = newconfig1 ^ s->prefetch.config1;
780
- if (changed & (0x80 | 0x7000000)) {
781
- /* Turning the engine on or off, or mapping it somewhere else.
782
- * cs_map() and cs_unmap() check the prefetch config and
783
- * overall CSVALID bits, so it is sufficient to unmap-and-map
784
- * both the old cs and the new one. Note that we adhere to
785
- * the "unmap/change config/map" order (and not unmap twice
786
- * if newcs == oldcs), otherwise we'll try to delete the wrong
787
- * memory region.
788
- */
789
- int oldcs = prefetch_cs(s->prefetch.config1);
790
- int newcs = prefetch_cs(newconfig1);
791
- omap_gpmc_cs_unmap(s, oldcs);
792
- if (oldcs != newcs) {
793
- omap_gpmc_cs_unmap(s, newcs);
794
- }
795
- s->prefetch.config1 = newconfig1;
796
- omap_gpmc_cs_map(s, oldcs);
797
- if (oldcs != newcs) {
798
- omap_gpmc_cs_map(s, newcs);
799
- }
800
- } else {
801
- s->prefetch.config1 = newconfig1;
802
- }
803
- }
804
- break;
805
-
806
- case 0x1e4:    /* GPMC_PREFETCH_CONFIG2 */
807
- if (!s->prefetch.startengine) {
808
- s->prefetch.transfercount = value & 0x3fff;
809
- }
810
- break;
811
-
812
- case 0x1ec:    /* GPMC_PREFETCH_CONTROL */
813
- if (s->prefetch.startengine != (value & 1)) {
814
- s->prefetch.startengine = value & 1;
815
- if (s->prefetch.startengine) {
816
- /* Prefetch engine start */
817
- s->prefetch.count = s->prefetch.transfercount;
818
- if (s->prefetch.config1 & 1) {
819
- /* Write */
820
- s->prefetch.fifopointer = 64;
821
- } else {
822
- /* Read */
823
- s->prefetch.fifopointer = 0;
824
- fill_prefetch_fifo(s);
825
- }
826
- } else {
827
- /* Prefetch engine forcibly stopped. The TRM
828
- * doesn't define the behaviour if you do this.
829
- * We clear the prefetch count, which means that
830
- * we permit no more writes, and don't read any
831
- * more data from NAND. The CPU can still drain
832
- * the FIFO of unread data.
833
- */
834
- s->prefetch.count = 0;
835
- }
836
- omap_gpmc_int_update(s);
837
- }
838
- break;
839
-
840
- case 0x1f4:    /* GPMC_ECC_CONFIG */
841
- s->ecc_cs = 0x8f;
842
- break;
843
- case 0x1f8:    /* GPMC_ECC_CONTROL */
844
- if (value & (1 << 8))
845
- for (cs = 0; cs < 9; cs ++)
846
- ecc_reset(&s->ecc[cs]);
847
- s->ecc_ptr = value & 0xf;
848
- if (s->ecc_ptr == 0 || s->ecc_ptr > 9) {
849
- s->ecc_ptr = 0;
850
- s->ecc_cs &= ~1;
851
- }
852
- break;
853
- case 0x1fc:    /* GPMC_ECC_SIZE_CONFIG */
854
- s->ecc_cfg = value & 0x3fcff1ff;
855
- break;
856
- case 0x230:    /* GPMC_TESTMODE_CTRL */
857
- if (value & 7)
858
- fprintf(stderr, "%s: test mode enable attempt\n", __func__);
859
- break;
860
-
861
- default:
862
- bad_reg:
863
- OMAP_BAD_REG(addr);
864
- return;
865
- }
866
-}
867
-
868
-static const MemoryRegionOps omap_gpmc_ops = {
869
- .read = omap_gpmc_read,
870
- .write = omap_gpmc_write,
871
- .endianness = DEVICE_NATIVE_ENDIAN,
872
-};
873
-
874
-struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
875
- hwaddr base,
876
- qemu_irq irq, qemu_irq drq)
877
-{
878
- int cs;
879
- struct omap_gpmc_s *s = g_new0(struct omap_gpmc_s, 1);
880
-
881
- memory_region_init_io(&s->iomem, NULL, &omap_gpmc_ops, s, "omap-gpmc", 0x1000);
882
- memory_region_add_subregion(get_system_memory(), base, &s->iomem);
883
-
884
- s->irq = irq;
885
- s->drq = drq;
886
- s->accept_256 = cpu_is_omap3630(mpu);
887
- s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
888
- s->lastirq = 0;
889
- omap_gpmc_reset(s);
890
-
891
- /* We have to register a different IO memory handler for each
892
- * chip select region in case a NAND device is mapped there. We
893
- * make the region the worst-case size of 256MB and rely on the
894
- * container memory region in cs_map to chop it down to the actual
895
- * guest-requested size.
896
- */
897
- for (cs = 0; cs < 8; cs++) {
898
- memory_region_init_io(&s->cs_file[cs].nandiomem, NULL,
899
- &omap_nand_ops,
900
- &s->cs_file[cs],
901
- "omap-nand",
902
- 256 * 1024 * 1024);
903
- }
904
-
905
- memory_region_init_io(&s->prefetch.iomem, NULL, &omap_prefetch_ops, s,
906
- "omap-gpmc-prefetch", 256 * 1024 * 1024);
907
- return s;
908
-}
909
-
910
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem)
911
-{
912
- struct omap_gpmc_cs_file_s *f;
913
- assert(iomem);
914
-
915
- if (cs < 0 || cs >= 8) {
916
- fprintf(stderr, "%s: bad chip-select %i\n", __func__, cs);
917
- exit(-1);
918
- }
919
- f = &s->cs_file[cs];
920
-
921
- omap_gpmc_cs_unmap(s, cs);
922
- f->config[0] &= ~(0xf << 10);
923
- f->iomem = iomem;
924
- omap_gpmc_cs_map(s, cs);
925
-}
926
-
927
-void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand)
928
-{
929
- struct omap_gpmc_cs_file_s *f;
930
- assert(nand);
931
-
932
- if (cs < 0 || cs >= 8) {
933
- fprintf(stderr, "%s: bad chip-select %i\n", __func__, cs);
934
- exit(-1);
935
- }
936
- f = &s->cs_file[cs];
937
-
938
- omap_gpmc_cs_unmap(s, cs);
939
- f->config[0] &= ~(0xf << 10);
940
- f->config[0] |= (OMAP_GPMC_NAND << 10);
941
- f->dev = nand;
942
- if (nand_getbuswidth(f->dev) == 16) {
943
- f->config[0] |= OMAP_GPMC_16BIT << 12;
944
- }
945
- omap_gpmc_cs_map(s, cs);
946
-}
947
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
948
index XXXXXXX..XXXXXXX 100644
949
--- a/hw/misc/meson.build
950
+++ b/hw/misc/meson.build
951
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
952
))
953
system_ss.add(when: 'CONFIG_OMAP', if_true: files(
954
'omap_clk.c',
955
- 'omap_gpmc.c',
956
'omap_l4.c',
957
'omap_tap.c',
958
))
959
--
56
--
960
2.34.1
57
2.34.1
961
962
diff view generated by jsdifflib
1
Remove the MUSB USB2.0 OTG-compliant USB host controller
1
We create our 128-bit default NaN by calling parts64_default_nan()
2
device model. This was only used by the tusb6010 USB
2
and then adjusting the result. We can do the same trick for creating
3
controller in the n800/n810 machines.
3
the floatx80 default NaN, which lets us drop a target ifdef.
4
5
floatx80 is used only by:
6
i386
7
m68k
8
arm nwfpe old floating-point emulation emulation support
9
(which is essentially dead, especially the parts involving floatx80)
10
PPC (only in the xsrqpxp instruction, which just rounds an input
11
value by converting to floatx80 and back, so will never generate
12
the default NaN)
13
14
The floatx80 default NaN as currently implemented is:
15
m68k: sign = 0, exp = 1...1, int = 1, frac = 1....1
16
i386: sign = 1, exp = 1...1, int = 1, frac = 10...0
17
18
These are the same as the parts64_default_nan for these architectures.
19
20
This is technically a possible behaviour change for arm linux-user
21
nwfpe emulation emulation, because the default NaN will now have the
22
sign bit clear. But we were already generating a different floatx80
23
default NaN from the real kernel emulation we are supposedly
24
following, which appears to use an all-bits-1 value:
25
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L267
26
27
This won't affect the only "real" use of the nwfpe emulation, which
28
is ancient binaries that used it as part of the old floating point
29
calling convention; that only uses loads and stores of 32 and 64 bit
30
floats, not any of the floatx80 behaviour the original hardware had.
31
We also get the nwfpe float64 default NaN value wrong:
32
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L166
33
so if we ever cared about this obscure corner the right fix would be
34
to correct that so nwfpe used its own default-NaN setting rather
35
than the Arm VFP one.
4
36
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
37
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Thomas Huth <thuth@redhat.com>
38
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20240903160751.4100218-35-peter.maydell@linaro.org
39
Message-id: 20241202131347.498124-29-peter.maydell@linaro.org
8
---
40
---
9
include/hw/usb/hcd-musb.h | 49 --
41
fpu/softfloat-specialize.c.inc | 20 ++++++++++----------
10
hw/usb/hcd-musb.c | 1553 -------------------------------------
42
1 file changed, 10 insertions(+), 10 deletions(-)
11
hw/usb/Kconfig | 4 -
12
hw/usb/meson.build | 1 -
13
4 files changed, 1607 deletions(-)
14
delete mode 100644 include/hw/usb/hcd-musb.h
15
delete mode 100644 hw/usb/hcd-musb.c
16
43
17
diff --git a/include/hw/usb/hcd-musb.h b/include/hw/usb/hcd-musb.h
44
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
18
deleted file mode 100644
45
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX
46
--- a/fpu/softfloat-specialize.c.inc
20
--- a/include/hw/usb/hcd-musb.h
47
+++ b/fpu/softfloat-specialize.c.inc
21
+++ /dev/null
48
@@ -XXX,XX +XXX,XX @@ static void parts128_silence_nan(FloatParts128 *p, float_status *status)
22
@@ -XXX,XX +XXX,XX @@
49
floatx80 floatx80_default_nan(float_status *status)
23
-/*
50
{
24
- * "Inventra" High-speed Dual-Role Controller (MUSB-HDRC), Mentor Graphics,
51
floatx80 r;
25
- * USB2.0 OTG compliant core used in various chips.
52
+ /*
26
- *
53
+ * Extrapolate from the choices made by parts64_default_nan to fill
27
- * Only host-mode and non-DMA accesses are currently supported.
54
+ * in the floatx80 format. We assume that floatx80's explicit
28
- *
55
+ * integer bit is always set (this is true for i386 and m68k,
29
- * Copyright (C) 2008 Nokia Corporation
56
+ * which are the only real users of this format).
30
- * Written by Andrzej Zaborowski <balrog@zabor.org>
57
+ */
31
- *
58
+ FloatParts64 p64;
32
- * SPDX-License-Identifier: GPL-2.0-or-later
59
+ parts64_default_nan(&p64, status);
33
- */
60
34
-
61
- /* None of the targets that have snan_bit_is_one use floatx80. */
35
-#ifndef HW_USB_HCD_MUSB_H
62
- assert(!snan_bit_is_one(status));
36
-#define HW_USB_HCD_MUSB_H
63
-#if defined(TARGET_M68K)
37
-
64
- r.low = UINT64_C(0xFFFFFFFFFFFFFFFF);
38
-#include "exec/hwaddr.h"
65
- r.high = 0x7FFF;
39
-
66
-#else
40
-enum musb_irq_source_e {
67
- /* X86 */
41
- musb_irq_suspend = 0,
68
- r.low = UINT64_C(0xC000000000000000);
42
- musb_irq_resume,
69
- r.high = 0xFFFF;
43
- musb_irq_rst_babble,
44
- musb_irq_sof,
45
- musb_irq_connect,
46
- musb_irq_disconnect,
47
- musb_irq_vbus_request,
48
- musb_irq_vbus_error,
49
- musb_irq_rx,
50
- musb_irq_tx,
51
- musb_set_vbus,
52
- musb_set_session,
53
- /* Add new interrupts here */
54
- musb_irq_max /* total number of interrupts defined */
55
-};
56
-
57
-/* TODO convert hcd-musb to QOM/qdev and remove MUSBReadFunc/MUSBWriteFunc */
58
-typedef void MUSBWriteFunc(void *opaque, hwaddr addr, uint32_t value);
59
-typedef uint32_t MUSBReadFunc(void *opaque, hwaddr addr);
60
-extern MUSBReadFunc * const musb_read[];
61
-extern MUSBWriteFunc * const musb_write[];
62
-
63
-typedef struct MUSBState MUSBState;
64
-
65
-MUSBState *musb_init(DeviceState *parent_device, int gpio_base);
66
-void musb_reset(MUSBState *s);
67
-uint32_t musb_core_intr_get(MUSBState *s);
68
-void musb_core_intr_clear(MUSBState *s, uint32_t mask);
69
-void musb_set_size(MUSBState *s, int epnum, int size, int is_tx);
70
-
71
-#endif
70
-#endif
72
diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c
71
+ r.high = 0x7FFF | (p64.sign << 15);
73
deleted file mode 100644
72
+ r.low = (1ULL << DECOMPOSED_BINARY_POINT) | p64.frac;
74
index XXXXXXX..XXXXXXX
73
return r;
75
--- a/hw/usb/hcd-musb.c
74
}
76
+++ /dev/null
77
@@ -XXX,XX +XXX,XX @@
78
-/*
79
- * "Inventra" High-speed Dual-Role Controller (MUSB-HDRC), Mentor Graphics,
80
- * USB2.0 OTG compliant core used in various chips.
81
- *
82
- * Copyright (C) 2008 Nokia Corporation
83
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
84
- *
85
- * This program is free software; you can redistribute it and/or
86
- * modify it under the terms of the GNU General Public License as
87
- * published by the Free Software Foundation; either version 2 or
88
- * (at your option) version 3 of the License.
89
- *
90
- * This program is distributed in the hope that it will be useful,
91
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
92
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
93
- * GNU General Public License for more details.
94
- *
95
- * You should have received a copy of the GNU General Public License along
96
- * with this program; if not, see <http://www.gnu.org/licenses/>.
97
- *
98
- * Only host-mode and non-DMA accesses are currently supported.
99
- */
100
-#include "qemu/osdep.h"
101
-#include "qemu/timer.h"
102
-#include "hw/usb.h"
103
-#include "hw/usb/hcd-musb.h"
104
-#include "hw/irq.h"
105
-#include "hw/hw.h"
106
-
107
-/* Common USB registers */
108
-#define MUSB_HDRC_FADDR 0x00 /* 8-bit */
109
-#define MUSB_HDRC_POWER 0x01 /* 8-bit */
110
-
111
-#define MUSB_HDRC_INTRTX 0x02 /* 16-bit */
112
-#define MUSB_HDRC_INTRRX 0x04
113
-#define MUSB_HDRC_INTRTXE 0x06
114
-#define MUSB_HDRC_INTRRXE 0x08
115
-#define MUSB_HDRC_INTRUSB 0x0a /* 8 bit */
116
-#define MUSB_HDRC_INTRUSBE 0x0b /* 8 bit */
117
-#define MUSB_HDRC_FRAME 0x0c /* 16-bit */
118
-#define MUSB_HDRC_INDEX 0x0e /* 8 bit */
119
-#define MUSB_HDRC_TESTMODE 0x0f /* 8 bit */
120
-
121
-/* Per-EP registers in indexed mode */
122
-#define MUSB_HDRC_EP_IDX 0x10 /* 8-bit */
123
-
124
-/* EP FIFOs */
125
-#define MUSB_HDRC_FIFO 0x20
126
-
127
-/* Additional Control Registers */
128
-#define MUSB_HDRC_DEVCTL 0x60 /* 8 bit */
129
-
130
-/* These are indexed */
131
-#define MUSB_HDRC_TXFIFOSZ 0x62 /* 8 bit (see masks) */
132
-#define MUSB_HDRC_RXFIFOSZ 0x63 /* 8 bit (see masks) */
133
-#define MUSB_HDRC_TXFIFOADDR 0x64 /* 16 bit offset shifted right 3 */
134
-#define MUSB_HDRC_RXFIFOADDR 0x66 /* 16 bit offset shifted right 3 */
135
-
136
-/* Some more registers */
137
-#define MUSB_HDRC_VCTRL 0x68 /* 8 bit */
138
-#define MUSB_HDRC_HWVERS 0x6c /* 8 bit */
139
-
140
-/* Added in HDRC 1.9(?) & MHDRC 1.4 */
141
-/* ULPI pass-through */
142
-#define MUSB_HDRC_ULPI_VBUSCTL 0x70
143
-#define MUSB_HDRC_ULPI_REGDATA 0x74
144
-#define MUSB_HDRC_ULPI_REGADDR 0x75
145
-#define MUSB_HDRC_ULPI_REGCTL 0x76
146
-
147
-/* Extended config & PHY control */
148
-#define MUSB_HDRC_ENDCOUNT 0x78 /* 8 bit */
149
-#define MUSB_HDRC_DMARAMCFG 0x79 /* 8 bit */
150
-#define MUSB_HDRC_PHYWAIT 0x7a /* 8 bit */
151
-#define MUSB_HDRC_PHYVPLEN 0x7b /* 8 bit */
152
-#define MUSB_HDRC_HS_EOF1 0x7c /* 8 bit, units of 546.1 us */
153
-#define MUSB_HDRC_FS_EOF1 0x7d /* 8 bit, units of 533.3 ns */
154
-#define MUSB_HDRC_LS_EOF1 0x7e /* 8 bit, units of 1.067 us */
155
-
156
-/* Per-EP BUSCTL registers */
157
-#define MUSB_HDRC_BUSCTL 0x80
158
-
159
-/* Per-EP registers in flat mode */
160
-#define MUSB_HDRC_EP 0x100
161
-
162
-/* offsets to registers in flat model */
163
-#define MUSB_HDRC_TXMAXP 0x00 /* 16 bit apparently */
164
-#define MUSB_HDRC_TXCSR 0x02 /* 16 bit apparently */
165
-#define MUSB_HDRC_CSR0 MUSB_HDRC_TXCSR /* re-used for EP0 */
166
-#define MUSB_HDRC_RXMAXP 0x04 /* 16 bit apparently */
167
-#define MUSB_HDRC_RXCSR 0x06 /* 16 bit apparently */
168
-#define MUSB_HDRC_RXCOUNT 0x08 /* 16 bit apparently */
169
-#define MUSB_HDRC_COUNT0 MUSB_HDRC_RXCOUNT /* re-used for EP0 */
170
-#define MUSB_HDRC_TXTYPE 0x0a /* 8 bit apparently */
171
-#define MUSB_HDRC_TYPE0 MUSB_HDRC_TXTYPE /* re-used for EP0 */
172
-#define MUSB_HDRC_TXINTERVAL 0x0b /* 8 bit apparently */
173
-#define MUSB_HDRC_NAKLIMIT0 MUSB_HDRC_TXINTERVAL /* re-used for EP0 */
174
-#define MUSB_HDRC_RXTYPE 0x0c /* 8 bit apparently */
175
-#define MUSB_HDRC_RXINTERVAL 0x0d /* 8 bit apparently */
176
-#define MUSB_HDRC_FIFOSIZE 0x0f /* 8 bit apparently */
177
-#define MUSB_HDRC_CONFIGDATA MGC_O_HDRC_FIFOSIZE /* re-used for EP0 */
178
-
179
-/* "Bus control" registers */
180
-#define MUSB_HDRC_TXFUNCADDR 0x00
181
-#define MUSB_HDRC_TXHUBADDR 0x02
182
-#define MUSB_HDRC_TXHUBPORT 0x03
183
-
184
-#define MUSB_HDRC_RXFUNCADDR 0x04
185
-#define MUSB_HDRC_RXHUBADDR 0x06
186
-#define MUSB_HDRC_RXHUBPORT 0x07
187
-
188
-/*
189
- * MUSBHDRC Register bit masks
190
- */
191
-
192
-/* POWER */
193
-#define MGC_M_POWER_ISOUPDATE 0x80
194
-#define MGC_M_POWER_SOFTCONN 0x40
195
-#define MGC_M_POWER_HSENAB 0x20
196
-#define MGC_M_POWER_HSMODE 0x10
197
-#define MGC_M_POWER_RESET 0x08
198
-#define MGC_M_POWER_RESUME 0x04
199
-#define MGC_M_POWER_SUSPENDM 0x02
200
-#define MGC_M_POWER_ENSUSPEND 0x01
201
-
202
-/* INTRUSB */
203
-#define MGC_M_INTR_SUSPEND 0x01
204
-#define MGC_M_INTR_RESUME 0x02
205
-#define MGC_M_INTR_RESET 0x04
206
-#define MGC_M_INTR_BABBLE 0x04
207
-#define MGC_M_INTR_SOF 0x08
208
-#define MGC_M_INTR_CONNECT 0x10
209
-#define MGC_M_INTR_DISCONNECT 0x20
210
-#define MGC_M_INTR_SESSREQ 0x40
211
-#define MGC_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */
212
-#define MGC_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */
213
-
214
-/* DEVCTL */
215
-#define MGC_M_DEVCTL_BDEVICE 0x80
216
-#define MGC_M_DEVCTL_FSDEV 0x40
217
-#define MGC_M_DEVCTL_LSDEV 0x20
218
-#define MGC_M_DEVCTL_VBUS 0x18
219
-#define MGC_S_DEVCTL_VBUS 3
220
-#define MGC_M_DEVCTL_HM 0x04
221
-#define MGC_M_DEVCTL_HR 0x02
222
-#define MGC_M_DEVCTL_SESSION 0x01
223
-
224
-/* TESTMODE */
225
-#define MGC_M_TEST_FORCE_HOST 0x80
226
-#define MGC_M_TEST_FIFO_ACCESS 0x40
227
-#define MGC_M_TEST_FORCE_FS 0x20
228
-#define MGC_M_TEST_FORCE_HS 0x10
229
-#define MGC_M_TEST_PACKET 0x08
230
-#define MGC_M_TEST_K 0x04
231
-#define MGC_M_TEST_J 0x02
232
-#define MGC_M_TEST_SE0_NAK 0x01
233
-
234
-/* CSR0 */
235
-#define MGC_M_CSR0_FLUSHFIFO 0x0100
236
-#define MGC_M_CSR0_TXPKTRDY 0x0002
237
-#define MGC_M_CSR0_RXPKTRDY 0x0001
238
-
239
-/* CSR0 in Peripheral mode */
240
-#define MGC_M_CSR0_P_SVDSETUPEND 0x0080
241
-#define MGC_M_CSR0_P_SVDRXPKTRDY 0x0040
242
-#define MGC_M_CSR0_P_SENDSTALL 0x0020
243
-#define MGC_M_CSR0_P_SETUPEND 0x0010
244
-#define MGC_M_CSR0_P_DATAEND 0x0008
245
-#define MGC_M_CSR0_P_SENTSTALL 0x0004
246
-
247
-/* CSR0 in Host mode */
248
-#define MGC_M_CSR0_H_NO_PING 0x0800
249
-#define MGC_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */
250
-#define MGC_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */
251
-#define MGC_M_CSR0_H_NAKTIMEOUT 0x0080
252
-#define MGC_M_CSR0_H_STATUSPKT 0x0040
253
-#define MGC_M_CSR0_H_REQPKT 0x0020
254
-#define MGC_M_CSR0_H_ERROR 0x0010
255
-#define MGC_M_CSR0_H_SETUPPKT 0x0008
256
-#define MGC_M_CSR0_H_RXSTALL 0x0004
257
-
258
-/* CONFIGDATA */
259
-#define MGC_M_CONFIGDATA_MPRXE 0x80 /* auto bulk pkt combining */
260
-#define MGC_M_CONFIGDATA_MPTXE 0x40 /* auto bulk pkt splitting */
261
-#define MGC_M_CONFIGDATA_BIGENDIAN 0x20
262
-#define MGC_M_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */
263
-#define MGC_M_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */
264
-#define MGC_M_CONFIGDATA_DYNFIFO 0x04 /* dynamic FIFO sizing */
265
-#define MGC_M_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */
266
-#define MGC_M_CONFIGDATA_UTMIDW 0x01 /* Width, 0 => 8b, 1 => 16b */
267
-
268
-/* TXCSR in Peripheral and Host mode */
269
-#define MGC_M_TXCSR_AUTOSET 0x8000
270
-#define MGC_M_TXCSR_ISO 0x4000
271
-#define MGC_M_TXCSR_MODE 0x2000
272
-#define MGC_M_TXCSR_DMAENAB 0x1000
273
-#define MGC_M_TXCSR_FRCDATATOG 0x0800
274
-#define MGC_M_TXCSR_DMAMODE 0x0400
275
-#define MGC_M_TXCSR_CLRDATATOG 0x0040
276
-#define MGC_M_TXCSR_FLUSHFIFO 0x0008
277
-#define MGC_M_TXCSR_FIFONOTEMPTY 0x0002
278
-#define MGC_M_TXCSR_TXPKTRDY 0x0001
279
-
280
-/* TXCSR in Peripheral mode */
281
-#define MGC_M_TXCSR_P_INCOMPTX 0x0080
282
-#define MGC_M_TXCSR_P_SENTSTALL 0x0020
283
-#define MGC_M_TXCSR_P_SENDSTALL 0x0010
284
-#define MGC_M_TXCSR_P_UNDERRUN 0x0004
285
-
286
-/* TXCSR in Host mode */
287
-#define MGC_M_TXCSR_H_WR_DATATOGGLE 0x0200
288
-#define MGC_M_TXCSR_H_DATATOGGLE 0x0100
289
-#define MGC_M_TXCSR_H_NAKTIMEOUT 0x0080
290
-#define MGC_M_TXCSR_H_RXSTALL 0x0020
291
-#define MGC_M_TXCSR_H_ERROR 0x0004
292
-
293
-/* RXCSR in Peripheral and Host mode */
294
-#define MGC_M_RXCSR_AUTOCLEAR 0x8000
295
-#define MGC_M_RXCSR_DMAENAB 0x2000
296
-#define MGC_M_RXCSR_DISNYET 0x1000
297
-#define MGC_M_RXCSR_DMAMODE 0x0800
298
-#define MGC_M_RXCSR_INCOMPRX 0x0100
299
-#define MGC_M_RXCSR_CLRDATATOG 0x0080
300
-#define MGC_M_RXCSR_FLUSHFIFO 0x0010
301
-#define MGC_M_RXCSR_DATAERROR 0x0008
302
-#define MGC_M_RXCSR_FIFOFULL 0x0002
303
-#define MGC_M_RXCSR_RXPKTRDY 0x0001
304
-
305
-/* RXCSR in Peripheral mode */
306
-#define MGC_M_RXCSR_P_ISO 0x4000
307
-#define MGC_M_RXCSR_P_SENTSTALL 0x0040
308
-#define MGC_M_RXCSR_P_SENDSTALL 0x0020
309
-#define MGC_M_RXCSR_P_OVERRUN 0x0004
310
-
311
-/* RXCSR in Host mode */
312
-#define MGC_M_RXCSR_H_AUTOREQ 0x4000
313
-#define MGC_M_RXCSR_H_WR_DATATOGGLE 0x0400
314
-#define MGC_M_RXCSR_H_DATATOGGLE 0x0200
315
-#define MGC_M_RXCSR_H_RXSTALL 0x0040
316
-#define MGC_M_RXCSR_H_REQPKT 0x0020
317
-#define MGC_M_RXCSR_H_ERROR 0x0004
318
-
319
-/* HUBADDR */
320
-#define MGC_M_HUBADDR_MULTI_TT 0x80
321
-
322
-/* ULPI: Added in HDRC 1.9(?) & MHDRC 1.4 */
323
-#define MGC_M_ULPI_VBCTL_USEEXTVBUSIND 0x02
324
-#define MGC_M_ULPI_VBCTL_USEEXTVBUS 0x01
325
-#define MGC_M_ULPI_REGCTL_INT_ENABLE 0x08
326
-#define MGC_M_ULPI_REGCTL_READNOTWRITE 0x04
327
-#define MGC_M_ULPI_REGCTL_COMPLETE 0x02
328
-#define MGC_M_ULPI_REGCTL_REG 0x01
329
-
330
-/* #define MUSB_DEBUG */
331
-
332
-#ifdef MUSB_DEBUG
333
-#define TRACE(fmt, ...) fprintf(stderr, "%s@%d: " fmt "\n", __func__, \
334
- __LINE__, ##__VA_ARGS__)
335
-#else
336
-#define TRACE(...)
337
-#endif
338
-
339
-
340
-static void musb_attach(USBPort *port);
341
-static void musb_detach(USBPort *port);
342
-static void musb_child_detach(USBPort *port, USBDevice *child);
343
-static void musb_schedule_cb(USBPort *port, USBPacket *p);
344
-static void musb_async_cancel_device(MUSBState *s, USBDevice *dev);
345
-
346
-static USBPortOps musb_port_ops = {
347
- .attach = musb_attach,
348
- .detach = musb_detach,
349
- .child_detach = musb_child_detach,
350
- .complete = musb_schedule_cb,
351
-};
352
-
353
-static USBBusOps musb_bus_ops = {
354
-};
355
-
356
-typedef struct MUSBPacket MUSBPacket;
357
-typedef struct MUSBEndPoint MUSBEndPoint;
358
-
359
-struct MUSBPacket {
360
- USBPacket p;
361
- MUSBEndPoint *ep;
362
- int dir;
363
-};
364
-
365
-struct MUSBEndPoint {
366
- uint16_t faddr[2];
367
- uint8_t haddr[2];
368
- uint8_t hport[2];
369
- uint16_t csr[2];
370
- uint16_t maxp[2];
371
- uint16_t rxcount;
372
- uint8_t type[2];
373
- uint8_t interval[2];
374
- uint8_t config;
375
- uint8_t fifosize;
376
- int timeout[2]; /* Always in microframes */
377
-
378
- uint8_t *buf[2];
379
- int fifolen[2];
380
- int fifostart[2];
381
- int fifoaddr[2];
382
- MUSBPacket packey[2];
383
- int status[2];
384
- int ext_size[2];
385
-
386
- /* For callbacks' use */
387
- int epnum;
388
- int interrupt[2];
389
- MUSBState *musb;
390
- USBCallback *delayed_cb[2];
391
- QEMUTimer *intv_timer[2];
392
-};
393
-
394
-struct MUSBState {
395
- qemu_irq irqs[musb_irq_max];
396
- USBBus bus;
397
- USBPort port;
398
-
399
- int idx;
400
- uint8_t devctl;
401
- uint8_t power;
402
- uint8_t faddr;
403
-
404
- uint8_t intr;
405
- uint8_t mask;
406
- uint16_t tx_intr;
407
- uint16_t tx_mask;
408
- uint16_t rx_intr;
409
- uint16_t rx_mask;
410
-
411
- int setup_len;
412
- int session;
413
-
414
- uint8_t buf[0x8000];
415
-
416
- /* Duplicating the world since 2008!... probably we should have 32
417
- * logical, single endpoints instead. */
418
- MUSBEndPoint ep[16];
419
-};
420
-
421
-void musb_reset(MUSBState *s)
422
-{
423
- int i;
424
-
425
- s->faddr = 0x00;
426
- s->devctl = 0;
427
- s->power = MGC_M_POWER_HSENAB;
428
- s->tx_intr = 0x0000;
429
- s->rx_intr = 0x0000;
430
- s->tx_mask = 0xffff;
431
- s->rx_mask = 0xffff;
432
- s->intr = 0x00;
433
- s->mask = 0x06;
434
- s->idx = 0;
435
-
436
- s->setup_len = 0;
437
- s->session = 0;
438
- memset(s->buf, 0, sizeof(s->buf));
439
-
440
- /* TODO: _DW */
441
- s->ep[0].config = MGC_M_CONFIGDATA_SOFTCONE | MGC_M_CONFIGDATA_DYNFIFO;
442
- for (i = 0; i < 16; i ++) {
443
- s->ep[i].fifosize = 64;
444
- s->ep[i].maxp[0] = 0x40;
445
- s->ep[i].maxp[1] = 0x40;
446
- s->ep[i].musb = s;
447
- s->ep[i].epnum = i;
448
- usb_packet_init(&s->ep[i].packey[0].p);
449
- usb_packet_init(&s->ep[i].packey[1].p);
450
- }
451
-}
452
-
453
-struct MUSBState *musb_init(DeviceState *parent_device, int gpio_base)
454
-{
455
- MUSBState *s = g_malloc0(sizeof(*s));
456
- int i;
457
-
458
- for (i = 0; i < musb_irq_max; i++) {
459
- s->irqs[i] = qdev_get_gpio_in(parent_device, gpio_base + i);
460
- }
461
-
462
- musb_reset(s);
463
-
464
- usb_bus_new(&s->bus, sizeof(s->bus), &musb_bus_ops, parent_device);
465
- usb_register_port(&s->bus, &s->port, s, 0, &musb_port_ops,
466
- USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
467
-
468
- return s;
469
-}
470
-
471
-static void musb_vbus_set(MUSBState *s, int level)
472
-{
473
- if (level)
474
- s->devctl |= 3 << MGC_S_DEVCTL_VBUS;
475
- else
476
- s->devctl &= ~MGC_M_DEVCTL_VBUS;
477
-
478
- qemu_set_irq(s->irqs[musb_set_vbus], level);
479
-}
480
-
481
-static void musb_intr_set(MUSBState *s, int line, int level)
482
-{
483
- if (!level) {
484
- s->intr &= ~(1 << line);
485
- qemu_irq_lower(s->irqs[line]);
486
- } else if (s->mask & (1 << line)) {
487
- s->intr |= 1 << line;
488
- qemu_irq_raise(s->irqs[line]);
489
- }
490
-}
491
-
492
-static void musb_tx_intr_set(MUSBState *s, int line, int level)
493
-{
494
- if (!level) {
495
- s->tx_intr &= ~(1 << line);
496
- if (!s->tx_intr)
497
- qemu_irq_lower(s->irqs[musb_irq_tx]);
498
- } else if (s->tx_mask & (1 << line)) {
499
- s->tx_intr |= 1 << line;
500
- qemu_irq_raise(s->irqs[musb_irq_tx]);
501
- }
502
-}
503
-
504
-static void musb_rx_intr_set(MUSBState *s, int line, int level)
505
-{
506
- if (line) {
507
- if (!level) {
508
- s->rx_intr &= ~(1 << line);
509
- if (!s->rx_intr)
510
- qemu_irq_lower(s->irqs[musb_irq_rx]);
511
- } else if (s->rx_mask & (1 << line)) {
512
- s->rx_intr |= 1 << line;
513
- qemu_irq_raise(s->irqs[musb_irq_rx]);
514
- }
515
- } else
516
- musb_tx_intr_set(s, line, level);
517
-}
518
-
519
-uint32_t musb_core_intr_get(MUSBState *s)
520
-{
521
- return (s->rx_intr << 15) | s->tx_intr;
522
-}
523
-
524
-void musb_core_intr_clear(MUSBState *s, uint32_t mask)
525
-{
526
- if (s->rx_intr) {
527
- s->rx_intr &= mask >> 15;
528
- if (!s->rx_intr)
529
- qemu_irq_lower(s->irqs[musb_irq_rx]);
530
- }
531
-
532
- if (s->tx_intr) {
533
- s->tx_intr &= mask & 0xffff;
534
- if (!s->tx_intr)
535
- qemu_irq_lower(s->irqs[musb_irq_tx]);
536
- }
537
-}
538
-
539
-void musb_set_size(MUSBState *s, int epnum, int size, int is_tx)
540
-{
541
- s->ep[epnum].ext_size[!is_tx] = size;
542
- s->ep[epnum].fifostart[0] = 0;
543
- s->ep[epnum].fifostart[1] = 0;
544
- s->ep[epnum].fifolen[0] = 0;
545
- s->ep[epnum].fifolen[1] = 0;
546
-}
547
-
548
-static void musb_session_update(MUSBState *s, int prev_dev, int prev_sess)
549
-{
550
- int detect_prev = prev_dev && prev_sess;
551
- int detect = !!s->port.dev && s->session;
552
-
553
- if (detect && !detect_prev) {
554
- /* Let's skip the ID pin sense and VBUS sense formalities and
555
- * and signal a successful SRP directly. This should work at least
556
- * for the Linux driver stack. */
557
- musb_intr_set(s, musb_irq_connect, 1);
558
-
559
- if (s->port.dev->speed == USB_SPEED_LOW) {
560
- s->devctl &= ~MGC_M_DEVCTL_FSDEV;
561
- s->devctl |= MGC_M_DEVCTL_LSDEV;
562
- } else {
563
- s->devctl |= MGC_M_DEVCTL_FSDEV;
564
- s->devctl &= ~MGC_M_DEVCTL_LSDEV;
565
- }
566
-
567
- /* A-mode? */
568
- s->devctl &= ~MGC_M_DEVCTL_BDEVICE;
569
-
570
- /* Host-mode bit? */
571
- s->devctl |= MGC_M_DEVCTL_HM;
572
-#if 1
573
- musb_vbus_set(s, 1);
574
-#endif
575
- } else if (!detect && detect_prev) {
576
-#if 1
577
- musb_vbus_set(s, 0);
578
-#endif
579
- }
580
-}
581
-
582
-/* Attach or detach a device on our only port. */
583
-static void musb_attach(USBPort *port)
584
-{
585
- MUSBState *s = (MUSBState *) port->opaque;
586
-
587
- musb_intr_set(s, musb_irq_vbus_request, 1);
588
- musb_session_update(s, 0, s->session);
589
-}
590
-
591
-static void musb_detach(USBPort *port)
592
-{
593
- MUSBState *s = (MUSBState *) port->opaque;
594
-
595
- musb_async_cancel_device(s, port->dev);
596
-
597
- musb_intr_set(s, musb_irq_disconnect, 1);
598
- musb_session_update(s, 1, s->session);
599
-}
600
-
601
-static void musb_child_detach(USBPort *port, USBDevice *child)
602
-{
603
- MUSBState *s = (MUSBState *) port->opaque;
604
-
605
- musb_async_cancel_device(s, child);
606
-}
607
-
608
-static void musb_cb_tick0(void *opaque)
609
-{
610
- MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
611
-
612
- ep->delayed_cb[0](&ep->packey[0].p, opaque);
613
-}
614
-
615
-static void musb_cb_tick1(void *opaque)
616
-{
617
- MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
618
-
619
- ep->delayed_cb[1](&ep->packey[1].p, opaque);
620
-}
621
-
622
-#define musb_cb_tick (dir ? musb_cb_tick1 : musb_cb_tick0)
623
-
624
-static void musb_schedule_cb(USBPort *port, USBPacket *packey)
625
-{
626
- MUSBPacket *p = container_of(packey, MUSBPacket, p);
627
- MUSBEndPoint *ep = p->ep;
628
- int dir = p->dir;
629
- int timeout = 0;
630
-
631
- if (ep->status[dir] == USB_RET_NAK)
632
- timeout = ep->timeout[dir];
633
- else if (ep->interrupt[dir])
634
- timeout = 8;
635
- else {
636
- musb_cb_tick(ep);
637
- return;
638
- }
639
-
640
- if (!ep->intv_timer[dir])
641
- ep->intv_timer[dir] = timer_new_ns(QEMU_CLOCK_VIRTUAL, musb_cb_tick, ep);
642
-
643
- timer_mod(ep->intv_timer[dir], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
644
- muldiv64(timeout, NANOSECONDS_PER_SECOND, 8000));
645
-}
646
-
647
-static int musb_timeout(int ttype, int speed, int val)
648
-{
649
-#if 1
650
- return val << 3;
651
-#endif
652
-
653
- switch (ttype) {
654
- case USB_ENDPOINT_XFER_CONTROL:
655
- if (val < 2)
656
- return 0;
657
- else if (speed == USB_SPEED_HIGH)
658
- return 1 << (val - 1);
659
- else
660
- return 8 << (val - 1);
661
-
662
- case USB_ENDPOINT_XFER_INT:
663
- if (speed == USB_SPEED_HIGH)
664
- if (val < 2)
665
- return 0;
666
- else
667
- return 1 << (val - 1);
668
- else
669
- return val << 3;
670
-
671
- case USB_ENDPOINT_XFER_BULK:
672
- case USB_ENDPOINT_XFER_ISOC:
673
- if (val < 2)
674
- return 0;
675
- else if (speed == USB_SPEED_HIGH)
676
- return 1 << (val - 1);
677
- else
678
- return 8 << (val - 1);
679
- /* TODO: what with low-speed Bulk and Isochronous? */
680
- }
681
-
682
- hw_error("bad interval\n");
683
-}
684
-
685
-static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
686
- int epnum, int pid, int len, USBCallback cb, int dir)
687
-{
688
- USBDevice *dev;
689
- USBEndpoint *uep;
690
- int idx = epnum && dir;
691
- int id;
692
- int ttype;
693
-
694
- /* ep->type[0,1] contains:
695
- * in bits 7:6 the speed (0 - invalid, 1 - high, 2 - full, 3 - slow)
696
- * in bits 5:4 the transfer type (BULK / INT)
697
- * in bits 3:0 the EP num
698
- */
699
- ttype = epnum ? (ep->type[idx] >> 4) & 3 : 0;
700
-
701
- ep->timeout[dir] = musb_timeout(ttype,
702
- ep->type[idx] >> 6, ep->interval[idx]);
703
- ep->interrupt[dir] = ttype == USB_ENDPOINT_XFER_INT;
704
- ep->delayed_cb[dir] = cb;
705
-
706
- /* A wild guess on the FADDR semantics... */
707
- dev = usb_find_device(&s->port, ep->faddr[idx]);
708
- if (dev == NULL) {
709
- return;
710
- }
711
- uep = usb_ep_get(dev, pid, ep->type[idx] & 0xf);
712
- id = pid | (dev->addr << 16) | (uep->nr << 8);
713
- usb_packet_setup(&ep->packey[dir].p, pid, uep, 0, id, false, true);
714
- usb_packet_addbuf(&ep->packey[dir].p, ep->buf[idx], len);
715
- ep->packey[dir].ep = ep;
716
- ep->packey[dir].dir = dir;
717
-
718
- usb_handle_packet(dev, &ep->packey[dir].p);
719
-
720
- if (ep->packey[dir].p.status == USB_RET_ASYNC) {
721
- usb_device_flush_ep_queue(dev, uep);
722
- ep->status[dir] = len;
723
- return;
724
- }
725
-
726
- if (ep->packey[dir].p.status == USB_RET_SUCCESS) {
727
- ep->status[dir] = ep->packey[dir].p.actual_length;
728
- } else {
729
- ep->status[dir] = ep->packey[dir].p.status;
730
- }
731
- musb_schedule_cb(&s->port, &ep->packey[dir].p);
732
-}
733
-
734
-static void musb_tx_packet_complete(USBPacket *packey, void *opaque)
735
-{
736
- /* Unfortunately we can't use packey->devep because that's the remote
737
- * endpoint number and may be different than our local. */
738
- MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
739
- int epnum = ep->epnum;
740
- MUSBState *s = ep->musb;
741
-
742
- ep->fifostart[0] = 0;
743
- ep->fifolen[0] = 0;
744
-#ifdef CLEAR_NAK
745
- if (ep->status[0] != USB_RET_NAK) {
746
-#endif
747
- if (epnum)
748
- ep->csr[0] &= ~(MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_TXPKTRDY);
749
- else
750
- ep->csr[0] &= ~MGC_M_CSR0_TXPKTRDY;
751
-#ifdef CLEAR_NAK
752
- }
753
-#endif
754
-
755
- /* Clear all of the error bits first */
756
- if (epnum)
757
- ep->csr[0] &= ~(MGC_M_TXCSR_H_ERROR | MGC_M_TXCSR_H_RXSTALL |
758
- MGC_M_TXCSR_H_NAKTIMEOUT);
759
- else
760
- ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
761
- MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
762
-
763
- if (ep->status[0] == USB_RET_STALL) {
764
- /* Command not supported by target! */
765
- ep->status[0] = 0;
766
-
767
- if (epnum)
768
- ep->csr[0] |= MGC_M_TXCSR_H_RXSTALL;
769
- else
770
- ep->csr[0] |= MGC_M_CSR0_H_RXSTALL;
771
- }
772
-
773
- if (ep->status[0] == USB_RET_NAK) {
774
- ep->status[0] = 0;
775
-
776
- /* NAK timeouts are only generated in Bulk transfers and
777
- * Data-errors in Isochronous. */
778
- if (ep->interrupt[0]) {
779
- return;
780
- }
781
-
782
- if (epnum)
783
- ep->csr[0] |= MGC_M_TXCSR_H_NAKTIMEOUT;
784
- else
785
- ep->csr[0] |= MGC_M_CSR0_H_NAKTIMEOUT;
786
- }
787
-
788
- if (ep->status[0] < 0) {
789
- if (ep->status[0] == USB_RET_BABBLE)
790
- musb_intr_set(s, musb_irq_rst_babble, 1);
791
-
792
- /* Pretend we've tried three times already and failed (in
793
- * case of USB_TOKEN_SETUP). */
794
- if (epnum)
795
- ep->csr[0] |= MGC_M_TXCSR_H_ERROR;
796
- else
797
- ep->csr[0] |= MGC_M_CSR0_H_ERROR;
798
-
799
- musb_tx_intr_set(s, epnum, 1);
800
- return;
801
- }
802
- /* TODO: check len for over/underruns of an OUT packet? */
803
-
804
-#ifdef SETUPLEN_HACK
805
- if (!epnum && ep->packey[0].pid == USB_TOKEN_SETUP)
806
- s->setup_len = ep->packey[0].data[6];
807
-#endif
808
-
809
- /* In DMA mode: if no error, assert DMA request for this EP,
810
- * and skip the interrupt. */
811
- musb_tx_intr_set(s, epnum, 1);
812
-}
813
-
814
-static void musb_rx_packet_complete(USBPacket *packey, void *opaque)
815
-{
816
- /* Unfortunately we can't use packey->devep because that's the remote
817
- * endpoint number and may be different than our local. */
818
- MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
819
- int epnum = ep->epnum;
820
- MUSBState *s = ep->musb;
821
-
822
- ep->fifostart[1] = 0;
823
- ep->fifolen[1] = 0;
824
-
825
-#ifdef CLEAR_NAK
826
- if (ep->status[1] != USB_RET_NAK) {
827
-#endif
828
- ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT;
829
- if (!epnum)
830
- ep->csr[0] &= ~MGC_M_CSR0_H_REQPKT;
831
-#ifdef CLEAR_NAK
832
- }
833
-#endif
834
-
835
- /* Clear all of the imaginable error bits first */
836
- ep->csr[1] &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_H_RXSTALL |
837
- MGC_M_RXCSR_DATAERROR);
838
- if (!epnum)
839
- ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
840
- MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
841
-
842
- if (ep->status[1] == USB_RET_STALL) {
843
- ep->status[1] = 0;
844
-
845
- ep->csr[1] |= MGC_M_RXCSR_H_RXSTALL;
846
- if (!epnum)
847
- ep->csr[0] |= MGC_M_CSR0_H_RXSTALL;
848
- }
849
-
850
- if (ep->status[1] == USB_RET_NAK) {
851
- ep->status[1] = 0;
852
-
853
- /* NAK timeouts are only generated in Bulk transfers and
854
- * Data-errors in Isochronous. */
855
- if (ep->interrupt[1]) {
856
- musb_packet(s, ep, epnum, USB_TOKEN_IN,
857
- packey->iov.size, musb_rx_packet_complete, 1);
858
- return;
859
- }
860
-
861
- ep->csr[1] |= MGC_M_RXCSR_DATAERROR;
862
- if (!epnum)
863
- ep->csr[0] |= MGC_M_CSR0_H_NAKTIMEOUT;
864
- }
865
-
866
- if (ep->status[1] < 0) {
867
- if (ep->status[1] == USB_RET_BABBLE) {
868
- musb_intr_set(s, musb_irq_rst_babble, 1);
869
- return;
870
- }
871
-
872
- /* Pretend we've tried three times already and failed (in
873
- * case of a control transfer). */
874
- ep->csr[1] |= MGC_M_RXCSR_H_ERROR;
875
- if (!epnum)
876
- ep->csr[0] |= MGC_M_CSR0_H_ERROR;
877
-
878
- musb_rx_intr_set(s, epnum, 1);
879
- return;
880
- }
881
- /* TODO: check len for over/underruns of an OUT packet? */
882
- /* TODO: perhaps make use of e->ext_size[1] here. */
883
-
884
- if (!(ep->csr[1] & (MGC_M_RXCSR_H_RXSTALL | MGC_M_RXCSR_DATAERROR))) {
885
- ep->csr[1] |= MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY;
886
- if (!epnum)
887
- ep->csr[0] |= MGC_M_CSR0_RXPKTRDY;
888
-
889
- ep->rxcount = ep->status[1]; /* XXX: MIN(packey->len, ep->maxp[1]); */
890
- /* In DMA mode: assert DMA request for this EP */
891
- }
892
-
893
- /* Only if DMA has not been asserted */
894
- musb_rx_intr_set(s, epnum, 1);
895
-}
896
-
897
-static void musb_async_cancel_device(MUSBState *s, USBDevice *dev)
898
-{
899
- int ep, dir;
900
-
901
- for (ep = 0; ep < 16; ep++) {
902
- for (dir = 0; dir < 2; dir++) {
903
- if (!usb_packet_is_inflight(&s->ep[ep].packey[dir].p) ||
904
- s->ep[ep].packey[dir].p.ep->dev != dev) {
905
- continue;
906
- }
907
- usb_cancel_packet(&s->ep[ep].packey[dir].p);
908
- /* status updates needed here? */
909
- }
910
- }
911
-}
912
-
913
-static void musb_tx_rdy(MUSBState *s, int epnum)
914
-{
915
- MUSBEndPoint *ep = s->ep + epnum;
916
- int pid;
917
- int total, valid = 0;
918
- TRACE("start %d, len %d", ep->fifostart[0], ep->fifolen[0] );
919
- ep->fifostart[0] += ep->fifolen[0];
920
- ep->fifolen[0] = 0;
921
-
922
- /* XXX: how's the total size of the packet retrieved exactly in
923
- * the generic case? */
924
- total = ep->maxp[0] & 0x3ff;
925
-
926
- if (ep->ext_size[0]) {
927
- total = ep->ext_size[0];
928
- ep->ext_size[0] = 0;
929
- valid = 1;
930
- }
931
-
932
- /* If the packet is not fully ready yet, wait for a next segment. */
933
- if (epnum && (ep->fifostart[0]) < total)
934
- return;
935
-
936
- if (!valid)
937
- total = ep->fifostart[0];
938
-
939
- pid = USB_TOKEN_OUT;
940
- if (!epnum && (ep->csr[0] & MGC_M_CSR0_H_SETUPPKT)) {
941
- pid = USB_TOKEN_SETUP;
942
- if (total != 8) {
943
- TRACE("illegal SETUPPKT length of %i bytes", total);
944
- }
945
- /* Controller should retry SETUP packets three times on errors
946
- * but it doesn't make sense for us to do that. */
947
- }
948
-
949
- musb_packet(s, ep, epnum, pid, total, musb_tx_packet_complete, 0);
950
-}
951
-
952
-static void musb_rx_req(MUSBState *s, int epnum)
953
-{
954
- MUSBEndPoint *ep = s->ep + epnum;
955
- int total;
956
-
957
- /* If we already have a packet, which didn't fit into the
958
- * 64 bytes of the FIFO, only move the FIFO start and return. (Obsolete) */
959
- if (ep->packey[1].p.pid == USB_TOKEN_IN && ep->status[1] >= 0 &&
960
- (ep->fifostart[1]) + ep->rxcount <
961
- ep->packey[1].p.iov.size) {
962
- TRACE("0x%08x, %d", ep->fifostart[1], ep->rxcount );
963
- ep->fifostart[1] += ep->rxcount;
964
- ep->fifolen[1] = 0;
965
-
966
- ep->rxcount = MIN(ep->packey[0].p.iov.size - (ep->fifostart[1]),
967
- ep->maxp[1]);
968
-
969
- ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT;
970
- if (!epnum)
971
- ep->csr[0] &= ~MGC_M_CSR0_H_REQPKT;
972
-
973
- /* Clear all of the error bits first */
974
- ep->csr[1] &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_H_RXSTALL |
975
- MGC_M_RXCSR_DATAERROR);
976
- if (!epnum)
977
- ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
978
- MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
979
-
980
- ep->csr[1] |= MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY;
981
- if (!epnum)
982
- ep->csr[0] |= MGC_M_CSR0_RXPKTRDY;
983
- musb_rx_intr_set(s, epnum, 1);
984
- return;
985
- }
986
-
987
- /* The driver sets maxp[1] to 64 or less because it knows the hardware
988
- * FIFO is this deep. Bigger packets get split in
989
- * usb_generic_handle_packet but we can also do the splitting locally
990
- * for performance. It turns out we can also have a bigger FIFO and
991
- * ignore the limit set in ep->maxp[1]. The Linux MUSB driver deals
992
- * OK with single packets of even 32KB and we avoid splitting, however
993
- * usb_msd.c sometimes sends a packet bigger than what Linux expects
994
- * (e.g. 8192 bytes instead of 4096) and we get an OVERRUN. Splitting
995
- * hides this overrun from Linux. Up to 4096 everything is fine
996
- * though. Currently this is disabled.
997
- *
998
- * XXX: mind ep->fifosize. */
999
- total = MIN(ep->maxp[1] & 0x3ff, sizeof(s->buf));
1000
-
1001
-#ifdef SETUPLEN_HACK
1002
- /* Why should *we* do that instead of Linux? */
1003
- if (!epnum) {
1004
- if (ep->packey[0].p.devaddr == 2) {
1005
- total = MIN(s->setup_len, 8);
1006
- } else {
1007
- total = MIN(s->setup_len, 64);
1008
- }
1009
- s->setup_len -= total;
1010
- }
1011
-#endif
1012
-
1013
- musb_packet(s, ep, epnum, USB_TOKEN_IN, total, musb_rx_packet_complete, 1);
1014
-}
1015
-
1016
-static uint8_t musb_read_fifo(MUSBEndPoint *ep)
1017
-{
1018
- uint8_t value;
1019
- if (ep->fifolen[1] >= 64) {
1020
- /* We have a FIFO underrun */
1021
- TRACE("EP%d FIFO is now empty, stop reading", ep->epnum);
1022
- return 0x00000000;
1023
- }
1024
- /* In DMA mode clear RXPKTRDY and set REQPKT automatically
1025
- * (if AUTOREQ is set) */
1026
-
1027
- ep->csr[1] &= ~MGC_M_RXCSR_FIFOFULL;
1028
- value=ep->buf[1][ep->fifostart[1] + ep->fifolen[1] ++];
1029
- TRACE("EP%d 0x%02x, %d", ep->epnum, value, ep->fifolen[1] );
1030
- return value;
1031
-}
1032
-
1033
-static void musb_write_fifo(MUSBEndPoint *ep, uint8_t value)
1034
-{
1035
- TRACE("EP%d = %02x", ep->epnum, value);
1036
- if (ep->fifolen[0] >= 64) {
1037
- /* We have a FIFO overrun */
1038
- TRACE("EP%d FIFO exceeded 64 bytes, stop feeding data", ep->epnum);
1039
- return;
1040
- }
1041
-
1042
- ep->buf[0][ep->fifostart[0] + ep->fifolen[0] ++] = value;
1043
- ep->csr[0] |= MGC_M_TXCSR_FIFONOTEMPTY;
1044
-}
1045
-
1046
-static void musb_ep_frame_cancel(MUSBEndPoint *ep, int dir)
1047
-{
1048
- if (ep->intv_timer[dir])
1049
- timer_del(ep->intv_timer[dir]);
1050
-}
1051
-
1052
-/* Bus control */
1053
-static uint8_t musb_busctl_readb(void *opaque, int ep, int addr)
1054
-{
1055
- MUSBState *s = (MUSBState *) opaque;
1056
-
1057
- switch (addr) {
1058
- /* For USB2.0 HS hubs only */
1059
- case MUSB_HDRC_TXHUBADDR:
1060
- return s->ep[ep].haddr[0];
1061
- case MUSB_HDRC_TXHUBPORT:
1062
- return s->ep[ep].hport[0];
1063
- case MUSB_HDRC_RXHUBADDR:
1064
- return s->ep[ep].haddr[1];
1065
- case MUSB_HDRC_RXHUBPORT:
1066
- return s->ep[ep].hport[1];
1067
-
1068
- default:
1069
- TRACE("unknown register 0x%02x", addr);
1070
- return 0x00;
1071
- };
1072
-}
1073
-
1074
-static void musb_busctl_writeb(void *opaque, int ep, int addr, uint8_t value)
1075
-{
1076
- MUSBState *s = (MUSBState *) opaque;
1077
-
1078
- switch (addr) {
1079
- case MUSB_HDRC_TXFUNCADDR:
1080
- s->ep[ep].faddr[0] = value;
1081
- break;
1082
- case MUSB_HDRC_RXFUNCADDR:
1083
- s->ep[ep].faddr[1] = value;
1084
- break;
1085
- case MUSB_HDRC_TXHUBADDR:
1086
- s->ep[ep].haddr[0] = value;
1087
- break;
1088
- case MUSB_HDRC_TXHUBPORT:
1089
- s->ep[ep].hport[0] = value;
1090
- break;
1091
- case MUSB_HDRC_RXHUBADDR:
1092
- s->ep[ep].haddr[1] = value;
1093
- break;
1094
- case MUSB_HDRC_RXHUBPORT:
1095
- s->ep[ep].hport[1] = value;
1096
- break;
1097
-
1098
- default:
1099
- TRACE("unknown register 0x%02x", addr);
1100
- break;
1101
- };
1102
-}
1103
-
1104
-static uint16_t musb_busctl_readh(void *opaque, int ep, int addr)
1105
-{
1106
- MUSBState *s = (MUSBState *) opaque;
1107
-
1108
- switch (addr) {
1109
- case MUSB_HDRC_TXFUNCADDR:
1110
- return s->ep[ep].faddr[0];
1111
- case MUSB_HDRC_RXFUNCADDR:
1112
- return s->ep[ep].faddr[1];
1113
-
1114
- default:
1115
- return musb_busctl_readb(s, ep, addr) |
1116
- (musb_busctl_readb(s, ep, addr | 1) << 8);
1117
- };
1118
-}
1119
-
1120
-static void musb_busctl_writeh(void *opaque, int ep, int addr, uint16_t value)
1121
-{
1122
- MUSBState *s = (MUSBState *) opaque;
1123
-
1124
- switch (addr) {
1125
- case MUSB_HDRC_TXFUNCADDR:
1126
- s->ep[ep].faddr[0] = value;
1127
- break;
1128
- case MUSB_HDRC_RXFUNCADDR:
1129
- s->ep[ep].faddr[1] = value;
1130
- break;
1131
-
1132
- default:
1133
- musb_busctl_writeb(s, ep, addr, value & 0xff);
1134
- musb_busctl_writeb(s, ep, addr | 1, value >> 8);
1135
- };
1136
-}
1137
-
1138
-/* Endpoint control */
1139
-static uint8_t musb_ep_readb(void *opaque, int ep, int addr)
1140
-{
1141
- MUSBState *s = (MUSBState *) opaque;
1142
-
1143
- switch (addr) {
1144
- case MUSB_HDRC_TXTYPE:
1145
- return s->ep[ep].type[0];
1146
- case MUSB_HDRC_TXINTERVAL:
1147
- return s->ep[ep].interval[0];
1148
- case MUSB_HDRC_RXTYPE:
1149
- return s->ep[ep].type[1];
1150
- case MUSB_HDRC_RXINTERVAL:
1151
- return s->ep[ep].interval[1];
1152
- case (MUSB_HDRC_FIFOSIZE & ~1):
1153
- return 0x00;
1154
- case MUSB_HDRC_FIFOSIZE:
1155
- return ep ? s->ep[ep].fifosize : s->ep[ep].config;
1156
- case MUSB_HDRC_RXCOUNT:
1157
- return s->ep[ep].rxcount;
1158
-
1159
- default:
1160
- TRACE("unknown register 0x%02x", addr);
1161
- return 0x00;
1162
- };
1163
-}
1164
-
1165
-static void musb_ep_writeb(void *opaque, int ep, int addr, uint8_t value)
1166
-{
1167
- MUSBState *s = (MUSBState *) opaque;
1168
-
1169
- switch (addr) {
1170
- case MUSB_HDRC_TXTYPE:
1171
- s->ep[ep].type[0] = value;
1172
- break;
1173
- case MUSB_HDRC_TXINTERVAL:
1174
- s->ep[ep].interval[0] = value;
1175
- musb_ep_frame_cancel(&s->ep[ep], 0);
1176
- break;
1177
- case MUSB_HDRC_RXTYPE:
1178
- s->ep[ep].type[1] = value;
1179
- break;
1180
- case MUSB_HDRC_RXINTERVAL:
1181
- s->ep[ep].interval[1] = value;
1182
- musb_ep_frame_cancel(&s->ep[ep], 1);
1183
- break;
1184
- case (MUSB_HDRC_FIFOSIZE & ~1):
1185
- break;
1186
- case MUSB_HDRC_FIFOSIZE:
1187
- TRACE("somebody messes with fifosize (now %i bytes)", value);
1188
- s->ep[ep].fifosize = value;
1189
- break;
1190
- default:
1191
- TRACE("unknown register 0x%02x", addr);
1192
- break;
1193
- };
1194
-}
1195
-
1196
-static uint16_t musb_ep_readh(void *opaque, int ep, int addr)
1197
-{
1198
- MUSBState *s = (MUSBState *) opaque;
1199
- uint16_t ret;
1200
-
1201
- switch (addr) {
1202
- case MUSB_HDRC_TXMAXP:
1203
- return s->ep[ep].maxp[0];
1204
- case MUSB_HDRC_TXCSR:
1205
- return s->ep[ep].csr[0];
1206
- case MUSB_HDRC_RXMAXP:
1207
- return s->ep[ep].maxp[1];
1208
- case MUSB_HDRC_RXCSR:
1209
- ret = s->ep[ep].csr[1];
1210
-
1211
- /* TODO: This and other bits probably depend on
1212
- * ep->csr[1] & MGC_M_RXCSR_AUTOCLEAR. */
1213
- if (s->ep[ep].csr[1] & MGC_M_RXCSR_AUTOCLEAR)
1214
- s->ep[ep].csr[1] &= ~MGC_M_RXCSR_RXPKTRDY;
1215
-
1216
- return ret;
1217
- case MUSB_HDRC_RXCOUNT:
1218
- return s->ep[ep].rxcount;
1219
-
1220
- default:
1221
- return musb_ep_readb(s, ep, addr) |
1222
- (musb_ep_readb(s, ep, addr | 1) << 8);
1223
- };
1224
-}
1225
-
1226
-static void musb_ep_writeh(void *opaque, int ep, int addr, uint16_t value)
1227
-{
1228
- MUSBState *s = (MUSBState *) opaque;
1229
-
1230
- switch (addr) {
1231
- case MUSB_HDRC_TXMAXP:
1232
- s->ep[ep].maxp[0] = value;
1233
- break;
1234
- case MUSB_HDRC_TXCSR:
1235
- if (ep) {
1236
- s->ep[ep].csr[0] &= value & 0xa6;
1237
- s->ep[ep].csr[0] |= value & 0xff59;
1238
- } else {
1239
- s->ep[ep].csr[0] &= value & 0x85;
1240
- s->ep[ep].csr[0] |= value & 0xf7a;
1241
- }
1242
-
1243
- musb_ep_frame_cancel(&s->ep[ep], 0);
1244
-
1245
- if ((ep && (value & MGC_M_TXCSR_FLUSHFIFO)) ||
1246
- (!ep && (value & MGC_M_CSR0_FLUSHFIFO))) {
1247
- s->ep[ep].fifolen[0] = 0;
1248
- s->ep[ep].fifostart[0] = 0;
1249
- if (ep)
1250
- s->ep[ep].csr[0] &=
1251
- ~(MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_TXPKTRDY);
1252
- else
1253
- s->ep[ep].csr[0] &=
1254
- ~(MGC_M_CSR0_TXPKTRDY | MGC_M_CSR0_RXPKTRDY);
1255
- }
1256
- if (
1257
- (ep &&
1258
-#ifdef CLEAR_NAK
1259
- (value & MGC_M_TXCSR_TXPKTRDY) &&
1260
- !(value & MGC_M_TXCSR_H_NAKTIMEOUT)) ||
1261
-#else
1262
- (value & MGC_M_TXCSR_TXPKTRDY)) ||
1263
-#endif
1264
- (!ep &&
1265
-#ifdef CLEAR_NAK
1266
- (value & MGC_M_CSR0_TXPKTRDY) &&
1267
- !(value & MGC_M_CSR0_H_NAKTIMEOUT)))
1268
-#else
1269
- (value & MGC_M_CSR0_TXPKTRDY)))
1270
-#endif
1271
- musb_tx_rdy(s, ep);
1272
- if (!ep &&
1273
- (value & MGC_M_CSR0_H_REQPKT) &&
1274
-#ifdef CLEAR_NAK
1275
- !(value & (MGC_M_CSR0_H_NAKTIMEOUT |
1276
- MGC_M_CSR0_RXPKTRDY)))
1277
-#else
1278
- !(value & MGC_M_CSR0_RXPKTRDY))
1279
-#endif
1280
- musb_rx_req(s, ep);
1281
- break;
1282
-
1283
- case MUSB_HDRC_RXMAXP:
1284
- s->ep[ep].maxp[1] = value;
1285
- break;
1286
- case MUSB_HDRC_RXCSR:
1287
- /* (DMA mode only) */
1288
- if (
1289
- (value & MGC_M_RXCSR_H_AUTOREQ) &&
1290
- !(value & MGC_M_RXCSR_RXPKTRDY) &&
1291
- (s->ep[ep].csr[1] & MGC_M_RXCSR_RXPKTRDY))
1292
- value |= MGC_M_RXCSR_H_REQPKT;
1293
-
1294
- s->ep[ep].csr[1] &= 0x102 | (value & 0x4d);
1295
- s->ep[ep].csr[1] |= value & 0xfeb0;
1296
-
1297
- musb_ep_frame_cancel(&s->ep[ep], 1);
1298
-
1299
- if (value & MGC_M_RXCSR_FLUSHFIFO) {
1300
- s->ep[ep].fifolen[1] = 0;
1301
- s->ep[ep].fifostart[1] = 0;
1302
- s->ep[ep].csr[1] &= ~(MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY);
1303
- /* If double buffering and we have two packets ready, flush
1304
- * only the first one and set up the fifo at the second packet. */
1305
- }
1306
-#ifdef CLEAR_NAK
1307
- if ((value & MGC_M_RXCSR_H_REQPKT) && !(value & MGC_M_RXCSR_DATAERROR))
1308
-#else
1309
- if (value & MGC_M_RXCSR_H_REQPKT)
1310
-#endif
1311
- musb_rx_req(s, ep);
1312
- break;
1313
- case MUSB_HDRC_RXCOUNT:
1314
- s->ep[ep].rxcount = value;
1315
- break;
1316
-
1317
- default:
1318
- musb_ep_writeb(s, ep, addr, value & 0xff);
1319
- musb_ep_writeb(s, ep, addr | 1, value >> 8);
1320
- };
1321
-}
1322
-
1323
-/* Generic control */
1324
-static uint32_t musb_readb(void *opaque, hwaddr addr)
1325
-{
1326
- MUSBState *s = (MUSBState *) opaque;
1327
- int ep, i;
1328
- uint8_t ret;
1329
-
1330
- switch (addr) {
1331
- case MUSB_HDRC_FADDR:
1332
- return s->faddr;
1333
- case MUSB_HDRC_POWER:
1334
- return s->power;
1335
- case MUSB_HDRC_INTRUSB:
1336
- ret = s->intr;
1337
- for (i = 0; i < sizeof(ret) * 8; i ++)
1338
- if (ret & (1 << i))
1339
- musb_intr_set(s, i, 0);
1340
- return ret;
1341
- case MUSB_HDRC_INTRUSBE:
1342
- return s->mask;
1343
- case MUSB_HDRC_INDEX:
1344
- return s->idx;
1345
- case MUSB_HDRC_TESTMODE:
1346
- return 0x00;
1347
-
1348
- case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
1349
- return musb_ep_readb(s, s->idx, addr & 0xf);
1350
-
1351
- case MUSB_HDRC_DEVCTL:
1352
- return s->devctl;
1353
-
1354
- case MUSB_HDRC_TXFIFOSZ:
1355
- case MUSB_HDRC_RXFIFOSZ:
1356
- case MUSB_HDRC_VCTRL:
1357
- /* TODO */
1358
- return 0x00;
1359
-
1360
- case MUSB_HDRC_HWVERS:
1361
- return (1 << 10) | 400;
1362
-
1363
- case (MUSB_HDRC_VCTRL | 1):
1364
- case (MUSB_HDRC_HWVERS | 1):
1365
- case (MUSB_HDRC_DEVCTL | 1):
1366
- return 0x00;
1367
-
1368
- case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
1369
- ep = (addr >> 3) & 0xf;
1370
- return musb_busctl_readb(s, ep, addr & 0x7);
1371
-
1372
- case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
1373
- ep = (addr >> 4) & 0xf;
1374
- return musb_ep_readb(s, ep, addr & 0xf);
1375
-
1376
- case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1377
- ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1378
- return musb_read_fifo(s->ep + ep);
1379
-
1380
- default:
1381
- TRACE("unknown register 0x%02x", (int) addr);
1382
- return 0x00;
1383
- };
1384
-}
1385
-
1386
-static void musb_writeb(void *opaque, hwaddr addr, uint32_t value)
1387
-{
1388
- MUSBState *s = (MUSBState *) opaque;
1389
- int ep;
1390
-
1391
- switch (addr) {
1392
- case MUSB_HDRC_FADDR:
1393
- s->faddr = value & 0x7f;
1394
- break;
1395
- case MUSB_HDRC_POWER:
1396
- s->power = (value & 0xef) | (s->power & 0x10);
1397
- /* MGC_M_POWER_RESET is also read-only in Peripheral Mode */
1398
- if ((value & MGC_M_POWER_RESET) && s->port.dev) {
1399
- usb_device_reset(s->port.dev);
1400
- /* Negotiate high-speed operation if MGC_M_POWER_HSENAB is set. */
1401
- if ((value & MGC_M_POWER_HSENAB) &&
1402
- s->port.dev->speed == USB_SPEED_HIGH)
1403
- s->power |= MGC_M_POWER_HSMODE; /* Success */
1404
- /* Restart frame counting. */
1405
- }
1406
- if (value & MGC_M_POWER_SUSPENDM) {
1407
- /* When all transfers finish, suspend and if MGC_M_POWER_ENSUSPEND
1408
- * is set, also go into low power mode. Frame counting stops. */
1409
- /* XXX: Cleared when the interrupt register is read */
1410
- }
1411
- if (value & MGC_M_POWER_RESUME) {
1412
- /* Wait 20ms and signal resuming on the bus. Frame counting
1413
- * restarts. */
1414
- }
1415
- break;
1416
- case MUSB_HDRC_INTRUSB:
1417
- break;
1418
- case MUSB_HDRC_INTRUSBE:
1419
- s->mask = value & 0xff;
1420
- break;
1421
- case MUSB_HDRC_INDEX:
1422
- s->idx = value & 0xf;
1423
- break;
1424
- case MUSB_HDRC_TESTMODE:
1425
- break;
1426
-
1427
- case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
1428
- musb_ep_writeb(s, s->idx, addr & 0xf, value);
1429
- break;
1430
-
1431
- case MUSB_HDRC_DEVCTL:
1432
- s->session = !!(value & MGC_M_DEVCTL_SESSION);
1433
- musb_session_update(s,
1434
- !!s->port.dev,
1435
- !!(s->devctl & MGC_M_DEVCTL_SESSION));
1436
-
1437
- /* It seems this is the only R/W bit in this register? */
1438
- s->devctl &= ~MGC_M_DEVCTL_SESSION;
1439
- s->devctl |= value & MGC_M_DEVCTL_SESSION;
1440
- break;
1441
-
1442
- case MUSB_HDRC_TXFIFOSZ:
1443
- case MUSB_HDRC_RXFIFOSZ:
1444
- case MUSB_HDRC_VCTRL:
1445
- /* TODO */
1446
- break;
1447
-
1448
- case (MUSB_HDRC_VCTRL | 1):
1449
- case (MUSB_HDRC_DEVCTL | 1):
1450
- break;
1451
-
1452
- case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
1453
- ep = (addr >> 3) & 0xf;
1454
- musb_busctl_writeb(s, ep, addr & 0x7, value);
1455
- break;
1456
-
1457
- case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
1458
- ep = (addr >> 4) & 0xf;
1459
- musb_ep_writeb(s, ep, addr & 0xf, value);
1460
- break;
1461
-
1462
- case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1463
- ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1464
- musb_write_fifo(s->ep + ep, value & 0xff);
1465
- break;
1466
-
1467
- default:
1468
- TRACE("unknown register 0x%02x", (int) addr);
1469
- break;
1470
- };
1471
-}
1472
-
1473
-static uint32_t musb_readh(void *opaque, hwaddr addr)
1474
-{
1475
- MUSBState *s = (MUSBState *) opaque;
1476
- int ep, i;
1477
- uint16_t ret;
1478
-
1479
- switch (addr) {
1480
- case MUSB_HDRC_INTRTX:
1481
- ret = s->tx_intr;
1482
- /* Auto clear */
1483
- for (i = 0; i < sizeof(ret) * 8; i ++)
1484
- if (ret & (1 << i))
1485
- musb_tx_intr_set(s, i, 0);
1486
- return ret;
1487
- case MUSB_HDRC_INTRRX:
1488
- ret = s->rx_intr;
1489
- /* Auto clear */
1490
- for (i = 0; i < sizeof(ret) * 8; i ++)
1491
- if (ret & (1 << i))
1492
- musb_rx_intr_set(s, i, 0);
1493
- return ret;
1494
- case MUSB_HDRC_INTRTXE:
1495
- return s->tx_mask;
1496
- case MUSB_HDRC_INTRRXE:
1497
- return s->rx_mask;
1498
-
1499
- case MUSB_HDRC_FRAME:
1500
- /* TODO */
1501
- return 0x0000;
1502
- case MUSB_HDRC_TXFIFOADDR:
1503
- return s->ep[s->idx].fifoaddr[0];
1504
- case MUSB_HDRC_RXFIFOADDR:
1505
- return s->ep[s->idx].fifoaddr[1];
1506
-
1507
- case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
1508
- return musb_ep_readh(s, s->idx, addr & 0xf);
1509
-
1510
- case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
1511
- ep = (addr >> 3) & 0xf;
1512
- return musb_busctl_readh(s, ep, addr & 0x7);
1513
-
1514
- case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
1515
- ep = (addr >> 4) & 0xf;
1516
- return musb_ep_readh(s, ep, addr & 0xf);
1517
-
1518
- case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1519
- ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1520
- return (musb_read_fifo(s->ep + ep) | musb_read_fifo(s->ep + ep) << 8);
1521
-
1522
- default:
1523
- return musb_readb(s, addr) | (musb_readb(s, addr | 1) << 8);
1524
- };
1525
-}
1526
-
1527
-static void musb_writeh(void *opaque, hwaddr addr, uint32_t value)
1528
-{
1529
- MUSBState *s = (MUSBState *) opaque;
1530
- int ep;
1531
-
1532
- switch (addr) {
1533
- case MUSB_HDRC_INTRTXE:
1534
- s->tx_mask = value;
1535
- /* XXX: the masks seem to apply on the raising edge like with
1536
- * edge-triggered interrupts, thus no need to update. I may be
1537
- * wrong though. */
1538
- break;
1539
- case MUSB_HDRC_INTRRXE:
1540
- s->rx_mask = value;
1541
- break;
1542
-
1543
- case MUSB_HDRC_FRAME:
1544
- /* TODO */
1545
- break;
1546
- case MUSB_HDRC_TXFIFOADDR:
1547
- s->ep[s->idx].fifoaddr[0] = value;
1548
- s->ep[s->idx].buf[0] =
1549
- s->buf + ((value << 3) & 0x7ff );
1550
- break;
1551
- case MUSB_HDRC_RXFIFOADDR:
1552
- s->ep[s->idx].fifoaddr[1] = value;
1553
- s->ep[s->idx].buf[1] =
1554
- s->buf + ((value << 3) & 0x7ff);
1555
- break;
1556
-
1557
- case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
1558
- musb_ep_writeh(s, s->idx, addr & 0xf, value);
1559
- break;
1560
-
1561
- case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
1562
- ep = (addr >> 3) & 0xf;
1563
- musb_busctl_writeh(s, ep, addr & 0x7, value);
1564
- break;
1565
-
1566
- case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
1567
- ep = (addr >> 4) & 0xf;
1568
- musb_ep_writeh(s, ep, addr & 0xf, value);
1569
- break;
1570
-
1571
- case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1572
- ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1573
- musb_write_fifo(s->ep + ep, value & 0xff);
1574
- musb_write_fifo(s->ep + ep, (value >> 8) & 0xff);
1575
- break;
1576
-
1577
- default:
1578
- musb_writeb(s, addr, value & 0xff);
1579
- musb_writeb(s, addr | 1, value >> 8);
1580
- };
1581
-}
1582
-
1583
-static uint32_t musb_readw(void *opaque, hwaddr addr)
1584
-{
1585
- MUSBState *s = (MUSBState *) opaque;
1586
- int ep;
1587
-
1588
- switch (addr) {
1589
- case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1590
- ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1591
- return ( musb_read_fifo(s->ep + ep) |
1592
- musb_read_fifo(s->ep + ep) << 8 |
1593
- musb_read_fifo(s->ep + ep) << 16 |
1594
- musb_read_fifo(s->ep + ep) << 24 );
1595
- default:
1596
- TRACE("unknown register 0x%02x", (int) addr);
1597
- return 0x00000000;
1598
- };
1599
-}
1600
-
1601
-static void musb_writew(void *opaque, hwaddr addr, uint32_t value)
1602
-{
1603
- MUSBState *s = (MUSBState *) opaque;
1604
- int ep;
1605
-
1606
- switch (addr) {
1607
- case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
1608
- ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
1609
- musb_write_fifo(s->ep + ep, value & 0xff);
1610
- musb_write_fifo(s->ep + ep, (value >> 8 ) & 0xff);
1611
- musb_write_fifo(s->ep + ep, (value >> 16) & 0xff);
1612
- musb_write_fifo(s->ep + ep, (value >> 24) & 0xff);
1613
- break;
1614
- default:
1615
- TRACE("unknown register 0x%02x", (int) addr);
1616
- break;
1617
- };
1618
-}
1619
-
1620
-MUSBReadFunc * const musb_read[] = {
1621
- musb_readb,
1622
- musb_readh,
1623
- musb_readw,
1624
-};
1625
-
1626
-MUSBWriteFunc * const musb_write[] = {
1627
- musb_writeb,
1628
- musb_writeh,
1629
- musb_writew,
1630
-};
1631
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
1632
index XXXXXXX..XXXXXXX 100644
1633
--- a/hw/usb/Kconfig
1634
+++ b/hw/usb/Kconfig
1635
@@ -XXX,XX +XXX,XX @@ config USB_XHCI_SYSBUS
1636
bool
1637
select USB_XHCI
1638
1639
-config USB_MUSB
1640
- bool
1641
- select USB
1642
-
1643
config USB_DWC2
1644
bool
1645
select USB
1646
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
1647
index XXXXXXX..XXXXXXX 100644
1648
--- a/hw/usb/meson.build
1649
+++ b/hw/usb/meson.build
1650
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_USB_XHCI', if_true: files('hcd-xhci.c'))
1651
system_ss.add(when: 'CONFIG_USB_XHCI_PCI', if_true: files('hcd-xhci-pci.c'))
1652
system_ss.add(when: 'CONFIG_USB_XHCI_SYSBUS', if_true: files('hcd-xhci-sysbus.c'))
1653
system_ss.add(when: 'CONFIG_USB_XHCI_NEC', if_true: files('hcd-xhci-nec.c'))
1654
-system_ss.add(when: 'CONFIG_USB_MUSB', if_true: files('hcd-musb.c'))
1655
system_ss.add(when: 'CONFIG_USB_DWC2', if_true: files('hcd-dwc2.c'))
1656
system_ss.add(when: 'CONFIG_USB_DWC3', if_true: files('hcd-dwc3.c'))
1657
75
1658
--
76
--
1659
2.34.1
77
2.34.1
diff view generated by jsdifflib
1
The omap_sdrc device is only in OMAP2, which we are removing.
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".
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.
2
17
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
20
Message-id: 20241202131347.498124-30-peter.maydell@linaro.org
6
Message-id: 20240903160751.4100218-43-peter.maydell@linaro.org
7
---
21
---
8
include/hw/arm/omap.h | 7 --
22
target/loongarch/tcg/fpu_helper.c | 6 ++----
9
hw/misc/omap_sdrc.c | 167 ------------------------------------------
23
1 file changed, 2 insertions(+), 4 deletions(-)
10
hw/misc/meson.build | 1 -
11
3 files changed, 175 deletions(-)
12
delete mode 100644 hw/misc/omap_sdrc.c
13
24
14
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
25
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/omap.h
27
--- a/target/loongarch/tcg/fpu_helper.c
17
+++ b/include/hw/arm/omap.h
28
+++ b/target/loongarch/tcg/fpu_helper.c
18
@@ -XXX,XX +XXX,XX @@ hwaddr omap_l4_region_base(struct omap_target_agent_s *ta,
29
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
19
hwaddr omap_l4_region_size(struct omap_target_agent_s *ta,
30
} else if (float32_is_zero_or_denormal(f)) {
20
int region);
31
return sign ? 1 << 4 : 1 << 8;
21
32
} else if (float32_is_any_nan(f)) {
22
-/* OMAP2 SDRAM controller */
33
- float_status s = { }; /* for snan_bit_is_one */
23
-struct omap_sdrc_s;
34
- return float32_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
24
-struct omap_sdrc_s *omap_sdrc_init(MemoryRegion *sysmem,
35
+ return float32_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
25
- hwaddr base);
36
} else {
26
-void omap_sdrc_reset(struct omap_sdrc_s *s);
37
return sign ? 1 << 3 : 1 << 7;
27
-
38
}
28
/* OMAP2 general purpose memory controller */
39
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
29
struct omap_gpmc_s;
40
} else if (float64_is_zero_or_denormal(f)) {
30
struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
41
return sign ? 1 << 4 : 1 << 8;
31
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s {
42
} else if (float64_is_any_nan(f)) {
32
struct omap_gp_timer_s *gptimer[12];
43
- float_status s = { }; /* for snan_bit_is_one */
33
struct omap_synctimer_s *synctimer;
44
- return float64_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
34
45
+ return float64_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
35
- struct omap_sdrc_s *sdrc;
46
} else {
36
struct omap_gpmc_s *gpmc;
47
return sign ? 1 << 3 : 1 << 7;
37
48
}
38
struct omap_mcspi_s *mcspi[2];
39
diff --git a/hw/misc/omap_sdrc.c b/hw/misc/omap_sdrc.c
40
deleted file mode 100644
41
index XXXXXXX..XXXXXXX
42
--- a/hw/misc/omap_sdrc.c
43
+++ /dev/null
44
@@ -XXX,XX +XXX,XX @@
45
-/*
46
- * TI OMAP SDRAM controller emulation.
47
- *
48
- * Copyright (C) 2007-2008 Nokia Corporation
49
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
50
- *
51
- * This program is free software; you can redistribute it and/or
52
- * modify it under the terms of the GNU General Public License as
53
- * published by the Free Software Foundation; either version 2 or
54
- * (at your option) any later version of the License.
55
- *
56
- * This program is distributed in the hope that it will be useful,
57
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59
- * GNU General Public License for more details.
60
- *
61
- * You should have received a copy of the GNU General Public License along
62
- * with this program; if not, see <http://www.gnu.org/licenses/>.
63
- */
64
-#include "qemu/osdep.h"
65
-#include "hw/arm/omap.h"
66
-
67
-/* SDRAM Controller Subsystem */
68
-struct omap_sdrc_s {
69
- MemoryRegion iomem;
70
- uint8_t config;
71
-};
72
-
73
-void omap_sdrc_reset(struct omap_sdrc_s *s)
74
-{
75
- s->config = 0x10;
76
-}
77
-
78
-static uint64_t omap_sdrc_read(void *opaque, hwaddr addr, unsigned size)
79
-{
80
- struct omap_sdrc_s *s = opaque;
81
-
82
- if (size != 4) {
83
- return omap_badwidth_read32(opaque, addr);
84
- }
85
-
86
- switch (addr) {
87
- case 0x00:    /* SDRC_REVISION */
88
- return 0x20;
89
-
90
- case 0x10:    /* SDRC_SYSCONFIG */
91
- return s->config;
92
-
93
- case 0x14:    /* SDRC_SYSSTATUS */
94
- return 1;                        /* RESETDONE */
95
-
96
- case 0x40:    /* SDRC_CS_CFG */
97
- case 0x44:    /* SDRC_SHARING */
98
- case 0x48:    /* SDRC_ERR_ADDR */
99
- case 0x4c:    /* SDRC_ERR_TYPE */
100
- case 0x60:    /* SDRC_DLLA_SCTRL */
101
- case 0x64:    /* SDRC_DLLA_STATUS */
102
- case 0x68:    /* SDRC_DLLB_CTRL */
103
- case 0x6c:    /* SDRC_DLLB_STATUS */
104
- case 0x70:    /* SDRC_POWER */
105
- case 0x80:    /* SDRC_MCFG_0 */
106
- case 0x84:    /* SDRC_MR_0 */
107
- case 0x88:    /* SDRC_EMR1_0 */
108
- case 0x8c:    /* SDRC_EMR2_0 */
109
- case 0x90:    /* SDRC_EMR3_0 */
110
- case 0x94:    /* SDRC_DCDL1_CTRL */
111
- case 0x98:    /* SDRC_DCDL2_CTRL */
112
- case 0x9c:    /* SDRC_ACTIM_CTRLA_0 */
113
- case 0xa0:    /* SDRC_ACTIM_CTRLB_0 */
114
- case 0xa4:    /* SDRC_RFR_CTRL_0 */
115
- case 0xa8:    /* SDRC_MANUAL_0 */
116
- case 0xb0:    /* SDRC_MCFG_1 */
117
- case 0xb4:    /* SDRC_MR_1 */
118
- case 0xb8:    /* SDRC_EMR1_1 */
119
- case 0xbc:    /* SDRC_EMR2_1 */
120
- case 0xc0:    /* SDRC_EMR3_1 */
121
- case 0xc4:    /* SDRC_ACTIM_CTRLA_1 */
122
- case 0xc8:    /* SDRC_ACTIM_CTRLB_1 */
123
- case 0xd4:    /* SDRC_RFR_CTRL_1 */
124
- case 0xd8:    /* SDRC_MANUAL_1 */
125
- return 0x00;
126
- }
127
-
128
- OMAP_BAD_REG(addr);
129
- return 0;
130
-}
131
-
132
-static void omap_sdrc_write(void *opaque, hwaddr addr,
133
- uint64_t value, unsigned size)
134
-{
135
- struct omap_sdrc_s *s = opaque;
136
-
137
- if (size != 4) {
138
- omap_badwidth_write32(opaque, addr, value);
139
- return;
140
- }
141
-
142
- switch (addr) {
143
- case 0x00:    /* SDRC_REVISION */
144
- case 0x14:    /* SDRC_SYSSTATUS */
145
- case 0x48:    /* SDRC_ERR_ADDR */
146
- case 0x64:    /* SDRC_DLLA_STATUS */
147
- case 0x6c:    /* SDRC_DLLB_STATUS */
148
- OMAP_RO_REG(addr);
149
- return;
150
-
151
- case 0x10:    /* SDRC_SYSCONFIG */
152
- if ((value >> 3) != 0x2)
153
- fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
154
- __func__, (unsigned)value >> 3);
155
- if (value & 2)
156
- omap_sdrc_reset(s);
157
- s->config = value & 0x18;
158
- break;
159
-
160
- case 0x40:    /* SDRC_CS_CFG */
161
- case 0x44:    /* SDRC_SHARING */
162
- case 0x4c:    /* SDRC_ERR_TYPE */
163
- case 0x60:    /* SDRC_DLLA_SCTRL */
164
- case 0x68:    /* SDRC_DLLB_CTRL */
165
- case 0x70:    /* SDRC_POWER */
166
- case 0x80:    /* SDRC_MCFG_0 */
167
- case 0x84:    /* SDRC_MR_0 */
168
- case 0x88:    /* SDRC_EMR1_0 */
169
- case 0x8c:    /* SDRC_EMR2_0 */
170
- case 0x90:    /* SDRC_EMR3_0 */
171
- case 0x94:    /* SDRC_DCDL1_CTRL */
172
- case 0x98:    /* SDRC_DCDL2_CTRL */
173
- case 0x9c:    /* SDRC_ACTIM_CTRLA_0 */
174
- case 0xa0:    /* SDRC_ACTIM_CTRLB_0 */
175
- case 0xa4:    /* SDRC_RFR_CTRL_0 */
176
- case 0xa8:    /* SDRC_MANUAL_0 */
177
- case 0xb0:    /* SDRC_MCFG_1 */
178
- case 0xb4:    /* SDRC_MR_1 */
179
- case 0xb8:    /* SDRC_EMR1_1 */
180
- case 0xbc:    /* SDRC_EMR2_1 */
181
- case 0xc0:    /* SDRC_EMR3_1 */
182
- case 0xc4:    /* SDRC_ACTIM_CTRLA_1 */
183
- case 0xc8:    /* SDRC_ACTIM_CTRLB_1 */
184
- case 0xd4:    /* SDRC_RFR_CTRL_1 */
185
- case 0xd8:    /* SDRC_MANUAL_1 */
186
- break;
187
-
188
- default:
189
- OMAP_BAD_REG(addr);
190
- return;
191
- }
192
-}
193
-
194
-static const MemoryRegionOps omap_sdrc_ops = {
195
- .read = omap_sdrc_read,
196
- .write = omap_sdrc_write,
197
- .endianness = DEVICE_NATIVE_ENDIAN,
198
-};
199
-
200
-struct omap_sdrc_s *omap_sdrc_init(MemoryRegion *sysmem,
201
- hwaddr base)
202
-{
203
- struct omap_sdrc_s *s = g_new0(struct omap_sdrc_s, 1);
204
-
205
- omap_sdrc_reset(s);
206
-
207
- memory_region_init_io(&s->iomem, NULL, &omap_sdrc_ops, s, "omap.sdrc", 0x1000);
208
- memory_region_add_subregion(sysmem, base, &s->iomem);
209
-
210
- return s;
211
-}
212
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
213
index XXXXXXX..XXXXXXX 100644
214
--- a/hw/misc/meson.build
215
+++ b/hw/misc/meson.build
216
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_OMAP', if_true: files(
217
'omap_clk.c',
218
'omap_gpmc.c',
219
'omap_l4.c',
220
- 'omap_sdrc.c',
221
'omap_tap.c',
222
))
223
system_ss.add(when: 'CONFIG_RASPI', if_true: files(
224
--
49
--
225
2.34.1
50
2.34.1
226
227
diff view generated by jsdifflib
1
Remove the OMAP2 specific code from omap_mmc.c.
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.
2
9
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20241202131347.498124-31-peter.maydell@linaro.org
6
Message-id: 20240903160751.4100218-42-peter.maydell@linaro.org
7
---
13
---
8
include/hw/arm/omap.h | 5 ----
14
target/m68k/fpu_helper.c | 6 ++----
9
hw/sd/omap_mmc.c | 63 -------------------------------------------
15
1 file changed, 2 insertions(+), 4 deletions(-)
10
2 files changed, 68 deletions(-)
11
16
12
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
17
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/omap.h
19
--- a/target/m68k/fpu_helper.c
15
+++ b/include/hw/arm/omap.h
20
+++ b/target/m68k/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
21
@@ -XXX,XX +XXX,XX @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
17
MemoryRegion *sysmem,
22
18
BlockBackend *blk,
23
fp_rem = floatx80_rem(val1->d, val0->d, &env->fp_status);
19
qemu_irq irq, qemu_irq dma[], omap_clk clk);
24
if (!floatx80_is_any_nan(fp_rem)) {
20
-struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
25
- float_status fp_status = { };
21
- BlockBackend *blk, qemu_irq irq, qemu_irq dma[],
26
+ /* Use local temporary fp_status to set different rounding mode */
22
- omap_clk fclk, omap_clk iclk);
27
+ float_status fp_status = env->fp_status;
23
void omap_mmc_reset(struct omap_mmc_s *s);
28
uint32_t quotient;
24
-void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover);
29
int sign;
25
-void omap_mmc_enable(struct omap_mmc_s *s, int enable);
30
26
31
/* Calculate quotient directly using round to nearest mode */
27
/* omap_i2c.c */
32
- set_float_2nan_prop_rule(float_2nan_prop_ab, &fp_status);
28
I2CBus *omap_i2c_bus(DeviceState *omap_i2c);
33
set_float_rounding_mode(float_round_nearest_even, &fp_status);
29
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
34
- set_floatx80_rounding_precision(
30
index XXXXXXX..XXXXXXX 100644
35
- get_floatx80_rounding_precision(&env->fp_status), &fp_status);
31
--- a/hw/sd/omap_mmc.c
36
fp_quot.d = floatx80_div(val1->d, val0->d, &fp_status);
32
+++ b/hw/sd/omap_mmc.c
37
33
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_mmc_ops = {
38
sign = extractFloatx80Sign(fp_quot.d);
34
.endianness = DEVICE_NATIVE_ENDIAN,
35
};
36
37
-static void omap_mmc_cover_cb(void *opaque, int line, int level)
38
-{
39
- struct omap_mmc_s *host = opaque;
40
-
41
- if (!host->cdet_state && level) {
42
- host->status |= 0x0002;
43
- omap_mmc_interrupts_update(host);
44
- if (host->cdet_wakeup) {
45
- /* TODO: Assert wake-up */
46
- }
47
- }
48
-
49
- if (host->cdet_state != level) {
50
- qemu_set_irq(host->coverswitch, level);
51
- host->cdet_state = level;
52
- }
53
-}
54
-
55
struct omap_mmc_s *omap_mmc_init(hwaddr base,
56
MemoryRegion *sysmem,
57
BlockBackend *blk,
58
@@ -XXX,XX +XXX,XX @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
59
60
return s;
61
}
62
-
63
-struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
64
- BlockBackend *blk, qemu_irq irq, qemu_irq dma[],
65
- omap_clk fclk, omap_clk iclk)
66
-{
67
- struct omap_mmc_s *s = g_new0(struct omap_mmc_s, 1);
68
-
69
- s->irq = irq;
70
- s->dma = dma;
71
- s->clk = fclk;
72
- s->lines = 4;
73
- s->rev = 2;
74
-
75
- memory_region_init_io(&s->iomem, NULL, &omap_mmc_ops, s, "omap.mmc",
76
- omap_l4_region_size(ta, 0));
77
- omap_l4_attach(ta, 0, &s->iomem);
78
-
79
- /* Instantiate the storage */
80
- s->card = sd_init(blk, false);
81
- if (s->card == NULL) {
82
- exit(1);
83
- }
84
-
85
- s->cdet = qemu_allocate_irq(omap_mmc_cover_cb, s, 0);
86
- sd_set_cb(s->card, NULL, s->cdet);
87
-
88
- omap_mmc_reset(s);
89
-
90
- return s;
91
-}
92
-
93
-void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover)
94
-{
95
- if (s->cdet) {
96
- sd_set_cb(s->card, ro, s->cdet);
97
- s->coverswitch = cover;
98
- qemu_set_irq(cover, s->cdet_state);
99
- } else
100
- sd_set_cb(s->card, ro, cover);
101
-}
102
-
103
-void omap_mmc_enable(struct omap_mmc_s *s, int enable)
104
-{
105
- sd_enable(s->card, enable);
106
-}
107
--
39
--
108
2.34.1
40
2.34.1
109
110
diff view generated by jsdifflib
1
Remove the OMAP2 specific code from omap_uart.c.
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.
2
9
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20241202131347.498124-32-peter.maydell@linaro.org
6
Message-id: 20240903160751.4100218-40-peter.maydell@linaro.org
7
---
13
---
8
include/hw/arm/omap.h | 5 --
14
target/m68k/helper.c | 6 ++++--
9
hw/char/omap_uart.c | 113 ------------------------------------------
15
1 file changed, 4 insertions(+), 2 deletions(-)
10
2 files changed, 118 deletions(-)
11
16
12
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
17
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/omap.h
19
--- a/target/m68k/helper.c
15
+++ b/include/hw/arm/omap.h
20
+++ b/target/m68k/helper.c
16
@@ -XXX,XX +XXX,XX @@ struct omap_uart_s *omap_uart_init(hwaddr base,
21
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
17
qemu_irq irq, omap_clk fclk, omap_clk iclk,
22
CPUM68KState *env = &cpu->env;
18
qemu_irq txdma, qemu_irq rxdma,
23
19
const char *label, Chardev *chr);
24
if (n < 8) {
20
-struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem,
25
- float_status s = {};
21
- struct omap_target_agent_s *ta,
26
+ /* Use scratch float_status so any exceptions don't change CPU state */
22
- qemu_irq irq, omap_clk fclk, omap_clk iclk,
27
+ float_status s = env->fp_status;
23
- qemu_irq txdma, qemu_irq rxdma,
28
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
24
- const char *label, Chardev *chr);
29
}
25
void omap_uart_reset(struct omap_uart_s *s);
30
switch (n) {
26
31
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
27
struct omap_mpuio_s;
32
CPUM68KState *env = &cpu->env;
28
diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c
33
29
index XXXXXXX..XXXXXXX 100644
34
if (n < 8) {
30
--- a/hw/char/omap_uart.c
35
- float_status s = {};
31
+++ b/hw/char/omap_uart.c
36
+ /* Use scratch float_status so any exceptions don't change CPU state */
32
@@ -XXX,XX +XXX,XX @@ struct omap_uart_s {
37
+ float_status s = env->fp_status;
33
MemoryRegion iomem;
38
env->fregs[n].d = float64_to_floatx80(ldq_be_p(mem_buf), &s);
34
hwaddr base;
39
return 8;
35
SerialMM *serial; /* TODO */
40
}
36
- struct omap_target_agent_s *ta;
37
omap_clk fclk;
38
qemu_irq irq;
39
40
@@ -XXX,XX +XXX,XX @@ struct omap_uart_s {
41
uint8_t syscontrol;
42
uint8_t wkup;
43
uint8_t cfps;
44
- uint8_t mdr[2];
45
- uint8_t scr;
46
uint8_t clksel;
47
};
48
49
@@ -XXX,XX +XXX,XX @@ struct omap_uart_s *omap_uart_init(hwaddr base,
50
DEVICE_NATIVE_ENDIAN);
51
return s;
52
}
53
-
54
-static uint64_t omap_uart_read(void *opaque, hwaddr addr, unsigned size)
55
-{
56
- struct omap_uart_s *s = opaque;
57
-
58
- if (size == 4) {
59
- return omap_badwidth_read8(opaque, addr);
60
- }
61
-
62
- switch (addr) {
63
- case 0x20: /* MDR1 */
64
- return s->mdr[0];
65
- case 0x24: /* MDR2 */
66
- return s->mdr[1];
67
- case 0x40: /* SCR */
68
- return s->scr;
69
- case 0x44: /* SSR */
70
- return 0x0;
71
- case 0x48: /* EBLR (OMAP2) */
72
- return s->eblr;
73
- case 0x4C: /* OSC_12M_SEL (OMAP1) */
74
- return s->clksel;
75
- case 0x50: /* MVR */
76
- return 0x30;
77
- case 0x54: /* SYSC (OMAP2) */
78
- return s->syscontrol;
79
- case 0x58: /* SYSS (OMAP2) */
80
- return 1;
81
- case 0x5c: /* WER (OMAP2) */
82
- return s->wkup;
83
- case 0x60: /* CFPS (OMAP2) */
84
- return s->cfps;
85
- }
86
-
87
- OMAP_BAD_REG(addr);
88
- return 0;
89
-}
90
-
91
-static void omap_uart_write(void *opaque, hwaddr addr,
92
- uint64_t value, unsigned size)
93
-{
94
- struct omap_uart_s *s = opaque;
95
-
96
- if (size == 4) {
97
- omap_badwidth_write8(opaque, addr, value);
98
- return;
99
- }
100
-
101
- switch (addr) {
102
- case 0x20: /* MDR1 */
103
- s->mdr[0] = value & 0x7f;
104
- break;
105
- case 0x24: /* MDR2 */
106
- s->mdr[1] = value & 0xff;
107
- break;
108
- case 0x40: /* SCR */
109
- s->scr = value & 0xff;
110
- break;
111
- case 0x48: /* EBLR (OMAP2) */
112
- s->eblr = value & 0xff;
113
- break;
114
- case 0x4C: /* OSC_12M_SEL (OMAP1) */
115
- s->clksel = value & 1;
116
- break;
117
- case 0x44: /* SSR */
118
- case 0x50: /* MVR */
119
- case 0x58: /* SYSS (OMAP2) */
120
- OMAP_RO_REG(addr);
121
- break;
122
- case 0x54: /* SYSC (OMAP2) */
123
- s->syscontrol = value & 0x1d;
124
- if (value & 2) {
125
- omap_uart_reset(s);
126
- }
127
- break;
128
- case 0x5c: /* WER (OMAP2) */
129
- s->wkup = value & 0x7f;
130
- break;
131
- case 0x60: /* CFPS (OMAP2) */
132
- s->cfps = value & 0xff;
133
- break;
134
- default:
135
- OMAP_BAD_REG(addr);
136
- }
137
-}
138
-
139
-static const MemoryRegionOps omap_uart_ops = {
140
- .read = omap_uart_read,
141
- .write = omap_uart_write,
142
- .endianness = DEVICE_NATIVE_ENDIAN,
143
-};
144
-
145
-struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem,
146
- struct omap_target_agent_s *ta,
147
- qemu_irq irq, omap_clk fclk, omap_clk iclk,
148
- qemu_irq txdma, qemu_irq rxdma,
149
- const char *label, Chardev *chr)
150
-{
151
- hwaddr base = omap_l4_attach(ta, 0, NULL);
152
- struct omap_uart_s *s = omap_uart_init(base, irq,
153
- fclk, iclk, txdma, rxdma, label, chr);
154
-
155
- memory_region_init_io(&s->iomem, NULL, &omap_uart_ops, s, "omap.uart", 0x100);
156
-
157
- s->ta = ta;
158
-
159
- memory_region_add_subregion(sysmem, base + 0x20, &s->iomem);
160
-
161
- return s;
162
-}
163
--
41
--
164
2.34.1
42
2.34.1
165
166
diff view generated by jsdifflib
1
We've removed the OMAP2 SoC, so we can remove the OMAP2 GPIO
1
In the helper functions flcmps and flcmpd we use a scratch float_status
2
device. (The source file remains, as it also has the model of
2
so that we don't change the CPU state if the comparison raises any
3
the OMAP1 GPIO device.)
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.
7
8
To do this we need to pass the CPU env pointer in to the helper.
4
9
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20241202131347.498124-33-peter.maydell@linaro.org
8
Message-id: 20240903160751.4100218-39-peter.maydell@linaro.org
9
---
13
---
10
include/hw/arm/omap.h | 8 -
14
target/sparc/helper.h | 4 ++--
11
hw/gpio/omap_gpio.c | 557 ------------------------------------------
15
target/sparc/fop_helper.c | 8 ++++----
12
2 files changed, 565 deletions(-)
16
target/sparc/translate.c | 4 ++--
17
3 files changed, 8 insertions(+), 8 deletions(-)
13
18
14
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
19
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/omap.h
21
--- a/target/sparc/helper.h
17
+++ b/include/hw/arm/omap.h
22
+++ b/target/sparc/helper.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct Omap1GpioState Omap1GpioState;
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
19
DECLARE_INSTANCE_CHECKER(Omap1GpioState, OMAP1_GPIO,
24
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
20
TYPE_OMAP1_GPIO)
25
DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
21
26
DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
22
-#define TYPE_OMAP2_GPIO "omap2-gpio"
27
-DEF_HELPER_FLAGS_2(flcmps, TCG_CALL_NO_RWG_SE, i32, f32, f32)
23
-typedef struct Omap2GpioState Omap2GpioState;
28
-DEF_HELPER_FLAGS_2(flcmpd, TCG_CALL_NO_RWG_SE, i32, f64, f64)
24
-DECLARE_INSTANCE_CHECKER(Omap2GpioState, OMAP2_GPIO,
29
+DEF_HELPER_FLAGS_3(flcmps, TCG_CALL_NO_RWG_SE, i32, env, f32, f32)
25
- TYPE_OMAP2_GPIO)
30
+DEF_HELPER_FLAGS_3(flcmpd, TCG_CALL_NO_RWG_SE, i32, env, f64, f64)
26
-
31
DEF_HELPER_2(raise_exception, noreturn, env, int)
27
/* TODO: clock framework (see above) */
32
28
void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk);
33
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
29
34
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
30
-void omap2_gpio_set_iclk(Omap2GpioState *gpio, omap_clk clk);
31
-void omap2_gpio_set_fclk(Omap2GpioState *gpio, uint8_t i, omap_clk clk);
32
-
33
/* OMAP2 l4 Interconnect */
34
struct omap_l4_s;
35
struct omap_l4_region_s {
36
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
37
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/gpio/omap_gpio.c
36
--- a/target/sparc/fop_helper.c
39
+++ b/hw/gpio/omap_gpio.c
37
+++ b/target/sparc/fop_helper.c
40
@@ -XXX,XX +XXX,XX @@ static void omap_gpio_reset(struct omap_gpio_s *s)
38
@@ -XXX,XX +XXX,XX @@ uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
41
s->pins = ~0;
39
return finish_fcmp(env, r, GETPC());
42
}
40
}
43
41
44
-struct omap2_gpio_s {
42
-uint32_t helper_flcmps(float32 src1, float32 src2)
45
- qemu_irq irq[2];
43
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
46
- qemu_irq wkup;
47
- qemu_irq *handler;
48
- MemoryRegion iomem;
49
-
50
- uint8_t revision;
51
- uint8_t config[2];
52
- uint32_t inputs;
53
- uint32_t outputs;
54
- uint32_t dir;
55
- uint32_t level[2];
56
- uint32_t edge[2];
57
- uint32_t mask[2];
58
- uint32_t wumask;
59
- uint32_t ints[2];
60
- uint32_t debounce;
61
- uint8_t delay;
62
-};
63
-
64
-struct Omap2GpioState {
65
- SysBusDevice parent_obj;
66
-
67
- MemoryRegion iomem;
68
- int mpu_model;
69
- void *iclk;
70
- void *fclk[6];
71
- int modulecount;
72
- struct omap2_gpio_s *modules;
73
- qemu_irq *handler;
74
- int autoidle;
75
- int gpo;
76
-};
77
-
78
-/* General-Purpose Interface of OMAP2/3 */
79
-static inline void omap2_gpio_module_int_update(struct omap2_gpio_s *s,
80
- int line)
81
-{
82
- qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
83
-}
84
-
85
-static void omap2_gpio_module_wake(struct omap2_gpio_s *s, int line)
86
-{
87
- if (!(s->config[0] & (1 << 2)))            /* ENAWAKEUP */
88
- return;
89
- if (!(s->config[0] & (3 << 3)))            /* Force Idle */
90
- return;
91
- if (!(s->wumask & (1 << line)))
92
- return;
93
-
94
- qemu_irq_raise(s->wkup);
95
-}
96
-
97
-static inline void omap2_gpio_module_out_update(struct omap2_gpio_s *s,
98
- uint32_t diff)
99
-{
100
- int ln;
101
-
102
- s->outputs ^= diff;
103
- diff &= ~s->dir;
104
- while ((ln = ctz32(diff)) != 32) {
105
- qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
106
- diff &= ~(1 << ln);
107
- }
108
-}
109
-
110
-static void omap2_gpio_module_level_update(struct omap2_gpio_s *s, int line)
111
-{
112
- s->ints[line] |= s->dir &
113
- ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
114
- omap2_gpio_module_int_update(s, line);
115
-}
116
-
117
-static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line)
118
-{
119
- s->ints[0] |= 1 << line;
120
- omap2_gpio_module_int_update(s, 0);
121
- s->ints[1] |= 1 << line;
122
- omap2_gpio_module_int_update(s, 1);
123
- omap2_gpio_module_wake(s, line);
124
-}
125
-
126
-static void omap2_gpio_set(void *opaque, int line, int level)
127
-{
128
- Omap2GpioState *p = opaque;
129
- struct omap2_gpio_s *s = &p->modules[line >> 5];
130
-
131
- line &= 31;
132
- if (level) {
133
- if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
134
- omap2_gpio_module_int(s, line);
135
- s->inputs |= 1 << line;
136
- } else {
137
- if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
138
- omap2_gpio_module_int(s, line);
139
- s->inputs &= ~(1 << line);
140
- }
141
-}
142
-
143
-static void omap2_gpio_module_reset(struct omap2_gpio_s *s)
144
-{
145
- s->config[0] = 0;
146
- s->config[1] = 2;
147
- s->ints[0] = 0;
148
- s->ints[1] = 0;
149
- s->mask[0] = 0;
150
- s->mask[1] = 0;
151
- s->wumask = 0;
152
- s->dir = ~0;
153
- s->level[0] = 0;
154
- s->level[1] = 0;
155
- s->edge[0] = 0;
156
- s->edge[1] = 0;
157
- s->debounce = 0;
158
- s->delay = 0;
159
-}
160
-
161
-static uint32_t omap2_gpio_module_read(void *opaque, hwaddr addr)
162
-{
163
- struct omap2_gpio_s *s = opaque;
164
-
165
- switch (addr) {
166
- case 0x00:    /* GPIO_REVISION */
167
- return s->revision;
168
-
169
- case 0x10:    /* GPIO_SYSCONFIG */
170
- return s->config[0];
171
-
172
- case 0x14:    /* GPIO_SYSSTATUS */
173
- return 0x01;
174
-
175
- case 0x18:    /* GPIO_IRQSTATUS1 */
176
- return s->ints[0];
177
-
178
- case 0x1c:    /* GPIO_IRQENABLE1 */
179
- case 0x60:    /* GPIO_CLEARIRQENABLE1 */
180
- case 0x64:    /* GPIO_SETIRQENABLE1 */
181
- return s->mask[0];
182
-
183
- case 0x20:    /* GPIO_WAKEUPENABLE */
184
- case 0x80:    /* GPIO_CLEARWKUENA */
185
- case 0x84:    /* GPIO_SETWKUENA */
186
- return s->wumask;
187
-
188
- case 0x28:    /* GPIO_IRQSTATUS2 */
189
- return s->ints[1];
190
-
191
- case 0x2c:    /* GPIO_IRQENABLE2 */
192
- case 0x70:    /* GPIO_CLEARIRQENABLE2 */
193
- case 0x74:    /* GPIO_SETIREQNEABLE2 */
194
- return s->mask[1];
195
-
196
- case 0x30:    /* GPIO_CTRL */
197
- return s->config[1];
198
-
199
- case 0x34:    /* GPIO_OE */
200
- return s->dir;
201
-
202
- case 0x38:    /* GPIO_DATAIN */
203
- return s->inputs;
204
-
205
- case 0x3c:    /* GPIO_DATAOUT */
206
- case 0x90:    /* GPIO_CLEARDATAOUT */
207
- case 0x94:    /* GPIO_SETDATAOUT */
208
- return s->outputs;
209
-
210
- case 0x40:    /* GPIO_LEVELDETECT0 */
211
- return s->level[0];
212
-
213
- case 0x44:    /* GPIO_LEVELDETECT1 */
214
- return s->level[1];
215
-
216
- case 0x48:    /* GPIO_RISINGDETECT */
217
- return s->edge[0];
218
-
219
- case 0x4c:    /* GPIO_FALLINGDETECT */
220
- return s->edge[1];
221
-
222
- case 0x50:    /* GPIO_DEBOUNCENABLE */
223
- return s->debounce;
224
-
225
- case 0x54:    /* GPIO_DEBOUNCINGTIME */
226
- return s->delay;
227
- }
228
-
229
- OMAP_BAD_REG(addr);
230
- return 0;
231
-}
232
-
233
-static void omap2_gpio_module_write(void *opaque, hwaddr addr,
234
- uint32_t value)
235
-{
236
- struct omap2_gpio_s *s = opaque;
237
- uint32_t diff;
238
- int ln;
239
-
240
- switch (addr) {
241
- case 0x00:    /* GPIO_REVISION */
242
- case 0x14:    /* GPIO_SYSSTATUS */
243
- case 0x38:    /* GPIO_DATAIN */
244
- OMAP_RO_REG(addr);
245
- break;
246
-
247
- case 0x10:    /* GPIO_SYSCONFIG */
248
- if (((value >> 3) & 3) == 3) {
249
- qemu_log_mask(LOG_GUEST_ERROR,
250
- "%s: Illegal IDLEMODE value: 3\n", __func__);
251
- }
252
- if (value & 2)
253
- omap2_gpio_module_reset(s);
254
- s->config[0] = value & 0x1d;
255
- break;
256
-
257
- case 0x18:    /* GPIO_IRQSTATUS1 */
258
- if (s->ints[0] & value) {
259
- s->ints[0] &= ~value;
260
- omap2_gpio_module_level_update(s, 0);
261
- }
262
- break;
263
-
264
- case 0x1c:    /* GPIO_IRQENABLE1 */
265
- s->mask[0] = value;
266
- omap2_gpio_module_int_update(s, 0);
267
- break;
268
-
269
- case 0x20:    /* GPIO_WAKEUPENABLE */
270
- s->wumask = value;
271
- break;
272
-
273
- case 0x28:    /* GPIO_IRQSTATUS2 */
274
- if (s->ints[1] & value) {
275
- s->ints[1] &= ~value;
276
- omap2_gpio_module_level_update(s, 1);
277
- }
278
- break;
279
-
280
- case 0x2c:    /* GPIO_IRQENABLE2 */
281
- s->mask[1] = value;
282
- omap2_gpio_module_int_update(s, 1);
283
- break;
284
-
285
- case 0x30:    /* GPIO_CTRL */
286
- s->config[1] = value & 7;
287
- break;
288
-
289
- case 0x34:    /* GPIO_OE */
290
- diff = s->outputs & (s->dir ^ value);
291
- s->dir = value;
292
-
293
- value = s->outputs & ~s->dir;
294
- while ((ln = ctz32(diff)) != 32) {
295
- diff &= ~(1 << ln);
296
- qemu_set_irq(s->handler[ln], (value >> ln) & 1);
297
- }
298
-
299
- omap2_gpio_module_level_update(s, 0);
300
- omap2_gpio_module_level_update(s, 1);
301
- break;
302
-
303
- case 0x3c:    /* GPIO_DATAOUT */
304
- omap2_gpio_module_out_update(s, s->outputs ^ value);
305
- break;
306
-
307
- case 0x40:    /* GPIO_LEVELDETECT0 */
308
- s->level[0] = value;
309
- omap2_gpio_module_level_update(s, 0);
310
- omap2_gpio_module_level_update(s, 1);
311
- break;
312
-
313
- case 0x44:    /* GPIO_LEVELDETECT1 */
314
- s->level[1] = value;
315
- omap2_gpio_module_level_update(s, 0);
316
- omap2_gpio_module_level_update(s, 1);
317
- break;
318
-
319
- case 0x48:    /* GPIO_RISINGDETECT */
320
- s->edge[0] = value;
321
- break;
322
-
323
- case 0x4c:    /* GPIO_FALLINGDETECT */
324
- s->edge[1] = value;
325
- break;
326
-
327
- case 0x50:    /* GPIO_DEBOUNCENABLE */
328
- s->debounce = value;
329
- break;
330
-
331
- case 0x54:    /* GPIO_DEBOUNCINGTIME */
332
- s->delay = value;
333
- break;
334
-
335
- case 0x60:    /* GPIO_CLEARIRQENABLE1 */
336
- s->mask[0] &= ~value;
337
- omap2_gpio_module_int_update(s, 0);
338
- break;
339
-
340
- case 0x64:    /* GPIO_SETIRQENABLE1 */
341
- s->mask[0] |= value;
342
- omap2_gpio_module_int_update(s, 0);
343
- break;
344
-
345
- case 0x70:    /* GPIO_CLEARIRQENABLE2 */
346
- s->mask[1] &= ~value;
347
- omap2_gpio_module_int_update(s, 1);
348
- break;
349
-
350
- case 0x74:    /* GPIO_SETIREQNEABLE2 */
351
- s->mask[1] |= value;
352
- omap2_gpio_module_int_update(s, 1);
353
- break;
354
-
355
- case 0x80:    /* GPIO_CLEARWKUENA */
356
- s->wumask &= ~value;
357
- break;
358
-
359
- case 0x84:    /* GPIO_SETWKUENA */
360
- s->wumask |= value;
361
- break;
362
-
363
- case 0x90:    /* GPIO_CLEARDATAOUT */
364
- omap2_gpio_module_out_update(s, s->outputs & value);
365
- break;
366
-
367
- case 0x94:    /* GPIO_SETDATAOUT */
368
- omap2_gpio_module_out_update(s, ~s->outputs & value);
369
- break;
370
-
371
- default:
372
- OMAP_BAD_REG(addr);
373
- return;
374
- }
375
-}
376
-
377
-static uint64_t omap2_gpio_module_readp(void *opaque, hwaddr addr,
378
- unsigned size)
379
-{
380
- return omap2_gpio_module_read(opaque, addr & ~3) >> ((addr & 3) << 3);
381
-}
382
-
383
-static void omap2_gpio_module_writep(void *opaque, hwaddr addr,
384
- uint64_t value, unsigned size)
385
-{
386
- uint32_t cur = 0;
387
- uint32_t mask = 0xffff;
388
-
389
- if (size == 4) {
390
- omap2_gpio_module_write(opaque, addr, value);
391
- return;
392
- }
393
-
394
- switch (addr & ~3) {
395
- case 0x00:    /* GPIO_REVISION */
396
- case 0x14:    /* GPIO_SYSSTATUS */
397
- case 0x38:    /* GPIO_DATAIN */
398
- OMAP_RO_REG(addr);
399
- break;
400
-
401
- case 0x10:    /* GPIO_SYSCONFIG */
402
- case 0x1c:    /* GPIO_IRQENABLE1 */
403
- case 0x20:    /* GPIO_WAKEUPENABLE */
404
- case 0x2c:    /* GPIO_IRQENABLE2 */
405
- case 0x30:    /* GPIO_CTRL */
406
- case 0x34:    /* GPIO_OE */
407
- case 0x3c:    /* GPIO_DATAOUT */
408
- case 0x40:    /* GPIO_LEVELDETECT0 */
409
- case 0x44:    /* GPIO_LEVELDETECT1 */
410
- case 0x48:    /* GPIO_RISINGDETECT */
411
- case 0x4c:    /* GPIO_FALLINGDETECT */
412
- case 0x50:    /* GPIO_DEBOUNCENABLE */
413
- case 0x54:    /* GPIO_DEBOUNCINGTIME */
414
- cur = omap2_gpio_module_read(opaque, addr & ~3) &
415
- ~(mask << ((addr & 3) << 3));
416
-
417
- /* Fall through. */
418
- case 0x18:    /* GPIO_IRQSTATUS1 */
419
- case 0x28:    /* GPIO_IRQSTATUS2 */
420
- case 0x60:    /* GPIO_CLEARIRQENABLE1 */
421
- case 0x64:    /* GPIO_SETIRQENABLE1 */
422
- case 0x70:    /* GPIO_CLEARIRQENABLE2 */
423
- case 0x74:    /* GPIO_SETIREQNEABLE2 */
424
- case 0x80:    /* GPIO_CLEARWKUENA */
425
- case 0x84:    /* GPIO_SETWKUENA */
426
- case 0x90:    /* GPIO_CLEARDATAOUT */
427
- case 0x94:    /* GPIO_SETDATAOUT */
428
- value <<= (addr & 3) << 3;
429
- omap2_gpio_module_write(opaque, addr, cur | value);
430
- break;
431
-
432
- default:
433
- OMAP_BAD_REG(addr);
434
- return;
435
- }
436
-}
437
-
438
-static const MemoryRegionOps omap2_gpio_module_ops = {
439
- .read = omap2_gpio_module_readp,
440
- .write = omap2_gpio_module_writep,
441
- .valid.min_access_size = 1,
442
- .valid.max_access_size = 4,
443
- .endianness = DEVICE_NATIVE_ENDIAN,
444
-};
445
-
446
static void omap_gpif_reset(DeviceState *dev)
447
{
44
{
448
Omap1GpioState *s = OMAP1_GPIO(dev);
45
/*
449
@@ -XXX,XX +XXX,XX @@ static void omap_gpif_reset(DeviceState *dev)
46
* FLCMP never raises an exception nor modifies any FSR fields.
450
omap_gpio_reset(&s->omap1);
47
* Perform the comparison with a dummy fp environment.
48
*/
49
- float_status discard = { };
50
+ float_status discard = env->fp_status;
51
FloatRelation r;
52
53
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
54
@@ -XXX,XX +XXX,XX @@ uint32_t helper_flcmps(float32 src1, float32 src2)
55
g_assert_not_reached();
451
}
56
}
452
57
453
-static void omap2_gpif_reset(DeviceState *dev)
58
-uint32_t helper_flcmpd(float64 src1, float64 src2)
454
-{
59
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
455
- Omap2GpioState *s = OMAP2_GPIO(dev);
456
- int i;
457
-
458
- for (i = 0; i < s->modulecount; i++) {
459
- omap2_gpio_module_reset(&s->modules[i]);
460
- }
461
- s->autoidle = 0;
462
- s->gpo = 0;
463
-}
464
-
465
-static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr, unsigned size)
466
-{
467
- Omap2GpioState *s = opaque;
468
-
469
- switch (addr) {
470
- case 0x00:    /* IPGENERICOCPSPL_REVISION */
471
- return 0x18;
472
-
473
- case 0x10:    /* IPGENERICOCPSPL_SYSCONFIG */
474
- return s->autoidle;
475
-
476
- case 0x14:    /* IPGENERICOCPSPL_SYSSTATUS */
477
- return 0x01;
478
-
479
- case 0x18:    /* IPGENERICOCPSPL_IRQSTATUS */
480
- return 0x00;
481
-
482
- case 0x40:    /* IPGENERICOCPSPL_GPO */
483
- return s->gpo;
484
-
485
- case 0x50:    /* IPGENERICOCPSPL_GPI */
486
- return 0x00;
487
- }
488
-
489
- OMAP_BAD_REG(addr);
490
- return 0;
491
-}
492
-
493
-static void omap2_gpif_top_write(void *opaque, hwaddr addr,
494
- uint64_t value, unsigned size)
495
-{
496
- Omap2GpioState *s = opaque;
497
-
498
- switch (addr) {
499
- case 0x00:    /* IPGENERICOCPSPL_REVISION */
500
- case 0x14:    /* IPGENERICOCPSPL_SYSSTATUS */
501
- case 0x18:    /* IPGENERICOCPSPL_IRQSTATUS */
502
- case 0x50:    /* IPGENERICOCPSPL_GPI */
503
- OMAP_RO_REG(addr);
504
- break;
505
-
506
- case 0x10:    /* IPGENERICOCPSPL_SYSCONFIG */
507
- if (value & (1 << 1))                    /* SOFTRESET */
508
- omap2_gpif_reset(DEVICE(s));
509
- s->autoidle = value & 1;
510
- break;
511
-
512
- case 0x40:    /* IPGENERICOCPSPL_GPO */
513
- s->gpo = value & 1;
514
- break;
515
-
516
- default:
517
- OMAP_BAD_REG(addr);
518
- return;
519
- }
520
-}
521
-
522
-static const MemoryRegionOps omap2_gpif_top_ops = {
523
- .read = omap2_gpif_top_read,
524
- .write = omap2_gpif_top_write,
525
- .endianness = DEVICE_NATIVE_ENDIAN,
526
-};
527
-
528
static void omap_gpio_init(Object *obj)
529
{
60
{
530
DeviceState *dev = DEVICE(obj);
61
- float_status discard = { };
531
@@ -XXX,XX +XXX,XX @@ static void omap_gpio_realize(DeviceState *dev, Error **errp)
62
+ float_status discard = env->fp_status;
532
}
63
FloatRelation r;
64
65
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
66
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/sparc/translate.c
69
+++ b/target/sparc/translate.c
70
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPs(DisasContext *dc, arg_FLCMPs *a)
71
72
src1 = gen_load_fpr_F(dc, a->rs1);
73
src2 = gen_load_fpr_F(dc, a->rs2);
74
- gen_helper_flcmps(cpu_fcc[a->cc], src1, src2);
75
+ gen_helper_flcmps(cpu_fcc[a->cc], tcg_env, src1, src2);
76
return advance_pc(dc);
533
}
77
}
534
78
535
-static void omap2_gpio_realize(DeviceState *dev, Error **errp)
79
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPd(DisasContext *dc, arg_FLCMPd *a)
536
-{
80
537
- Omap2GpioState *s = OMAP2_GPIO(dev);
81
src1 = gen_load_fpr_D(dc, a->rs1);
538
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
82
src2 = gen_load_fpr_D(dc, a->rs2);
539
- int i;
83
- gen_helper_flcmpd(cpu_fcc[a->cc], src1, src2);
540
-
84
+ gen_helper_flcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
541
- if (!s->iclk) {
85
return advance_pc(dc);
542
- error_setg(errp, "omap2-gpio: iclk not connected");
543
- return;
544
- }
545
-
546
- s->modulecount = s->mpu_model < omap2430 ? 4
547
- : s->mpu_model < omap3430 ? 5
548
- : 6;
549
-
550
- if (s->mpu_model < omap3430) {
551
- memory_region_init_io(&s->iomem, OBJECT(dev), &omap2_gpif_top_ops, s,
552
- "omap2.gpio", 0x1000);
553
- sysbus_init_mmio(sbd, &s->iomem);
554
- }
555
-
556
- s->modules = g_new0(struct omap2_gpio_s, s->modulecount);
557
- s->handler = g_new0(qemu_irq, s->modulecount * 32);
558
- qdev_init_gpio_in(dev, omap2_gpio_set, s->modulecount * 32);
559
- qdev_init_gpio_out(dev, s->handler, s->modulecount * 32);
560
-
561
- for (i = 0; i < s->modulecount; i++) {
562
- struct omap2_gpio_s *m = &s->modules[i];
563
-
564
- if (!s->fclk[i]) {
565
- error_setg(errp, "omap2-gpio: fclk%d not connected", i);
566
- return;
567
- }
568
-
569
- m->revision = (s->mpu_model < omap3430) ? 0x18 : 0x25;
570
- m->handler = &s->handler[i * 32];
571
- sysbus_init_irq(sbd, &m->irq[0]); /* mpu irq */
572
- sysbus_init_irq(sbd, &m->irq[1]); /* dsp irq */
573
- sysbus_init_irq(sbd, &m->wkup);
574
- memory_region_init_io(&m->iomem, OBJECT(dev), &omap2_gpio_module_ops, m,
575
- "omap.gpio-module", 0x1000);
576
- sysbus_init_mmio(sbd, &m->iomem);
577
- }
578
-}
579
-
580
void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk)
581
{
582
gpio->clk = clk;
583
@@ -XXX,XX +XXX,XX @@ static const TypeInfo omap_gpio_info = {
584
.class_init = omap_gpio_class_init,
585
};
586
587
-void omap2_gpio_set_iclk(Omap2GpioState *gpio, omap_clk clk)
588
-{
589
- gpio->iclk = clk;
590
-}
591
-
592
-void omap2_gpio_set_fclk(Omap2GpioState *gpio, uint8_t i, omap_clk clk)
593
-{
594
- assert(i <= 5);
595
- gpio->fclk[i] = clk;
596
-}
597
-
598
-static Property omap2_gpio_properties[] = {
599
- DEFINE_PROP_INT32("mpu_model", Omap2GpioState, mpu_model, 0),
600
- DEFINE_PROP_END_OF_LIST(),
601
-};
602
-
603
-static void omap2_gpio_class_init(ObjectClass *klass, void *data)
604
-{
605
- DeviceClass *dc = DEVICE_CLASS(klass);
606
-
607
- dc->realize = omap2_gpio_realize;
608
- device_class_set_legacy_reset(dc, omap2_gpif_reset);
609
- device_class_set_props(dc, omap2_gpio_properties);
610
- /* Reason: pointer properties "iclk", "fclk0", ..., "fclk5" */
611
- dc->user_creatable = false;
612
-}
613
-
614
-static const TypeInfo omap2_gpio_info = {
615
- .name = TYPE_OMAP2_GPIO,
616
- .parent = TYPE_SYS_BUS_DEVICE,
617
- .instance_size = sizeof(Omap2GpioState),
618
- .class_init = omap2_gpio_class_init,
619
-};
620
-
621
static void omap_gpio_register_types(void)
622
{
623
type_register_static(&omap_gpio_info);
624
- type_register_static(&omap2_gpio_info);
625
}
86
}
626
87
627
type_init(omap_gpio_register_types)
628
--
88
--
629
2.34.1
89
2.34.1
630
631
diff view generated by jsdifflib
1
The tusb6010 was only used by the n800/n810 machines, so it
1
In the helper_compute_fprf functions, we pass a dummy float_status
2
can be removed now.
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.
8
9
Use env->fp_status instead of the dummy fp_status.
3
10
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20240903160751.4100218-34-peter.maydell@linaro.org
13
Message-id: 20241202131347.498124-34-peter.maydell@linaro.org
7
---
14
---
8
hw/usb/tusb6010.c | 850 ---------------------------------------------
15
target/ppc/fpu_helper.c | 3 +--
9
hw/usb/Kconfig | 4 -
16
1 file changed, 1 insertion(+), 2 deletions(-)
10
hw/usb/meson.build | 1 -
11
3 files changed, 855 deletions(-)
12
delete mode 100644 hw/usb/tusb6010.c
13
17
14
diff --git a/hw/usb/tusb6010.c b/hw/usb/tusb6010.c
18
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
15
deleted file mode 100644
16
index XXXXXXX..XXXXXXX
17
--- a/hw/usb/tusb6010.c
18
+++ /dev/null
19
@@ -XXX,XX +XXX,XX @@
20
-/*
21
- * Texas Instruments TUSB6010 emulation.
22
- * Based on reverse-engineering of a linux driver.
23
- *
24
- * Copyright (C) 2008 Nokia Corporation
25
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
26
- *
27
- * This program is free software; you can redistribute it and/or
28
- * modify it under the terms of the GNU General Public License as
29
- * published by the Free Software Foundation; either version 2 or
30
- * (at your option) version 3 of the License.
31
- *
32
- * This program is distributed in the hope that it will be useful,
33
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
34
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35
- * GNU General Public License for more details.
36
- *
37
- * You should have received a copy of the GNU General Public License along
38
- * with this program; if not, see <http://www.gnu.org/licenses/>.
39
- */
40
-
41
-#include "qemu/osdep.h"
42
-#include "qemu/module.h"
43
-#include "qemu/timer.h"
44
-#include "hw/usb.h"
45
-#include "hw/usb/hcd-musb.h"
46
-#include "hw/arm/omap.h"
47
-#include "hw/hw.h"
48
-#include "hw/irq.h"
49
-#include "hw/sysbus.h"
50
-#include "qom/object.h"
51
-
52
-#define TYPE_TUSB6010 "tusb6010"
53
-OBJECT_DECLARE_SIMPLE_TYPE(TUSBState, TUSB6010)
54
-
55
-struct TUSBState {
56
- SysBusDevice parent_obj;
57
-
58
- MemoryRegion iomem[2];
59
- qemu_irq irq;
60
- MUSBState *musb;
61
- QEMUTimer *otg_timer;
62
- QEMUTimer *pwr_timer;
63
-
64
- int power;
65
- uint32_t scratch;
66
- uint16_t test_reset;
67
- uint32_t prcm_config;
68
- uint32_t prcm_mngmt;
69
- uint16_t otg_status;
70
- uint32_t dev_config;
71
- int host_mode;
72
- uint32_t intr;
73
- uint32_t intr_ok;
74
- uint32_t mask;
75
- uint32_t usbip_intr;
76
- uint32_t usbip_mask;
77
- uint32_t gpio_intr;
78
- uint32_t gpio_mask;
79
- uint32_t gpio_config;
80
- uint32_t dma_intr;
81
- uint32_t dma_mask;
82
- uint32_t dma_map;
83
- uint32_t dma_config;
84
- uint32_t ep0_config;
85
- uint32_t rx_config[15];
86
- uint32_t tx_config[15];
87
- uint32_t wkup_mask;
88
- uint32_t pullup[2];
89
- uint32_t control_config;
90
- uint32_t otg_timer_val;
91
-};
92
-
93
-#define TUSB_DEVCLOCK            60000000    /* 60 MHz */
94
-
95
-#define TUSB_VLYNQ_CTRL            0x004
96
-
97
-/* Mentor Graphics OTG core registers. */
98
-#define TUSB_BASE_OFFSET        0x400
99
-
100
-/* FIFO registers, 32-bit. */
101
-#define TUSB_FIFO_BASE            0x600
102
-
103
-/* Device System & Control registers, 32-bit. */
104
-#define TUSB_SYS_REG_BASE        0x800
105
-
106
-#define TUSB_DEV_CONF            (TUSB_SYS_REG_BASE + 0x000)
107
-#define    TUSB_DEV_CONF_USB_HOST_MODE    (1 << 16)
108
-#define    TUSB_DEV_CONF_PROD_TEST_MODE    (1 << 15)
109
-#define    TUSB_DEV_CONF_SOFT_ID        (1 << 1)
110
-#define    TUSB_DEV_CONF_ID_SEL        (1 << 0)
111
-
112
-#define TUSB_PHY_OTG_CTRL_ENABLE    (TUSB_SYS_REG_BASE + 0x004)
113
-#define TUSB_PHY_OTG_CTRL        (TUSB_SYS_REG_BASE + 0x008)
114
-#define    TUSB_PHY_OTG_CTRL_WRPROTECT    (0xa5 << 24)
115
-#define    TUSB_PHY_OTG_CTRL_O_ID_PULLUP    (1 << 23)
116
-#define    TUSB_PHY_OTG_CTRL_O_VBUS_DET_EN    (1 << 19)
117
-#define    TUSB_PHY_OTG_CTRL_O_SESS_END_EN    (1 << 18)
118
-#define    TUSB_PHY_OTG_CTRL_TESTM2    (1 << 17)
119
-#define    TUSB_PHY_OTG_CTRL_TESTM1    (1 << 16)
120
-#define    TUSB_PHY_OTG_CTRL_TESTM0    (1 << 15)
121
-#define    TUSB_PHY_OTG_CTRL_TX_DATA2    (1 << 14)
122
-#define    TUSB_PHY_OTG_CTRL_TX_GZ2    (1 << 13)
123
-#define    TUSB_PHY_OTG_CTRL_TX_ENABLE2    (1 << 12)
124
-#define    TUSB_PHY_OTG_CTRL_DM_PULLDOWN    (1 << 11)
125
-#define    TUSB_PHY_OTG_CTRL_DP_PULLDOWN    (1 << 10)
126
-#define    TUSB_PHY_OTG_CTRL_OSC_EN    (1 << 9)
127
-#define    TUSB_PHY_OTG_CTRL_PHYREF_CLK(v)    (((v) & 3) << 7)
128
-#define    TUSB_PHY_OTG_CTRL_PD        (1 << 6)
129
-#define    TUSB_PHY_OTG_CTRL_PLL_ON    (1 << 5)
130
-#define    TUSB_PHY_OTG_CTRL_EXT_RPU    (1 << 4)
131
-#define    TUSB_PHY_OTG_CTRL_PWR_GOOD    (1 << 3)
132
-#define    TUSB_PHY_OTG_CTRL_RESET        (1 << 2)
133
-#define    TUSB_PHY_OTG_CTRL_SUSPENDM    (1 << 1)
134
-#define    TUSB_PHY_OTG_CTRL_CLK_MODE    (1 << 0)
135
-
136
-/* OTG status register */
137
-#define TUSB_DEV_OTG_STAT        (TUSB_SYS_REG_BASE + 0x00c)
138
-#define    TUSB_DEV_OTG_STAT_PWR_CLK_GOOD    (1 << 8)
139
-#define    TUSB_DEV_OTG_STAT_SESS_END    (1 << 7)
140
-#define    TUSB_DEV_OTG_STAT_SESS_VALID    (1 << 6)
141
-#define    TUSB_DEV_OTG_STAT_VBUS_VALID    (1 << 5)
142
-#define    TUSB_DEV_OTG_STAT_VBUS_SENSE    (1 << 4)
143
-#define    TUSB_DEV_OTG_STAT_ID_STATUS    (1 << 3)
144
-#define    TUSB_DEV_OTG_STAT_HOST_DISCON    (1 << 2)
145
-#define    TUSB_DEV_OTG_STAT_LINE_STATE    (3 << 0)
146
-#define    TUSB_DEV_OTG_STAT_DP_ENABLE    (1 << 1)
147
-#define    TUSB_DEV_OTG_STAT_DM_ENABLE    (1 << 0)
148
-
149
-#define TUSB_DEV_OTG_TIMER        (TUSB_SYS_REG_BASE + 0x010)
150
-#define TUSB_DEV_OTG_TIMER_ENABLE    (1 << 31)
151
-#define TUSB_DEV_OTG_TIMER_VAL(v)    ((v) & 0x07ffffff)
152
-#define TUSB_PRCM_REV            (TUSB_SYS_REG_BASE + 0x014)
153
-
154
-/* PRCM configuration register */
155
-#define TUSB_PRCM_CONF            (TUSB_SYS_REG_BASE + 0x018)
156
-#define    TUSB_PRCM_CONF_SFW_CPEN        (1 << 24)
157
-#define    TUSB_PRCM_CONF_SYS_CLKSEL(v)    (((v) & 3) << 16)
158
-
159
-/* PRCM management register */
160
-#define TUSB_PRCM_MNGMT            (TUSB_SYS_REG_BASE + 0x01c)
161
-#define    TUSB_PRCM_MNGMT_SRP_FIX_TMR(v)    (((v) & 0xf) << 25)
162
-#define    TUSB_PRCM_MNGMT_SRP_FIX_EN    (1 << 24)
163
-#define    TUSB_PRCM_MNGMT_VBUS_VAL_TMR(v)    (((v) & 0xf) << 20)
164
-#define    TUSB_PRCM_MNGMT_VBUS_VAL_FLT_EN    (1 << 19)
165
-#define    TUSB_PRCM_MNGMT_DFT_CLK_DIS    (1 << 18)
166
-#define    TUSB_PRCM_MNGMT_VLYNQ_CLK_DIS    (1 << 17)
167
-#define    TUSB_PRCM_MNGMT_OTG_SESS_END_EN    (1 << 10)
168
-#define    TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN    (1 << 9)
169
-#define    TUSB_PRCM_MNGMT_OTG_ID_PULLUP    (1 << 8)
170
-#define    TUSB_PRCM_MNGMT_15_SW_EN    (1 << 4)
171
-#define    TUSB_PRCM_MNGMT_33_SW_EN    (1 << 3)
172
-#define    TUSB_PRCM_MNGMT_5V_CPEN        (1 << 2)
173
-#define    TUSB_PRCM_MNGMT_PM_IDLE        (1 << 1)
174
-#define    TUSB_PRCM_MNGMT_DEV_IDLE    (1 << 0)
175
-
176
-/* Wake-up source clear and mask registers */
177
-#define TUSB_PRCM_WAKEUP_SOURCE        (TUSB_SYS_REG_BASE + 0x020)
178
-#define TUSB_PRCM_WAKEUP_CLEAR        (TUSB_SYS_REG_BASE + 0x028)
179
-#define TUSB_PRCM_WAKEUP_MASK        (TUSB_SYS_REG_BASE + 0x02c)
180
-#define    TUSB_PRCM_WAKEUP_RESERVED_BITS    (0xffffe << 13)
181
-#define    TUSB_PRCM_WGPIO_7        (1 << 12)
182
-#define    TUSB_PRCM_WGPIO_6        (1 << 11)
183
-#define    TUSB_PRCM_WGPIO_5        (1 << 10)
184
-#define    TUSB_PRCM_WGPIO_4        (1 << 9)
185
-#define    TUSB_PRCM_WGPIO_3        (1 << 8)
186
-#define    TUSB_PRCM_WGPIO_2        (1 << 7)
187
-#define    TUSB_PRCM_WGPIO_1        (1 << 6)
188
-#define    TUSB_PRCM_WGPIO_0        (1 << 5)
189
-#define    TUSB_PRCM_WHOSTDISCON        (1 << 4)    /* Host disconnect */
190
-#define    TUSB_PRCM_WBUS            (1 << 3)    /* USB bus resume */
191
-#define    TUSB_PRCM_WNORCS        (1 << 2)    /* NOR chip select */
192
-#define    TUSB_PRCM_WVBUS            (1 << 1)    /* OTG PHY VBUS */
193
-#define    TUSB_PRCM_WID            (1 << 0)    /* OTG PHY ID detect */
194
-
195
-#define TUSB_PULLUP_1_CTRL        (TUSB_SYS_REG_BASE + 0x030)
196
-#define TUSB_PULLUP_2_CTRL        (TUSB_SYS_REG_BASE + 0x034)
197
-#define TUSB_INT_CTRL_REV        (TUSB_SYS_REG_BASE + 0x038)
198
-#define TUSB_INT_CTRL_CONF        (TUSB_SYS_REG_BASE + 0x03c)
199
-#define TUSB_USBIP_INT_SRC        (TUSB_SYS_REG_BASE + 0x040)
200
-#define TUSB_USBIP_INT_SET        (TUSB_SYS_REG_BASE + 0x044)
201
-#define TUSB_USBIP_INT_CLEAR        (TUSB_SYS_REG_BASE + 0x048)
202
-#define TUSB_USBIP_INT_MASK        (TUSB_SYS_REG_BASE + 0x04c)
203
-#define TUSB_DMA_INT_SRC        (TUSB_SYS_REG_BASE + 0x050)
204
-#define TUSB_DMA_INT_SET        (TUSB_SYS_REG_BASE + 0x054)
205
-#define TUSB_DMA_INT_CLEAR        (TUSB_SYS_REG_BASE + 0x058)
206
-#define TUSB_DMA_INT_MASK        (TUSB_SYS_REG_BASE + 0x05c)
207
-#define TUSB_GPIO_INT_SRC        (TUSB_SYS_REG_BASE + 0x060)
208
-#define TUSB_GPIO_INT_SET        (TUSB_SYS_REG_BASE + 0x064)
209
-#define TUSB_GPIO_INT_CLEAR        (TUSB_SYS_REG_BASE + 0x068)
210
-#define TUSB_GPIO_INT_MASK        (TUSB_SYS_REG_BASE + 0x06c)
211
-
212
-/* NOR flash interrupt source registers */
213
-#define TUSB_INT_SRC            (TUSB_SYS_REG_BASE + 0x070)
214
-#define TUSB_INT_SRC_SET        (TUSB_SYS_REG_BASE + 0x074)
215
-#define TUSB_INT_SRC_CLEAR        (TUSB_SYS_REG_BASE + 0x078)
216
-#define TUSB_INT_MASK            (TUSB_SYS_REG_BASE + 0x07c)
217
-#define    TUSB_INT_SRC_TXRX_DMA_DONE    (1 << 24)
218
-#define    TUSB_INT_SRC_USB_IP_CORE    (1 << 17)
219
-#define    TUSB_INT_SRC_OTG_TIMEOUT    (1 << 16)
220
-#define    TUSB_INT_SRC_VBUS_SENSE_CHNG    (1 << 15)
221
-#define    TUSB_INT_SRC_ID_STATUS_CHNG    (1 << 14)
222
-#define    TUSB_INT_SRC_DEV_WAKEUP        (1 << 13)
223
-#define    TUSB_INT_SRC_DEV_READY        (1 << 12)
224
-#define    TUSB_INT_SRC_USB_IP_TX        (1 << 9)
225
-#define    TUSB_INT_SRC_USB_IP_RX        (1 << 8)
226
-#define    TUSB_INT_SRC_USB_IP_VBUS_ERR    (1 << 7)
227
-#define    TUSB_INT_SRC_USB_IP_VBUS_REQ    (1 << 6)
228
-#define    TUSB_INT_SRC_USB_IP_DISCON    (1 << 5)
229
-#define    TUSB_INT_SRC_USB_IP_CONN    (1 << 4)
230
-#define    TUSB_INT_SRC_USB_IP_SOF        (1 << 3)
231
-#define    TUSB_INT_SRC_USB_IP_RST_BABBLE    (1 << 2)
232
-#define    TUSB_INT_SRC_USB_IP_RESUME    (1 << 1)
233
-#define    TUSB_INT_SRC_USB_IP_SUSPEND    (1 << 0)
234
-
235
-#define TUSB_GPIO_REV            (TUSB_SYS_REG_BASE + 0x080)
236
-#define TUSB_GPIO_CONF            (TUSB_SYS_REG_BASE + 0x084)
237
-#define TUSB_DMA_CTRL_REV        (TUSB_SYS_REG_BASE + 0x100)
238
-#define TUSB_DMA_REQ_CONF        (TUSB_SYS_REG_BASE + 0x104)
239
-#define TUSB_EP0_CONF            (TUSB_SYS_REG_BASE + 0x108)
240
-#define TUSB_EP_IN_SIZE            (TUSB_SYS_REG_BASE + 0x10c)
241
-#define TUSB_DMA_EP_MAP            (TUSB_SYS_REG_BASE + 0x148)
242
-#define TUSB_EP_OUT_SIZE        (TUSB_SYS_REG_BASE + 0x14c)
243
-#define TUSB_EP_MAX_PACKET_SIZE_OFFSET    (TUSB_SYS_REG_BASE + 0x188)
244
-#define TUSB_SCRATCH_PAD        (TUSB_SYS_REG_BASE + 0x1c4)
245
-#define TUSB_WAIT_COUNT            (TUSB_SYS_REG_BASE + 0x1c8)
246
-#define TUSB_PROD_TEST_RESET        (TUSB_SYS_REG_BASE + 0x1d8)
247
-
248
-#define TUSB_DIDR1_LO            (TUSB_SYS_REG_BASE + 0x1f8)
249
-#define TUSB_DIDR1_HI            (TUSB_SYS_REG_BASE + 0x1fc)
250
-
251
-/* Device System & Control register bitfields */
252
-#define TUSB_INT_CTRL_CONF_INT_RLCYC(v)    (((v) & 0x7) << 18)
253
-#define TUSB_INT_CTRL_CONF_INT_POLARITY    (1 << 17)
254
-#define TUSB_INT_CTRL_CONF_INT_MODE    (1 << 16)
255
-#define TUSB_GPIO_CONF_DMAREQ(v)    (((v) & 0x3f) << 24)
256
-#define TUSB_DMA_REQ_CONF_BURST_SIZE(v)    (((v) & 3) << 26)
257
-#define TUSB_DMA_REQ_CONF_DMA_RQ_EN(v)    (((v) & 0x3f) << 20)
258
-#define TUSB_DMA_REQ_CONF_DMA_RQ_ASR(v)    (((v) & 0xf) << 16)
259
-#define TUSB_EP0_CONFIG_SW_EN        (1 << 8)
260
-#define TUSB_EP0_CONFIG_DIR_TX        (1 << 7)
261
-#define TUSB_EP0_CONFIG_XFR_SIZE(v)    ((v) & 0x7f)
262
-#define TUSB_EP_CONFIG_SW_EN        (1 << 31)
263
-#define TUSB_EP_CONFIG_XFR_SIZE(v)    ((v) & 0x7fffffff)
264
-#define TUSB_PROD_TEST_RESET_VAL    0xa596
265
-
266
-static void tusb_intr_update(TUSBState *s)
267
-{
268
- if (s->control_config & TUSB_INT_CTRL_CONF_INT_POLARITY)
269
- qemu_set_irq(s->irq, s->intr & ~s->mask & s->intr_ok);
270
- else
271
- qemu_set_irq(s->irq, (!(s->intr & ~s->mask)) & s->intr_ok);
272
-}
273
-
274
-static void tusb_usbip_intr_update(TUSBState *s)
275
-{
276
- /* TX interrupt in the MUSB */
277
- if (s->usbip_intr & 0x0000ffff & ~s->usbip_mask)
278
- s->intr |= TUSB_INT_SRC_USB_IP_TX;
279
- else
280
- s->intr &= ~TUSB_INT_SRC_USB_IP_TX;
281
-
282
- /* RX interrupt in the MUSB */
283
- if (s->usbip_intr & 0xffff0000 & ~s->usbip_mask)
284
- s->intr |= TUSB_INT_SRC_USB_IP_RX;
285
- else
286
- s->intr &= ~TUSB_INT_SRC_USB_IP_RX;
287
-
288
- /* XXX: What about TUSB_INT_SRC_USB_IP_CORE? */
289
-
290
- tusb_intr_update(s);
291
-}
292
-
293
-static void tusb_dma_intr_update(TUSBState *s)
294
-{
295
- if (s->dma_intr & ~s->dma_mask)
296
- s->intr |= TUSB_INT_SRC_TXRX_DMA_DONE;
297
- else
298
- s->intr &= ~TUSB_INT_SRC_TXRX_DMA_DONE;
299
-
300
- tusb_intr_update(s);
301
-}
302
-
303
-static void tusb_gpio_intr_update(TUSBState *s)
304
-{
305
- /* TODO: How is this signalled? */
306
-}
307
-
308
-static uint32_t tusb_async_readb(void *opaque, hwaddr addr)
309
-{
310
- TUSBState *s = (TUSBState *) opaque;
311
-
312
- switch (addr & 0xfff) {
313
- case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
314
- return musb_read[0](s->musb, addr & 0x1ff);
315
-
316
- case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
317
- return musb_read[0](s->musb, 0x20 + ((addr >> 3) & 0x3c));
318
- }
319
-
320
- printf("%s: unknown register at %03x\n",
321
- __func__, (int) (addr & 0xfff));
322
- return 0;
323
-}
324
-
325
-static uint32_t tusb_async_readh(void *opaque, hwaddr addr)
326
-{
327
- TUSBState *s = (TUSBState *) opaque;
328
-
329
- switch (addr & 0xfff) {
330
- case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
331
- return musb_read[1](s->musb, addr & 0x1ff);
332
-
333
- case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
334
- return musb_read[1](s->musb, 0x20 + ((addr >> 3) & 0x3c));
335
- }
336
-
337
- printf("%s: unknown register at %03x\n",
338
- __func__, (int) (addr & 0xfff));
339
- return 0;
340
-}
341
-
342
-static uint32_t tusb_async_readw(void *opaque, hwaddr addr)
343
-{
344
- TUSBState *s = (TUSBState *) opaque;
345
- int offset = addr & 0xfff;
346
- int epnum;
347
- uint32_t ret;
348
-
349
- switch (offset) {
350
- case TUSB_DEV_CONF:
351
- return s->dev_config;
352
-
353
- case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
354
- return musb_read[2](s->musb, offset & 0x1ff);
355
-
356
- case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
357
- return musb_read[2](s->musb, 0x20 + ((addr >> 3) & 0x3c));
358
-
359
- case TUSB_PHY_OTG_CTRL_ENABLE:
360
- case TUSB_PHY_OTG_CTRL:
361
- return 0x00;    /* TODO */
362
-
363
- case TUSB_DEV_OTG_STAT:
364
- ret = s->otg_status;
365
-#if 0
366
- if (!(s->prcm_mngmt & TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN))
367
- ret &= ~TUSB_DEV_OTG_STAT_VBUS_VALID;
368
-#endif
369
- return ret;
370
- case TUSB_DEV_OTG_TIMER:
371
- return s->otg_timer_val;
372
-
373
- case TUSB_PRCM_REV:
374
- return 0x20;
375
- case TUSB_PRCM_CONF:
376
- return s->prcm_config;
377
- case TUSB_PRCM_MNGMT:
378
- return s->prcm_mngmt;
379
- case TUSB_PRCM_WAKEUP_SOURCE:
380
- case TUSB_PRCM_WAKEUP_CLEAR:    /* TODO: What does this one return? */
381
- return 0x00000000;
382
- case TUSB_PRCM_WAKEUP_MASK:
383
- return s->wkup_mask;
384
-
385
- case TUSB_PULLUP_1_CTRL:
386
- return s->pullup[0];
387
- case TUSB_PULLUP_2_CTRL:
388
- return s->pullup[1];
389
-
390
- case TUSB_INT_CTRL_REV:
391
- return 0x20;
392
- case TUSB_INT_CTRL_CONF:
393
- return s->control_config;
394
-
395
- case TUSB_USBIP_INT_SRC:
396
- case TUSB_USBIP_INT_SET:    /* TODO: What do these two return? */
397
- case TUSB_USBIP_INT_CLEAR:
398
- return s->usbip_intr;
399
- case TUSB_USBIP_INT_MASK:
400
- return s->usbip_mask;
401
-
402
- case TUSB_DMA_INT_SRC:
403
- case TUSB_DMA_INT_SET:    /* TODO: What do these two return? */
404
- case TUSB_DMA_INT_CLEAR:
405
- return s->dma_intr;
406
- case TUSB_DMA_INT_MASK:
407
- return s->dma_mask;
408
-
409
- case TUSB_GPIO_INT_SRC:    /* TODO: What do these two return? */
410
- case TUSB_GPIO_INT_SET:
411
- case TUSB_GPIO_INT_CLEAR:
412
- return s->gpio_intr;
413
- case TUSB_GPIO_INT_MASK:
414
- return s->gpio_mask;
415
-
416
- case TUSB_INT_SRC:
417
- case TUSB_INT_SRC_SET:    /* TODO: What do these two return? */
418
- case TUSB_INT_SRC_CLEAR:
419
- return s->intr;
420
- case TUSB_INT_MASK:
421
- return s->mask;
422
-
423
- case TUSB_GPIO_REV:
424
- return 0x30;
425
- case TUSB_GPIO_CONF:
426
- return s->gpio_config;
427
-
428
- case TUSB_DMA_CTRL_REV:
429
- return 0x30;
430
- case TUSB_DMA_REQ_CONF:
431
- return s->dma_config;
432
- case TUSB_EP0_CONF:
433
- return s->ep0_config;
434
- case TUSB_EP_IN_SIZE ... (TUSB_EP_IN_SIZE + 0x3b):
435
- epnum = (offset - TUSB_EP_IN_SIZE) >> 2;
436
- return s->tx_config[epnum];
437
- case TUSB_DMA_EP_MAP:
438
- return s->dma_map;
439
- case TUSB_EP_OUT_SIZE ... (TUSB_EP_OUT_SIZE + 0x3b):
440
- epnum = (offset - TUSB_EP_OUT_SIZE) >> 2;
441
- return s->rx_config[epnum];
442
- case TUSB_EP_MAX_PACKET_SIZE_OFFSET ...
443
- (TUSB_EP_MAX_PACKET_SIZE_OFFSET + 0x3b):
444
- return 0x00000000;    /* TODO */
445
- case TUSB_WAIT_COUNT:
446
- return 0x00;        /* TODO */
447
-
448
- case TUSB_SCRATCH_PAD:
449
- return s->scratch;
450
-
451
- case TUSB_PROD_TEST_RESET:
452
- return s->test_reset;
453
-
454
- /* DIE IDs */
455
- case TUSB_DIDR1_LO:
456
- return 0xa9453c59;
457
- case TUSB_DIDR1_HI:
458
- return 0x54059adf;
459
- }
460
-
461
- printf("%s: unknown register at %03x\n", __func__, offset);
462
- return 0;
463
-}
464
-
465
-static void tusb_async_writeb(void *opaque, hwaddr addr,
466
- uint32_t value)
467
-{
468
- TUSBState *s = (TUSBState *) opaque;
469
-
470
- switch (addr & 0xfff) {
471
- case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
472
- musb_write[0](s->musb, addr & 0x1ff, value);
473
- break;
474
-
475
- case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
476
- musb_write[0](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);
477
- break;
478
-
479
- default:
480
- printf("%s: unknown register at %03x\n",
481
- __func__, (int) (addr & 0xfff));
482
- return;
483
- }
484
-}
485
-
486
-static void tusb_async_writeh(void *opaque, hwaddr addr,
487
- uint32_t value)
488
-{
489
- TUSBState *s = (TUSBState *) opaque;
490
-
491
- switch (addr & 0xfff) {
492
- case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
493
- musb_write[1](s->musb, addr & 0x1ff, value);
494
- break;
495
-
496
- case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
497
- musb_write[1](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);
498
- break;
499
-
500
- default:
501
- printf("%s: unknown register at %03x\n",
502
- __func__, (int) (addr & 0xfff));
503
- return;
504
- }
505
-}
506
-
507
-static void tusb_async_writew(void *opaque, hwaddr addr,
508
- uint32_t value)
509
-{
510
- TUSBState *s = (TUSBState *) opaque;
511
- int offset = addr & 0xfff;
512
- int epnum;
513
-
514
- switch (offset) {
515
- case TUSB_VLYNQ_CTRL:
516
- break;
517
-
518
- case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
519
- musb_write[2](s->musb, offset & 0x1ff, value);
520
- break;
521
-
522
- case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
523
- musb_write[2](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);
524
- break;
525
-
526
- case TUSB_DEV_CONF:
527
- s->dev_config = value;
528
- s->host_mode = (value & TUSB_DEV_CONF_USB_HOST_MODE);
529
- if (value & TUSB_DEV_CONF_PROD_TEST_MODE)
530
- hw_error("%s: Product Test mode not allowed\n", __func__);
531
- break;
532
-
533
- case TUSB_PHY_OTG_CTRL_ENABLE:
534
- case TUSB_PHY_OTG_CTRL:
535
- return;        /* TODO */
536
- case TUSB_DEV_OTG_TIMER:
537
- s->otg_timer_val = value;
538
- if (value & TUSB_DEV_OTG_TIMER_ENABLE)
539
- timer_mod(s->otg_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
540
- muldiv64(TUSB_DEV_OTG_TIMER_VAL(value),
541
- NANOSECONDS_PER_SECOND, TUSB_DEVCLOCK));
542
- else
543
- timer_del(s->otg_timer);
544
- break;
545
-
546
- case TUSB_PRCM_CONF:
547
- s->prcm_config = value;
548
- break;
549
- case TUSB_PRCM_MNGMT:
550
- s->prcm_mngmt = value;
551
- break;
552
- case TUSB_PRCM_WAKEUP_CLEAR:
553
- break;
554
- case TUSB_PRCM_WAKEUP_MASK:
555
- s->wkup_mask = value;
556
- break;
557
-
558
- case TUSB_PULLUP_1_CTRL:
559
- s->pullup[0] = value;
560
- break;
561
- case TUSB_PULLUP_2_CTRL:
562
- s->pullup[1] = value;
563
- break;
564
- case TUSB_INT_CTRL_CONF:
565
- s->control_config = value;
566
- tusb_intr_update(s);
567
- break;
568
-
569
- case TUSB_USBIP_INT_SET:
570
- s->usbip_intr |= value;
571
- tusb_usbip_intr_update(s);
572
- break;
573
- case TUSB_USBIP_INT_CLEAR:
574
- s->usbip_intr &= ~value;
575
- tusb_usbip_intr_update(s);
576
- musb_core_intr_clear(s->musb, ~value);
577
- break;
578
- case TUSB_USBIP_INT_MASK:
579
- s->usbip_mask = value;
580
- tusb_usbip_intr_update(s);
581
- break;
582
-
583
- case TUSB_DMA_INT_SET:
584
- s->dma_intr |= value;
585
- tusb_dma_intr_update(s);
586
- break;
587
- case TUSB_DMA_INT_CLEAR:
588
- s->dma_intr &= ~value;
589
- tusb_dma_intr_update(s);
590
- break;
591
- case TUSB_DMA_INT_MASK:
592
- s->dma_mask = value;
593
- tusb_dma_intr_update(s);
594
- break;
595
-
596
- case TUSB_GPIO_INT_SET:
597
- s->gpio_intr |= value;
598
- tusb_gpio_intr_update(s);
599
- break;
600
- case TUSB_GPIO_INT_CLEAR:
601
- s->gpio_intr &= ~value;
602
- tusb_gpio_intr_update(s);
603
- break;
604
- case TUSB_GPIO_INT_MASK:
605
- s->gpio_mask = value;
606
- tusb_gpio_intr_update(s);
607
- break;
608
-
609
- case TUSB_INT_SRC_SET:
610
- s->intr |= value;
611
- tusb_intr_update(s);
612
- break;
613
- case TUSB_INT_SRC_CLEAR:
614
- s->intr &= ~value;
615
- tusb_intr_update(s);
616
- break;
617
- case TUSB_INT_MASK:
618
- s->mask = value;
619
- tusb_intr_update(s);
620
- break;
621
-
622
- case TUSB_GPIO_CONF:
623
- s->gpio_config = value;
624
- break;
625
- case TUSB_DMA_REQ_CONF:
626
- s->dma_config = value;
627
- break;
628
- case TUSB_EP0_CONF:
629
- s->ep0_config = value & 0x1ff;
630
- musb_set_size(s->musb, 0, TUSB_EP0_CONFIG_XFR_SIZE(value),
631
- value & TUSB_EP0_CONFIG_DIR_TX);
632
- break;
633
- case TUSB_EP_IN_SIZE ... (TUSB_EP_IN_SIZE + 0x3b):
634
- epnum = (offset - TUSB_EP_IN_SIZE) >> 2;
635
- s->tx_config[epnum] = value;
636
- musb_set_size(s->musb, epnum + 1, TUSB_EP_CONFIG_XFR_SIZE(value), 1);
637
- break;
638
- case TUSB_DMA_EP_MAP:
639
- s->dma_map = value;
640
- break;
641
- case TUSB_EP_OUT_SIZE ... (TUSB_EP_OUT_SIZE + 0x3b):
642
- epnum = (offset - TUSB_EP_OUT_SIZE) >> 2;
643
- s->rx_config[epnum] = value;
644
- musb_set_size(s->musb, epnum + 1, TUSB_EP_CONFIG_XFR_SIZE(value), 0);
645
- break;
646
- case TUSB_EP_MAX_PACKET_SIZE_OFFSET ...
647
- (TUSB_EP_MAX_PACKET_SIZE_OFFSET + 0x3b):
648
- return;        /* TODO */
649
- case TUSB_WAIT_COUNT:
650
- return;        /* TODO */
651
-
652
- case TUSB_SCRATCH_PAD:
653
- s->scratch = value;
654
- break;
655
-
656
- case TUSB_PROD_TEST_RESET:
657
- s->test_reset = value;
658
- break;
659
-
660
- default:
661
- printf("%s: unknown register at %03x\n", __func__, offset);
662
- return;
663
- }
664
-}
665
-
666
-static uint64_t tusb_async_readfn(void *opaque, hwaddr addr, unsigned size)
667
-{
668
- switch (size) {
669
- case 1:
670
- return tusb_async_readb(opaque, addr);
671
- case 2:
672
- return tusb_async_readh(opaque, addr);
673
- case 4:
674
- return tusb_async_readw(opaque, addr);
675
- default:
676
- g_assert_not_reached();
677
- }
678
-}
679
-
680
-static void tusb_async_writefn(void *opaque, hwaddr addr,
681
- uint64_t value, unsigned size)
682
-{
683
- switch (size) {
684
- case 1:
685
- tusb_async_writeb(opaque, addr, value);
686
- break;
687
- case 2:
688
- tusb_async_writeh(opaque, addr, value);
689
- break;
690
- case 4:
691
- tusb_async_writew(opaque, addr, value);
692
- break;
693
- default:
694
- g_assert_not_reached();
695
- }
696
-}
697
-
698
-static const MemoryRegionOps tusb_async_ops = {
699
- .read = tusb_async_readfn,
700
- .write = tusb_async_writefn,
701
- .valid.min_access_size = 1,
702
- .valid.max_access_size = 4,
703
- .endianness = DEVICE_NATIVE_ENDIAN,
704
-};
705
-
706
-static void tusb_otg_tick(void *opaque)
707
-{
708
- TUSBState *s = (TUSBState *) opaque;
709
-
710
- s->otg_timer_val = 0;
711
- s->intr |= TUSB_INT_SRC_OTG_TIMEOUT;
712
- tusb_intr_update(s);
713
-}
714
-
715
-static void tusb_power_tick(void *opaque)
716
-{
717
- TUSBState *s = (TUSBState *) opaque;
718
-
719
- if (s->power) {
720
- s->intr_ok = ~0;
721
- tusb_intr_update(s);
722
- }
723
-}
724
-
725
-static void tusb_musb_core_intr(void *opaque, int source, int level)
726
-{
727
- TUSBState *s = (TUSBState *) opaque;
728
- uint16_t otg_status = s->otg_status;
729
-
730
- switch (source) {
731
- case musb_set_vbus:
732
- if (level)
733
- otg_status |= TUSB_DEV_OTG_STAT_VBUS_VALID;
734
- else
735
- otg_status &= ~TUSB_DEV_OTG_STAT_VBUS_VALID;
736
-
737
- /* XXX: only if TUSB_PHY_OTG_CTRL_OTG_VBUS_DET_EN set? */
738
- /* XXX: only if TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN set? */
739
- if (s->otg_status != otg_status) {
740
- s->otg_status = otg_status;
741
- s->intr |= TUSB_INT_SRC_VBUS_SENSE_CHNG;
742
- tusb_intr_update(s);
743
- }
744
- break;
745
-
746
- case musb_set_session:
747
- /* XXX: only if TUSB_PHY_OTG_CTRL_OTG_SESS_END_EN set? */
748
- /* XXX: only if TUSB_PRCM_MNGMT_OTG_SESS_END_EN set? */
749
- if (level) {
750
- s->otg_status |= TUSB_DEV_OTG_STAT_SESS_VALID;
751
- s->otg_status &= ~TUSB_DEV_OTG_STAT_SESS_END;
752
- } else {
753
- s->otg_status &= ~TUSB_DEV_OTG_STAT_SESS_VALID;
754
- s->otg_status |= TUSB_DEV_OTG_STAT_SESS_END;
755
- }
756
-
757
- /* XXX: some IRQ or anything? */
758
- break;
759
-
760
- case musb_irq_tx:
761
- case musb_irq_rx:
762
- s->usbip_intr = musb_core_intr_get(s->musb);
763
- /* Fall through. */
764
- default:
765
- if (level)
766
- s->intr |= 1 << source;
767
- else
768
- s->intr &= ~(1 << source);
769
- tusb_intr_update(s);
770
- break;
771
- }
772
-}
773
-
774
-static void tusb6010_power(TUSBState *s, int on)
775
-{
776
- if (!on) {
777
- s->power = 0;
778
- } else if (!s->power && on) {
779
- s->power = 1;
780
- /* Pull the interrupt down after TUSB6010 comes up. */
781
- s->intr_ok = 0;
782
- tusb_intr_update(s);
783
- timer_mod(s->pwr_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
784
- NANOSECONDS_PER_SECOND / 2);
785
- }
786
-}
787
-
788
-static void tusb6010_irq(void *opaque, int source, int level)
789
-{
790
- if (source) {
791
- tusb_musb_core_intr(opaque, source - 1, level);
792
- } else {
793
- tusb6010_power(opaque, level);
794
- }
795
-}
796
-
797
-static void tusb6010_reset(DeviceState *dev)
798
-{
799
- TUSBState *s = TUSB6010(dev);
800
- int i;
801
-
802
- s->test_reset = TUSB_PROD_TEST_RESET_VAL;
803
- s->host_mode = 0;
804
- s->dev_config = 0;
805
- s->otg_status = 0;    /* !TUSB_DEV_OTG_STAT_ID_STATUS means host mode */
806
- s->power = 0;
807
- s->mask = 0xffffffff;
808
- s->intr = 0x00000000;
809
- s->otg_timer_val = 0;
810
- s->scratch = 0;
811
- s->prcm_config = 0;
812
- s->prcm_mngmt = 0;
813
- s->intr_ok = 0;
814
- s->usbip_intr = 0;
815
- s->usbip_mask = 0;
816
- s->gpio_intr = 0;
817
- s->gpio_mask = 0;
818
- s->gpio_config = 0;
819
- s->dma_intr = 0;
820
- s->dma_mask = 0;
821
- s->dma_map = 0;
822
- s->dma_config = 0;
823
- s->ep0_config = 0;
824
- s->wkup_mask = 0;
825
- s->pullup[0] = s->pullup[1] = 0;
826
- s->control_config = 0;
827
- for (i = 0; i < 15; i++) {
828
- s->rx_config[i] = s->tx_config[i] = 0;
829
- }
830
- musb_reset(s->musb);
831
-}
832
-
833
-static void tusb6010_realize(DeviceState *dev, Error **errp)
834
-{
835
- TUSBState *s = TUSB6010(dev);
836
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
837
-
838
- s->otg_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_otg_tick, s);
839
- s->pwr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_power_tick, s);
840
- memory_region_init_io(&s->iomem[1], OBJECT(s), &tusb_async_ops, s,
841
- "tusb-async", UINT32_MAX);
842
- sysbus_init_mmio(sbd, &s->iomem[0]);
843
- sysbus_init_mmio(sbd, &s->iomem[1]);
844
- sysbus_init_irq(sbd, &s->irq);
845
- qdev_init_gpio_in(dev, tusb6010_irq, musb_irq_max + 1);
846
- s->musb = musb_init(dev, 1);
847
-}
848
-
849
-static void tusb6010_class_init(ObjectClass *klass, void *data)
850
-{
851
- DeviceClass *dc = DEVICE_CLASS(klass);
852
-
853
- dc->realize = tusb6010_realize;
854
- device_class_set_legacy_reset(dc, tusb6010_reset);
855
-}
856
-
857
-static const TypeInfo tusb6010_info = {
858
- .name = TYPE_TUSB6010,
859
- .parent = TYPE_SYS_BUS_DEVICE,
860
- .instance_size = sizeof(TUSBState),
861
- .class_init = tusb6010_class_init,
862
-};
863
-
864
-static void tusb6010_register_types(void)
865
-{
866
- type_register_static(&tusb6010_info);
867
-}
868
-
869
-type_init(tusb6010_register_types)
870
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
871
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
872
--- a/hw/usb/Kconfig
20
--- a/target/ppc/fpu_helper.c
873
+++ b/hw/usb/Kconfig
21
+++ b/target/ppc/fpu_helper.c
874
@@ -XXX,XX +XXX,XX @@ config USB_DWC2
22
@@ -XXX,XX +XXX,XX @@ void helper_compute_fprf_##tp(CPUPPCState *env, tp arg) \
875
bool
23
} else if (tp##_is_infinity(arg)) { \
876
select USB
24
fprf = neg ? 0x09 << FPSCR_FPRF : 0x05 << FPSCR_FPRF; \
877
25
} else { \
878
-config TUSB6010
26
- float_status dummy = { }; /* snan_bit_is_one = 0 */ \
879
- bool
27
- if (tp##_is_signaling_nan(arg, &dummy)) { \
880
- select USB_MUSB
28
+ if (tp##_is_signaling_nan(arg, &env->fp_status)) { \
881
-
29
fprf = 0x00 << FPSCR_FPRF; \
882
config USB_HUB
30
} else { \
883
bool
31
fprf = 0x11 << FPSCR_FPRF; \
884
default y
885
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
886
index XXXXXXX..XXXXXXX 100644
887
--- a/hw/usb/meson.build
888
+++ b/hw/usb/meson.build
889
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_USB_MUSB', if_true: files('hcd-musb.c'))
890
system_ss.add(when: 'CONFIG_USB_DWC2', if_true: files('hcd-dwc2.c'))
891
system_ss.add(when: 'CONFIG_USB_DWC3', if_true: files('hcd-dwc3.c'))
892
893
-system_ss.add(when: 'CONFIG_TUSB6010', if_true: files('tusb6010.c'))
894
system_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c'))
895
system_ss.add(when: 'CONFIG_IMX_USBPHY', if_true: files('imx-usb-phy.c'))
896
system_ss.add(when: 'CONFIG_VT82C686', if_true: files('vt82c686-uhci-pci.c'))
897
--
32
--
898
2.34.1
33
2.34.1
diff view generated by jsdifflib
1
Now we have removed all the board types that it covers, we can move
1
From: Richard Henderson <richard.henderson@linaro.org>
2
the text about old Arm boards from deprecated.rst to
3
removed-features.rst, tweaking it appropriately.
4
2
3
Now that float_status has a bunch of fp parameters,
4
it is easier to copy an existing structure than create
5
one from scratch. Begin by copying the structure that
6
corresponds to the FPSR and make only the adjustments
7
required for BFloat16 semantics.
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
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240903160751.4100218-37-peter.maydell@linaro.org
8
---
14
---
9
docs/about/deprecated.rst | 15 ---------------
15
target/arm/tcg/vec_helper.c | 20 +++++++-------------
10
docs/about/removed-features.rst | 14 ++++++++++++++
16
1 file changed, 7 insertions(+), 13 deletions(-)
11
2 files changed, 14 insertions(+), 15 deletions(-)
12
17
13
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
18
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/about/deprecated.rst
20
--- a/target/arm/tcg/vec_helper.c
16
+++ b/docs/about/deprecated.rst
21
+++ b/target/arm/tcg/vec_helper.c
17
@@ -XXX,XX +XXX,XX @@ to correct issues, mostly regarding migration compatibility. These are
22
@@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
18
no longer maintained and removing them will make the code easier to
23
* no effect on AArch32 instructions.
19
read and maintain. Use versions 3.0 and above as a replacement.
24
*/
20
25
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
21
-Arm machines ``akita``, ``borzoi``, ``cheetah``, ``connex``, ``mainstone``, ``n800``, ``n810``, ``spitz``, ``terrier``, ``tosa``, ``verdex``, ``z2`` (since 9.0)
26
- *statusp = (float_status){
22
-''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
27
- .tininess_before_rounding = float_tininess_before_rounding,
28
- .float_rounding_mode = float_round_to_odd_inf,
29
- .flush_to_zero = true,
30
- .flush_inputs_to_zero = true,
31
- .default_nan_mode = true,
32
- };
33
+
34
+ *statusp = env->vfp.fp_status;
35
+ set_default_nan_mode(true, statusp);
36
37
if (ebf) {
38
- float_status *fpst = &env->vfp.fp_status;
39
- set_flush_to_zero(get_flush_to_zero(fpst), statusp);
40
- set_flush_inputs_to_zero(get_flush_inputs_to_zero(fpst), statusp);
41
- set_float_rounding_mode(get_float_rounding_mode(fpst), statusp);
23
-
42
-
24
-QEMU includes models of some machine types where the QEMU code that
43
/* EBF=1 needs to do a step with round-to-odd semantics */
25
-emulates their SoCs is very old and unmaintained. This code is now
44
*oddstatusp = *statusp;
26
-blocking our ability to move forward with various changes across
45
set_float_rounding_mode(float_round_to_odd, oddstatusp);
27
-the codebase, and over many years nobody has been interested in
46
+ } else {
28
-trying to modernise it. We don't expect any of these machines to have
47
+ set_flush_to_zero(true, statusp);
29
-a large number of users, because they're all modelling hardware that
48
+ set_flush_inputs_to_zero(true, statusp);
30
-has now passed away into history. We are therefore dropping support
49
+ set_float_rounding_mode(float_round_to_odd_inf, statusp);
31
-for all machine types using the PXA2xx and OMAP2 SoCs. We are also
50
}
32
-dropping the ``cheetah`` OMAP1 board, because we don't have any
33
-test images for it and don't know of anybody who does; the ``sx1``
34
-and ``sx1-v1`` OMAP1 machines remain supported for now.
35
-
51
-
36
PPC 405 ``ref405ep`` machine (since 9.1)
52
return ebf;
37
''''''''''''''''''''''''''''''''''''''''
53
}
38
39
diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
40
index XXXXXXX..XXXXXXX 100644
41
--- a/docs/about/removed-features.rst
42
+++ b/docs/about/removed-features.rst
43
@@ -XXX,XX +XXX,XX @@ The Nios II architecture was orphan.
44
45
The machine was unmaintained.
46
47
+Arm machines ``akita``, ``borzoi``, ``cheetah``, ``connex``, ``mainstone``, ``n800``, ``n810``, ``spitz``, ``terrier``, ``tosa``, ``verdex``, ``z2`` (removed in 9.2)
48
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
49
+
50
+QEMU included models of some machine types where the QEMU code that
51
+emulates their SoCs was very old and unmaintained. This code was
52
+blocking our ability to move forward with various changes across
53
+the codebase, and over many years nobody has been interested in
54
+trying to modernise it. We don't expect any of these machines to have
55
+a large number of users, because they're all modelling hardware that
56
+has now passed away into history. We are therefore dropping support
57
+for all machine types using the PXA2xx and OMAP2 SoCs. We are also
58
+dropping the ``cheetah`` OMAP1 board, because we don't have any
59
+test images for it and don't know of anybody who does.
60
+
61
linux-user mode CPUs
62
--------------------
63
54
64
--
55
--
65
2.34.1
56
2.34.1
66
57
67
58
diff view generated by jsdifflib
1
From: Matheus Tavares Bernardino <quic_mathbern@quicinc.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
At e72a7f65c1 (hw: Move declaration of IRQState to header and add init
7
Add a field to float_status to specify the default NaN value; fall
4
function, 2024-06-29), we've changed qemu_allocate_irq() to use a
8
back to the old ifdef behaviour if these are not set.
5
combination of g_new() + object_initialize() instead of
6
IRQ(object_new()). The latter sets obj->free, so that that the memory is
7
properly cleaned when the object is finalized, but the former doesn't.
8
9
9
Fixes: e72a7f65c1 (hw: Move declaration of IRQState to header and add init function)
10
The default NaN value is specified by setting a uint8_t to a
10
Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
11
pattern corresponding to the sign and upper fraction parts of
11
Reviewed-by: BALATON Zoltan <balaton@eik.bme.hu>
12
the NaN; the lower bits of the fraction are set from bit 0 of
12
Reviewed-by: Brian Cain <bcain@quicinc.com>
13
the pattern.
13
Message-id: 1723deb603afec3fa69a75970cef9aac62d57d62.1726674185.git.quic_mathbern@quicinc.com
14
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
15
---
18
---
16
hw/core/irq.c | 19 +++++++++++--------
19
include/fpu/softfloat-helpers.h | 11 +++++++
17
1 file changed, 11 insertions(+), 8 deletions(-)
20
include/fpu/softfloat-types.h | 10 ++++++
21
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
22
3 files changed, 54 insertions(+), 22 deletions(-)
18
23
19
diff --git a/hw/core/irq.c b/hw/core/irq.c
24
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/core/irq.c
26
--- a/include/fpu/softfloat-helpers.h
22
+++ b/hw/core/irq.c
27
+++ b/include/fpu/softfloat-helpers.h
23
@@ -XXX,XX +XXX,XX @@ void qemu_set_irq(qemu_irq irq, int level)
28
@@ -XXX,XX +XXX,XX @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
24
irq->handler(irq->opaque, irq->n, level);
29
status->float_infzeronan_rule = rule;
25
}
30
}
26
31
27
+static void init_irq_fields(IRQState *irq, qemu_irq_handler handler,
32
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
28
+ void *opaque, int n)
33
+ float_status *status)
29
+{
34
+{
30
+ irq->handler = handler;
35
+ status->default_nan_pattern = dnan_pattern;
31
+ irq->opaque = opaque;
32
+ irq->n = n;
33
+}
36
+}
34
+
37
+
35
void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
38
static inline void set_flush_to_zero(bool val, float_status *status)
36
int n)
37
{
39
{
38
object_initialize(irq, sizeof(*irq), TYPE_IRQ);
40
status->flush_to_zero = val;
39
- irq->handler = handler;
41
@@ -XXX,XX +XXX,XX @@ static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status
40
- irq->opaque = opaque;
42
return status->float_infzeronan_rule;
41
- irq->n = n;
42
+ init_irq_fields(irq, handler, opaque, n);
43
}
43
}
44
44
45
qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler,
45
+static inline uint8_t get_float_default_nan_pattern(float_status *status)
46
@@ -XXX,XX +XXX,XX @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
46
+{
47
47
+ return status->default_nan_pattern;
48
qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
48
+}
49
+
50
static inline bool get_flush_to_zero(float_status *status)
49
{
51
{
50
- IRQState *irq;
52
return status->flush_to_zero;
51
-
53
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
52
- irq = g_new(IRQState, 1);
54
index XXXXXXX..XXXXXXX 100644
53
- qemu_init_irq(irq, handler, opaque, n);
55
--- a/include/fpu/softfloat-types.h
54
-
56
+++ b/include/fpu/softfloat-types.h
55
+ IRQState *irq = IRQ(object_new(TYPE_IRQ));
57
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
56
+ init_irq_fields(irq, handler, opaque, n);
58
/* should denormalised inputs go to zero and set the input_denormal flag? */
57
return irq;
59
bool flush_inputs_to_zero;
58
}
60
bool default_nan_mode;
59
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);
136
+
137
+ sign = dnan_pattern >> 7;
138
+ /*
139
+ * Place default_nan_pattern [6:0] into bits [62:56],
140
+ * and replecate bit [0] down into [55:0]
141
+ */
142
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
143
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
144
145
*p = (FloatParts64) {
146
.cls = float_class_qnan,
60
--
147
--
61
2.34.1
148
2.34.1
diff view generated by jsdifflib
1
Remove the lm832x keyboard-and-pwm i2c device model. This
1
Set the default NaN pattern explicitly for the tests/fp code.
2
was only used by the n800 and n810 machines.
3
4
(Although this is an i2c device and so in theory available to create
5
on the command line, in practice it has an outbound IRQ line that the
6
machine model needs to wire up, and the only way to inject keys events
7
into it is to call the lm832x_key_event() function, so it isn't
8
in practice possible to use it separately from the n800/n810.)
9
2
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20240903160751.4100218-32-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-36-peter.maydell@linaro.org
13
---
6
---
14
MAINTAINERS | 7 -
7
tests/fp/fp-bench.c | 1 +
15
include/hw/input/lm832x.h | 28 --
8
tests/fp/fp-test-log2.c | 1 +
16
hw/input/lm832x.c | 528 --------------------------------------
9
tests/fp/fp-test.c | 1 +
17
hw/input/Kconfig | 4 -
10
3 files changed, 3 insertions(+)
18
hw/input/meson.build | 1 -
19
5 files changed, 568 deletions(-)
20
delete mode 100644 include/hw/input/lm832x.h
21
delete mode 100644 hw/input/lm832x.c
22
11
23
diff --git a/MAINTAINERS b/MAINTAINERS
12
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
24
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
25
--- a/MAINTAINERS
14
--- a/tests/fp/fp-bench.c
26
+++ b/MAINTAINERS
15
+++ b/tests/fp/fp-bench.c
27
@@ -XXX,XX +XXX,XX @@ F: pc-bios/npcm7xx_bootrom.bin
16
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
28
F: roms/vbootrom
17
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
29
F: docs/system/arm/nuvoton.rst
18
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
30
19
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
31
-nSeries
20
+ set_float_default_nan_pattern(0b01000000, &soft_status);
32
-M: Peter Maydell <peter.maydell@linaro.org>
21
33
-L: qemu-arm@nongnu.org
22
f = bench_funcs[operation][precision];
34
-S: Odd Fixes
23
g_assert(f);
35
-F: hw/input/lm832x.c
24
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c
36
-F: include/hw/input/lm832x.h
37
-
38
Raspberry Pi
39
M: Peter Maydell <peter.maydell@linaro.org>
40
R: Philippe Mathieu-Daudé <philmd@linaro.org>
41
diff --git a/include/hw/input/lm832x.h b/include/hw/input/lm832x.h
42
deleted file mode 100644
43
index XXXXXXX..XXXXXXX
44
--- a/include/hw/input/lm832x.h
45
+++ /dev/null
46
@@ -XXX,XX +XXX,XX @@
47
-/*
48
- * National Semiconductor LM8322/8323 GPIO keyboard & PWM chips.
49
- *
50
- * Copyright (C) 2008 Nokia Corporation
51
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
52
- *
53
- * This program is free software; you can redistribute it and/or
54
- * modify it under the terms of the GNU General Public License as
55
- * published by the Free Software Foundation; either version 2 or
56
- * (at your option) version 3 of the License.
57
- *
58
- * This program is distributed in the hope that it will be useful,
59
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
60
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
61
- * GNU General Public License for more details.
62
- *
63
- * You should have received a copy of the GNU General Public License along
64
- * with this program; if not, see <http://www.gnu.org/licenses/>.
65
- */
66
-
67
-#ifndef HW_INPUT_LM832X_H
68
-#define HW_INPUT_LM832X_H
69
-
70
-#define TYPE_LM8323 "lm8323"
71
-
72
-void lm832x_key_event(DeviceState *dev, int key, int state);
73
-
74
-#endif
75
diff --git a/hw/input/lm832x.c b/hw/input/lm832x.c
76
deleted file mode 100644
77
index XXXXXXX..XXXXXXX
78
--- a/hw/input/lm832x.c
79
+++ /dev/null
80
@@ -XXX,XX +XXX,XX @@
81
-/*
82
- * National Semiconductor LM8322/8323 GPIO keyboard & PWM chips.
83
- *
84
- * Copyright (C) 2008 Nokia Corporation
85
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
86
- *
87
- * This program is free software; you can redistribute it and/or
88
- * modify it under the terms of the GNU General Public License as
89
- * published by the Free Software Foundation; either version 2 or
90
- * (at your option) version 3 of the License.
91
- *
92
- * This program is distributed in the hope that it will be useful,
93
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
94
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
95
- * GNU General Public License for more details.
96
- *
97
- * You should have received a copy of the GNU General Public License along
98
- * with this program; if not, see <http://www.gnu.org/licenses/>.
99
- */
100
-
101
-#include "qemu/osdep.h"
102
-#include "hw/input/lm832x.h"
103
-#include "hw/i2c/i2c.h"
104
-#include "hw/irq.h"
105
-#include "migration/vmstate.h"
106
-#include "qemu/module.h"
107
-#include "qemu/timer.h"
108
-#include "ui/console.h"
109
-#include "qom/object.h"
110
-
111
-OBJECT_DECLARE_SIMPLE_TYPE(LM823KbdState, LM8323)
112
-
113
-struct LM823KbdState {
114
- I2CSlave parent_obj;
115
-
116
- uint8_t i2c_dir;
117
- uint8_t i2c_cycle;
118
- uint8_t reg;
119
-
120
- qemu_irq nirq;
121
- uint16_t model;
122
-
123
- struct {
124
- qemu_irq out[2];
125
- int in[2][2];
126
- } mux;
127
-
128
- uint8_t config;
129
- uint8_t status;
130
- uint8_t acttime;
131
- uint8_t error;
132
- uint8_t clock;
133
-
134
- struct {
135
- uint16_t pull;
136
- uint16_t mask;
137
- uint16_t dir;
138
- uint16_t level;
139
- qemu_irq out[16];
140
- } gpio;
141
-
142
- struct {
143
- uint8_t dbnctime;
144
- uint8_t size;
145
- uint8_t start;
146
- uint8_t len;
147
- uint8_t fifo[16];
148
- } kbd;
149
-
150
- struct {
151
- uint16_t file[256];
152
- uint8_t faddr;
153
- uint8_t addr[3];
154
- QEMUTimer *tm[3];
155
- } pwm;
156
-};
157
-
158
-#define INT_KEYPAD        (1 << 0)
159
-#define INT_ERROR        (1 << 3)
160
-#define INT_NOINIT        (1 << 4)
161
-#define INT_PWMEND(n)        (1 << (5 + n))
162
-
163
-#define ERR_BADPAR        (1 << 0)
164
-#define ERR_CMDUNK        (1 << 1)
165
-#define ERR_KEYOVR        (1 << 2)
166
-#define ERR_FIFOOVR        (1 << 6)
167
-
168
-static void lm_kbd_irq_update(LM823KbdState *s)
169
-{
170
- qemu_set_irq(s->nirq, !s->status);
171
-}
172
-
173
-static void lm_kbd_gpio_update(LM823KbdState *s)
174
-{
175
-}
176
-
177
-static void lm_kbd_reset(DeviceState *dev)
178
-{
179
- LM823KbdState *s = LM8323(dev);
180
-
181
- s->config = 0x80;
182
- s->status = INT_NOINIT;
183
- s->acttime = 125;
184
- s->kbd.dbnctime = 3;
185
- s->kbd.size = 0x33;
186
- s->clock = 0x08;
187
-
188
- lm_kbd_irq_update(s);
189
- lm_kbd_gpio_update(s);
190
-}
191
-
192
-static void lm_kbd_error(LM823KbdState *s, int err)
193
-{
194
- s->error |= err;
195
- s->status |= INT_ERROR;
196
- lm_kbd_irq_update(s);
197
-}
198
-
199
-static void lm_kbd_pwm_tick(LM823KbdState *s, int line)
200
-{
201
-}
202
-
203
-static void lm_kbd_pwm_start(LM823KbdState *s, int line)
204
-{
205
- lm_kbd_pwm_tick(s, line);
206
-}
207
-
208
-static void lm_kbd_pwm0_tick(void *opaque)
209
-{
210
- lm_kbd_pwm_tick(opaque, 0);
211
-}
212
-static void lm_kbd_pwm1_tick(void *opaque)
213
-{
214
- lm_kbd_pwm_tick(opaque, 1);
215
-}
216
-static void lm_kbd_pwm2_tick(void *opaque)
217
-{
218
- lm_kbd_pwm_tick(opaque, 2);
219
-}
220
-
221
-enum {
222
- LM832x_CMD_READ_ID        = 0x80, /* Read chip ID. */
223
- LM832x_CMD_WRITE_CFG    = 0x81, /* Set configuration item. */
224
- LM832x_CMD_READ_INT        = 0x82, /* Get interrupt status. */
225
- LM832x_CMD_RESET        = 0x83, /* Reset, same as external one */
226
- LM823x_CMD_WRITE_PULL_DOWN    = 0x84, /* Select GPIO pull-up/down. */
227
- LM832x_CMD_WRITE_PORT_SEL    = 0x85, /* Select GPIO in/out. */
228
- LM832x_CMD_WRITE_PORT_STATE    = 0x86, /* Set GPIO pull-up/down. */
229
- LM832x_CMD_READ_PORT_SEL    = 0x87, /* Get GPIO in/out. */
230
- LM832x_CMD_READ_PORT_STATE    = 0x88, /* Get GPIO pull-up/down. */
231
- LM832x_CMD_READ_FIFO    = 0x89, /* Read byte from FIFO. */
232
- LM832x_CMD_RPT_READ_FIFO    = 0x8a, /* Read FIFO (no increment). */
233
- LM832x_CMD_SET_ACTIVE    = 0x8b, /* Set active time. */
234
- LM832x_CMD_READ_ERROR    = 0x8c, /* Get error status. */
235
- LM832x_CMD_READ_ROTATOR    = 0x8e, /* Read rotator status. */
236
- LM832x_CMD_SET_DEBOUNCE    = 0x8f, /* Set debouncing time. */
237
- LM832x_CMD_SET_KEY_SIZE    = 0x90, /* Set keypad size. */
238
- LM832x_CMD_READ_KEY_SIZE    = 0x91, /* Get keypad size. */
239
- LM832x_CMD_READ_CFG        = 0x92, /* Get configuration item. */
240
- LM832x_CMD_WRITE_CLOCK    = 0x93, /* Set clock config. */
241
- LM832x_CMD_READ_CLOCK    = 0x94, /* Get clock config. */
242
- LM832x_CMD_PWM_WRITE    = 0x95, /* Write PWM script. */
243
- LM832x_CMD_PWM_START    = 0x96, /* Start PWM engine. */
244
- LM832x_CMD_PWM_STOP        = 0x97, /* Stop PWM engine. */
245
- LM832x_GENERAL_ERROR    = 0xff, /* There was one error.
246
- Previously was represented by -1
247
- This is not a command */
248
-};
249
-
250
-#define LM832x_MAX_KPX        8
251
-#define LM832x_MAX_KPY        12
252
-
253
-static uint8_t lm_kbd_read(LM823KbdState *s, int reg, int byte)
254
-{
255
- int ret;
256
-
257
- switch (reg) {
258
- case LM832x_CMD_READ_ID:
259
- ret = 0x0400;
260
- break;
261
-
262
- case LM832x_CMD_READ_INT:
263
- ret = s->status;
264
- if (!(s->status & INT_NOINIT)) {
265
- s->status = 0;
266
- lm_kbd_irq_update(s);
267
- }
268
- break;
269
-
270
- case LM832x_CMD_READ_PORT_SEL:
271
- ret = s->gpio.dir;
272
- break;
273
- case LM832x_CMD_READ_PORT_STATE:
274
- ret = s->gpio.mask;
275
- break;
276
-
277
- case LM832x_CMD_READ_FIFO:
278
- if (s->kbd.len <= 1)
279
- return 0x00;
280
-
281
- /* Example response from the two commands after a INT_KEYPAD
282
- * interrupt caused by the key 0x3c being pressed:
283
- * RPT_READ_FIFO: 55 bc 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
284
- * READ_FIFO: bc 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
285
- * RPT_READ_FIFO: bc 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
286
- *
287
- * 55 is the code of the key release event serviced in the previous
288
- * interrupt handling.
289
- *
290
- * TODO: find out whether the FIFO is advanced a single character
291
- * before reading every byte or the whole size of the FIFO at the
292
- * last LM832x_CMD_READ_FIFO. This affects LM832x_CMD_RPT_READ_FIFO
293
- * output in cases where there are more than one event in the FIFO.
294
- * Assume 0xbc and 0x3c events are in the FIFO:
295
- * RPT_READ_FIFO: 55 bc 3c 00 4e ff 0a 50 08 00 29 d9 08 01 c9
296
- * READ_FIFO: bc 3c 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9
297
- * Does RPT_READ_FIFO now return 0xbc and 0x3c or only 0x3c?
298
- */
299
- s->kbd.start ++;
300
- s->kbd.start &= sizeof(s->kbd.fifo) - 1;
301
- s->kbd.len --;
302
-
303
- return s->kbd.fifo[s->kbd.start];
304
- case LM832x_CMD_RPT_READ_FIFO:
305
- if (byte >= s->kbd.len)
306
- return 0x00;
307
-
308
- return s->kbd.fifo[(s->kbd.start + byte) & (sizeof(s->kbd.fifo) - 1)];
309
-
310
- case LM832x_CMD_READ_ERROR:
311
- return s->error;
312
-
313
- case LM832x_CMD_READ_ROTATOR:
314
- return 0;
315
-
316
- case LM832x_CMD_READ_KEY_SIZE:
317
- return s->kbd.size;
318
-
319
- case LM832x_CMD_READ_CFG:
320
- return s->config & 0xf;
321
-
322
- case LM832x_CMD_READ_CLOCK:
323
- return (s->clock & 0xfc) | 2;
324
-
325
- default:
326
- lm_kbd_error(s, ERR_CMDUNK);
327
- fprintf(stderr, "%s: unknown command %02x\n", __func__, reg);
328
- return 0x00;
329
- }
330
-
331
- return ret >> (byte << 3);
332
-}
333
-
334
-static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value)
335
-{
336
- switch (reg) {
337
- case LM832x_CMD_WRITE_CFG:
338
- s->config = value;
339
- /* This must be done whenever s->mux.in is updated (never). */
340
- if ((s->config >> 1) & 1)            /* MUX1EN */
341
- qemu_set_irq(s->mux.out[0], s->mux.in[0][(s->config >> 0) & 1]);
342
- if ((s->config >> 3) & 1)            /* MUX2EN */
343
- qemu_set_irq(s->mux.out[0], s->mux.in[0][(s->config >> 2) & 1]);
344
- /* TODO: check that this is issued only following the chip reset
345
- * and not in the middle of operation and that it is followed by
346
- * the GPIO ports re-resablishing through WRITE_PORT_SEL and
347
- * WRITE_PORT_STATE (using a timer perhaps) and otherwise output
348
- * warnings. */
349
- s->status = 0;
350
- lm_kbd_irq_update(s);
351
- s->kbd.len = 0;
352
- s->kbd.start = 0;
353
- s->reg = LM832x_GENERAL_ERROR;
354
- break;
355
-
356
- case LM832x_CMD_RESET:
357
- if (value == 0xaa)
358
- lm_kbd_reset(DEVICE(s));
359
- else
360
- lm_kbd_error(s, ERR_BADPAR);
361
- s->reg = LM832x_GENERAL_ERROR;
362
- break;
363
-
364
- case LM823x_CMD_WRITE_PULL_DOWN:
365
- if (!byte)
366
- s->gpio.pull = value;
367
- else {
368
- s->gpio.pull |= value << 8;
369
- lm_kbd_gpio_update(s);
370
- s->reg = LM832x_GENERAL_ERROR;
371
- }
372
- break;
373
- case LM832x_CMD_WRITE_PORT_SEL:
374
- if (!byte)
375
- s->gpio.dir = value;
376
- else {
377
- s->gpio.dir |= value << 8;
378
- lm_kbd_gpio_update(s);
379
- s->reg = LM832x_GENERAL_ERROR;
380
- }
381
- break;
382
- case LM832x_CMD_WRITE_PORT_STATE:
383
- if (!byte)
384
- s->gpio.mask = value;
385
- else {
386
- s->gpio.mask |= value << 8;
387
- lm_kbd_gpio_update(s);
388
- s->reg = LM832x_GENERAL_ERROR;
389
- }
390
- break;
391
-
392
- case LM832x_CMD_SET_ACTIVE:
393
- s->acttime = value;
394
- s->reg = LM832x_GENERAL_ERROR;
395
- break;
396
-
397
- case LM832x_CMD_SET_DEBOUNCE:
398
- s->kbd.dbnctime = value;
399
- s->reg = LM832x_GENERAL_ERROR;
400
- if (!value)
401
- lm_kbd_error(s, ERR_BADPAR);
402
- break;
403
-
404
- case LM832x_CMD_SET_KEY_SIZE:
405
- s->kbd.size = value;
406
- s->reg = LM832x_GENERAL_ERROR;
407
- if (
408
- (value & 0xf) < 3 || (value & 0xf) > LM832x_MAX_KPY ||
409
- (value >> 4) < 3 || (value >> 4) > LM832x_MAX_KPX)
410
- lm_kbd_error(s, ERR_BADPAR);
411
- break;
412
-
413
- case LM832x_CMD_WRITE_CLOCK:
414
- s->clock = value;
415
- s->reg = LM832x_GENERAL_ERROR;
416
- if ((value & 3) && (value & 3) != 3) {
417
- lm_kbd_error(s, ERR_BADPAR);
418
- fprintf(stderr, "%s: invalid clock setting in RCPWM\n",
419
- __func__);
420
- }
421
- /* TODO: Validate that the command is only issued once */
422
- break;
423
-
424
- case LM832x_CMD_PWM_WRITE:
425
- if (byte == 0) {
426
- if (!(value & 3) || (value >> 2) > 59) {
427
- lm_kbd_error(s, ERR_BADPAR);
428
- s->reg = LM832x_GENERAL_ERROR;
429
- break;
430
- }
431
-
432
- s->pwm.faddr = value;
433
- s->pwm.file[s->pwm.faddr] = 0;
434
- } else if (byte == 1) {
435
- s->pwm.file[s->pwm.faddr] |= value << 8;
436
- } else if (byte == 2) {
437
- s->pwm.file[s->pwm.faddr] |= value << 0;
438
- s->reg = LM832x_GENERAL_ERROR;
439
- }
440
- break;
441
- case LM832x_CMD_PWM_START:
442
- s->reg = LM832x_GENERAL_ERROR;
443
- if (!(value & 3) || (value >> 2) > 59) {
444
- lm_kbd_error(s, ERR_BADPAR);
445
- break;
446
- }
447
-
448
- s->pwm.addr[(value & 3) - 1] = value >> 2;
449
- lm_kbd_pwm_start(s, (value & 3) - 1);
450
- break;
451
- case LM832x_CMD_PWM_STOP:
452
- s->reg = LM832x_GENERAL_ERROR;
453
- if (!(value & 3)) {
454
- lm_kbd_error(s, ERR_BADPAR);
455
- break;
456
- }
457
-
458
- timer_del(s->pwm.tm[(value & 3) - 1]);
459
- break;
460
-
461
- case LM832x_GENERAL_ERROR:
462
- lm_kbd_error(s, ERR_BADPAR);
463
- break;
464
- default:
465
- lm_kbd_error(s, ERR_CMDUNK);
466
- fprintf(stderr, "%s: unknown command %02x\n", __func__, reg);
467
- break;
468
- }
469
-}
470
-
471
-static int lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
472
-{
473
- LM823KbdState *s = LM8323(i2c);
474
-
475
- switch (event) {
476
- case I2C_START_RECV:
477
- case I2C_START_SEND:
478
- s->i2c_cycle = 0;
479
- s->i2c_dir = (event == I2C_START_SEND);
480
- break;
481
-
482
- default:
483
- break;
484
- }
485
-
486
- return 0;
487
-}
488
-
489
-static uint8_t lm_i2c_rx(I2CSlave *i2c)
490
-{
491
- LM823KbdState *s = LM8323(i2c);
492
-
493
- return lm_kbd_read(s, s->reg, s->i2c_cycle ++);
494
-}
495
-
496
-static int lm_i2c_tx(I2CSlave *i2c, uint8_t data)
497
-{
498
- LM823KbdState *s = LM8323(i2c);
499
-
500
- if (!s->i2c_cycle)
501
- s->reg = data;
502
- else
503
- lm_kbd_write(s, s->reg, s->i2c_cycle - 1, data);
504
- s->i2c_cycle ++;
505
-
506
- return 0;
507
-}
508
-
509
-static int lm_kbd_post_load(void *opaque, int version_id)
510
-{
511
- LM823KbdState *s = opaque;
512
-
513
- lm_kbd_irq_update(s);
514
- lm_kbd_gpio_update(s);
515
-
516
- return 0;
517
-}
518
-
519
-static const VMStateDescription vmstate_lm_kbd = {
520
- .name = "LM8323",
521
- .version_id = 0,
522
- .minimum_version_id = 0,
523
- .post_load = lm_kbd_post_load,
524
- .fields = (const VMStateField[]) {
525
- VMSTATE_I2C_SLAVE(parent_obj, LM823KbdState),
526
- VMSTATE_UINT8(i2c_dir, LM823KbdState),
527
- VMSTATE_UINT8(i2c_cycle, LM823KbdState),
528
- VMSTATE_UINT8(reg, LM823KbdState),
529
- VMSTATE_UINT8(config, LM823KbdState),
530
- VMSTATE_UINT8(status, LM823KbdState),
531
- VMSTATE_UINT8(acttime, LM823KbdState),
532
- VMSTATE_UINT8(error, LM823KbdState),
533
- VMSTATE_UINT8(clock, LM823KbdState),
534
- VMSTATE_UINT16(gpio.pull, LM823KbdState),
535
- VMSTATE_UINT16(gpio.mask, LM823KbdState),
536
- VMSTATE_UINT16(gpio.dir, LM823KbdState),
537
- VMSTATE_UINT16(gpio.level, LM823KbdState),
538
- VMSTATE_UINT8(kbd.dbnctime, LM823KbdState),
539
- VMSTATE_UINT8(kbd.size, LM823KbdState),
540
- VMSTATE_UINT8(kbd.start, LM823KbdState),
541
- VMSTATE_UINT8(kbd.len, LM823KbdState),
542
- VMSTATE_BUFFER(kbd.fifo, LM823KbdState),
543
- VMSTATE_UINT16_ARRAY(pwm.file, LM823KbdState, 256),
544
- VMSTATE_UINT8(pwm.faddr, LM823KbdState),
545
- VMSTATE_BUFFER(pwm.addr, LM823KbdState),
546
- VMSTATE_TIMER_PTR_ARRAY(pwm.tm, LM823KbdState, 3),
547
- VMSTATE_END_OF_LIST()
548
- }
549
-};
550
-
551
-
552
-static void lm8323_realize(DeviceState *dev, Error **errp)
553
-{
554
- LM823KbdState *s = LM8323(dev);
555
-
556
- s->model = 0x8323;
557
- s->pwm.tm[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm0_tick, s);
558
- s->pwm.tm[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm1_tick, s);
559
- s->pwm.tm[2] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm2_tick, s);
560
- qdev_init_gpio_out(dev, &s->nirq, 1);
561
-}
562
-
563
-void lm832x_key_event(DeviceState *dev, int key, int state)
564
-{
565
- LM823KbdState *s = LM8323(dev);
566
-
567
- if ((s->status & INT_ERROR) && (s->error & ERR_FIFOOVR))
568
- return;
569
-
570
- if (s->kbd.len >= sizeof(s->kbd.fifo)) {
571
- lm_kbd_error(s, ERR_FIFOOVR);
572
- return;
573
- }
574
-
575
- s->kbd.fifo[(s->kbd.start + s->kbd.len ++) & (sizeof(s->kbd.fifo) - 1)] =
576
- key | (state << 7);
577
-
578
- /* We never set ERR_KEYOVR because we support multiple keys fine. */
579
- s->status |= INT_KEYPAD;
580
- lm_kbd_irq_update(s);
581
-}
582
-
583
-static void lm8323_class_init(ObjectClass *klass, void *data)
584
-{
585
- DeviceClass *dc = DEVICE_CLASS(klass);
586
- I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
587
-
588
- device_class_set_legacy_reset(dc, lm_kbd_reset);
589
- dc->realize = lm8323_realize;
590
- k->event = lm_i2c_event;
591
- k->recv = lm_i2c_rx;
592
- k->send = lm_i2c_tx;
593
- dc->vmsd = &vmstate_lm_kbd;
594
-}
595
-
596
-static const TypeInfo lm8323_info = {
597
- .name = TYPE_LM8323,
598
- .parent = TYPE_I2C_SLAVE,
599
- .instance_size = sizeof(LM823KbdState),
600
- .class_init = lm8323_class_init,
601
-};
602
-
603
-static void lm832x_register_types(void)
604
-{
605
- type_register_static(&lm8323_info);
606
-}
607
-
608
-type_init(lm832x_register_types)
609
diff --git a/hw/input/Kconfig b/hw/input/Kconfig
610
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
611
--- a/hw/input/Kconfig
26
--- a/tests/fp/fp-test-log2.c
612
+++ b/hw/input/Kconfig
27
+++ b/tests/fp/fp-test-log2.c
613
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ int main(int ac, char **av)
614
config ADB
29
int i;
615
bool
30
616
31
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
617
-config LM832X
32
+ set_float_default_nan_pattern(0b01000000, &qsf);
618
- bool
33
set_float_rounding_mode(float_round_nearest_even, &qsf);
619
- depends on I2C
34
620
-
35
test.d = 0.0;
621
config PCKBD
36
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
622
bool
623
select PS2
624
diff --git a/hw/input/meson.build b/hw/input/meson.build
625
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
626
--- a/hw/input/meson.build
38
--- a/tests/fp/fp-test.c
627
+++ b/hw/input/meson.build
39
+++ b/tests/fp/fp-test.c
628
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@ void run_test(void)
629
system_ss.add(files('hid.c'))
41
*/
630
system_ss.add(when: 'CONFIG_ADB', if_true: files('adb.c', 'adb-mouse.c', 'adb-kbd.c'))
42
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
631
-system_ss.add(when: 'CONFIG_LM832X', if_true: files('lm832x.c'))
43
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
632
system_ss.add(when: 'CONFIG_PCKBD', if_true: files('pckbd.c'))
44
+ set_float_default_nan_pattern(0b01000000, &qsf);
633
system_ss.add(when: 'CONFIG_PL050', if_true: files('pl050.c'))
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
634
system_ss.add(when: 'CONFIG_PS2', if_true: files('ps2.c'))
46
47
genCases_setLevel(test_level);
635
--
48
--
636
2.34.1
49
2.34.1
637
638
diff view generated by jsdifflib
1
Remove the tsc210x touchscreen controller device, which was
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
only used by the n800 and n810 and cheetah.
2
parts64_default_nan().
3
4
The uWireSlave struct is still used in omap1.c (at least for
5
compilation purposes -- nothing any longer calls omap_uwire_attach()
6
and so the struct's members will not be used at runtime), so
7
we move it into omap.h so we can delete tsc2xxx.h.
8
3
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20240903160751.4100218-30-peter.maydell@linaro.org
6
Message-id: 20241202131347.498124-37-peter.maydell@linaro.org
12
---
7
---
13
MAINTAINERS | 2 -
8
target/microblaze/cpu.c | 2 ++
14
include/hw/arm/omap.h | 7 +-
9
fpu/softfloat-specialize.c.inc | 3 +--
15
include/hw/input/tsc2xxx.h | 36 --
10
2 files changed, 3 insertions(+), 2 deletions(-)
16
hw/input/tsc210x.c | 1241 ------------------------------------
17
hw/input/Kconfig | 3 -
18
hw/input/meson.build | 1 -
19
6 files changed, 6 insertions(+), 1284 deletions(-)
20
delete mode 100644 include/hw/input/tsc2xxx.h
21
delete mode 100644 hw/input/tsc210x.c
22
11
23
diff --git a/MAINTAINERS b/MAINTAINERS
12
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
24
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
25
--- a/MAINTAINERS
14
--- a/target/microblaze/cpu.c
26
+++ b/MAINTAINERS
15
+++ b/target/microblaze/cpu.c
27
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
16
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_reset_hold(Object *obj, ResetType type)
28
L: qemu-arm@nongnu.org
17
* this architecture.
29
S: Odd Fixes
18
*/
30
F: hw/input/lm832x.c
19
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
31
-F: hw/input/tsc210x.c
20
+ /* Default NaN: sign bit set, most significant frac bit set */
32
F: hw/rtc/twl92230.c
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
33
F: include/hw/input/lm832x.h
22
34
-F: include/hw/input/tsc2xxx.h
23
#if defined(CONFIG_USER_ONLY)
35
24
/* start in user mode with interrupts enabled. */
36
Raspberry Pi
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
37
M: Peter Maydell <peter.maydell@linaro.org>
38
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
39
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
40
--- a/include/hw/arm/omap.h
27
--- a/fpu/softfloat-specialize.c.inc
41
+++ b/include/hw/arm/omap.h
28
+++ b/fpu/softfloat-specialize.c.inc
42
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
43
#define HW_ARM_OMAP_H
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
44
31
/* Sign bit clear, all frac bits set */
45
#include "exec/memory.h"
32
dnan_pattern = 0b01111111;
46
-#include "hw/input/tsc2xxx.h"
33
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
47
#include "target/arm/cpu-qom.h"
34
- || defined(TARGET_MICROBLAZE)
48
#include "qemu/log.h"
35
+#elif defined(TARGET_I386) || defined(TARGET_X86_64)
49
#include "qom/object.h"
36
/* Sign bit set, most significant frac bit set */
50
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
37
dnan_pattern = 0b11000000;
51
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
38
#elif defined(TARGET_HPPA)
52
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
53
54
+typedef struct uWireSlave {
55
+ uint16_t (*receive)(void *opaque);
56
+ void (*send)(void *opaque, uint16_t data);
57
+ void *opaque;
58
+} uWireSlave;
59
+
60
struct omap_uwire_s;
61
void omap_uwire_attach(struct omap_uwire_s *s,
62
uWireSlave *slave, int chipselect);
63
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
64
deleted file mode 100644
65
index XXXXXXX..XXXXXXX
66
--- a/include/hw/input/tsc2xxx.h
67
+++ /dev/null
68
@@ -XXX,XX +XXX,XX @@
69
-/*
70
- * TI touchscreen controller
71
- *
72
- * Copyright (c) 2006 Andrzej Zaborowski
73
- * Copyright (C) 2008 Nokia Corporation
74
- *
75
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
76
- * See the COPYING file in the top-level directory.
77
- */
78
-
79
-#ifndef HW_INPUT_TSC2XXX_H
80
-#define HW_INPUT_TSC2XXX_H
81
-
82
-typedef struct MouseTransformInfo {
83
- /* Touchscreen resolution */
84
- int x;
85
- int y;
86
- /* Calibration values as used/generated by tslib */
87
- int a[7];
88
-} MouseTransformInfo;
89
-
90
-typedef struct uWireSlave {
91
- uint16_t (*receive)(void *opaque);
92
- void (*send)(void *opaque, uint16_t data);
93
- void *opaque;
94
-} uWireSlave;
95
-
96
-/* tsc210x.c */
97
-uWireSlave *tsc2102_init(qemu_irq pint);
98
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
99
-I2SCodec *tsc210x_codec(uWireSlave *chip);
100
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
101
-void tsc210x_set_transform(uWireSlave *chip, const MouseTransformInfo *info);
102
-void tsc210x_key_event(uWireSlave *chip, int key, int down);
103
-
104
-#endif
105
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
106
deleted file mode 100644
107
index XXXXXXX..XXXXXXX
108
--- a/hw/input/tsc210x.c
109
+++ /dev/null
110
@@ -XXX,XX +XXX,XX @@
111
-/*
112
- * TI TSC2102 (touchscreen/sensors/audio controller) emulator.
113
- * TI TSC2301 (touchscreen/sensors/keypad).
114
- *
115
- * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
116
- * Copyright (C) 2008 Nokia Corporation
117
- *
118
- * This program is free software; you can redistribute it and/or
119
- * modify it under the terms of the GNU General Public License as
120
- * published by the Free Software Foundation; either version 2 or
121
- * (at your option) version 3 of the License.
122
- *
123
- * This program is distributed in the hope that it will be useful,
124
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
125
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
126
- * GNU General Public License for more details.
127
- *
128
- * You should have received a copy of the GNU General Public License along
129
- * with this program; if not, see <http://www.gnu.org/licenses/>.
130
- */
131
-
132
-#include "qemu/osdep.h"
133
-#include "hw/hw.h"
134
-#include "audio/audio.h"
135
-#include "qemu/timer.h"
136
-#include "qemu/log.h"
137
-#include "sysemu/reset.h"
138
-#include "ui/console.h"
139
-#include "hw/arm/omap.h" /* For I2SCodec */
140
-#include "hw/boards.h" /* for current_machine */
141
-#include "hw/input/tsc2xxx.h"
142
-#include "hw/irq.h"
143
-#include "migration/vmstate.h"
144
-#include "qapi/error.h"
145
-
146
-#define TSC_DATA_REGISTERS_PAGE        0x0
147
-#define TSC_CONTROL_REGISTERS_PAGE    0x1
148
-#define TSC_AUDIO_REGISTERS_PAGE    0x2
149
-
150
-#define TSC_VERBOSE
151
-
152
-#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - resolution[p]))
153
-
154
-typedef struct {
155
- qemu_irq pint;
156
- qemu_irq kbint;
157
- qemu_irq davint;
158
- QEMUTimer *timer;
159
- QEMUSoundCard card;
160
- uWireSlave chip;
161
- I2SCodec codec;
162
- uint8_t in_fifo[16384];
163
- uint8_t out_fifo[16384];
164
- uint16_t model;
165
-
166
- int32_t x, y;
167
- bool pressure;
168
-
169
- uint8_t page, offset;
170
- uint16_t dav;
171
-
172
- bool state;
173
- bool irq;
174
- bool command;
175
- bool busy;
176
- bool enabled;
177
- bool host_mode;
178
- uint8_t function, nextfunction;
179
- uint8_t precision, nextprecision;
180
- uint8_t filter;
181
- uint8_t pin_func;
182
- uint8_t ref;
183
- uint8_t timing;
184
- uint8_t noise;
185
-
186
- uint16_t audio_ctrl1;
187
- uint16_t audio_ctrl2;
188
- uint16_t audio_ctrl3;
189
- uint16_t pll[3];
190
- uint16_t volume;
191
- int64_t volume_change;
192
- bool softstep;
193
- uint16_t dac_power;
194
- int64_t powerdown;
195
- uint16_t filter_data[0x14];
196
-
197
- const char *name;
198
- SWVoiceIn *adc_voice[1];
199
- SWVoiceOut *dac_voice[1];
200
- int i2s_rx_rate;
201
- int i2s_tx_rate;
202
-
203
- int tr[8];
204
-
205
- struct {
206
- uint16_t down;
207
- uint16_t mask;
208
- int scan;
209
- int debounce;
210
- int mode;
211
- int intr;
212
- } kb;
213
- int64_t now; /* Time at migration */
214
-} TSC210xState;
215
-
216
-static const int resolution[4] = { 12, 8, 10, 12 };
217
-
218
-#define TSC_MODE_NO_SCAN    0x0
219
-#define TSC_MODE_XY_SCAN    0x1
220
-#define TSC_MODE_XYZ_SCAN    0x2
221
-#define TSC_MODE_X        0x3
222
-#define TSC_MODE_Y        0x4
223
-#define TSC_MODE_Z        0x5
224
-#define TSC_MODE_BAT1        0x6
225
-#define TSC_MODE_BAT2        0x7
226
-#define TSC_MODE_AUX        0x8
227
-#define TSC_MODE_AUX_SCAN    0x9
228
-#define TSC_MODE_TEMP1        0xa
229
-#define TSC_MODE_PORT_SCAN    0xb
230
-#define TSC_MODE_TEMP2        0xc
231
-#define TSC_MODE_XX_DRV        0xd
232
-#define TSC_MODE_YY_DRV        0xe
233
-#define TSC_MODE_YX_DRV        0xf
234
-
235
-static const uint16_t mode_regs[16] = {
236
- 0x0000,    /* No scan */
237
- 0x0600,    /* X, Y scan */
238
- 0x0780,    /* X, Y, Z scan */
239
- 0x0400,    /* X */
240
- 0x0200,    /* Y */
241
- 0x0180,    /* Z */
242
- 0x0040,    /* BAT1 */
243
- 0x0030,    /* BAT2 */
244
- 0x0010,    /* AUX */
245
- 0x0010,    /* AUX scan */
246
- 0x0004,    /* TEMP1 */
247
- 0x0070,    /* Port scan */
248
- 0x0002,    /* TEMP2 */
249
- 0x0000,    /* X+, X- drivers */
250
- 0x0000,    /* Y+, Y- drivers */
251
- 0x0000,    /* Y+, X- drivers */
252
-};
253
-
254
-#define X_TRANSFORM(s)            \
255
- ((s->y * s->tr[0] - s->x * s->tr[1]) / s->tr[2] + s->tr[3])
256
-#define Y_TRANSFORM(s)            \
257
- ((s->y * s->tr[4] - s->x * s->tr[5]) / s->tr[6] + s->tr[7])
258
-#define Z1_TRANSFORM(s)            \
259
- ((400 - ((s)->x >> 7) + ((s)->pressure << 10)) << 4)
260
-#define Z2_TRANSFORM(s)            \
261
- ((4000 + ((s)->y >> 7) - ((s)->pressure << 10)) << 4)
262
-
263
-#define BAT1_VAL            0x8660
264
-#define BAT2_VAL            0x0000
265
-#define AUX1_VAL            0x35c0
266
-#define AUX2_VAL            0xffff
267
-#define TEMP1_VAL            0x8c70
268
-#define TEMP2_VAL            0xa5b0
269
-
270
-#define TSC_POWEROFF_DELAY        50
271
-#define TSC_SOFTSTEP_DELAY        50
272
-
273
-static void tsc210x_reset(TSC210xState *s)
274
-{
275
- s->state = false;
276
- s->pin_func = 2;
277
- s->enabled = false;
278
- s->busy = false;
279
- s->nextfunction = 0;
280
- s->ref = 0;
281
- s->timing = 0;
282
- s->irq = false;
283
- s->dav = 0;
284
-
285
- s->audio_ctrl1 = 0x0000;
286
- s->audio_ctrl2 = 0x4410;
287
- s->audio_ctrl3 = 0x0000;
288
- s->pll[0] = 0x1004;
289
- s->pll[1] = 0x0000;
290
- s->pll[2] = 0x1fff;
291
- s->volume = 0xffff;
292
- s->dac_power = 0x8540;
293
- s->softstep = true;
294
- s->volume_change = 0;
295
- s->powerdown = 0;
296
- s->filter_data[0x00] = 0x6be3;
297
- s->filter_data[0x01] = 0x9666;
298
- s->filter_data[0x02] = 0x675d;
299
- s->filter_data[0x03] = 0x6be3;
300
- s->filter_data[0x04] = 0x9666;
301
- s->filter_data[0x05] = 0x675d;
302
- s->filter_data[0x06] = 0x7d83;
303
- s->filter_data[0x07] = 0x84ee;
304
- s->filter_data[0x08] = 0x7d83;
305
- s->filter_data[0x09] = 0x84ee;
306
- s->filter_data[0x0a] = 0x6be3;
307
- s->filter_data[0x0b] = 0x9666;
308
- s->filter_data[0x0c] = 0x675d;
309
- s->filter_data[0x0d] = 0x6be3;
310
- s->filter_data[0x0e] = 0x9666;
311
- s->filter_data[0x0f] = 0x675d;
312
- s->filter_data[0x10] = 0x7d83;
313
- s->filter_data[0x11] = 0x84ee;
314
- s->filter_data[0x12] = 0x7d83;
315
- s->filter_data[0x13] = 0x84ee;
316
-
317
- s->i2s_tx_rate = 0;
318
- s->i2s_rx_rate = 0;
319
-
320
- s->kb.scan = 1;
321
- s->kb.debounce = 0;
322
- s->kb.mask = 0x0000;
323
- s->kb.mode = 3;
324
- s->kb.intr = 0;
325
-
326
- qemu_set_irq(s->pint, !s->irq);
327
- qemu_set_irq(s->davint, !s->dav);
328
- qemu_irq_raise(s->kbint);
329
-}
330
-
331
-typedef struct {
332
- int rate;
333
- int dsor;
334
- int fsref;
335
-} TSC210xRateInfo;
336
-
337
-/* { rate, dsor, fsref }    */
338
-static const TSC210xRateInfo tsc2102_rates[] = {
339
- /* Fsref / 6.0 */
340
- { 7350,    63,    1 },
341
- { 8000,    63,    0 },
342
- /* Fsref / 6.0 */
343
- { 7350,    54,    1 },
344
- { 8000,    54,    0 },
345
- /* Fsref / 5.0 */
346
- { 8820,    45,    1 },
347
- { 9600,    45,    0 },
348
- /* Fsref / 4.0 */
349
- { 11025,    36,    1 },
350
- { 12000,    36,    0 },
351
- /* Fsref / 3.0 */
352
- { 14700,    27,    1 },
353
- { 16000,    27,    0 },
354
- /* Fsref / 2.0 */
355
- { 22050,    18,    1 },
356
- { 24000,    18,    0 },
357
- /* Fsref / 1.5 */
358
- { 29400,    9,    1 },
359
- { 32000,    9,    0 },
360
- /* Fsref */
361
- { 44100,    0,    1 },
362
- { 48000,    0,    0 },
363
-
364
- { 0,    0,     0 },
365
-};
366
-
367
-static inline void tsc210x_out_flush(TSC210xState *s, int len)
368
-{
369
- uint8_t *data = s->codec.out.fifo + s->codec.out.start;
370
- uint8_t *end = data + len;
371
-
372
- while (data < end)
373
- data += AUD_write(s->dac_voice[0], data, end - data) ?: (end - data);
374
-
375
- s->codec.out.len -= len;
376
- if (s->codec.out.len)
377
- memmove(s->codec.out.fifo, end, s->codec.out.len);
378
- s->codec.out.start = 0;
379
-}
380
-
381
-static void tsc210x_audio_out_cb(TSC210xState *s, int free_b)
382
-{
383
- if (s->codec.out.len >= free_b) {
384
- tsc210x_out_flush(s, free_b);
385
- return;
386
- }
387
-
388
- s->codec.out.size = MIN(free_b, 16384);
389
- qemu_irq_raise(s->codec.tx_start);
390
-}
391
-
392
-static void tsc2102_audio_rate_update(TSC210xState *s)
393
-{
394
- const TSC210xRateInfo *rate;
395
-
396
- s->codec.tx_rate = 0;
397
- s->codec.rx_rate = 0;
398
- if (s->dac_power & (1 << 15))                /* PWDNC */
399
- return;
400
-
401
- for (rate = tsc2102_rates; rate->rate; rate ++)
402
- if (rate->dsor == (s->audio_ctrl1 & 0x3f) &&        /* DACFS */
403
- rate->fsref == ((s->audio_ctrl3 >> 13) & 1))/* REFFS */
404
- break;
405
- if (!rate->rate) {
406
- printf("%s: unknown sampling rate configured\n", __func__);
407
- return;
408
- }
409
-
410
- s->codec.tx_rate = rate->rate;
411
-}
412
-
413
-static void tsc2102_audio_output_update(TSC210xState *s)
414
-{
415
- int enable;
416
- struct audsettings fmt;
417
-
418
- if (s->dac_voice[0]) {
419
- tsc210x_out_flush(s, s->codec.out.len);
420
- s->codec.out.size = 0;
421
- AUD_set_active_out(s->dac_voice[0], 0);
422
- AUD_close_out(&s->card, s->dac_voice[0]);
423
- s->dac_voice[0] = NULL;
424
- }
425
- s->codec.cts = 0;
426
-
427
- enable =
428
- (~s->dac_power & (1 << 15)) &&            /* PWDNC */
429
- (~s->dac_power & (1 << 10));            /* DAPWDN */
430
- if (!enable || !s->codec.tx_rate)
431
- return;
432
-
433
- /* Force our own sampling rate even in slave DAC mode */
434
- fmt.endianness = 0;
435
- fmt.nchannels = 2;
436
- fmt.freq = s->codec.tx_rate;
437
- fmt.fmt = AUDIO_FORMAT_S16;
438
-
439
- s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0],
440
- "tsc2102.sink", s, (void *) tsc210x_audio_out_cb, &fmt);
441
- if (s->dac_voice[0]) {
442
- s->codec.cts = 1;
443
- AUD_set_active_out(s->dac_voice[0], 1);
444
- }
445
-}
446
-
447
-static uint16_t tsc2102_data_register_read(TSC210xState *s, int reg)
448
-{
449
- switch (reg) {
450
- case 0x00:    /* X */
451
- s->dav &= 0xfbff;
452
- return TSC_CUT_RESOLUTION(X_TRANSFORM(s), s->precision) +
453
- (s->noise & 3);
454
-
455
- case 0x01:    /* Y */
456
- s->noise ++;
457
- s->dav &= 0xfdff;
458
- return TSC_CUT_RESOLUTION(Y_TRANSFORM(s), s->precision) ^
459
- (s->noise & 3);
460
-
461
- case 0x02:    /* Z1 */
462
- s->dav &= 0xfeff;
463
- return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
464
- (s->noise & 3);
465
-
466
- case 0x03:    /* Z2 */
467
- s->dav &= 0xff7f;
468
- return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
469
- (s->noise & 3);
470
-
471
- case 0x04:    /* KPData */
472
- if ((s->model & 0xff00) == 0x2300) {
473
- if (s->kb.intr && (s->kb.mode & 2)) {
474
- s->kb.intr = 0;
475
- qemu_irq_raise(s->kbint);
476
- }
477
- return s->kb.down;
478
- }
479
-
480
- return 0xffff;
481
-
482
- case 0x05:    /* BAT1 */
483
- s->dav &= 0xffbf;
484
- return TSC_CUT_RESOLUTION(BAT1_VAL, s->precision) +
485
- (s->noise & 6);
486
-
487
- case 0x06:    /* BAT2 */
488
- s->dav &= 0xffdf;
489
- return TSC_CUT_RESOLUTION(BAT2_VAL, s->precision);
490
-
491
- case 0x07:    /* AUX1 */
492
- s->dav &= 0xffef;
493
- return TSC_CUT_RESOLUTION(AUX1_VAL, s->precision);
494
-
495
- case 0x08:    /* AUX2 */
496
- s->dav &= 0xfff7;
497
- return 0xffff;
498
-
499
- case 0x09:    /* TEMP1 */
500
- s->dav &= 0xfffb;
501
- return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision) -
502
- (s->noise & 5);
503
-
504
- case 0x0a:    /* TEMP2 */
505
- s->dav &= 0xfffd;
506
- return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision) ^
507
- (s->noise & 3);
508
-
509
- case 0x0b:    /* DAC */
510
- s->dav &= 0xfffe;
511
- return 0xffff;
512
-
513
- default:
514
-#ifdef TSC_VERBOSE
515
- fprintf(stderr, "tsc2102_data_register_read: "
516
- "no such register: 0x%02x\n", reg);
517
-#endif
518
- return 0xffff;
519
- }
520
-}
521
-
522
-static uint16_t tsc2102_control_register_read(
523
- TSC210xState *s, int reg)
524
-{
525
- switch (reg) {
526
- case 0x00:    /* TSC ADC */
527
- return (s->pressure << 15) | ((!s->busy) << 14) |
528
- (s->nextfunction << 10) | (s->nextprecision << 8) | s->filter;
529
-
530
- case 0x01:    /* Status / Keypad Control */
531
- if ((s->model & 0xff00) == 0x2100)
532
- return (s->pin_func << 14) | ((!s->enabled) << 13) |
533
- (s->host_mode << 12) | ((!!s->dav) << 11) | s->dav;
534
- else
535
- return (s->kb.intr << 15) | ((s->kb.scan || !s->kb.down) << 14) |
536
- (s->kb.debounce << 11);
537
-
538
- case 0x02:    /* DAC Control */
539
- if ((s->model & 0xff00) == 0x2300)
540
- return s->dac_power & 0x8000;
541
- else
542
- goto bad_reg;
543
-
544
- case 0x03:    /* Reference */
545
- return s->ref;
546
-
547
- case 0x04:    /* Reset */
548
- return 0xffff;
549
-
550
- case 0x05:    /* Configuration */
551
- return s->timing;
552
-
553
- case 0x06:    /* Secondary configuration */
554
- if ((s->model & 0xff00) == 0x2100)
555
- goto bad_reg;
556
- return ((!s->dav) << 15) | ((s->kb.mode & 1) << 14) | s->pll[2];
557
-
558
- case 0x10:    /* Keypad Mask */
559
- if ((s->model & 0xff00) == 0x2100)
560
- goto bad_reg;
561
- return s->kb.mask;
562
-
563
- default:
564
- bad_reg:
565
-#ifdef TSC_VERBOSE
566
- fprintf(stderr, "tsc2102_control_register_read: "
567
- "no such register: 0x%02x\n", reg);
568
-#endif
569
- return 0xffff;
570
- }
571
-}
572
-
573
-static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg)
574
-{
575
- int l_ch, r_ch;
576
- uint16_t val;
577
-
578
- switch (reg) {
579
- case 0x00:    /* Audio Control 1 */
580
- return s->audio_ctrl1;
581
-
582
- case 0x01:
583
- return 0xff00;
584
-
585
- case 0x02:    /* DAC Volume Control */
586
- return s->volume;
587
-
588
- case 0x03:
589
- return 0x8b00;
590
-
591
- case 0x04:    /* Audio Control 2 */
592
- l_ch = 1;
593
- r_ch = 1;
594
- if (s->softstep && !(s->dac_power & (1 << 10))) {
595
- l_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
596
- s->volume_change + TSC_SOFTSTEP_DELAY);
597
- r_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
598
- s->volume_change + TSC_SOFTSTEP_DELAY);
599
- }
600
-
601
- return s->audio_ctrl2 | (l_ch << 3) | (r_ch << 2);
602
-
603
- case 0x05:    /* Stereo DAC Power Control */
604
- return 0x2aa0 | s->dac_power |
605
- (((s->dac_power & (1 << 10)) &&
606
- (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
607
- s->powerdown + TSC_POWEROFF_DELAY)) << 6);
608
-
609
- case 0x06:    /* Audio Control 3 */
610
- val = s->audio_ctrl3 | 0x0001;
611
- s->audio_ctrl3 &= 0xff3f;
612
- return val;
613
-
614
- case 0x07:    /* LCH_BASS_BOOST_N0 */
615
- case 0x08:    /* LCH_BASS_BOOST_N1 */
616
- case 0x09:    /* LCH_BASS_BOOST_N2 */
617
- case 0x0a:    /* LCH_BASS_BOOST_N3 */
618
- case 0x0b:    /* LCH_BASS_BOOST_N4 */
619
- case 0x0c:    /* LCH_BASS_BOOST_N5 */
620
- case 0x0d:    /* LCH_BASS_BOOST_D1 */
621
- case 0x0e:    /* LCH_BASS_BOOST_D2 */
622
- case 0x0f:    /* LCH_BASS_BOOST_D4 */
623
- case 0x10:    /* LCH_BASS_BOOST_D5 */
624
- case 0x11:    /* RCH_BASS_BOOST_N0 */
625
- case 0x12:    /* RCH_BASS_BOOST_N1 */
626
- case 0x13:    /* RCH_BASS_BOOST_N2 */
627
- case 0x14:    /* RCH_BASS_BOOST_N3 */
628
- case 0x15:    /* RCH_BASS_BOOST_N4 */
629
- case 0x16:    /* RCH_BASS_BOOST_N5 */
630
- case 0x17:    /* RCH_BASS_BOOST_D1 */
631
- case 0x18:    /* RCH_BASS_BOOST_D2 */
632
- case 0x19:    /* RCH_BASS_BOOST_D4 */
633
- case 0x1a:    /* RCH_BASS_BOOST_D5 */
634
- return s->filter_data[reg - 0x07];
635
-
636
- case 0x1b:    /* PLL Programmability 1 */
637
- return s->pll[0];
638
-
639
- case 0x1c:    /* PLL Programmability 2 */
640
- return s->pll[1];
641
-
642
- case 0x1d:    /* Audio Control 4 */
643
- return (!s->softstep) << 14;
644
-
645
- default:
646
-#ifdef TSC_VERBOSE
647
- fprintf(stderr, "tsc2102_audio_register_read: "
648
- "no such register: 0x%02x\n", reg);
649
-#endif
650
- return 0xffff;
651
- }
652
-}
653
-
654
-static void tsc2102_data_register_write(
655
- TSC210xState *s, int reg, uint16_t value)
656
-{
657
- switch (reg) {
658
- case 0x00:    /* X */
659
- case 0x01:    /* Y */
660
- case 0x02:    /* Z1 */
661
- case 0x03:    /* Z2 */
662
- case 0x05:    /* BAT1 */
663
- case 0x06:    /* BAT2 */
664
- case 0x07:    /* AUX1 */
665
- case 0x08:    /* AUX2 */
666
- case 0x09:    /* TEMP1 */
667
- case 0x0a:    /* TEMP2 */
668
- return;
669
-
670
- default:
671
- qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_data_register_write: "
672
- "no such register: 0x%02x\n", reg);
673
- }
674
-}
675
-
676
-static void tsc2102_control_register_write(
677
- TSC210xState *s, int reg, uint16_t value)
678
-{
679
- switch (reg) {
680
- case 0x00:    /* TSC ADC */
681
- s->host_mode = value >> 15;
682
- s->enabled = !(value & 0x4000);
683
- if (s->busy && !s->enabled)
684
- timer_del(s->timer);
685
- s->busy = s->busy && s->enabled;
686
- s->nextfunction = (value >> 10) & 0xf;
687
- s->nextprecision = (value >> 8) & 3;
688
- s->filter = value & 0xff;
689
- return;
690
-
691
- case 0x01:    /* Status / Keypad Control */
692
- if ((s->model & 0xff00) == 0x2100)
693
- s->pin_func = value >> 14;
694
- else {
695
- s->kb.scan = (value >> 14) & 1;
696
- s->kb.debounce = (value >> 11) & 7;
697
- if (s->kb.intr && s->kb.scan) {
698
- s->kb.intr = 0;
699
- qemu_irq_raise(s->kbint);
700
- }
701
- }
702
- return;
703
-
704
- case 0x02:    /* DAC Control */
705
- if ((s->model & 0xff00) == 0x2300) {
706
- s->dac_power &= 0x7fff;
707
- s->dac_power |= 0x8000 & value;
708
- } else
709
- goto bad_reg;
710
- break;
711
-
712
- case 0x03:    /* Reference */
713
- s->ref = value & 0x1f;
714
- return;
715
-
716
- case 0x04:    /* Reset */
717
- if (value == 0xbb00) {
718
- if (s->busy)
719
- timer_del(s->timer);
720
- tsc210x_reset(s);
721
-#ifdef TSC_VERBOSE
722
- } else {
723
- fprintf(stderr, "tsc2102_control_register_write: "
724
- "wrong value written into RESET\n");
725
-#endif
726
- }
727
- return;
728
-
729
- case 0x05:    /* Configuration */
730
- s->timing = value & 0x3f;
731
-#ifdef TSC_VERBOSE
732
- if (value & ~0x3f)
733
- fprintf(stderr, "tsc2102_control_register_write: "
734
- "wrong value written into CONFIG\n");
735
-#endif
736
- return;
737
-
738
- case 0x06:    /* Secondary configuration */
739
- if ((s->model & 0xff00) == 0x2100)
740
- goto bad_reg;
741
- s->kb.mode = value >> 14;
742
- s->pll[2] = value & 0x3ffff;
743
- return;
744
-
745
- case 0x10:    /* Keypad Mask */
746
- if ((s->model & 0xff00) == 0x2100)
747
- goto bad_reg;
748
- s->kb.mask = value;
749
- return;
750
-
751
- default:
752
- bad_reg:
753
- qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_control_register_write: "
754
- "no such register: 0x%02x\n", reg);
755
- }
756
-}
757
-
758
-static void tsc2102_audio_register_write(
759
- TSC210xState *s, int reg, uint16_t value)
760
-{
761
- switch (reg) {
762
- case 0x00:    /* Audio Control 1 */
763
- s->audio_ctrl1 = value & 0x0f3f;
764
-#ifdef TSC_VERBOSE
765
- if ((value & ~0x0f3f) || ((value & 7) != ((value >> 3) & 7)))
766
- fprintf(stderr, "tsc2102_audio_register_write: "
767
- "wrong value written into Audio 1\n");
768
-#endif
769
- tsc2102_audio_rate_update(s);
770
- tsc2102_audio_output_update(s);
771
- return;
772
-
773
- case 0x01:
774
-#ifdef TSC_VERBOSE
775
- if (value != 0xff00)
776
- fprintf(stderr, "tsc2102_audio_register_write: "
777
- "wrong value written into reg 0x01\n");
778
-#endif
779
- return;
780
-
781
- case 0x02:    /* DAC Volume Control */
782
- s->volume = value;
783
- s->volume_change = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
784
- return;
785
-
786
- case 0x03:
787
-#ifdef TSC_VERBOSE
788
- if (value != 0x8b00)
789
- fprintf(stderr, "tsc2102_audio_register_write: "
790
- "wrong value written into reg 0x03\n");
791
-#endif
792
- return;
793
-
794
- case 0x04:    /* Audio Control 2 */
795
- s->audio_ctrl2 = value & 0xf7f2;
796
-#ifdef TSC_VERBOSE
797
- if (value & ~0xf7fd)
798
- fprintf(stderr, "tsc2102_audio_register_write: "
799
- "wrong value written into Audio 2\n");
800
-#endif
801
- return;
802
-
803
- case 0x05:    /* Stereo DAC Power Control */
804
- if ((value & ~s->dac_power) & (1 << 10))
805
- s->powerdown = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
806
-
807
- s->dac_power = value & 0x9543;
808
-#ifdef TSC_VERBOSE
809
- if ((value & ~0x9543) != 0x2aa0)
810
- fprintf(stderr, "tsc2102_audio_register_write: "
811
- "wrong value written into Power\n");
812
-#endif
813
- tsc2102_audio_rate_update(s);
814
- tsc2102_audio_output_update(s);
815
- return;
816
-
817
- case 0x06:    /* Audio Control 3 */
818
- s->audio_ctrl3 &= 0x00c0;
819
- s->audio_ctrl3 |= value & 0xf800;
820
-#ifdef TSC_VERBOSE
821
- if (value & ~0xf8c7)
822
- fprintf(stderr, "tsc2102_audio_register_write: "
823
- "wrong value written into Audio 3\n");
824
-#endif
825
- tsc2102_audio_output_update(s);
826
- return;
827
-
828
- case 0x07:    /* LCH_BASS_BOOST_N0 */
829
- case 0x08:    /* LCH_BASS_BOOST_N1 */
830
- case 0x09:    /* LCH_BASS_BOOST_N2 */
831
- case 0x0a:    /* LCH_BASS_BOOST_N3 */
832
- case 0x0b:    /* LCH_BASS_BOOST_N4 */
833
- case 0x0c:    /* LCH_BASS_BOOST_N5 */
834
- case 0x0d:    /* LCH_BASS_BOOST_D1 */
835
- case 0x0e:    /* LCH_BASS_BOOST_D2 */
836
- case 0x0f:    /* LCH_BASS_BOOST_D4 */
837
- case 0x10:    /* LCH_BASS_BOOST_D5 */
838
- case 0x11:    /* RCH_BASS_BOOST_N0 */
839
- case 0x12:    /* RCH_BASS_BOOST_N1 */
840
- case 0x13:    /* RCH_BASS_BOOST_N2 */
841
- case 0x14:    /* RCH_BASS_BOOST_N3 */
842
- case 0x15:    /* RCH_BASS_BOOST_N4 */
843
- case 0x16:    /* RCH_BASS_BOOST_N5 */
844
- case 0x17:    /* RCH_BASS_BOOST_D1 */
845
- case 0x18:    /* RCH_BASS_BOOST_D2 */
846
- case 0x19:    /* RCH_BASS_BOOST_D4 */
847
- case 0x1a:    /* RCH_BASS_BOOST_D5 */
848
- s->filter_data[reg - 0x07] = value;
849
- return;
850
-
851
- case 0x1b:    /* PLL Programmability 1 */
852
- s->pll[0] = value & 0xfffc;
853
-#ifdef TSC_VERBOSE
854
- if (value & ~0xfffc)
855
- fprintf(stderr, "tsc2102_audio_register_write: "
856
- "wrong value written into PLL 1\n");
857
-#endif
858
- return;
859
-
860
- case 0x1c:    /* PLL Programmability 2 */
861
- s->pll[1] = value & 0xfffc;
862
-#ifdef TSC_VERBOSE
863
- if (value & ~0xfffc)
864
- fprintf(stderr, "tsc2102_audio_register_write: "
865
- "wrong value written into PLL 2\n");
866
-#endif
867
- return;
868
-
869
- case 0x1d:    /* Audio Control 4 */
870
- s->softstep = !(value & 0x4000);
871
-#ifdef TSC_VERBOSE
872
- if (value & ~0x4000)
873
- fprintf(stderr, "tsc2102_audio_register_write: "
874
- "wrong value written into Audio 4\n");
875
-#endif
876
- return;
877
-
878
- default:
879
- qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_audio_register_write: "
880
- "no such register: 0x%02x\n", reg);
881
- }
882
-}
883
-
884
-/* This handles most of the chip logic. */
885
-static void tsc210x_pin_update(TSC210xState *s)
886
-{
887
- int64_t expires;
888
- bool pin_state;
889
-
890
- switch (s->pin_func) {
891
- case 0:
892
- pin_state = s->pressure;
893
- break;
894
- case 1:
895
- pin_state = !!s->dav;
896
- break;
897
- case 2:
898
- default:
899
- pin_state = s->pressure && !s->dav;
900
- }
901
-
902
- if (!s->enabled)
903
- pin_state = false;
904
-
905
- if (pin_state != s->irq) {
906
- s->irq = pin_state;
907
- qemu_set_irq(s->pint, !s->irq);
908
- }
909
-
910
- switch (s->nextfunction) {
911
- case TSC_MODE_XY_SCAN:
912
- case TSC_MODE_XYZ_SCAN:
913
- if (!s->pressure)
914
- return;
915
- break;
916
-
917
- case TSC_MODE_X:
918
- case TSC_MODE_Y:
919
- case TSC_MODE_Z:
920
- if (!s->pressure)
921
- return;
922
- /* Fall through */
923
- case TSC_MODE_BAT1:
924
- case TSC_MODE_BAT2:
925
- case TSC_MODE_AUX:
926
- case TSC_MODE_TEMP1:
927
- case TSC_MODE_TEMP2:
928
- if (s->dav)
929
- s->enabled = false;
930
- break;
931
-
932
- case TSC_MODE_AUX_SCAN:
933
- case TSC_MODE_PORT_SCAN:
934
- break;
935
-
936
- case TSC_MODE_NO_SCAN:
937
- case TSC_MODE_XX_DRV:
938
- case TSC_MODE_YY_DRV:
939
- case TSC_MODE_YX_DRV:
940
- default:
941
- return;
942
- }
943
-
944
- if (!s->enabled || s->busy || s->dav)
945
- return;
946
-
947
- s->busy = true;
948
- s->precision = s->nextprecision;
949
- s->function = s->nextfunction;
950
- expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
951
- (NANOSECONDS_PER_SECOND >> 10);
952
- timer_mod(s->timer, expires);
953
-}
954
-
955
-static uint16_t tsc210x_read(TSC210xState *s)
956
-{
957
- uint16_t ret = 0x0000;
958
-
959
- if (!s->command)
960
- fprintf(stderr, "tsc210x_read: SPI underrun!\n");
961
-
962
- switch (s->page) {
963
- case TSC_DATA_REGISTERS_PAGE:
964
- ret = tsc2102_data_register_read(s, s->offset);
965
- if (!s->dav)
966
- qemu_irq_raise(s->davint);
967
- break;
968
- case TSC_CONTROL_REGISTERS_PAGE:
969
- ret = tsc2102_control_register_read(s, s->offset);
970
- break;
971
- case TSC_AUDIO_REGISTERS_PAGE:
972
- ret = tsc2102_audio_register_read(s, s->offset);
973
- break;
974
- default:
975
- hw_error("tsc210x_read: wrong memory page\n");
976
- }
977
-
978
- tsc210x_pin_update(s);
979
-
980
- /* Allow sequential reads. */
981
- s->offset ++;
982
- s->state = false;
983
- return ret;
984
-}
985
-
986
-static void tsc210x_write(TSC210xState *s, uint16_t value)
987
-{
988
- /*
989
- * This is a two-state state machine for reading
990
- * command and data every second time.
991
- */
992
- if (!s->state) {
993
- s->command = (value >> 15) != 0;
994
- s->page = (value >> 11) & 0x0f;
995
- s->offset = (value >> 5) & 0x3f;
996
- s->state = true;
997
- } else {
998
- if (s->command)
999
- fprintf(stderr, "tsc210x_write: SPI overrun!\n");
1000
- else
1001
- switch (s->page) {
1002
- case TSC_DATA_REGISTERS_PAGE:
1003
- tsc2102_data_register_write(s, s->offset, value);
1004
- break;
1005
- case TSC_CONTROL_REGISTERS_PAGE:
1006
- tsc2102_control_register_write(s, s->offset, value);
1007
- break;
1008
- case TSC_AUDIO_REGISTERS_PAGE:
1009
- tsc2102_audio_register_write(s, s->offset, value);
1010
- break;
1011
- default:
1012
- hw_error("tsc210x_write: wrong memory page\n");
1013
- }
1014
-
1015
- tsc210x_pin_update(s);
1016
- s->state = false;
1017
- }
1018
-}
1019
-
1020
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
1021
-{
1022
- TSC210xState *s = opaque;
1023
- uint32_t ret = 0;
1024
-
1025
- if (len != 16) {
1026
- qemu_log_mask(LOG_GUEST_ERROR,
1027
- "%s: bad SPI word width %i\n", __func__, len);
1028
- return 0;
1029
- }
1030
-
1031
- /* TODO: sequential reads etc - how do we make sure the host doesn't
1032
- * unintentionally read out a conversion result from a register while
1033
- * transmitting the command word of the next command? */
1034
- if (!value || (s->state && s->command))
1035
- ret = tsc210x_read(s);
1036
- if (value || (s->state && !s->command))
1037
- tsc210x_write(s, value);
1038
-
1039
- return ret;
1040
-}
1041
-
1042
-static void tsc210x_timer_tick(void *opaque)
1043
-{
1044
- TSC210xState *s = opaque;
1045
-
1046
- /* Timer ticked -- a set of conversions has been finished. */
1047
-
1048
- if (!s->busy)
1049
- return;
1050
-
1051
- s->busy = false;
1052
- s->dav |= mode_regs[s->function];
1053
- tsc210x_pin_update(s);
1054
- qemu_irq_lower(s->davint);
1055
-}
1056
-
1057
-static void tsc210x_touchscreen_event(void *opaque,
1058
- int x, int y, int z, int buttons_state)
1059
-{
1060
- TSC210xState *s = opaque;
1061
- int p = s->pressure;
1062
-
1063
- if (buttons_state) {
1064
- s->x = x;
1065
- s->y = y;
1066
- }
1067
- s->pressure = !!buttons_state;
1068
-
1069
- /*
1070
- * Note: We would get better responsiveness in the guest by
1071
- * signaling TS events immediately, but for now we simulate
1072
- * the first conversion delay for sake of correctness.
1073
- */
1074
- if (p != s->pressure)
1075
- tsc210x_pin_update(s);
1076
-}
1077
-
1078
-static void tsc210x_i2s_swallow(TSC210xState *s)
1079
-{
1080
- if (s->dac_voice[0])
1081
- tsc210x_out_flush(s, s->codec.out.len);
1082
- else
1083
- s->codec.out.len = 0;
1084
-}
1085
-
1086
-static void tsc210x_i2s_set_rate(TSC210xState *s, int in, int out)
1087
-{
1088
- s->i2s_tx_rate = out;
1089
- s->i2s_rx_rate = in;
1090
-}
1091
-
1092
-static int tsc210x_pre_save(void *opaque)
1093
-{
1094
- TSC210xState *s = (TSC210xState *) opaque;
1095
- s->now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
1096
-
1097
- return 0;
1098
-}
1099
-
1100
-static int tsc210x_post_load(void *opaque, int version_id)
1101
-{
1102
- TSC210xState *s = (TSC210xState *) opaque;
1103
- int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
1104
-
1105
- if (s->function >= ARRAY_SIZE(mode_regs)) {
1106
- return -EINVAL;
1107
- }
1108
- if (s->nextfunction >= ARRAY_SIZE(mode_regs)) {
1109
- return -EINVAL;
1110
- }
1111
- if (s->precision >= ARRAY_SIZE(resolution)) {
1112
- return -EINVAL;
1113
- }
1114
- if (s->nextprecision >= ARRAY_SIZE(resolution)) {
1115
- return -EINVAL;
1116
- }
1117
-
1118
- s->volume_change -= s->now;
1119
- s->volume_change += now;
1120
- s->powerdown -= s->now;
1121
- s->powerdown += now;
1122
-
1123
- s->busy = timer_pending(s->timer);
1124
- qemu_set_irq(s->pint, !s->irq);
1125
- qemu_set_irq(s->davint, !s->dav);
1126
-
1127
- return 0;
1128
-}
1129
-
1130
-static const VMStateField vmstatefields_tsc210x[] = {
1131
- VMSTATE_BOOL(enabled, TSC210xState),
1132
- VMSTATE_BOOL(host_mode, TSC210xState),
1133
- VMSTATE_BOOL(irq, TSC210xState),
1134
- VMSTATE_BOOL(command, TSC210xState),
1135
- VMSTATE_BOOL(pressure, TSC210xState),
1136
- VMSTATE_BOOL(softstep, TSC210xState),
1137
- VMSTATE_BOOL(state, TSC210xState),
1138
- VMSTATE_UINT16(dav, TSC210xState),
1139
- VMSTATE_INT32(x, TSC210xState),
1140
- VMSTATE_INT32(y, TSC210xState),
1141
- VMSTATE_UINT8(offset, TSC210xState),
1142
- VMSTATE_UINT8(page, TSC210xState),
1143
- VMSTATE_UINT8(filter, TSC210xState),
1144
- VMSTATE_UINT8(pin_func, TSC210xState),
1145
- VMSTATE_UINT8(ref, TSC210xState),
1146
- VMSTATE_UINT8(timing, TSC210xState),
1147
- VMSTATE_UINT8(noise, TSC210xState),
1148
- VMSTATE_UINT8(function, TSC210xState),
1149
- VMSTATE_UINT8(nextfunction, TSC210xState),
1150
- VMSTATE_UINT8(precision, TSC210xState),
1151
- VMSTATE_UINT8(nextprecision, TSC210xState),
1152
- VMSTATE_UINT16(audio_ctrl1, TSC210xState),
1153
- VMSTATE_UINT16(audio_ctrl2, TSC210xState),
1154
- VMSTATE_UINT16(audio_ctrl3, TSC210xState),
1155
- VMSTATE_UINT16_ARRAY(pll, TSC210xState, 3),
1156
- VMSTATE_UINT16(volume, TSC210xState),
1157
- VMSTATE_UINT16(dac_power, TSC210xState),
1158
- VMSTATE_INT64(volume_change, TSC210xState),
1159
- VMSTATE_INT64(powerdown, TSC210xState),
1160
- VMSTATE_INT64(now, TSC210xState),
1161
- VMSTATE_UINT16_ARRAY(filter_data, TSC210xState, 0x14),
1162
- VMSTATE_TIMER_PTR(timer, TSC210xState),
1163
- VMSTATE_END_OF_LIST()
1164
-};
1165
-
1166
-static const VMStateDescription vmstate_tsc2102 = {
1167
- .name = "tsc2102",
1168
- .version_id = 1,
1169
- .minimum_version_id = 1,
1170
- .pre_save = tsc210x_pre_save,
1171
- .post_load = tsc210x_post_load,
1172
- .fields = vmstatefields_tsc210x,
1173
-};
1174
-
1175
-static const VMStateDescription vmstate_tsc2301 = {
1176
- .name = "tsc2301",
1177
- .version_id = 1,
1178
- .minimum_version_id = 1,
1179
- .pre_save = tsc210x_pre_save,
1180
- .post_load = tsc210x_post_load,
1181
- .fields = vmstatefields_tsc210x,
1182
-};
1183
-
1184
-static void tsc210x_init(TSC210xState *s,
1185
- const char *name,
1186
- const VMStateDescription *vmsd)
1187
-{
1188
- s->tr[0] = 0;
1189
- s->tr[1] = 1;
1190
- s->tr[2] = 1;
1191
- s->tr[3] = 0;
1192
- s->tr[4] = 1;
1193
- s->tr[5] = 0;
1194
- s->tr[6] = 1;
1195
- s->tr[7] = 0;
1196
-
1197
- s->chip.opaque = s;
1198
- s->chip.send = (void *) tsc210x_write;
1199
- s->chip.receive = (void *) tsc210x_read;
1200
-
1201
- s->codec.opaque = s;
1202
- s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
1203
- s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
1204
- s->codec.in.fifo = s->in_fifo;
1205
- s->codec.out.fifo = s->out_fifo;
1206
-
1207
- tsc210x_reset(s);
1208
-
1209
- qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1, name);
1210
-
1211
- if (current_machine->audiodev) {
1212
- s->card.name = g_strdup(current_machine->audiodev);
1213
- s->card.state = audio_state_by_name(s->card.name, &error_fatal);
1214
- }
1215
- AUD_register_card(s->name, &s->card, &error_fatal);
1216
-
1217
- qemu_register_reset((void *) tsc210x_reset, s);
1218
- vmstate_register(NULL, 0, vmsd, s);
1219
-}
1220
-
1221
-uWireSlave *tsc2102_init(qemu_irq pint)
1222
-{
1223
- TSC210xState *s;
1224
-
1225
- s = g_new0(TSC210xState, 1);
1226
- s->x = 160;
1227
- s->y = 160;
1228
- s->pressure = 0;
1229
- s->precision = s->nextprecision = 0;
1230
- s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
1231
- s->pint = pint;
1232
- s->model = 0x2102;
1233
- s->name = "tsc2102";
1234
-
1235
- tsc210x_init(s, "QEMU TSC2102-driven Touchscreen", &vmstate_tsc2102);
1236
-
1237
- return &s->chip;
1238
-}
1239
-
1240
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
1241
-{
1242
- TSC210xState *s;
1243
-
1244
- s = g_new0(TSC210xState, 1);
1245
- s->x = 400;
1246
- s->y = 240;
1247
- s->pressure = 0;
1248
- s->precision = s->nextprecision = 0;
1249
- s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
1250
- s->pint = penirq;
1251
- s->kbint = kbirq;
1252
- s->davint = dav;
1253
- s->model = 0x2301;
1254
- s->name = "tsc2301";
1255
-
1256
- tsc210x_init(s, "QEMU TSC2301-driven Touchscreen", &vmstate_tsc2301);
1257
-
1258
- return &s->chip;
1259
-}
1260
-
1261
-I2SCodec *tsc210x_codec(uWireSlave *chip)
1262
-{
1263
- TSC210xState *s = (TSC210xState *) chip->opaque;
1264
-
1265
- return &s->codec;
1266
-}
1267
-
1268
-/*
1269
- * Use tslib generated calibration data to generate ADC input values
1270
- * from the touchscreen. Assuming 12-bit precision was used during
1271
- * tslib calibration.
1272
- */
1273
-void tsc210x_set_transform(uWireSlave *chip, const MouseTransformInfo *info)
1274
-{
1275
- TSC210xState *s = (TSC210xState *) chip->opaque;
1276
-#if 0
1277
- int64_t ltr[8];
1278
-
1279
- ltr[0] = (int64_t) info->a[1] * info->y;
1280
- ltr[1] = (int64_t) info->a[4] * info->x;
1281
- ltr[2] = (int64_t) info->a[1] * info->a[3] -
1282
- (int64_t) info->a[4] * info->a[0];
1283
- ltr[3] = (int64_t) info->a[2] * info->a[4] -
1284
- (int64_t) info->a[5] * info->a[1];
1285
- ltr[4] = (int64_t) info->a[0] * info->y;
1286
- ltr[5] = (int64_t) info->a[3] * info->x;
1287
- ltr[6] = (int64_t) info->a[4] * info->a[0] -
1288
- (int64_t) info->a[1] * info->a[3];
1289
- ltr[7] = (int64_t) info->a[2] * info->a[3] -
1290
- (int64_t) info->a[5] * info->a[0];
1291
-
1292
- /* Avoid integer overflow */
1293
- s->tr[0] = ltr[0] >> 11;
1294
- s->tr[1] = ltr[1] >> 11;
1295
- s->tr[2] = muldiv64(ltr[2], 1, info->a[6]);
1296
- s->tr[3] = muldiv64(ltr[3], 1 << 4, ltr[2]);
1297
- s->tr[4] = ltr[4] >> 11;
1298
- s->tr[5] = ltr[5] >> 11;
1299
- s->tr[6] = muldiv64(ltr[6], 1, info->a[6]);
1300
- s->tr[7] = muldiv64(ltr[7], 1 << 4, ltr[6]);
1301
-#else
1302
-
1303
- /* This version assumes touchscreen X & Y axis are parallel or
1304
- * perpendicular to LCD's X & Y axis in some way. */
1305
- if (abs(info->a[0]) > abs(info->a[1])) {
1306
- s->tr[0] = 0;
1307
- s->tr[1] = -info->a[6] * info->x;
1308
- s->tr[2] = info->a[0];
1309
- s->tr[3] = -info->a[2] / info->a[0];
1310
- s->tr[4] = info->a[6] * info->y;
1311
- s->tr[5] = 0;
1312
- s->tr[6] = info->a[4];
1313
- s->tr[7] = -info->a[5] / info->a[4];
1314
- } else {
1315
- s->tr[0] = info->a[6] * info->y;
1316
- s->tr[1] = 0;
1317
- s->tr[2] = info->a[1];
1318
- s->tr[3] = -info->a[2] / info->a[1];
1319
- s->tr[4] = 0;
1320
- s->tr[5] = -info->a[6] * info->x;
1321
- s->tr[6] = info->a[3];
1322
- s->tr[7] = -info->a[5] / info->a[3];
1323
- }
1324
-
1325
- s->tr[0] >>= 11;
1326
- s->tr[1] >>= 11;
1327
- s->tr[3] <<= 4;
1328
- s->tr[4] >>= 11;
1329
- s->tr[5] >>= 11;
1330
- s->tr[7] <<= 4;
1331
-#endif
1332
-}
1333
-
1334
-void tsc210x_key_event(uWireSlave *chip, int key, int down)
1335
-{
1336
- TSC210xState *s = (TSC210xState *) chip->opaque;
1337
-
1338
- if (down)
1339
- s->kb.down |= 1 << key;
1340
- else
1341
- s->kb.down &= ~(1 << key);
1342
-
1343
- if (down && (s->kb.down & ~s->kb.mask) && !s->kb.intr) {
1344
- s->kb.intr = 1;
1345
- qemu_irq_lower(s->kbint);
1346
- } else if (s->kb.intr && !(s->kb.down & ~s->kb.mask) &&
1347
- !(s->kb.mode & 1)) {
1348
- s->kb.intr = 0;
1349
- qemu_irq_raise(s->kbint);
1350
- }
1351
-}
1352
diff --git a/hw/input/Kconfig b/hw/input/Kconfig
1353
index XXXXXXX..XXXXXXX 100644
1354
--- a/hw/input/Kconfig
1355
+++ b/hw/input/Kconfig
1356
@@ -XXX,XX +XXX,XX @@ config VHOST_USER_INPUT
1357
default y
1358
depends on VIRTIO_INPUT && VHOST_USER
1359
1360
-config TSC210X
1361
- bool
1362
-
1363
config LASIPS2
1364
select PS2
1365
diff --git a/hw/input/meson.build b/hw/input/meson.build
1366
index XXXXXXX..XXXXXXX 100644
1367
--- a/hw/input/meson.build
1368
+++ b/hw/input/meson.build
1369
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: files('virtio-input.c'))
1370
system_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: files('virtio-input-hid.c'))
1371
system_ss.add(when: 'CONFIG_VIRTIO_INPUT_HOST', if_true: files('virtio-input-host.c'))
1372
1373
-system_ss.add(when: 'CONFIG_TSC210X', if_true: files('tsc210x.c'))
1374
system_ss.add(when: 'CONFIG_LASIPS2', if_true: files('lasips2.c'))
1375
--
39
--
1376
2.34.1
40
2.34.1
diff view generated by jsdifflib
1
The devices in hw/misc/cbus.c were used only by the
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
now-removed nseries machine types, so they can be removed.
2
parts64_default_nan().
3
4
As this is the last use of the CONFIG_NSERIES define we
5
can remove that from KConfig now.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20240903160751.4100218-27-peter.maydell@linaro.org
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-38-peter.maydell@linaro.org
9
---
7
---
10
MAINTAINERS | 2 -
8
target/i386/tcg/fpu_helper.c | 4 ++++
11
include/hw/misc/cbus.h | 31 ---
9
fpu/softfloat-specialize.c.inc | 3 ---
12
hw/misc/cbus.c | 619 -----------------------------------------
10
2 files changed, 4 insertions(+), 3 deletions(-)
13
hw/arm/Kconfig | 14 -
14
hw/misc/meson.build | 1 -
15
5 files changed, 667 deletions(-)
16
delete mode 100644 include/hw/misc/cbus.h
17
delete mode 100644 hw/misc/cbus.c
18
11
19
diff --git a/MAINTAINERS b/MAINTAINERS
12
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/MAINTAINERS
14
--- a/target/i386/tcg/fpu_helper.c
22
+++ b/MAINTAINERS
15
+++ b/target/i386/tcg/fpu_helper.c
23
@@ -XXX,XX +XXX,XX @@ F: hw/display/blizzard.c
16
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
24
F: hw/input/lm832x.c
17
*/
25
F: hw/input/tsc2005.c
18
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
26
F: hw/input/tsc210x.c
19
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
27
-F: hw/misc/cbus.c
20
+ /* Default NaN: sign bit set, most significant frac bit set */
28
F: hw/rtc/twl92230.c
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
29
F: include/hw/display/blizzard.h
22
+ set_float_default_nan_pattern(0b11000000, &env->mmx_status);
30
F: include/hw/input/lm832x.h
23
+ set_float_default_nan_pattern(0b11000000, &env->sse_status);
31
F: include/hw/input/tsc2xxx.h
24
}
32
-F: include/hw/misc/cbus.h
25
33
26
static inline uint8_t save_exception_flags(CPUX86State *env)
34
Raspberry Pi
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
35
M: Peter Maydell <peter.maydell@linaro.org>
36
diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h
37
deleted file mode 100644
38
index XXXXXXX..XXXXXXX
39
--- a/include/hw/misc/cbus.h
40
+++ /dev/null
41
@@ -XXX,XX +XXX,XX @@
42
-/*
43
- * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma /
44
- * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms.
45
- * Based on reverse-engineering of a linux driver.
46
- *
47
- * Copyright (C) 2008 Nokia Corporation
48
- * Written by Andrzej Zaborowski
49
- *
50
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
51
- * See the COPYING file in the top-level directory.
52
- */
53
-
54
-#ifndef HW_MISC_CBUS_H
55
-#define HW_MISC_CBUS_H
56
-
57
-
58
-typedef struct {
59
- qemu_irq clk;
60
- qemu_irq dat;
61
- qemu_irq sel;
62
-} CBus;
63
-
64
-CBus *cbus_init(qemu_irq dat_out);
65
-void cbus_attach(CBus *bus, void *slave_opaque);
66
-
67
-void *retu_init(qemu_irq irq, int vilma);
68
-void *tahvo_init(qemu_irq irq, int betty);
69
-
70
-void retu_key_event(void *retu, int state);
71
-
72
-#endif
73
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
74
deleted file mode 100644
75
index XXXXXXX..XXXXXXX
76
--- a/hw/misc/cbus.c
77
+++ /dev/null
78
@@ -XXX,XX +XXX,XX @@
79
-/*
80
- * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma /
81
- * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms.
82
- * Based on reverse-engineering of a linux driver.
83
- *
84
- * Copyright (C) 2008 Nokia Corporation
85
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
86
- *
87
- * This program is free software; you can redistribute it and/or
88
- * modify it under the terms of the GNU General Public License as
89
- * published by the Free Software Foundation; either version 2 or
90
- * (at your option) version 3 of the License.
91
- *
92
- * This program is distributed in the hope that it will be useful,
93
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
94
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
95
- * GNU General Public License for more details.
96
- *
97
- * You should have received a copy of the GNU General Public License along
98
- * with this program; if not, see <http://www.gnu.org/licenses/>.
99
- */
100
-
101
-#include "qemu/osdep.h"
102
-#include "hw/hw.h"
103
-#include "hw/irq.h"
104
-#include "hw/misc/cbus.h"
105
-#include "sysemu/runstate.h"
106
-
107
-//#define DEBUG
108
-
109
-typedef struct {
110
- void *opaque;
111
- void (*io)(void *opaque, int rw, int reg, uint16_t *val);
112
- int addr;
113
-} CBusSlave;
114
-
115
-typedef struct {
116
- CBus cbus;
117
-
118
- int sel;
119
- int dat;
120
- int clk;
121
- int bit;
122
- int dir;
123
- uint16_t val;
124
- qemu_irq dat_out;
125
-
126
- int addr;
127
- int reg;
128
- int rw;
129
- enum {
130
- cbus_address,
131
- cbus_value,
132
- } cycle;
133
-
134
- CBusSlave *slave[8];
135
-} CBusPriv;
136
-
137
-static void cbus_io(CBusPriv *s)
138
-{
139
- if (s->slave[s->addr])
140
- s->slave[s->addr]->io(s->slave[s->addr]->opaque,
141
- s->rw, s->reg, &s->val);
142
- else
143
- hw_error("%s: bad slave address %i\n", __func__, s->addr);
144
-}
145
-
146
-static void cbus_cycle(CBusPriv *s)
147
-{
148
- switch (s->cycle) {
149
- case cbus_address:
150
- s->addr = (s->val >> 6) & 7;
151
- s->rw = (s->val >> 5) & 1;
152
- s->reg = (s->val >> 0) & 0x1f;
153
-
154
- s->cycle = cbus_value;
155
- s->bit = 15;
156
- s->dir = !s->rw;
157
- s->val = 0;
158
-
159
- if (s->rw)
160
- cbus_io(s);
161
- break;
162
-
163
- case cbus_value:
164
- if (!s->rw)
165
- cbus_io(s);
166
-
167
- s->cycle = cbus_address;
168
- s->bit = 8;
169
- s->dir = 1;
170
- s->val = 0;
171
- break;
172
- }
173
-}
174
-
175
-static void cbus_clk(void *opaque, int line, int level)
176
-{
177
- CBusPriv *s = (CBusPriv *) opaque;
178
-
179
- if (!s->sel && level && !s->clk) {
180
- if (s->dir)
181
- s->val |= s->dat << (s->bit --);
182
- else
183
- qemu_set_irq(s->dat_out, (s->val >> (s->bit --)) & 1);
184
-
185
- if (s->bit < 0)
186
- cbus_cycle(s);
187
- }
188
-
189
- s->clk = level;
190
-}
191
-
192
-static void cbus_dat(void *opaque, int line, int level)
193
-{
194
- CBusPriv *s = (CBusPriv *) opaque;
195
-
196
- s->dat = level;
197
-}
198
-
199
-static void cbus_sel(void *opaque, int line, int level)
200
-{
201
- CBusPriv *s = (CBusPriv *) opaque;
202
-
203
- if (!level) {
204
- s->dir = 1;
205
- s->bit = 8;
206
- s->val = 0;
207
- }
208
-
209
- s->sel = level;
210
-}
211
-
212
-CBus *cbus_init(qemu_irq dat)
213
-{
214
- CBusPriv *s = g_malloc0(sizeof(*s));
215
-
216
- s->dat_out = dat;
217
- s->cbus.clk = qemu_allocate_irq(cbus_clk, s, 0);
218
- s->cbus.dat = qemu_allocate_irq(cbus_dat, s, 0);
219
- s->cbus.sel = qemu_allocate_irq(cbus_sel, s, 0);
220
-
221
- s->sel = 1;
222
- s->clk = 0;
223
- s->dat = 0;
224
-
225
- return &s->cbus;
226
-}
227
-
228
-void cbus_attach(CBus *bus, void *slave_opaque)
229
-{
230
- CBusSlave *slave = (CBusSlave *) slave_opaque;
231
- CBusPriv *s = (CBusPriv *) bus;
232
-
233
- s->slave[slave->addr] = slave;
234
-}
235
-
236
-/* Retu/Vilma */
237
-typedef struct {
238
- uint16_t irqst;
239
- uint16_t irqen;
240
- uint16_t cc[2];
241
- int channel;
242
- uint16_t result[16];
243
- uint16_t sample;
244
- uint16_t status;
245
-
246
- struct {
247
- uint16_t cal;
248
- } rtc;
249
-
250
- int is_vilma;
251
- qemu_irq irq;
252
- CBusSlave cbus;
253
-} CBusRetu;
254
-
255
-static void retu_interrupt_update(CBusRetu *s)
256
-{
257
- qemu_set_irq(s->irq, s->irqst & ~s->irqen);
258
-}
259
-
260
-#define RETU_REG_ASICR        0x00    /* (RO) ASIC ID & revision */
261
-#define RETU_REG_IDR        0x01    /* (T) Interrupt ID */
262
-#define RETU_REG_IMR        0x02    /* (RW) Interrupt mask */
263
-#define RETU_REG_RTCDSR        0x03    /* (RW) RTC seconds register */
264
-#define RETU_REG_RTCHMR        0x04    /* (RO) RTC hours and minutes reg */
265
-#define RETU_REG_RTCHMAR    0x05    /* (RW) RTC hours and minutes set reg */
266
-#define RETU_REG_RTCCALR    0x06    /* (RW) RTC calibration register */
267
-#define RETU_REG_ADCR        0x08    /* (RW) ADC result register */
268
-#define RETU_REG_ADCSCR        0x09    /* (RW) ADC sample control register */
269
-#define RETU_REG_AFCR        0x0a    /* (RW) AFC register */
270
-#define RETU_REG_ANTIFR        0x0b    /* (RW) AntiF register */
271
-#define RETU_REG_CALIBR        0x0c    /* (RW) CalibR register*/
272
-#define RETU_REG_CCR1        0x0d    /* (RW) Common control register 1 */
273
-#define RETU_REG_CCR2        0x0e    /* (RW) Common control register 2 */
274
-#define RETU_REG_RCTRL_CLR    0x0f    /* (T) Regulator clear register */
275
-#define RETU_REG_RCTRL_SET    0x10    /* (T) Regulator set register */
276
-#define RETU_REG_TXCR        0x11    /* (RW) TxC register */
277
-#define RETU_REG_STATUS        0x16    /* (RO) Status register */
278
-#define RETU_REG_WATCHDOG    0x17    /* (RW) Watchdog register */
279
-#define RETU_REG_AUDTXR        0x18    /* (RW) Audio Codec Tx register */
280
-#define RETU_REG_AUDPAR        0x19    /* (RW) AudioPA register */
281
-#define RETU_REG_AUDRXR1    0x1a    /* (RW) Audio receive register 1 */
282
-#define RETU_REG_AUDRXR2    0x1b    /* (RW) Audio receive register 2 */
283
-#define RETU_REG_SGR1        0x1c    /* (RW) */
284
-#define RETU_REG_SCR1        0x1d    /* (RW) */
285
-#define RETU_REG_SGR2        0x1e    /* (RW) */
286
-#define RETU_REG_SCR2        0x1f    /* (RW) */
287
-
288
-/* Retu Interrupt sources */
289
-enum {
290
- retu_int_pwr    = 0,    /* Power button */
291
- retu_int_char    = 1,    /* Charger */
292
- retu_int_rtcs    = 2,    /* Seconds */
293
- retu_int_rtcm    = 3,    /* Minutes */
294
- retu_int_rtcd    = 4,    /* Days */
295
- retu_int_rtca    = 5,    /* Alarm */
296
- retu_int_hook    = 6,    /* Hook */
297
- retu_int_head    = 7,    /* Headset */
298
- retu_int_adcs    = 8,    /* ADC sample */
299
-};
300
-
301
-/* Retu ADC channel wiring */
302
-enum {
303
- retu_adc_bsi    = 1,    /* BSI */
304
- retu_adc_batt_temp    = 2,    /* Battery temperature */
305
- retu_adc_chg_volt    = 3,    /* Charger voltage */
306
- retu_adc_head_det    = 4,    /* Headset detection */
307
- retu_adc_hook_det    = 5,    /* Hook detection */
308
- retu_adc_rf_gp    = 6,    /* RF GP */
309
- retu_adc_tx_det    = 7,    /* Wideband Tx detection */
310
- retu_adc_batt_volt    = 8,    /* Battery voltage */
311
- retu_adc_sens    = 10,    /* Light sensor */
312
- retu_adc_sens_temp    = 11,    /* Light sensor temperature */
313
- retu_adc_bbatt_volt    = 12,    /* Backup battery voltage */
314
- retu_adc_self_temp    = 13,    /* RETU temperature */
315
-};
316
-
317
-static inline uint16_t retu_read(CBusRetu *s, int reg)
318
-{
319
-#ifdef DEBUG
320
- printf("RETU read at %02x\n", reg);
321
-#endif
322
-
323
- switch (reg) {
324
- case RETU_REG_ASICR:
325
- return 0x0215 | (s->is_vilma << 7);
326
-
327
- case RETU_REG_IDR:    /* TODO: Or is this ffs(s->irqst)? */
328
- return s->irqst;
329
-
330
- case RETU_REG_IMR:
331
- return s->irqen;
332
-
333
- case RETU_REG_RTCDSR:
334
- case RETU_REG_RTCHMR:
335
- case RETU_REG_RTCHMAR:
336
- /* TODO */
337
- return 0x0000;
338
-
339
- case RETU_REG_RTCCALR:
340
- return s->rtc.cal;
341
-
342
- case RETU_REG_ADCR:
343
- return (s->channel << 10) | s->result[s->channel];
344
- case RETU_REG_ADCSCR:
345
- return s->sample;
346
-
347
- case RETU_REG_AFCR:
348
- case RETU_REG_ANTIFR:
349
- case RETU_REG_CALIBR:
350
- /* TODO */
351
- return 0x0000;
352
-
353
- case RETU_REG_CCR1:
354
- return s->cc[0];
355
- case RETU_REG_CCR2:
356
- return s->cc[1];
357
-
358
- case RETU_REG_RCTRL_CLR:
359
- case RETU_REG_RCTRL_SET:
360
- case RETU_REG_TXCR:
361
- /* TODO */
362
- return 0x0000;
363
-
364
- case RETU_REG_STATUS:
365
- return s->status;
366
-
367
- case RETU_REG_WATCHDOG:
368
- case RETU_REG_AUDTXR:
369
- case RETU_REG_AUDPAR:
370
- case RETU_REG_AUDRXR1:
371
- case RETU_REG_AUDRXR2:
372
- case RETU_REG_SGR1:
373
- case RETU_REG_SCR1:
374
- case RETU_REG_SGR2:
375
- case RETU_REG_SCR2:
376
- /* TODO */
377
- return 0x0000;
378
-
379
- default:
380
- hw_error("%s: bad register %02x\n", __func__, reg);
381
- }
382
-}
383
-
384
-static inline void retu_write(CBusRetu *s, int reg, uint16_t val)
385
-{
386
-#ifdef DEBUG
387
- printf("RETU write of %04x at %02x\n", val, reg);
388
-#endif
389
-
390
- switch (reg) {
391
- case RETU_REG_IDR:
392
- s->irqst ^= val;
393
- retu_interrupt_update(s);
394
- break;
395
-
396
- case RETU_REG_IMR:
397
- s->irqen = val;
398
- retu_interrupt_update(s);
399
- break;
400
-
401
- case RETU_REG_RTCDSR:
402
- case RETU_REG_RTCHMAR:
403
- /* TODO */
404
- break;
405
-
406
- case RETU_REG_RTCCALR:
407
- s->rtc.cal = val;
408
- break;
409
-
410
- case RETU_REG_ADCR:
411
- s->channel = (val >> 10) & 0xf;
412
- s->irqst |= 1 << retu_int_adcs;
413
- retu_interrupt_update(s);
414
- break;
415
- case RETU_REG_ADCSCR:
416
- s->sample &= ~val;
417
- break;
418
-
419
- case RETU_REG_AFCR:
420
- case RETU_REG_ANTIFR:
421
- case RETU_REG_CALIBR:
422
-
423
- case RETU_REG_CCR1:
424
- s->cc[0] = val;
425
- break;
426
- case RETU_REG_CCR2:
427
- s->cc[1] = val;
428
- break;
429
-
430
- case RETU_REG_RCTRL_CLR:
431
- case RETU_REG_RCTRL_SET:
432
- /* TODO */
433
- break;
434
-
435
- case RETU_REG_WATCHDOG:
436
- if (val == 0 && (s->cc[0] & 2))
437
- qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
438
- break;
439
-
440
- case RETU_REG_TXCR:
441
- case RETU_REG_AUDTXR:
442
- case RETU_REG_AUDPAR:
443
- case RETU_REG_AUDRXR1:
444
- case RETU_REG_AUDRXR2:
445
- case RETU_REG_SGR1:
446
- case RETU_REG_SCR1:
447
- case RETU_REG_SGR2:
448
- case RETU_REG_SCR2:
449
- /* TODO */
450
- break;
451
-
452
- default:
453
- hw_error("%s: bad register %02x\n", __func__, reg);
454
- }
455
-}
456
-
457
-static void retu_io(void *opaque, int rw, int reg, uint16_t *val)
458
-{
459
- CBusRetu *s = (CBusRetu *) opaque;
460
-
461
- if (rw)
462
- *val = retu_read(s, reg);
463
- else
464
- retu_write(s, reg, *val);
465
-}
466
-
467
-void *retu_init(qemu_irq irq, int vilma)
468
-{
469
- CBusRetu *s = g_malloc0(sizeof(*s));
470
-
471
- s->irq = irq;
472
- s->irqen = 0xffff;
473
- s->irqst = 0x0000;
474
- s->status = 0x0020;
475
- s->is_vilma = !!vilma;
476
- s->rtc.cal = 0x01;
477
- s->result[retu_adc_bsi] = 0x3c2;
478
- s->result[retu_adc_batt_temp] = 0x0fc;
479
- s->result[retu_adc_chg_volt] = 0x165;
480
- s->result[retu_adc_head_det] = 123;
481
- s->result[retu_adc_hook_det] = 1023;
482
- s->result[retu_adc_rf_gp] = 0x11;
483
- s->result[retu_adc_tx_det] = 0x11;
484
- s->result[retu_adc_batt_volt] = 0x250;
485
- s->result[retu_adc_sens] = 2;
486
- s->result[retu_adc_sens_temp] = 0x11;
487
- s->result[retu_adc_bbatt_volt] = 0x3d0;
488
- s->result[retu_adc_self_temp] = 0x330;
489
-
490
- s->cbus.opaque = s;
491
- s->cbus.io = retu_io;
492
- s->cbus.addr = 1;
493
-
494
- return &s->cbus;
495
-}
496
-
497
-void retu_key_event(void *retu, int state)
498
-{
499
- CBusSlave *slave = (CBusSlave *) retu;
500
- CBusRetu *s = (CBusRetu *) slave->opaque;
501
-
502
- s->irqst |= 1 << retu_int_pwr;
503
- retu_interrupt_update(s);
504
-
505
- if (state)
506
- s->status &= ~(1 << 5);
507
- else
508
- s->status |= 1 << 5;
509
-}
510
-
511
-#if 0
512
-static void retu_head_event(void *retu, int state)
513
-{
514
- CBusSlave *slave = (CBusSlave *) retu;
515
- CBusRetu *s = (CBusRetu *) slave->opaque;
516
-
517
- if ((s->cc[0] & 0x500) == 0x500) {    /* TODO: Which bits? */
518
- /* TODO: reissue the interrupt every 100ms or so. */
519
- s->irqst |= 1 << retu_int_head;
520
- retu_interrupt_update(s);
521
- }
522
-
523
- if (state)
524
- s->result[retu_adc_head_det] = 50;
525
- else
526
- s->result[retu_adc_head_det] = 123;
527
-}
528
-
529
-static void retu_hook_event(void *retu, int state)
530
-{
531
- CBusSlave *slave = (CBusSlave *) retu;
532
- CBusRetu *s = (CBusRetu *) slave->opaque;
533
-
534
- if ((s->cc[0] & 0x500) == 0x500) {
535
- /* TODO: reissue the interrupt every 100ms or so. */
536
- s->irqst |= 1 << retu_int_hook;
537
- retu_interrupt_update(s);
538
- }
539
-
540
- if (state)
541
- s->result[retu_adc_hook_det] = 50;
542
- else
543
- s->result[retu_adc_hook_det] = 123;
544
-}
545
-#endif
546
-
547
-/* Tahvo/Betty */
548
-typedef struct {
549
- uint16_t irqst;
550
- uint16_t irqen;
551
- uint8_t charger;
552
- uint8_t backlight;
553
- uint16_t usbr;
554
- uint16_t power;
555
-
556
- int is_betty;
557
- qemu_irq irq;
558
- CBusSlave cbus;
559
-} CBusTahvo;
560
-
561
-static void tahvo_interrupt_update(CBusTahvo *s)
562
-{
563
- qemu_set_irq(s->irq, s->irqst & ~s->irqen);
564
-}
565
-
566
-#define TAHVO_REG_ASICR        0x00    /* (RO) ASIC ID & revision */
567
-#define TAHVO_REG_IDR        0x01    /* (T) Interrupt ID */
568
-#define TAHVO_REG_IDSR        0x02    /* (RO) Interrupt status */
569
-#define TAHVO_REG_IMR        0x03    /* (RW) Interrupt mask */
570
-#define TAHVO_REG_CHAPWMR    0x04    /* (RW) Charger PWM */
571
-#define TAHVO_REG_LEDPWMR    0x05    /* (RW) LED PWM */
572
-#define TAHVO_REG_USBR        0x06    /* (RW) USB control */
573
-#define TAHVO_REG_RCR        0x07    /* (RW) Some kind of power management */
574
-#define TAHVO_REG_CCR1        0x08    /* (RW) Common control register 1 */
575
-#define TAHVO_REG_CCR2        0x09    /* (RW) Common control register 2 */
576
-#define TAHVO_REG_TESTR1    0x0a    /* (RW) Test register 1 */
577
-#define TAHVO_REG_TESTR2    0x0b    /* (RW) Test register 2 */
578
-#define TAHVO_REG_NOPR        0x0c    /* (RW) Number of periods */
579
-#define TAHVO_REG_FRR        0x0d    /* (RO) FR */
580
-
581
-static inline uint16_t tahvo_read(CBusTahvo *s, int reg)
582
-{
583
-#ifdef DEBUG
584
- printf("TAHVO read at %02x\n", reg);
585
-#endif
586
-
587
- switch (reg) {
588
- case TAHVO_REG_ASICR:
589
- return 0x0021 | (s->is_betty ? 0x0b00 : 0x0300);    /* 22 in N810 */
590
-
591
- case TAHVO_REG_IDR:
592
- case TAHVO_REG_IDSR:    /* XXX: what does this do? */
593
- return s->irqst;
594
-
595
- case TAHVO_REG_IMR:
596
- return s->irqen;
597
-
598
- case TAHVO_REG_CHAPWMR:
599
- return s->charger;
600
-
601
- case TAHVO_REG_LEDPWMR:
602
- return s->backlight;
603
-
604
- case TAHVO_REG_USBR:
605
- return s->usbr;
606
-
607
- case TAHVO_REG_RCR:
608
- return s->power;
609
-
610
- case TAHVO_REG_CCR1:
611
- case TAHVO_REG_CCR2:
612
- case TAHVO_REG_TESTR1:
613
- case TAHVO_REG_TESTR2:
614
- case TAHVO_REG_NOPR:
615
- case TAHVO_REG_FRR:
616
- return 0x0000;
617
-
618
- default:
619
- hw_error("%s: bad register %02x\n", __func__, reg);
620
- }
621
-}
622
-
623
-static inline void tahvo_write(CBusTahvo *s, int reg, uint16_t val)
624
-{
625
-#ifdef DEBUG
626
- printf("TAHVO write of %04x at %02x\n", val, reg);
627
-#endif
628
-
629
- switch (reg) {
630
- case TAHVO_REG_IDR:
631
- s->irqst ^= val;
632
- tahvo_interrupt_update(s);
633
- break;
634
-
635
- case TAHVO_REG_IMR:
636
- s->irqen = val;
637
- tahvo_interrupt_update(s);
638
- break;
639
-
640
- case TAHVO_REG_CHAPWMR:
641
- s->charger = val;
642
- break;
643
-
644
- case TAHVO_REG_LEDPWMR:
645
- if (s->backlight != (val & 0x7f)) {
646
- s->backlight = val & 0x7f;
647
- printf("%s: LCD backlight now at %i / 127\n",
648
- __func__, s->backlight);
649
- }
650
- break;
651
-
652
- case TAHVO_REG_USBR:
653
- s->usbr = val;
654
- break;
655
-
656
- case TAHVO_REG_RCR:
657
- s->power = val;
658
- break;
659
-
660
- case TAHVO_REG_CCR1:
661
- case TAHVO_REG_CCR2:
662
- case TAHVO_REG_TESTR1:
663
- case TAHVO_REG_TESTR2:
664
- case TAHVO_REG_NOPR:
665
- case TAHVO_REG_FRR:
666
- break;
667
-
668
- default:
669
- hw_error("%s: bad register %02x\n", __func__, reg);
670
- }
671
-}
672
-
673
-static void tahvo_io(void *opaque, int rw, int reg, uint16_t *val)
674
-{
675
- CBusTahvo *s = (CBusTahvo *) opaque;
676
-
677
- if (rw)
678
- *val = tahvo_read(s, reg);
679
- else
680
- tahvo_write(s, reg, *val);
681
-}
682
-
683
-void *tahvo_init(qemu_irq irq, int betty)
684
-{
685
- CBusTahvo *s = g_malloc0(sizeof(*s));
686
-
687
- s->irq = irq;
688
- s->irqen = 0xffff;
689
- s->irqst = 0x0000;
690
- s->is_betty = !!betty;
691
-
692
- s->cbus.opaque = s;
693
- s->cbus.io = tahvo_io;
694
- s->cbus.addr = 2;
695
-
696
- return &s->cbus;
697
-}
698
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
699
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
700
--- a/hw/arm/Kconfig
29
--- a/fpu/softfloat-specialize.c.inc
701
+++ b/hw/arm/Kconfig
30
+++ b/fpu/softfloat-specialize.c.inc
702
@@ -XXX,XX +XXX,XX @@ config OLIMEX_STM32_H405
31
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
703
depends on TCG && ARM
32
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
704
select STM32F405_SOC
33
/* Sign bit clear, all frac bits set */
705
34
dnan_pattern = 0b01111111;
706
-config NSERIES
35
-#elif defined(TARGET_I386) || defined(TARGET_X86_64)
707
- bool
36
- /* Sign bit set, most significant frac bit set */
708
- default y
37
- dnan_pattern = 0b11000000;
709
- depends on TCG && ARM
38
#elif defined(TARGET_HPPA)
710
- select OMAP
39
/* Sign bit clear, msb-1 frac bit set */
711
- select TMP105 # temperature sensor
40
dnan_pattern = 0b00100000;
712
- select BLIZZARD # LCD/TV controller
713
- select ONENAND
714
- select TSC210X # touchscreen/sensors/audio
715
- select TSC2005 # touchscreen/sensors/keypad
716
- select LM832X # GPIO keyboard chip
717
- select TWL92230 # energy-management
718
- select TUSB6010
719
-
720
config OMAP
721
bool
722
select FRAMEBUFFER
723
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
724
index XXXXXXX..XXXXXXX 100644
725
--- a/hw/misc/meson.build
726
+++ b/hw/misc/meson.build
727
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40-ccu.c'
728
system_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40-dramc.c'))
729
system_ss.add(when: 'CONFIG_AXP2XX_PMU', if_true: files('axp2xx.c'))
730
system_ss.add(when: 'CONFIG_REALVIEW', if_true: files('arm_sysctl.c'))
731
-system_ss.add(when: 'CONFIG_NSERIES', if_true: files('cbus.c'))
732
system_ss.add(when: 'CONFIG_ECCMEMCTL', if_true: files('eccmemctl.c'))
733
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_pmu.c', 'exynos4210_clk.c', 'exynos4210_rng.c'))
734
system_ss.add(when: 'CONFIG_IMX', if_true: files(
735
--
41
--
736
2.34.1
42
2.34.1
diff view generated by jsdifflib
1
Remove the 'n800' and 'n810' machine types, which modelled
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
Nokia internet tablets. These were deprecated in 9.0 and
2
parts64_default_nan().
3
so we can remove them for 9.2.
4
3
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20240903160751.4100218-26-peter.maydell@linaro.org
6
Message-id: 20241202131347.498124-39-peter.maydell@linaro.org
8
[PMM: added removal of arm-n800-machine.c post-review]
9
---
7
---
10
MAINTAINERS | 3 -
8
target/hppa/fpu_helper.c | 2 ++
11
docs/system/arm/nseries.rst | 33 -
9
fpu/softfloat-specialize.c.inc | 3 ---
12
docs/system/target-arm.rst | 1 -
10
2 files changed, 2 insertions(+), 3 deletions(-)
13
configs/devices/arm-softmmu/default.mak | 1 -
14
hw/arm/nseries.c | 1473 -----------------------
15
tests/qtest/libqos/arm-n800-machine.c | 92 --
16
hw/arm/meson.build | 1 -
17
tests/avocado/machine_arm_n8x0.py | 49 -
18
tests/qtest/libqos/meson.build | 1 -
19
9 files changed, 1654 deletions(-)
20
delete mode 100644 docs/system/arm/nseries.rst
21
delete mode 100644 hw/arm/nseries.c
22
delete mode 100644 tests/qtest/libqos/arm-n800-machine.c
23
delete mode 100755 tests/avocado/machine_arm_n8x0.py
24
11
25
diff --git a/MAINTAINERS b/MAINTAINERS
12
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
26
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
27
--- a/MAINTAINERS
14
--- a/target/hppa/fpu_helper.c
28
+++ b/MAINTAINERS
15
+++ b/target/hppa/fpu_helper.c
29
@@ -XXX,XX +XXX,XX @@ nSeries
16
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
30
M: Peter Maydell <peter.maydell@linaro.org>
17
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
31
L: qemu-arm@nongnu.org
18
/* For inf * 0 + NaN, return the input NaN */
32
S: Odd Fixes
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
33
-F: hw/arm/nseries.c
20
+ /* Default NaN: sign bit clear, msb-1 frac bit set */
34
F: hw/display/blizzard.c
21
+ set_float_default_nan_pattern(0b00100000, &env->fp_status);
35
F: hw/input/lm832x.c
22
}
36
F: hw/input/tsc2005.c
23
37
@@ -XXX,XX +XXX,XX @@ F: include/hw/display/blizzard.h
24
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
38
F: include/hw/input/lm832x.h
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
39
F: include/hw/input/tsc2xxx.h
40
F: include/hw/misc/cbus.h
41
-F: tests/avocado/machine_arm_n8x0.py
42
-F: docs/system/arm/nseries.rst
43
44
Raspberry Pi
45
M: Peter Maydell <peter.maydell@linaro.org>
46
diff --git a/docs/system/arm/nseries.rst b/docs/system/arm/nseries.rst
47
deleted file mode 100644
48
index XXXXXXX..XXXXXXX
49
--- a/docs/system/arm/nseries.rst
50
+++ /dev/null
51
@@ -XXX,XX +XXX,XX @@
52
-Nokia N800 and N810 tablets (``n800``, ``n810``)
53
-================================================
54
-
55
-Nokia N800 and N810 internet tablets (known also as RX-34 and RX-44 /
56
-48) emulation supports the following elements:
57
-
58
-- Texas Instruments OMAP2420 System-on-chip (ARM1136 core)
59
-
60
-- RAM and non-volatile OneNAND Flash memories
61
-
62
-- Display connected to EPSON remote framebuffer chip and OMAP on-chip
63
- display controller and a LS041y3 MIPI DBI-C controller
64
-
65
-- TI TSC2301 (in N800) and TI TSC2005 (in N810) touchscreen
66
- controllers driven through SPI bus
67
-
68
-- National Semiconductor LM8323-controlled qwerty keyboard driven
69
- through |I2C| bus
70
-
71
-- Secure Digital card connected to OMAP MMC/SD host
72
-
73
-- Three OMAP on-chip UARTs and on-chip STI debugging console
74
-
75
-- Mentor Graphics \"Inventra\" dual-role USB controller embedded in a
76
- TI TUSB6010 chip - only USB host mode is supported
77
-
78
-- TI TMP105 temperature sensor driven through |I2C| bus
79
-
80
-- TI TWL92230C power management companion with an RTC on
81
- |I2C| bus
82
-
83
-- Nokia RETU and TAHVO multi-purpose chips with an RTC, connected
84
- through CBUS
85
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
86
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
87
--- a/docs/system/target-arm.rst
27
--- a/fpu/softfloat-specialize.c.inc
88
+++ b/docs/system/target-arm.rst
28
+++ b/fpu/softfloat-specialize.c.inc
89
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
90
arm/emcraft-sf2
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
91
arm/musicpal
31
/* Sign bit clear, all frac bits set */
92
arm/kzm
32
dnan_pattern = 0b01111111;
93
- arm/nseries
33
-#elif defined(TARGET_HPPA)
94
arm/nrf
34
- /* Sign bit clear, msb-1 frac bit set */
95
arm/nuvoton
35
- dnan_pattern = 0b00100000;
96
arm/imx25-pdk
36
#elif defined(TARGET_HEXAGON)
97
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
37
/* Sign bit set, all frac bits set. */
98
index XXXXXXX..XXXXXXX 100644
38
dnan_pattern = 0b11111111;
99
--- a/configs/devices/arm-softmmu/default.mak
100
+++ b/configs/devices/arm-softmmu/default.mak
101
@@ -XXX,XX +XXX,XX @@
102
# CONFIG_MPS3R=n
103
# CONFIG_MUSCA=n
104
# CONFIG_SX1=n
105
-# CONFIG_NSERIES=n
106
# CONFIG_STELLARIS=n
107
# CONFIG_STM32VLDISCOVERY=n
108
# CONFIG_B_L475E_IOT01A=n
109
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
110
deleted file mode 100644
111
index XXXXXXX..XXXXXXX
112
--- a/hw/arm/nseries.c
113
+++ /dev/null
114
@@ -XXX,XX +XXX,XX @@
115
-/*
116
- * Nokia N-series internet tablets.
117
- *
118
- * Copyright (C) 2007 Nokia Corporation
119
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
120
- *
121
- * This program is free software; you can redistribute it and/or
122
- * modify it under the terms of the GNU General Public License as
123
- * published by the Free Software Foundation; either version 2 or
124
- * (at your option) version 3 of the License.
125
- *
126
- * This program is distributed in the hope that it will be useful,
127
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
128
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
129
- * GNU General Public License for more details.
130
- *
131
- * You should have received a copy of the GNU General Public License along
132
- * with this program; if not, see <http://www.gnu.org/licenses/>.
133
- */
134
-
135
-#include "qemu/osdep.h"
136
-#include "qapi/error.h"
137
-#include "cpu.h"
138
-#include "chardev/char.h"
139
-#include "qemu/cutils.h"
140
-#include "qemu/bswap.h"
141
-#include "qemu/hw-version.h"
142
-#include "sysemu/reset.h"
143
-#include "sysemu/runstate.h"
144
-#include "sysemu/sysemu.h"
145
-#include "hw/arm/omap.h"
146
-#include "hw/arm/boot.h"
147
-#include "hw/irq.h"
148
-#include "ui/console.h"
149
-#include "hw/boards.h"
150
-#include "hw/i2c/i2c.h"
151
-#include "hw/display/blizzard.h"
152
-#include "hw/input/lm832x.h"
153
-#include "hw/input/tsc2xxx.h"
154
-#include "hw/misc/cbus.h"
155
-#include "hw/sensor/tmp105.h"
156
-#include "hw/qdev-properties.h"
157
-#include "hw/block/flash.h"
158
-#include "hw/hw.h"
159
-#include "hw/loader.h"
160
-#include "hw/sysbus.h"
161
-#include "qemu/log.h"
162
-#include "qemu/error-report.h"
163
-
164
-
165
-/* Nokia N8x0 support */
166
-struct n800_s {
167
- struct omap_mpu_state_s *mpu;
168
-
169
- struct rfbi_chip_s blizzard;
170
- struct {
171
- void *opaque;
172
- uint32_t (*txrx)(void *opaque, uint32_t value, int len);
173
- uWireSlave *chip;
174
- } ts;
175
-
176
- int keymap[0x80];
177
- DeviceState *kbd;
178
-
179
- DeviceState *usb;
180
- void *retu;
181
- void *tahvo;
182
- DeviceState *nand;
183
-};
184
-
185
-/* GPIO pins */
186
-#define N8X0_TUSB_ENABLE_GPIO        0
187
-#define N800_MMC2_WP_GPIO        8
188
-#define N800_UNKNOWN_GPIO0        9    /* out */
189
-#define N810_MMC2_VIOSD_GPIO        9
190
-#define N810_HEADSET_AMP_GPIO        10
191
-#define N800_CAM_TURN_GPIO        12
192
-#define N810_GPS_RESET_GPIO        12
193
-#define N800_BLIZZARD_POWERDOWN_GPIO    15
194
-#define N800_MMC1_WP_GPIO        23
195
-#define N810_MMC2_VSD_GPIO        23
196
-#define N8X0_ONENAND_GPIO        26
197
-#define N810_BLIZZARD_RESET_GPIO    30
198
-#define N800_UNKNOWN_GPIO2        53    /* out */
199
-#define N8X0_TUSB_INT_GPIO        58
200
-#define N8X0_BT_WKUP_GPIO        61
201
-#define N8X0_STI_GPIO            62
202
-#define N8X0_CBUS_SEL_GPIO        64
203
-#define N8X0_CBUS_DAT_GPIO        65
204
-#define N8X0_CBUS_CLK_GPIO        66
205
-#define N8X0_WLAN_IRQ_GPIO        87
206
-#define N8X0_BT_RESET_GPIO        92
207
-#define N8X0_TEA5761_CS_GPIO        93
208
-#define N800_UNKNOWN_GPIO        94
209
-#define N810_TSC_RESET_GPIO        94
210
-#define N800_CAM_ACT_GPIO        95
211
-#define N810_GPS_WAKEUP_GPIO        95
212
-#define N8X0_MMC_CS_GPIO        96
213
-#define N8X0_WLAN_PWR_GPIO        97
214
-#define N8X0_BT_HOST_WKUP_GPIO        98
215
-#define N810_SPEAKER_AMP_GPIO        101
216
-#define N810_KB_LOCK_GPIO        102
217
-#define N800_TSC_TS_GPIO        103
218
-#define N810_TSC_TS_GPIO        106
219
-#define N8X0_HEADPHONE_GPIO        107
220
-#define N8X0_RETU_GPIO            108
221
-#define N800_TSC_KP_IRQ_GPIO        109
222
-#define N810_KEYBOARD_GPIO        109
223
-#define N800_BAT_COVER_GPIO        110
224
-#define N810_SLIDE_GPIO            110
225
-#define N8X0_TAHVO_GPIO            111
226
-#define N800_UNKNOWN_GPIO4        112    /* out */
227
-#define N810_SLEEPX_LED_GPIO        112
228
-#define N800_TSC_RESET_GPIO        118    /* ? */
229
-#define N810_AIC33_RESET_GPIO        118
230
-#define N800_TSC_UNKNOWN_GPIO        119    /* out */
231
-#define N8X0_TMP105_GPIO        125
232
-
233
-/* Config */
234
-#define BT_UART                0
235
-#define XLDR_LL_UART            1
236
-
237
-/* Addresses on the I2C bus 0 */
238
-#define N810_TLV320AIC33_ADDR        0x18    /* Audio CODEC */
239
-#define N8X0_TCM825x_ADDR        0x29    /* Camera */
240
-#define N810_LP5521_ADDR        0x32    /* LEDs */
241
-#define N810_TSL2563_ADDR        0x3d    /* Light sensor */
242
-#define N810_LM8323_ADDR        0x45    /* Keyboard */
243
-/* Addresses on the I2C bus 1 */
244
-#define N8X0_TMP105_ADDR        0x48    /* Temperature sensor */
245
-#define N8X0_MENELAUS_ADDR        0x72    /* Power management */
246
-
247
-/* Chipselects on GPMC NOR interface */
248
-#define N8X0_ONENAND_CS            0
249
-#define N8X0_USB_ASYNC_CS        1
250
-#define N8X0_USB_SYNC_CS        4
251
-
252
-#define N8X0_BD_ADDR            0x00, 0x1a, 0x89, 0x9e, 0x3e, 0x81
253
-
254
-static void n800_mmc_cs_cb(void *opaque, int line, int level)
255
-{
256
- /* TODO: this seems to actually be connected to the menelaus, to
257
- * which also both MMC slots connect. */
258
- omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
259
-}
260
-
261
-static void n8x0_gpio_setup(struct n800_s *s)
262
-{
263
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_MMC_CS_GPIO,
264
- qemu_allocate_irq(n800_mmc_cs_cb, s->mpu->mmc, 0));
265
- qemu_irq_lower(qdev_get_gpio_in(s->mpu->gpio, N800_BAT_COVER_GPIO));
266
-}
267
-
268
-#define MAEMO_CAL_HEADER(...)                \
269
- 'C', 'o', 'n', 'F', 0x02, 0x00, 0x04, 0x00,    \
270
- __VA_ARGS__,                    \
271
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272
-
273
-static const uint8_t n8x0_cal_wlan_mac[] = {
274
- MAEMO_CAL_HEADER('w', 'l', 'a', 'n', '-', 'm', 'a', 'c')
275
- 0x1c, 0x00, 0x00, 0x00, 0x47, 0xd6, 0x69, 0xb3,
276
- 0x30, 0x08, 0xa0, 0x83, 0x00, 0x00, 0x00, 0x00,
277
- 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
278
- 0x89, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
279
- 0x5d, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00,
280
-};
281
-
282
-static const uint8_t n8x0_cal_bt_id[] = {
283
- MAEMO_CAL_HEADER('b', 't', '-', 'i', 'd', 0, 0, 0)
284
- 0x0a, 0x00, 0x00, 0x00, 0xa3, 0x4b, 0xf6, 0x96,
285
- 0xa8, 0xeb, 0xb2, 0x41, 0x00, 0x00, 0x00, 0x00,
286
- N8X0_BD_ADDR,
287
-};
288
-
289
-static void n8x0_nand_setup(struct n800_s *s)
290
-{
291
- char *otp_region;
292
- DriveInfo *dinfo;
293
-
294
- s->nand = qdev_new("onenand");
295
- qdev_prop_set_uint16(s->nand, "manufacturer_id", NAND_MFR_SAMSUNG);
296
- /* Either 0x40 or 0x48 are OK for the device ID */
297
- qdev_prop_set_uint16(s->nand, "device_id", 0x48);
298
- qdev_prop_set_uint16(s->nand, "version_id", 0);
299
- qdev_prop_set_int32(s->nand, "shift", 1);
300
- dinfo = drive_get(IF_MTD, 0, 0);
301
- if (dinfo) {
302
- qdev_prop_set_drive_err(s->nand, "drive", blk_by_legacy_dinfo(dinfo),
303
- &error_fatal);
304
- }
305
- sysbus_realize_and_unref(SYS_BUS_DEVICE(s->nand), &error_fatal);
306
- sysbus_connect_irq(SYS_BUS_DEVICE(s->nand), 0,
307
- qdev_get_gpio_in(s->mpu->gpio, N8X0_ONENAND_GPIO));
308
- omap_gpmc_attach(s->mpu->gpmc, N8X0_ONENAND_CS,
309
- sysbus_mmio_get_region(SYS_BUS_DEVICE(s->nand), 0));
310
- otp_region = onenand_raw_otp(s->nand);
311
-
312
- memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
313
- memcpy(otp_region + 0x800, n8x0_cal_bt_id, sizeof(n8x0_cal_bt_id));
314
- /* XXX: in theory should also update the OOB for both pages */
315
-}
316
-
317
-static qemu_irq n8x0_system_powerdown;
318
-
319
-static void n8x0_powerdown_req(Notifier *n, void *opaque)
320
-{
321
- qemu_irq_raise(n8x0_system_powerdown);
322
-}
323
-
324
-static Notifier n8x0_system_powerdown_notifier = {
325
- .notify = n8x0_powerdown_req
326
-};
327
-
328
-static void n8x0_i2c_setup(struct n800_s *s)
329
-{
330
- DeviceState *dev;
331
- qemu_irq tmp_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TMP105_GPIO);
332
- I2CBus *i2c = omap_i2c_bus(s->mpu->i2c[0]);
333
-
334
- /* Attach a menelaus PM chip */
335
- dev = DEVICE(i2c_slave_create_simple(i2c, "twl92230", N8X0_MENELAUS_ADDR));
336
- qdev_connect_gpio_out(dev, 3,
337
- qdev_get_gpio_in(s->mpu->ih[0],
338
- OMAP_INT_24XX_SYS_NIRQ));
339
-
340
- n8x0_system_powerdown = qdev_get_gpio_in(dev, 3);
341
- qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
342
-
343
- /* Attach a TMP105 PM chip (A0 wired to ground) */
344
- dev = DEVICE(i2c_slave_create_simple(i2c, TYPE_TMP105, N8X0_TMP105_ADDR));
345
- qdev_connect_gpio_out(dev, 0, tmp_irq);
346
-}
347
-
348
-/* Touchscreen and keypad controller */
349
-static const MouseTransformInfo n800_pointercal = {
350
- .x = 800,
351
- .y = 480,
352
- .a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 },
353
-};
354
-
355
-static const MouseTransformInfo n810_pointercal = {
356
- .x = 800,
357
- .y = 480,
358
- .a = { 15041, 148, -4731056, 171, -10238, 35933380, 65536 },
359
-};
360
-
361
-#define RETU_KEYCODE    61    /* F3 */
362
-
363
-static void n800_key_event(void *opaque, int keycode)
364
-{
365
- struct n800_s *s = (struct n800_s *) opaque;
366
- int code = s->keymap[keycode & 0x7f];
367
-
368
- if (code == -1) {
369
- if ((keycode & 0x7f) == RETU_KEYCODE) {
370
- retu_key_event(s->retu, !(keycode & 0x80));
371
- }
372
- return;
373
- }
374
-
375
- tsc210x_key_event(s->ts.chip, code, !(keycode & 0x80));
376
-}
377
-
378
-static const int n800_keys[16] = {
379
- -1,
380
- 72,    /* Up */
381
- 63,    /* Home (F5) */
382
- -1,
383
- 75,    /* Left */
384
- 28,    /* Enter */
385
- 77,    /* Right */
386
- -1,
387
- 1,    /* Cycle (ESC) */
388
- 80,    /* Down */
389
- 62,    /* Menu (F4) */
390
- -1,
391
- 66,    /* Zoom- (F8) */
392
- 64,    /* FullScreen (F6) */
393
- 65,    /* Zoom+ (F7) */
394
- -1,
395
-};
396
-
397
-static void n800_tsc_kbd_setup(struct n800_s *s)
398
-{
399
- int i;
400
-
401
- /* XXX: are the three pins inverted inside the chip between the
402
- * tsc and the cpu (N4111)? */
403
- qemu_irq penirq = NULL;    /* NC */
404
- qemu_irq kbirq = qdev_get_gpio_in(s->mpu->gpio, N800_TSC_KP_IRQ_GPIO);
405
- qemu_irq dav = qdev_get_gpio_in(s->mpu->gpio, N800_TSC_TS_GPIO);
406
-
407
- s->ts.chip = tsc2301_init(penirq, kbirq, dav);
408
- s->ts.opaque = s->ts.chip->opaque;
409
- s->ts.txrx = tsc210x_txrx;
410
-
411
- for (i = 0; i < 0x80; i++) {
412
- s->keymap[i] = -1;
413
- }
414
- for (i = 0; i < 0x10; i++) {
415
- if (n800_keys[i] >= 0) {
416
- s->keymap[n800_keys[i]] = i;
417
- }
418
- }
419
-
420
- qemu_add_kbd_event_handler(n800_key_event, s);
421
-
422
- tsc210x_set_transform(s->ts.chip, &n800_pointercal);
423
-}
424
-
425
-static void n810_tsc_setup(struct n800_s *s)
426
-{
427
- qemu_irq pintdav = qdev_get_gpio_in(s->mpu->gpio, N810_TSC_TS_GPIO);
428
-
429
- s->ts.opaque = tsc2005_init(pintdav);
430
- s->ts.txrx = tsc2005_txrx;
431
-
432
- tsc2005_set_transform(s->ts.opaque, &n810_pointercal);
433
-}
434
-
435
-/* N810 Keyboard controller */
436
-static void n810_key_event(void *opaque, int keycode)
437
-{
438
- struct n800_s *s = (struct n800_s *) opaque;
439
- int code = s->keymap[keycode & 0x7f];
440
-
441
- if (code == -1) {
442
- if ((keycode & 0x7f) == RETU_KEYCODE) {
443
- retu_key_event(s->retu, !(keycode & 0x80));
444
- }
445
- return;
446
- }
447
-
448
- lm832x_key_event(s->kbd, code, !(keycode & 0x80));
449
-}
450
-
451
-#define M    0
452
-
453
-static const int n810_keys[0x80] = {
454
- [0x01] = 16,    /* Q */
455
- [0x02] = 37,    /* K */
456
- [0x03] = 24,    /* O */
457
- [0x04] = 25,    /* P */
458
- [0x05] = 14,    /* Backspace */
459
- [0x06] = 30,    /* A */
460
- [0x07] = 31,    /* S */
461
- [0x08] = 32,    /* D */
462
- [0x09] = 33,    /* F */
463
- [0x0a] = 34,    /* G */
464
- [0x0b] = 35,    /* H */
465
- [0x0c] = 36,    /* J */
466
-
467
- [0x11] = 17,    /* W */
468
- [0x12] = 62,    /* Menu (F4) */
469
- [0x13] = 38,    /* L */
470
- [0x14] = 40,    /* ' (Apostrophe) */
471
- [0x16] = 44,    /* Z */
472
- [0x17] = 45,    /* X */
473
- [0x18] = 46,    /* C */
474
- [0x19] = 47,    /* V */
475
- [0x1a] = 48,    /* B */
476
- [0x1b] = 49,    /* N */
477
- [0x1c] = 42,    /* Shift (Left shift) */
478
- [0x1f] = 65,    /* Zoom+ (F7) */
479
-
480
- [0x21] = 18,    /* E */
481
- [0x22] = 39,    /* ; (Semicolon) */
482
- [0x23] = 12,    /* - (Minus) */
483
- [0x24] = 13,    /* = (Equal) */
484
- [0x2b] = 56,    /* Fn (Left Alt) */
485
- [0x2c] = 50,    /* M */
486
- [0x2f] = 66,    /* Zoom- (F8) */
487
-
488
- [0x31] = 19,    /* R */
489
- [0x32] = 29 | M,    /* Right Ctrl */
490
- [0x34] = 57,    /* Space */
491
- [0x35] = 51,    /* , (Comma) */
492
- [0x37] = 72 | M,    /* Up */
493
- [0x3c] = 82 | M,    /* Compose (Insert) */
494
- [0x3f] = 64,    /* FullScreen (F6) */
495
-
496
- [0x41] = 20,    /* T */
497
- [0x44] = 52,    /* . (Dot) */
498
- [0x46] = 77 | M,    /* Right */
499
- [0x4f] = 63,    /* Home (F5) */
500
- [0x51] = 21,    /* Y */
501
- [0x53] = 80 | M,    /* Down */
502
- [0x55] = 28,    /* Enter */
503
- [0x5f] = 1,    /* Cycle (ESC) */
504
-
505
- [0x61] = 22,    /* U */
506
- [0x64] = 75 | M,    /* Left */
507
-
508
- [0x71] = 23,    /* I */
509
-#if 0
510
- [0x75] = 28 | M,    /* KP Enter (KP Enter) */
511
-#else
512
- [0x75] = 15,    /* KP Enter (Tab) */
513
-#endif
514
-};
515
-
516
-#undef M
517
-
518
-static void n810_kbd_setup(struct n800_s *s)
519
-{
520
- qemu_irq kbd_irq = qdev_get_gpio_in(s->mpu->gpio, N810_KEYBOARD_GPIO);
521
- int i;
522
-
523
- for (i = 0; i < 0x80; i++) {
524
- s->keymap[i] = -1;
525
- }
526
- for (i = 0; i < 0x80; i++) {
527
- if (n810_keys[i] > 0) {
528
- s->keymap[n810_keys[i]] = i;
529
- }
530
- }
531
-
532
- qemu_add_kbd_event_handler(n810_key_event, s);
533
-
534
- /* Attach the LM8322 keyboard to the I2C bus,
535
- * should happen in n8x0_i2c_setup and s->kbd be initialised here. */
536
- s->kbd = DEVICE(i2c_slave_create_simple(omap_i2c_bus(s->mpu->i2c[0]),
537
- TYPE_LM8323, N810_LM8323_ADDR));
538
- qdev_connect_gpio_out(s->kbd, 0, kbd_irq);
539
-}
540
-
541
-/* LCD MIPI DBI-C controller (URAL) */
542
-struct mipid_s {
543
- int resp[4];
544
- int param[4];
545
- int p;
546
- int pm;
547
- int cmd;
548
-
549
- int sleep;
550
- int booster;
551
- int te;
552
- int selfcheck;
553
- int partial;
554
- int normal;
555
- int vscr;
556
- int invert;
557
- int onoff;
558
- int gamma;
559
- uint32_t id;
560
-};
561
-
562
-static void mipid_reset(struct mipid_s *s)
563
-{
564
- s->pm = 0;
565
- s->cmd = 0;
566
-
567
- s->sleep = 1;
568
- s->booster = 0;
569
- s->selfcheck =
570
- (1 << 7) |    /* Register loading OK. */
571
- (1 << 5) |    /* The chip is attached. */
572
- (1 << 4);    /* Display glass still in one piece. */
573
- s->te = 0;
574
- s->partial = 0;
575
- s->normal = 1;
576
- s->vscr = 0;
577
- s->invert = 0;
578
- s->onoff = 1;
579
- s->gamma = 0;
580
-}
581
-
582
-static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
583
-{
584
- struct mipid_s *s = (struct mipid_s *) opaque;
585
- uint8_t ret;
586
-
587
- if (len > 9) {
588
- hw_error("%s: FIXME: bad SPI word width %i\n", __func__, len);
589
- }
590
-
591
- if (s->p >= ARRAY_SIZE(s->resp)) {
592
- ret = 0;
593
- } else {
594
- ret = s->resp[s->p++];
595
- }
596
- if (s->pm-- > 0) {
597
- s->param[s->pm] = cmd;
598
- } else {
599
- s->cmd = cmd;
600
- }
601
-
602
- switch (s->cmd) {
603
- case 0x00:    /* NOP */
604
- break;
605
-
606
- case 0x01:    /* SWRESET */
607
- mipid_reset(s);
608
- break;
609
-
610
- case 0x02:    /* BSTROFF */
611
- s->booster = 0;
612
- break;
613
- case 0x03:    /* BSTRON */
614
- s->booster = 1;
615
- break;
616
-
617
- case 0x04:    /* RDDID */
618
- s->p = 0;
619
- s->resp[0] = (s->id >> 16) & 0xff;
620
- s->resp[1] = (s->id >> 8) & 0xff;
621
- s->resp[2] = (s->id >> 0) & 0xff;
622
- break;
623
-
624
- case 0x06:    /* RD_RED */
625
- case 0x07:    /* RD_GREEN */
626
- /* XXX the bootloader sometimes issues RD_BLUE meaning RDDID so
627
- * for the bootloader one needs to change this. */
628
- case 0x08:    /* RD_BLUE */
629
- s->p = 0;
630
- /* TODO: return first pixel components */
631
- s->resp[0] = 0x01;
632
- break;
633
-
634
- case 0x09:    /* RDDST */
635
- s->p = 0;
636
- s->resp[0] = s->booster << 7;
637
- s->resp[1] = (5 << 4) | (s->partial << 2) |
638
- (s->sleep << 1) | s->normal;
639
- s->resp[2] = (s->vscr << 7) | (s->invert << 5) |
640
- (s->onoff << 2) | (s->te << 1) | (s->gamma >> 2);
641
- s->resp[3] = s->gamma << 6;
642
- break;
643
-
644
- case 0x0a:    /* RDDPM */
645
- s->p = 0;
646
- s->resp[0] = (s->onoff << 2) | (s->normal << 3) | (s->sleep << 4) |
647
- (s->partial << 5) | (s->sleep << 6) | (s->booster << 7);
648
- break;
649
- case 0x0b:    /* RDDMADCTR */
650
- s->p = 0;
651
- s->resp[0] = 0;
652
- break;
653
- case 0x0c:    /* RDDCOLMOD */
654
- s->p = 0;
655
- s->resp[0] = 5;    /* 65K colours */
656
- break;
657
- case 0x0d:    /* RDDIM */
658
- s->p = 0;
659
- s->resp[0] = (s->invert << 5) | (s->vscr << 7) | s->gamma;
660
- break;
661
- case 0x0e:    /* RDDSM */
662
- s->p = 0;
663
- s->resp[0] = s->te << 7;
664
- break;
665
- case 0x0f:    /* RDDSDR */
666
- s->p = 0;
667
- s->resp[0] = s->selfcheck;
668
- break;
669
-
670
- case 0x10:    /* SLPIN */
671
- s->sleep = 1;
672
- break;
673
- case 0x11:    /* SLPOUT */
674
- s->sleep = 0;
675
- s->selfcheck ^= 1 << 6;    /* POFF self-diagnosis Ok */
676
- break;
677
-
678
- case 0x12:    /* PTLON */
679
- s->partial = 1;
680
- s->normal = 0;
681
- s->vscr = 0;
682
- break;
683
- case 0x13:    /* NORON */
684
- s->partial = 0;
685
- s->normal = 1;
686
- s->vscr = 0;
687
- break;
688
-
689
- case 0x20:    /* INVOFF */
690
- s->invert = 0;
691
- break;
692
- case 0x21:    /* INVON */
693
- s->invert = 1;
694
- break;
695
-
696
- case 0x22:    /* APOFF */
697
- case 0x23:    /* APON */
698
- goto bad_cmd;
699
-
700
- case 0x25:    /* WRCNTR */
701
- if (s->pm < 0) {
702
- s->pm = 1;
703
- }
704
- goto bad_cmd;
705
-
706
- case 0x26:    /* GAMSET */
707
- if (!s->pm) {
708
- s->gamma = ctz32(s->param[0] & 0xf);
709
- if (s->gamma == 32) {
710
- s->gamma = -1; /* XXX: should this be 0? */
711
- }
712
- } else if (s->pm < 0) {
713
- s->pm = 1;
714
- }
715
- break;
716
-
717
- case 0x28:    /* DISPOFF */
718
- s->onoff = 0;
719
- break;
720
- case 0x29:    /* DISPON */
721
- s->onoff = 1;
722
- break;
723
-
724
- case 0x2a:    /* CASET */
725
- case 0x2b:    /* RASET */
726
- case 0x2c:    /* RAMWR */
727
- case 0x2d:    /* RGBSET */
728
- case 0x2e:    /* RAMRD */
729
- case 0x30:    /* PTLAR */
730
- case 0x33:    /* SCRLAR */
731
- goto bad_cmd;
732
-
733
- case 0x34:    /* TEOFF */
734
- s->te = 0;
735
- break;
736
- case 0x35:    /* TEON */
737
- if (!s->pm) {
738
- s->te = 1;
739
- } else if (s->pm < 0) {
740
- s->pm = 1;
741
- }
742
- break;
743
-
744
- case 0x36:    /* MADCTR */
745
- goto bad_cmd;
746
-
747
- case 0x37:    /* VSCSAD */
748
- s->partial = 0;
749
- s->normal = 0;
750
- s->vscr = 1;
751
- break;
752
-
753
- case 0x38:    /* IDMOFF */
754
- case 0x39:    /* IDMON */
755
- case 0x3a:    /* COLMOD */
756
- goto bad_cmd;
757
-
758
- case 0xb0:    /* CLKINT / DISCTL */
759
- case 0xb1:    /* CLKEXT */
760
- if (s->pm < 0) {
761
- s->pm = 2;
762
- }
763
- break;
764
-
765
- case 0xb4:    /* FRMSEL */
766
- break;
767
-
768
- case 0xb5:    /* FRM8SEL */
769
- case 0xb6:    /* TMPRNG / INIESC */
770
- case 0xb7:    /* TMPHIS / NOP2 */
771
- case 0xb8:    /* TMPREAD / MADCTL */
772
- case 0xba:    /* DISTCTR */
773
- case 0xbb:    /* EPVOL */
774
- goto bad_cmd;
775
-
776
- case 0xbd:    /* Unknown */
777
- s->p = 0;
778
- s->resp[0] = 0;
779
- s->resp[1] = 1;
780
- break;
781
-
782
- case 0xc2:    /* IFMOD */
783
- if (s->pm < 0) {
784
- s->pm = 2;
785
- }
786
- break;
787
-
788
- case 0xc6:    /* PWRCTL */
789
- case 0xc7:    /* PPWRCTL */
790
- case 0xd0:    /* EPWROUT */
791
- case 0xd1:    /* EPWRIN */
792
- case 0xd4:    /* RDEV */
793
- case 0xd5:    /* RDRR */
794
- goto bad_cmd;
795
-
796
- case 0xda:    /* RDID1 */
797
- s->p = 0;
798
- s->resp[0] = (s->id >> 16) & 0xff;
799
- break;
800
- case 0xdb:    /* RDID2 */
801
- s->p = 0;
802
- s->resp[0] = (s->id >> 8) & 0xff;
803
- break;
804
- case 0xdc:    /* RDID3 */
805
- s->p = 0;
806
- s->resp[0] = (s->id >> 0) & 0xff;
807
- break;
808
-
809
- default:
810
- bad_cmd:
811
- qemu_log_mask(LOG_GUEST_ERROR,
812
- "%s: unknown command 0x%02x\n", __func__, s->cmd);
813
- break;
814
- }
815
-
816
- return ret;
817
-}
818
-
819
-static void *mipid_init(void)
820
-{
821
- struct mipid_s *s = g_malloc0(sizeof(*s));
822
-
823
- s->id = 0x838f03;
824
- mipid_reset(s);
825
-
826
- return s;
827
-}
828
-
829
-static void n8x0_spi_setup(struct n800_s *s)
830
-{
831
- void *tsc = s->ts.opaque;
832
- void *mipid = mipid_init();
833
-
834
- omap_mcspi_attach(s->mpu->mcspi[0], s->ts.txrx, tsc, 0);
835
- omap_mcspi_attach(s->mpu->mcspi[0], mipid_txrx, mipid, 1);
836
-}
837
-
838
-/* This task is normally performed by the bootloader. If we're loading
839
- * a kernel directly, we need to enable the Blizzard ourselves. */
840
-static void n800_dss_init(struct rfbi_chip_s *chip)
841
-{
842
- uint8_t *fb_blank;
843
-
844
- chip->write(chip->opaque, 0, 0x2a);        /* LCD Width register */
845
- chip->write(chip->opaque, 1, 0x64);
846
- chip->write(chip->opaque, 0, 0x2c);        /* LCD HNDP register */
847
- chip->write(chip->opaque, 1, 0x1e);
848
- chip->write(chip->opaque, 0, 0x2e);        /* LCD Height 0 register */
849
- chip->write(chip->opaque, 1, 0xe0);
850
- chip->write(chip->opaque, 0, 0x30);        /* LCD Height 1 register */
851
- chip->write(chip->opaque, 1, 0x01);
852
- chip->write(chip->opaque, 0, 0x32);        /* LCD VNDP register */
853
- chip->write(chip->opaque, 1, 0x06);
854
- chip->write(chip->opaque, 0, 0x68);        /* Display Mode register */
855
- chip->write(chip->opaque, 1, 1);        /* Enable bit */
856
-
857
- chip->write(chip->opaque, 0, 0x6c);    
858
- chip->write(chip->opaque, 1, 0x00);        /* Input X Start Position */
859
- chip->write(chip->opaque, 1, 0x00);        /* Input X Start Position */
860
- chip->write(chip->opaque, 1, 0x00);        /* Input Y Start Position */
861
- chip->write(chip->opaque, 1, 0x00);        /* Input Y Start Position */
862
- chip->write(chip->opaque, 1, 0x1f);        /* Input X End Position */
863
- chip->write(chip->opaque, 1, 0x03);        /* Input X End Position */
864
- chip->write(chip->opaque, 1, 0xdf);        /* Input Y End Position */
865
- chip->write(chip->opaque, 1, 0x01);        /* Input Y End Position */
866
- chip->write(chip->opaque, 1, 0x00);        /* Output X Start Position */
867
- chip->write(chip->opaque, 1, 0x00);        /* Output X Start Position */
868
- chip->write(chip->opaque, 1, 0x00);        /* Output Y Start Position */
869
- chip->write(chip->opaque, 1, 0x00);        /* Output Y Start Position */
870
- chip->write(chip->opaque, 1, 0x1f);        /* Output X End Position */
871
- chip->write(chip->opaque, 1, 0x03);        /* Output X End Position */
872
- chip->write(chip->opaque, 1, 0xdf);        /* Output Y End Position */
873
- chip->write(chip->opaque, 1, 0x01);        /* Output Y End Position */
874
- chip->write(chip->opaque, 1, 0x01);        /* Input Data Format */
875
- chip->write(chip->opaque, 1, 0x01);        /* Data Source Select */
876
-
877
- fb_blank = memset(g_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
878
- /* Display Memory Data Port */
879
- chip->block(chip->opaque, 1, fb_blank, 800 * 480 * 2, 800);
880
- g_free(fb_blank);
881
-}
882
-
883
-static void n8x0_dss_setup(struct n800_s *s)
884
-{
885
- s->blizzard.opaque = s1d13745_init(NULL);
886
- s->blizzard.block = s1d13745_write_block;
887
- s->blizzard.write = s1d13745_write;
888
- s->blizzard.read = s1d13745_read;
889
-
890
- omap_rfbi_attach(s->mpu->dss, 0, &s->blizzard);
891
-}
892
-
893
-static void n8x0_cbus_setup(struct n800_s *s)
894
-{
895
- qemu_irq dat_out = qdev_get_gpio_in(s->mpu->gpio, N8X0_CBUS_DAT_GPIO);
896
- qemu_irq retu_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_RETU_GPIO);
897
- qemu_irq tahvo_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TAHVO_GPIO);
898
-
899
- CBus *cbus = cbus_init(dat_out);
900
-
901
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_CLK_GPIO, cbus->clk);
902
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_DAT_GPIO, cbus->dat);
903
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_SEL_GPIO, cbus->sel);
904
-
905
- cbus_attach(cbus, s->retu = retu_init(retu_irq, 1));
906
- cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
907
-}
908
-
909
-static void n8x0_usb_setup(struct n800_s *s)
910
-{
911
- SysBusDevice *dev;
912
- s->usb = qdev_new("tusb6010");
913
- dev = SYS_BUS_DEVICE(s->usb);
914
- sysbus_realize_and_unref(dev, &error_fatal);
915
- sysbus_connect_irq(dev, 0,
916
- qdev_get_gpio_in(s->mpu->gpio, N8X0_TUSB_INT_GPIO));
917
- /* Using the NOR interface */
918
- omap_gpmc_attach(s->mpu->gpmc, N8X0_USB_ASYNC_CS,
919
- sysbus_mmio_get_region(dev, 0));
920
- omap_gpmc_attach(s->mpu->gpmc, N8X0_USB_SYNC_CS,
921
- sysbus_mmio_get_region(dev, 1));
922
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_TUSB_ENABLE_GPIO,
923
- qdev_get_gpio_in(s->usb, 0)); /* tusb_pwr */
924
-}
925
-
926
-/* Setup done before the main bootloader starts by some early setup code
927
- * - used when we want to run the main bootloader in emulation. This
928
- * isn't documented. */
929
-static const uint32_t n800_pinout[104] = {
930
- 0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0,
931
- 0x00dc0808, 0x0b0f0f00, 0x080800b4, 0x00c00808,
932
- 0x08080808, 0x180800c4, 0x00b80000, 0x08080808,
933
- 0x080800bc, 0x00cc0808, 0x08081818, 0x18180128,
934
- 0x01241800, 0x18181818, 0x000000f0, 0x01300000,
935
- 0x00001b0b, 0x1b0f0138, 0x00e0181b, 0x1b031b0b,
936
- 0x180f0078, 0x00740018, 0x0f0f0f1a, 0x00000080,
937
- 0x007c0000, 0x00000000, 0x00000088, 0x00840000,
938
- 0x00000000, 0x00000094, 0x00980300, 0x0f180003,
939
- 0x0000008c, 0x00900f0f, 0x0f0f1b00, 0x0f00009c,
940
- 0x01140000, 0x1b1b0f18, 0x0818013c, 0x01400008,
941
- 0x00001818, 0x000b0110, 0x010c1800, 0x0b030b0f,
942
- 0x181800f4, 0x00f81818, 0x00000018, 0x000000fc,
943
- 0x00401808, 0x00000000, 0x0f1b0030, 0x003c0008,
944
- 0x00000000, 0x00000038, 0x00340000, 0x00000000,
945
- 0x1a080070, 0x00641a1a, 0x08080808, 0x08080060,
946
- 0x005c0808, 0x08080808, 0x08080058, 0x00540808,
947
- 0x08080808, 0x0808006c, 0x00680808, 0x08080808,
948
- 0x000000a8, 0x00b00000, 0x08080808, 0x000000a0,
949
- 0x00a40000, 0x00000000, 0x08ff0050, 0x004c0808,
950
- 0xffffffff, 0xffff0048, 0x0044ffff, 0xffffffff,
951
- 0x000000ac, 0x01040800, 0x08080b0f, 0x18180100,
952
- 0x01081818, 0x0b0b1808, 0x1a0300e4, 0x012c0b1a,
953
- 0x02020018, 0x0b000134, 0x011c0800, 0x0b1b1b00,
954
- 0x0f0000c8, 0x00ec181b, 0x000f0f02, 0x00180118,
955
- 0x01200000, 0x0f0b1b1b, 0x0f0200e8, 0x0000020b,
956
-};
957
-
958
-static void n800_setup_nolo_tags(void *sram_base)
959
-{
960
- int i;
961
- uint32_t *p = sram_base + 0x8000;
962
- uint32_t *v = sram_base + 0xa000;
963
-
964
- memset(p, 0, 0x3000);
965
-
966
- strcpy((void *) (p + 0), "QEMU N800");
967
-
968
- strcpy((void *) (p + 8), "F5");
969
-
970
- stl_p(p + 10, 0x04f70000);
971
- strcpy((void *) (p + 9), "RX-34");
972
-
973
- /* RAM size in MB? */
974
- stl_p(p + 12, 0x80);
975
-
976
- /* Pointer to the list of tags */
977
- stl_p(p + 13, OMAP2_SRAM_BASE + 0x9000);
978
-
979
- /* The NOLO tags start here */
980
- p = sram_base + 0x9000;
981
-#define ADD_TAG(tag, len)                \
982
- stw_p((uint16_t *) p + 0, tag);            \
983
- stw_p((uint16_t *) p + 1, len); p++;        \
984
- stl_p(p++, OMAP2_SRAM_BASE | (((void *) v - sram_base) & 0xffff));
985
-
986
- /* OMAP STI console? Pin out settings? */
987
- ADD_TAG(0x6e01, 414);
988
- for (i = 0; i < ARRAY_SIZE(n800_pinout); i++) {
989
- stl_p(v++, n800_pinout[i]);
990
- }
991
-
992
- /* Kernel memsize? */
993
- ADD_TAG(0x6e05, 1);
994
- stl_p(v++, 2);
995
-
996
- /* NOLO serial console */
997
- ADD_TAG(0x6e02, 4);
998
- stl_p(v++, XLDR_LL_UART);        /* UART number (1 - 3) */
999
-
1000
-#if 0
1001
- /* CBUS settings (Retu/AVilma) */
1002
- ADD_TAG(0x6e03, 6);
1003
- stw_p((uint16_t *) v + 0, 65);    /* CBUS GPIO0 */
1004
- stw_p((uint16_t *) v + 1, 66);    /* CBUS GPIO1 */
1005
- stw_p((uint16_t *) v + 2, 64);    /* CBUS GPIO2 */
1006
- v += 2;
1007
-#endif
1008
-
1009
- /* Nokia ASIC BB5 (Retu/Tahvo) */
1010
- ADD_TAG(0x6e0a, 4);
1011
- stw_p((uint16_t *) v + 0, 111);    /* "Retu" interrupt GPIO */
1012
- stw_p((uint16_t *) v + 1, 108);    /* "Tahvo" interrupt GPIO */
1013
- v++;
1014
-
1015
- /* LCD console? */
1016
- ADD_TAG(0x6e04, 4);
1017
- stw_p((uint16_t *) v + 0, 30);    /* ??? */
1018
- stw_p((uint16_t *) v + 1, 24);    /* ??? */
1019
- v++;
1020
-
1021
-#if 0
1022
- /* LCD settings */
1023
- ADD_TAG(0x6e06, 2);
1024
- stw_p((uint16_t *) (v++), 15);    /* ??? */
1025
-#endif
1026
-
1027
- /* I^2C (Menelaus) */
1028
- ADD_TAG(0x6e07, 4);
1029
- stl_p(v++, 0x00720000);        /* ??? */
1030
-
1031
- /* Unknown */
1032
- ADD_TAG(0x6e0b, 6);
1033
- stw_p((uint16_t *) v + 0, 94);    /* ??? */
1034
- stw_p((uint16_t *) v + 1, 23);    /* ??? */
1035
- stw_p((uint16_t *) v + 2, 0);    /* ??? */
1036
- v += 2;
1037
-
1038
- /* OMAP gpio switch info */
1039
- ADD_TAG(0x6e0c, 80);
1040
- strcpy((void *) v, "bat_cover");    v += 3;
1041
- stw_p((uint16_t *) v + 0, 110);    /* GPIO num ??? */
1042
- stw_p((uint16_t *) v + 1, 1);    /* GPIO num ??? */
1043
- v += 2;
1044
- strcpy((void *) v, "cam_act");    v += 3;
1045
- stw_p((uint16_t *) v + 0, 95);    /* GPIO num ??? */
1046
- stw_p((uint16_t *) v + 1, 32);    /* GPIO num ??? */
1047
- v += 2;
1048
- strcpy((void *) v, "cam_turn");    v += 3;
1049
- stw_p((uint16_t *) v + 0, 12);    /* GPIO num ??? */
1050
- stw_p((uint16_t *) v + 1, 33);    /* GPIO num ??? */
1051
- v += 2;
1052
- strcpy((void *) v, "headphone");    v += 3;
1053
- stw_p((uint16_t *) v + 0, 107);    /* GPIO num ??? */
1054
- stw_p((uint16_t *) v + 1, 17);    /* GPIO num ??? */
1055
- v += 2;
1056
-
1057
- /* Bluetooth */
1058
- ADD_TAG(0x6e0e, 12);
1059
- stl_p(v++, 0x5c623d01);        /* ??? */
1060
- stl_p(v++, 0x00000201);        /* ??? */
1061
- stl_p(v++, 0x00000000);        /* ??? */
1062
-
1063
- /* CX3110x WLAN settings */
1064
- ADD_TAG(0x6e0f, 8);
1065
- stl_p(v++, 0x00610025);        /* ??? */
1066
- stl_p(v++, 0xffff0057);        /* ??? */
1067
-
1068
- /* MMC host settings */
1069
- ADD_TAG(0x6e10, 12);
1070
- stl_p(v++, 0xffff000f);        /* ??? */
1071
- stl_p(v++, 0xffffffff);        /* ??? */
1072
- stl_p(v++, 0x00000060);        /* ??? */
1073
-
1074
- /* OneNAND chip select */
1075
- ADD_TAG(0x6e11, 10);
1076
- stl_p(v++, 0x00000401);        /* ??? */
1077
- stl_p(v++, 0x0002003a);        /* ??? */
1078
- stl_p(v++, 0x00000002);        /* ??? */
1079
-
1080
- /* TEA5761 sensor settings */
1081
- ADD_TAG(0x6e12, 2);
1082
- stl_p(v++, 93);            /* GPIO num ??? */
1083
-
1084
-#if 0
1085
- /* Unknown tag */
1086
- ADD_TAG(6e09, 0);
1087
-
1088
- /* Kernel UART / console */
1089
- ADD_TAG(6e12, 0);
1090
-#endif
1091
-
1092
- /* End of the list */
1093
- stl_p(p++, 0x00000000);
1094
- stl_p(p++, 0x00000000);
1095
-}
1096
-
1097
-/* This task is normally performed by the bootloader. If we're loading
1098
- * a kernel directly, we need to set up GPMC mappings ourselves. */
1099
-static void n800_gpmc_init(struct n800_s *s)
1100
-{
1101
- uint32_t config7 =
1102
- (0xf << 8) |    /* MASKADDRESS */
1103
- (1 << 6) |        /* CSVALID */
1104
- (4 << 0);        /* BASEADDRESS */
1105
-
1106
- cpu_physical_memory_write(0x6800a078,        /* GPMC_CONFIG7_0 */
1107
- &config7, sizeof(config7));
1108
-}
1109
-
1110
-/* Setup sequence done by the bootloader */
1111
-static void n8x0_boot_init(void *opaque)
1112
-{
1113
- struct n800_s *s = (struct n800_s *) opaque;
1114
- uint32_t buf;
1115
-
1116
- /* PRCM setup */
1117
-#define omap_writel(addr, val)    \
1118
- buf = (val);            \
1119
- cpu_physical_memory_write(addr, &buf, sizeof(buf))
1120
-
1121
- omap_writel(0x48008060, 0x41);        /* PRCM_CLKSRC_CTRL */
1122
- omap_writel(0x48008070, 1);            /* PRCM_CLKOUT_CTRL */
1123
- omap_writel(0x48008078, 0);            /* PRCM_CLKEMUL_CTRL */
1124
- omap_writel(0x48008090, 0);            /* PRCM_VOLTSETUP */
1125
- omap_writel(0x48008094, 0);            /* PRCM_CLKSSETUP */
1126
- omap_writel(0x48008098, 0);            /* PRCM_POLCTRL */
1127
- omap_writel(0x48008140, 2);            /* CM_CLKSEL_MPU */
1128
- omap_writel(0x48008148, 0);            /* CM_CLKSTCTRL_MPU */
1129
- omap_writel(0x48008158, 1);            /* RM_RSTST_MPU */
1130
- omap_writel(0x480081c8, 0x15);        /* PM_WKDEP_MPU */
1131
- omap_writel(0x480081d4, 0x1d4);        /* PM_EVGENCTRL_MPU */
1132
- omap_writel(0x480081d8, 0);            /* PM_EVEGENONTIM_MPU */
1133
- omap_writel(0x480081dc, 0);            /* PM_EVEGENOFFTIM_MPU */
1134
- omap_writel(0x480081e0, 0xc);        /* PM_PWSTCTRL_MPU */
1135
- omap_writel(0x48008200, 0x047e7ff7);    /* CM_FCLKEN1_CORE */
1136
- omap_writel(0x48008204, 0x00000004);    /* CM_FCLKEN2_CORE */
1137
- omap_writel(0x48008210, 0x047e7ff1);    /* CM_ICLKEN1_CORE */
1138
- omap_writel(0x48008214, 0x00000004);    /* CM_ICLKEN2_CORE */
1139
- omap_writel(0x4800821c, 0x00000000);    /* CM_ICLKEN4_CORE */
1140
- omap_writel(0x48008230, 0);            /* CM_AUTOIDLE1_CORE */
1141
- omap_writel(0x48008234, 0);            /* CM_AUTOIDLE2_CORE */
1142
- omap_writel(0x48008238, 7);            /* CM_AUTOIDLE3_CORE */
1143
- omap_writel(0x4800823c, 0);            /* CM_AUTOIDLE4_CORE */
1144
- omap_writel(0x48008240, 0x04360626);    /* CM_CLKSEL1_CORE */
1145
- omap_writel(0x48008244, 0x00000014);    /* CM_CLKSEL2_CORE */
1146
- omap_writel(0x48008248, 0);            /* CM_CLKSTCTRL_CORE */
1147
- omap_writel(0x48008300, 0x00000000);    /* CM_FCLKEN_GFX */
1148
- omap_writel(0x48008310, 0x00000000);    /* CM_ICLKEN_GFX */
1149
- omap_writel(0x48008340, 0x00000001);    /* CM_CLKSEL_GFX */
1150
- omap_writel(0x48008400, 0x00000004);    /* CM_FCLKEN_WKUP */
1151
- omap_writel(0x48008410, 0x00000004);    /* CM_ICLKEN_WKUP */
1152
- omap_writel(0x48008440, 0x00000000);    /* CM_CLKSEL_WKUP */
1153
- omap_writel(0x48008500, 0x000000cf);    /* CM_CLKEN_PLL */
1154
- omap_writel(0x48008530, 0x0000000c);    /* CM_AUTOIDLE_PLL */
1155
- omap_writel(0x48008540,            /* CM_CLKSEL1_PLL */
1156
- (0x78 << 12) | (6 << 8));
1157
- omap_writel(0x48008544, 2);            /* CM_CLKSEL2_PLL */
1158
-
1159
- /* GPMC setup */
1160
- n800_gpmc_init(s);
1161
-
1162
- /* Video setup */
1163
- n800_dss_init(&s->blizzard);
1164
-
1165
- /* CPU setup */
1166
- s->mpu->cpu->env.GE = 0x5;
1167
-
1168
- /* If the machine has a slided keyboard, open it */
1169
- if (s->kbd) {
1170
- qemu_irq_raise(qdev_get_gpio_in(s->mpu->gpio, N810_SLIDE_GPIO));
1171
- }
1172
-}
1173
-
1174
-#define OMAP_TAG_NOKIA_BT    0x4e01
1175
-#define OMAP_TAG_WLAN_CX3110X    0x4e02
1176
-#define OMAP_TAG_CBUS        0x4e03
1177
-#define OMAP_TAG_EM_ASIC_BB5    0x4e04
1178
-
1179
-static const struct omap_gpiosw_info_s {
1180
- const char *name;
1181
- int line;
1182
- int type;
1183
-} n800_gpiosw_info[] = {
1184
- {
1185
- "bat_cover", N800_BAT_COVER_GPIO,
1186
- OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1187
- }, {
1188
- "cam_act", N800_CAM_ACT_GPIO,
1189
- OMAP_GPIOSW_TYPE_ACTIVITY,
1190
- }, {
1191
- "cam_turn", N800_CAM_TURN_GPIO,
1192
- OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED,
1193
- }, {
1194
- "headphone", N8X0_HEADPHONE_GPIO,
1195
- OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
1196
- },
1197
- { /* end of list */ }
1198
-}, n810_gpiosw_info[] = {
1199
- {
1200
- "gps_reset", N810_GPS_RESET_GPIO,
1201
- OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
1202
- }, {
1203
- "gps_wakeup", N810_GPS_WAKEUP_GPIO,
1204
- OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
1205
- }, {
1206
- "headphone", N8X0_HEADPHONE_GPIO,
1207
- OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
1208
- }, {
1209
- "kb_lock", N810_KB_LOCK_GPIO,
1210
- OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1211
- }, {
1212
- "sleepx_led", N810_SLEEPX_LED_GPIO,
1213
- OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED | OMAP_GPIOSW_OUTPUT,
1214
- }, {
1215
- "slide", N810_SLIDE_GPIO,
1216
- OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1217
- },
1218
- { /* end of list */ }
1219
-};
1220
-
1221
-static const struct omap_partition_info_s {
1222
- uint32_t offset;
1223
- uint32_t size;
1224
- int mask;
1225
- const char *name;
1226
-} n800_part_info[] = {
1227
- { 0x00000000, 0x00020000, 0x3, "bootloader" },
1228
- { 0x00020000, 0x00060000, 0x0, "config" },
1229
- { 0x00080000, 0x00200000, 0x0, "kernel" },
1230
- { 0x00280000, 0x00200000, 0x3, "initfs" },
1231
- { 0x00480000, 0x0fb80000, 0x3, "rootfs" },
1232
- { /* end of list */ }
1233
-}, n810_part_info[] = {
1234
- { 0x00000000, 0x00020000, 0x3, "bootloader" },
1235
- { 0x00020000, 0x00060000, 0x0, "config" },
1236
- { 0x00080000, 0x00220000, 0x0, "kernel" },
1237
- { 0x002a0000, 0x00400000, 0x0, "initfs" },
1238
- { 0x006a0000, 0x0f960000, 0x0, "rootfs" },
1239
- { /* end of list */ }
1240
-};
1241
-
1242
-static const uint8_t n8x0_bd_addr[6] = { N8X0_BD_ADDR };
1243
-
1244
-static int n8x0_atag_setup(void *p, int model)
1245
-{
1246
- uint8_t *b;
1247
- uint16_t *w;
1248
- uint32_t *l;
1249
- const struct omap_gpiosw_info_s *gpiosw;
1250
- const struct omap_partition_info_s *partition;
1251
- const char *tag;
1252
-
1253
- w = p;
1254
-
1255
- stw_p(w++, OMAP_TAG_UART);            /* u16 tag */
1256
- stw_p(w++, 4);                /* u16 len */
1257
- stw_p(w++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
1258
- w++;
1259
-
1260
-#if 0
1261
- stw_p(w++, OMAP_TAG_SERIAL_CONSOLE);    /* u16 tag */
1262
- stw_p(w++, 4);                /* u16 len */
1263
- stw_p(w++, XLDR_LL_UART + 1);        /* u8 console_uart */
1264
- stw_p(w++, 115200);                /* u32 console_speed */
1265
-#endif
1266
-
1267
- stw_p(w++, OMAP_TAG_LCD);            /* u16 tag */
1268
- stw_p(w++, 36);                /* u16 len */
1269
- strcpy((void *) w, "QEMU LCD panel");    /* char panel_name[16] */
1270
- w += 8;
1271
- strcpy((void *) w, "blizzard");        /* char ctrl_name[16] */
1272
- w += 8;
1273
- stw_p(w++, N810_BLIZZARD_RESET_GPIO);    /* TODO: n800 s16 nreset_gpio */
1274
- stw_p(w++, 24);                /* u8 data_lines */
1275
-
1276
- stw_p(w++, OMAP_TAG_CBUS);            /* u16 tag */
1277
- stw_p(w++, 8);                /* u16 len */
1278
- stw_p(w++, N8X0_CBUS_CLK_GPIO);        /* s16 clk_gpio */
1279
- stw_p(w++, N8X0_CBUS_DAT_GPIO);        /* s16 dat_gpio */
1280
- stw_p(w++, N8X0_CBUS_SEL_GPIO);        /* s16 sel_gpio */
1281
- w++;
1282
-
1283
- stw_p(w++, OMAP_TAG_EM_ASIC_BB5);        /* u16 tag */
1284
- stw_p(w++, 4);                /* u16 len */
1285
- stw_p(w++, N8X0_RETU_GPIO);            /* s16 retu_irq_gpio */
1286
- stw_p(w++, N8X0_TAHVO_GPIO);        /* s16 tahvo_irq_gpio */
1287
-
1288
- gpiosw = (model == 810) ? n810_gpiosw_info : n800_gpiosw_info;
1289
- for (; gpiosw->name; gpiosw++) {
1290
- stw_p(w++, OMAP_TAG_GPIO_SWITCH);    /* u16 tag */
1291
- stw_p(w++, 20);                /* u16 len */
1292
- strcpy((void *) w, gpiosw->name);    /* char name[12] */
1293
- w += 6;
1294
- stw_p(w++, gpiosw->line);        /* u16 gpio */
1295
- stw_p(w++, gpiosw->type);
1296
- stw_p(w++, 0);
1297
- stw_p(w++, 0);
1298
- }
1299
-
1300
- stw_p(w++, OMAP_TAG_NOKIA_BT);        /* u16 tag */
1301
- stw_p(w++, 12);                /* u16 len */
1302
- b = (void *) w;
1303
- stb_p(b++, 0x01);                /* u8 chip_type    (CSR) */
1304
- stb_p(b++, N8X0_BT_WKUP_GPIO);        /* u8 bt_wakeup_gpio */
1305
- stb_p(b++, N8X0_BT_HOST_WKUP_GPIO);        /* u8 host_wakeup_gpio */
1306
- stb_p(b++, N8X0_BT_RESET_GPIO);        /* u8 reset_gpio */
1307
- stb_p(b++, BT_UART + 1);            /* u8 bt_uart */
1308
- memcpy(b, &n8x0_bd_addr, 6);        /* u8 bd_addr[6] */
1309
- b += 6;
1310
- stb_p(b++, 0x02);                /* u8 bt_sysclk (38.4) */
1311
- w = (void *) b;
1312
-
1313
- stw_p(w++, OMAP_TAG_WLAN_CX3110X);        /* u16 tag */
1314
- stw_p(w++, 8);                /* u16 len */
1315
- stw_p(w++, 0x25);                /* u8 chip_type */
1316
- stw_p(w++, N8X0_WLAN_PWR_GPIO);        /* s16 power_gpio */
1317
- stw_p(w++, N8X0_WLAN_IRQ_GPIO);        /* s16 irq_gpio */
1318
- stw_p(w++, -1);                /* s16 spi_cs_gpio */
1319
-
1320
- stw_p(w++, OMAP_TAG_MMC);            /* u16 tag */
1321
- stw_p(w++, 16);                /* u16 len */
1322
- if (model == 810) {
1323
- stw_p(w++, 0x23f);            /* unsigned flags */
1324
- stw_p(w++, -1);                /* s16 power_pin */
1325
- stw_p(w++, -1);                /* s16 switch_pin */
1326
- stw_p(w++, -1);                /* s16 wp_pin */
1327
- stw_p(w++, 0x240);            /* unsigned flags */
1328
- stw_p(w++, 0xc000);            /* s16 power_pin */
1329
- stw_p(w++, 0x0248);            /* s16 switch_pin */
1330
- stw_p(w++, 0xc000);            /* s16 wp_pin */
1331
- } else {
1332
- stw_p(w++, 0xf);            /* unsigned flags */
1333
- stw_p(w++, -1);                /* s16 power_pin */
1334
- stw_p(w++, -1);                /* s16 switch_pin */
1335
- stw_p(w++, -1);                /* s16 wp_pin */
1336
- stw_p(w++, 0);                /* unsigned flags */
1337
- stw_p(w++, 0);                /* s16 power_pin */
1338
- stw_p(w++, 0);                /* s16 switch_pin */
1339
- stw_p(w++, 0);                /* s16 wp_pin */
1340
- }
1341
-
1342
- stw_p(w++, OMAP_TAG_TEA5761);        /* u16 tag */
1343
- stw_p(w++, 4);                /* u16 len */
1344
- stw_p(w++, N8X0_TEA5761_CS_GPIO);        /* u16 enable_gpio */
1345
- w++;
1346
-
1347
- partition = (model == 810) ? n810_part_info : n800_part_info;
1348
- for (; partition->name; partition++) {
1349
- stw_p(w++, OMAP_TAG_PARTITION);        /* u16 tag */
1350
- stw_p(w++, 28);                /* u16 len */
1351
- strcpy((void *) w, partition->name);    /* char name[16] */
1352
- l = (void *) (w + 8);
1353
- stl_p(l++, partition->size);        /* unsigned int size */
1354
- stl_p(l++, partition->offset);        /* unsigned int offset */
1355
- stl_p(l++, partition->mask);        /* unsigned int mask_flags */
1356
- w = (void *) l;
1357
- }
1358
-
1359
- stw_p(w++, OMAP_TAG_BOOT_REASON);        /* u16 tag */
1360
- stw_p(w++, 12);                /* u16 len */
1361
-#if 0
1362
- strcpy((void *) w, "por");            /* char reason_str[12] */
1363
- strcpy((void *) w, "charger");        /* char reason_str[12] */
1364
- strcpy((void *) w, "32wd_to");        /* char reason_str[12] */
1365
- strcpy((void *) w, "sw_rst");        /* char reason_str[12] */
1366
- strcpy((void *) w, "mbus");            /* char reason_str[12] */
1367
- strcpy((void *) w, "unknown");        /* char reason_str[12] */
1368
- strcpy((void *) w, "swdg_to");        /* char reason_str[12] */
1369
- strcpy((void *) w, "sec_vio");        /* char reason_str[12] */
1370
- strcpy((void *) w, "pwr_key");        /* char reason_str[12] */
1371
- strcpy((void *) w, "rtc_alarm");        /* char reason_str[12] */
1372
-#else
1373
- strcpy((void *) w, "pwr_key");        /* char reason_str[12] */
1374
-#endif
1375
- w += 6;
1376
-
1377
- tag = (model == 810) ? "RX-44" : "RX-34";
1378
- stw_p(w++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1379
- stw_p(w++, 24);                /* u16 len */
1380
- strcpy((void *) w, "product");        /* char component[12] */
1381
- w += 6;
1382
- strcpy((void *) w, tag);            /* char version[12] */
1383
- w += 6;
1384
-
1385
- stw_p(w++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1386
- stw_p(w++, 24);                /* u16 len */
1387
- strcpy((void *) w, "hw-build");        /* char component[12] */
1388
- w += 6;
1389
- strcpy((void *) w, "QEMU ");
1390
- pstrcat((void *) w, 12, qemu_hw_version()); /* char version[12] */
1391
- w += 6;
1392
-
1393
- tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
1394
- stw_p(w++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1395
- stw_p(w++, 24);                /* u16 len */
1396
- strcpy((void *) w, "nolo");            /* char component[12] */
1397
- w += 6;
1398
- strcpy((void *) w, tag);            /* char version[12] */
1399
- w += 6;
1400
-
1401
- return (void *) w - p;
1402
-}
1403
-
1404
-static int n800_atag_setup(const struct arm_boot_info *info, void *p)
1405
-{
1406
- return n8x0_atag_setup(p, 800);
1407
-}
1408
-
1409
-static int n810_atag_setup(const struct arm_boot_info *info, void *p)
1410
-{
1411
- return n8x0_atag_setup(p, 810);
1412
-}
1413
-
1414
-static void n8x0_init(MachineState *machine,
1415
- struct arm_boot_info *binfo, int model)
1416
-{
1417
- struct n800_s *s = g_malloc0(sizeof(*s));
1418
- MachineClass *mc = MACHINE_GET_CLASS(machine);
1419
-
1420
- if (machine->ram_size != mc->default_ram_size) {
1421
- char *sz = size_to_str(mc->default_ram_size);
1422
- error_report("Invalid RAM size, should be %s", sz);
1423
- g_free(sz);
1424
- exit(EXIT_FAILURE);
1425
- }
1426
- binfo->ram_size = machine->ram_size;
1427
-
1428
- memory_region_add_subregion(get_system_memory(), OMAP2_Q2_BASE,
1429
- machine->ram);
1430
-
1431
- s->mpu = omap2420_mpu_init(machine->ram, machine->cpu_type);
1432
-
1433
- /* Setup peripherals
1434
- *
1435
- * Believed external peripherals layout in the N810:
1436
- * (spi bus 1)
1437
- * tsc2005
1438
- * lcd_mipid
1439
- * (spi bus 2)
1440
- * Conexant cx3110x (WLAN)
1441
- * optional: pc2400m (WiMAX)
1442
- * (i2c bus 0)
1443
- * TLV320AIC33 (audio codec)
1444
- * TCM825x (camera by Toshiba)
1445
- * lp5521 (clever LEDs)
1446
- * tsl2563 (light sensor, hwmon, model 7, rev. 0)
1447
- * lm8323 (keypad, manf 00, rev 04)
1448
- * (i2c bus 1)
1449
- * tmp105 (temperature sensor, hwmon)
1450
- * menelaus (pm)
1451
- * (somewhere on i2c - maybe N800-only)
1452
- * tea5761 (FM tuner)
1453
- * (serial 0)
1454
- * GPS
1455
- * (some serial port)
1456
- * csr41814 (Bluetooth)
1457
- */
1458
- n8x0_gpio_setup(s);
1459
- n8x0_nand_setup(s);
1460
- n8x0_i2c_setup(s);
1461
- if (model == 800) {
1462
- n800_tsc_kbd_setup(s);
1463
- } else if (model == 810) {
1464
- n810_tsc_setup(s);
1465
- n810_kbd_setup(s);
1466
- }
1467
- n8x0_spi_setup(s);
1468
- n8x0_dss_setup(s);
1469
- n8x0_cbus_setup(s);
1470
- n8x0_usb_setup(s);
1471
-
1472
- if (machine->kernel_filename) {
1473
- /* Or at the linux loader. */
1474
- arm_load_kernel(s->mpu->cpu, machine, binfo);
1475
-
1476
- qemu_register_reset(n8x0_boot_init, s);
1477
- }
1478
-
1479
- if (option_rom[0].name &&
1480
- (machine->boot_config.order[0] == 'n' || !machine->kernel_filename)) {
1481
- uint8_t *nolo_tags = g_new(uint8_t, 0x10000);
1482
- /* No, wait, better start at the ROM. */
1483
- s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
1484
-
1485
- /*
1486
- * This is intended for loading the `secondary.bin' program from
1487
- * Nokia images (the NOLO bootloader). The entry point seems
1488
- * to be at OMAP2_Q2_BASE + 0x400000.
1489
- *
1490
- * The `2nd.bin' files contain some kind of earlier boot code and
1491
- * for them the entry point needs to be set to OMAP2_SRAM_BASE.
1492
- *
1493
- * The code above is for loading the `zImage' file from Nokia
1494
- * images.
1495
- */
1496
- if (load_image_targphys(option_rom[0].name,
1497
- OMAP2_Q2_BASE + 0x400000,
1498
- machine->ram_size - 0x400000) < 0) {
1499
- error_report("Failed to load secondary bootloader %s",
1500
- option_rom[0].name);
1501
- exit(EXIT_FAILURE);
1502
- }
1503
-
1504
- n800_setup_nolo_tags(nolo_tags);
1505
- cpu_physical_memory_write(OMAP2_SRAM_BASE, nolo_tags, 0x10000);
1506
- g_free(nolo_tags);
1507
- }
1508
-}
1509
-
1510
-static struct arm_boot_info n800_binfo = {
1511
- .loader_start = OMAP2_Q2_BASE,
1512
- .board_id = 0x4f7,
1513
- .atag_board = n800_atag_setup,
1514
-};
1515
-
1516
-static struct arm_boot_info n810_binfo = {
1517
- .loader_start = OMAP2_Q2_BASE,
1518
- /* 0x60c and 0x6bf (WiMAX Edition) have been assigned but are not
1519
- * used by some older versions of the bootloader and 5555 is used
1520
- * instead (including versions that shipped with many devices). */
1521
- .board_id = 0x60c,
1522
- .atag_board = n810_atag_setup,
1523
-};
1524
-
1525
-static void n800_init(MachineState *machine)
1526
-{
1527
- n8x0_init(machine, &n800_binfo, 800);
1528
-}
1529
-
1530
-static void n810_init(MachineState *machine)
1531
-{
1532
- n8x0_init(machine, &n810_binfo, 810);
1533
-}
1534
-
1535
-static void n800_class_init(ObjectClass *oc, void *data)
1536
-{
1537
- MachineClass *mc = MACHINE_CLASS(oc);
1538
-
1539
- mc->desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)";
1540
- mc->init = n800_init;
1541
- mc->default_boot_order = "";
1542
- mc->ignore_memory_transaction_failures = true;
1543
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm1136-r2");
1544
- /* Actually two chips of 0x4000000 bytes each */
1545
- mc->default_ram_size = 0x08000000;
1546
- mc->default_ram_id = "omap2.dram";
1547
- mc->deprecation_reason = "machine is old and unmaintained";
1548
-
1549
- machine_add_audiodev_property(mc);
1550
-}
1551
-
1552
-static const TypeInfo n800_type = {
1553
- .name = MACHINE_TYPE_NAME("n800"),
1554
- .parent = TYPE_MACHINE,
1555
- .class_init = n800_class_init,
1556
-};
1557
-
1558
-static void n810_class_init(ObjectClass *oc, void *data)
1559
-{
1560
- MachineClass *mc = MACHINE_CLASS(oc);
1561
-
1562
- mc->desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)";
1563
- mc->init = n810_init;
1564
- mc->default_boot_order = "";
1565
- mc->ignore_memory_transaction_failures = true;
1566
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm1136-r2");
1567
- /* Actually two chips of 0x4000000 bytes each */
1568
- mc->default_ram_size = 0x08000000;
1569
- mc->default_ram_id = "omap2.dram";
1570
- mc->deprecation_reason = "machine is old and unmaintained";
1571
-
1572
- machine_add_audiodev_property(mc);
1573
-}
1574
-
1575
-static const TypeInfo n810_type = {
1576
- .name = MACHINE_TYPE_NAME("n810"),
1577
- .parent = TYPE_MACHINE,
1578
- .class_init = n810_class_init,
1579
-};
1580
-
1581
-static void nseries_machine_init(void)
1582
-{
1583
- type_register_static(&n800_type);
1584
- type_register_static(&n810_type);
1585
-}
1586
-
1587
-type_init(nseries_machine_init)
1588
diff --git a/tests/qtest/libqos/arm-n800-machine.c b/tests/qtest/libqos/arm-n800-machine.c
1589
deleted file mode 100644
1590
index XXXXXXX..XXXXXXX
1591
--- a/tests/qtest/libqos/arm-n800-machine.c
1592
+++ /dev/null
1593
@@ -XXX,XX +XXX,XX @@
1594
-/*
1595
- * libqos driver framework
1596
- *
1597
- * Copyright (c) 2019 Red Hat, Inc.
1598
- *
1599
- * Author: Paolo Bonzini <pbonzini@redhat.com>
1600
- *
1601
- * This library is free software; you can redistribute it and/or
1602
- * modify it under the terms of the GNU Lesser General Public
1603
- * License version 2.1 as published by the Free Software Foundation.
1604
- *
1605
- * This library is distributed in the hope that it will be useful,
1606
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1607
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1608
- * Lesser General Public License for more details.
1609
- *
1610
- * You should have received a copy of the GNU Lesser General Public
1611
- * License along with this library; if not, see <http://www.gnu.org/licenses/>
1612
- */
1613
-
1614
-#include "qemu/osdep.h"
1615
-#include "../libqtest.h"
1616
-#include "libqos-malloc.h"
1617
-#include "qgraph.h"
1618
-#include "i2c.h"
1619
-
1620
-#define ARM_PAGE_SIZE 4096
1621
-#define N800_RAM_START 0x80000000
1622
-#define N800_RAM_END 0x88000000
1623
-
1624
-typedef struct QN800Machine QN800Machine;
1625
-
1626
-struct QN800Machine {
1627
- QOSGraphObject obj;
1628
- QGuestAllocator alloc;
1629
- OMAPI2C i2c_1;
1630
-};
1631
-
1632
-static void *n800_get_driver(void *object, const char *interface)
1633
-{
1634
- QN800Machine *machine = object;
1635
- if (!g_strcmp0(interface, "memory")) {
1636
- return &machine->alloc;
1637
- }
1638
-
1639
- fprintf(stderr, "%s not present in arm/n800\n", interface);
1640
- g_assert_not_reached();
1641
-}
1642
-
1643
-static QOSGraphObject *n800_get_device(void *obj, const char *device)
1644
-{
1645
- QN800Machine *machine = obj;
1646
- if (!g_strcmp0(device, "omap_i2c")) {
1647
- return &machine->i2c_1.obj;
1648
- }
1649
-
1650
- fprintf(stderr, "%s not present in arm/n800\n", device);
1651
- g_assert_not_reached();
1652
-}
1653
-
1654
-static void n800_destructor(QOSGraphObject *obj)
1655
-{
1656
- QN800Machine *machine = (QN800Machine *) obj;
1657
- alloc_destroy(&machine->alloc);
1658
-}
1659
-
1660
-static void *qos_create_machine_arm_n800(QTestState *qts)
1661
-{
1662
- QN800Machine *machine = g_new0(QN800Machine, 1);
1663
-
1664
- alloc_init(&machine->alloc, 0,
1665
- N800_RAM_START,
1666
- N800_RAM_END,
1667
- ARM_PAGE_SIZE);
1668
- machine->obj.get_device = n800_get_device;
1669
- machine->obj.get_driver = n800_get_driver;
1670
- machine->obj.destructor = n800_destructor;
1671
-
1672
- omap_i2c_init(&machine->i2c_1, qts, 0x48070000);
1673
- return &machine->obj;
1674
-}
1675
-
1676
-static void n800_register_nodes(void)
1677
-{
1678
- QOSGraphEdgeOptions edge = {
1679
- .extra_device_opts = "bus=i2c-bus.0"
1680
- };
1681
- qos_node_create_machine("arm/n800", qos_create_machine_arm_n800);
1682
- qos_node_contains("arm/n800", "omap_i2c", &edge, NULL);
1683
-}
1684
-
1685
-libqos_init(n800_register_nodes);
1686
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
1687
index XXXXXXX..XXXXXXX 100644
1688
--- a/hw/arm/meson.build
1689
+++ b/hw/arm/meson.build
1690
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
1691
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
1692
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
1693
arm_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx.c', 'npcm7xx_boards.c'))
1694
-arm_ss.add(when: 'CONFIG_NSERIES', if_true: files('nseries.c'))
1695
arm_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview.c'))
1696
arm_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa-ref.c'))
1697
arm_ss.add(when: 'CONFIG_STELLARIS', if_true: files('stellaris.c'))
1698
diff --git a/tests/avocado/machine_arm_n8x0.py b/tests/avocado/machine_arm_n8x0.py
1699
deleted file mode 100755
1700
index XXXXXXX..XXXXXXX
1701
--- a/tests/avocado/machine_arm_n8x0.py
1702
+++ /dev/null
1703
@@ -XXX,XX +XXX,XX @@
1704
-# Functional test that boots a Linux kernel and checks the console
1705
-#
1706
-# Copyright (c) 2020 Red Hat, Inc.
1707
-#
1708
-# Author:
1709
-# Thomas Huth <thuth@redhat.com>
1710
-#
1711
-# This work is licensed under the terms of the GNU GPL, version 2 or
1712
-# later. See the COPYING file in the top-level directory.
1713
-
1714
-import os
1715
-
1716
-from avocado import skipUnless
1717
-from avocado_qemu import QemuSystemTest
1718
-from avocado_qemu import wait_for_console_pattern
1719
-
1720
-class N8x0Machine(QemuSystemTest):
1721
- """Boots the Linux kernel and checks that the console is operational"""
1722
-
1723
- timeout = 90
1724
-
1725
- def __do_test_n8x0(self):
1726
- kernel_url = ('http://stskeeps.subnetmask.net/meego-n8x0/'
1727
- 'meego-arm-n8x0-1.0.80.20100712.1431-'
1728
- 'vmlinuz-2.6.35~rc4-129.1-n8x0')
1729
- kernel_hash = 'e9d5ab8d7548923a0061b6fbf601465e479ed269'
1730
- kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
1731
-
1732
- self.vm.set_console(console_index=1)
1733
- self.vm.add_args('-kernel', kernel_path,
1734
- '-append', 'printk.time=0 console=ttyS1')
1735
- self.vm.launch()
1736
- wait_for_console_pattern(self, 'TSC2005 driver initializing')
1737
-
1738
- @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
1739
- def test_n800(self):
1740
- """
1741
- :avocado: tags=arch:arm
1742
- :avocado: tags=machine:n800
1743
- """
1744
- self.__do_test_n8x0()
1745
-
1746
- @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
1747
- def test_n810(self):
1748
- """
1749
- :avocado: tags=arch:arm
1750
- :avocado: tags=machine:n810
1751
- """
1752
- self.__do_test_n8x0()
1753
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
1754
index XXXXXXX..XXXXXXX 100644
1755
--- a/tests/qtest/libqos/meson.build
1756
+++ b/tests/qtest/libqos/meson.build
1757
@@ -XXX,XX +XXX,XX @@ libqos_srcs = files(
1758
# qgraph machines:
1759
'aarch64-xlnx-zcu102-machine.c',
1760
'arm-imx25-pdk-machine.c',
1761
- 'arm-n800-machine.c',
1762
'arm-raspi2-machine.c',
1763
'arm-sabrelite-machine.c',
1764
'arm-smdkc210-machine.c',
1765
--
39
--
1766
2.34.1
40
2.34.1
1767
1768
diff view generated by jsdifflib
1
Remove the pxa2xx-specific GPIO device.
1
Set the default NaN pattern explicitly for the alpha target.
2
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20240903160751.4100218-22-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-40-peter.maydell@linaro.org
6
---
6
---
7
include/hw/arm/pxa.h | 5 -
7
target/alpha/cpu.c | 2 ++
8
hw/arm/pxa2xx_gpio.c | 365 -------------------------------------------
8
1 file changed, 2 insertions(+)
9
hw/arm/meson.build | 2 +-
10
3 files changed, 1 insertion(+), 371 deletions(-)
11
delete mode 100644 hw/arm/pxa2xx_gpio.c
12
9
13
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
10
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/pxa.h
12
--- a/target/alpha/cpu.c
16
+++ b/include/hw/arm/pxa.h
13
+++ b/target/alpha/cpu.c
17
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_initfn(Object *obj)
18
/* pxa2xx_pic.c */
15
* operand in Fa. That is float_2nan_prop_ba.
19
DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu);
16
*/
20
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
21
-/* pxa2xx_gpio.c */
18
+ /* Default NaN: sign bit clear, msb frac bit set */
22
-DeviceState *pxa2xx_gpio_init(hwaddr base,
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
23
- ARMCPU *cpu, DeviceState *pic, int lines);
20
#if defined(CONFIG_USER_ONLY)
24
-void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler);
21
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
25
-
22
cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD
26
#endif /* PXA_H */
27
diff --git a/hw/arm/pxa2xx_gpio.c b/hw/arm/pxa2xx_gpio.c
28
deleted file mode 100644
29
index XXXXXXX..XXXXXXX
30
--- a/hw/arm/pxa2xx_gpio.c
31
+++ /dev/null
32
@@ -XXX,XX +XXX,XX @@
33
-/*
34
- * Intel XScale PXA255/270 GPIO controller emulation.
35
- *
36
- * Copyright (c) 2006 Openedhand Ltd.
37
- * Written by Andrzej Zaborowski <balrog@zabor.org>
38
- *
39
- * This code is licensed under the GPL.
40
- */
41
-
42
-#include "qemu/osdep.h"
43
-#include "cpu.h"
44
-#include "hw/irq.h"
45
-#include "hw/qdev-properties.h"
46
-#include "hw/sysbus.h"
47
-#include "migration/vmstate.h"
48
-#include "hw/arm/pxa.h"
49
-#include "qapi/error.h"
50
-#include "qemu/log.h"
51
-#include "qemu/module.h"
52
-#include "qom/object.h"
53
-
54
-#define PXA2XX_GPIO_BANKS    4
55
-
56
-#define TYPE_PXA2XX_GPIO "pxa2xx-gpio"
57
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxGPIOInfo, PXA2XX_GPIO)
58
-
59
-struct PXA2xxGPIOInfo {
60
- /*< private >*/
61
- SysBusDevice parent_obj;
62
- /*< public >*/
63
-
64
- MemoryRegion iomem;
65
- qemu_irq irq0, irq1, irqX;
66
- int lines;
67
- ARMCPU *cpu;
68
-
69
- /* XXX: GNU C vectors are more suitable */
70
- uint32_t ilevel[PXA2XX_GPIO_BANKS];
71
- uint32_t olevel[PXA2XX_GPIO_BANKS];
72
- uint32_t dir[PXA2XX_GPIO_BANKS];
73
- uint32_t rising[PXA2XX_GPIO_BANKS];
74
- uint32_t falling[PXA2XX_GPIO_BANKS];
75
- uint32_t status[PXA2XX_GPIO_BANKS];
76
- uint32_t gafr[PXA2XX_GPIO_BANKS * 2];
77
-
78
- uint32_t prev_level[PXA2XX_GPIO_BANKS];
79
- qemu_irq handler[PXA2XX_GPIO_BANKS * 32];
80
- qemu_irq read_notify;
81
-};
82
-
83
-static struct {
84
- enum {
85
- GPIO_NONE,
86
- GPLR,
87
- GPSR,
88
- GPCR,
89
- GPDR,
90
- GRER,
91
- GFER,
92
- GEDR,
93
- GAFR_L,
94
- GAFR_U,
95
- } reg;
96
- int bank;
97
-} pxa2xx_gpio_regs[0x200] = {
98
- [0 ... 0x1ff] = { GPIO_NONE, 0 },
99
-#define PXA2XX_REG(reg, a0, a1, a2, a3)    \
100
- [a0] = { reg, 0 }, [a1] = { reg, 1 }, [a2] = { reg, 2 }, [a3] = { reg, 3 },
101
-
102
- PXA2XX_REG(GPLR, 0x000, 0x004, 0x008, 0x100)
103
- PXA2XX_REG(GPSR, 0x018, 0x01c, 0x020, 0x118)
104
- PXA2XX_REG(GPCR, 0x024, 0x028, 0x02c, 0x124)
105
- PXA2XX_REG(GPDR, 0x00c, 0x010, 0x014, 0x10c)
106
- PXA2XX_REG(GRER, 0x030, 0x034, 0x038, 0x130)
107
- PXA2XX_REG(GFER, 0x03c, 0x040, 0x044, 0x13c)
108
- PXA2XX_REG(GEDR, 0x048, 0x04c, 0x050, 0x148)
109
- PXA2XX_REG(GAFR_L, 0x054, 0x05c, 0x064, 0x06c)
110
- PXA2XX_REG(GAFR_U, 0x058, 0x060, 0x068, 0x070)
111
-};
112
-
113
-static void pxa2xx_gpio_irq_update(PXA2xxGPIOInfo *s)
114
-{
115
- if (s->status[0] & (1 << 0))
116
- qemu_irq_raise(s->irq0);
117
- else
118
- qemu_irq_lower(s->irq0);
119
-
120
- if (s->status[0] & (1 << 1))
121
- qemu_irq_raise(s->irq1);
122
- else
123
- qemu_irq_lower(s->irq1);
124
-
125
- if ((s->status[0] & ~3) | s->status[1] | s->status[2] | s->status[3])
126
- qemu_irq_raise(s->irqX);
127
- else
128
- qemu_irq_lower(s->irqX);
129
-}
130
-
131
-/* Bitmap of pins used as standby and sleep wake-up sources. */
132
-static const int pxa2xx_gpio_wake[PXA2XX_GPIO_BANKS] = {
133
- 0x8003fe1b, 0x002001fc, 0xec080000, 0x0012007f,
134
-};
135
-
136
-static void pxa2xx_gpio_set(void *opaque, int line, int level)
137
-{
138
- PXA2xxGPIOInfo *s = (PXA2xxGPIOInfo *) opaque;
139
- CPUState *cpu = CPU(s->cpu);
140
- int bank;
141
- uint32_t mask;
142
-
143
- if (line >= s->lines) {
144
- printf("%s: No GPIO pin %i\n", __func__, line);
145
- return;
146
- }
147
-
148
- bank = line >> 5;
149
- mask = 1U << (line & 31);
150
-
151
- if (level) {
152
- s->status[bank] |= s->rising[bank] & mask &
153
- ~s->ilevel[bank] & ~s->dir[bank];
154
- s->ilevel[bank] |= mask;
155
- } else {
156
- s->status[bank] |= s->falling[bank] & mask &
157
- s->ilevel[bank] & ~s->dir[bank];
158
- s->ilevel[bank] &= ~mask;
159
- }
160
-
161
- if (s->status[bank] & mask)
162
- pxa2xx_gpio_irq_update(s);
163
-
164
- /* Wake-up GPIOs */
165
- if (cpu->halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank])) {
166
- cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
167
- }
168
-}
169
-
170
-static void pxa2xx_gpio_handler_update(PXA2xxGPIOInfo *s) {
171
- uint32_t level, diff;
172
- int i, bit, line;
173
- for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) {
174
- level = s->olevel[i] & s->dir[i];
175
-
176
- for (diff = s->prev_level[i] ^ level; diff; diff ^= 1 << bit) {
177
- bit = ctz32(diff);
178
- line = bit + 32 * i;
179
- qemu_set_irq(s->handler[line], (level >> bit) & 1);
180
- }
181
-
182
- s->prev_level[i] = level;
183
- }
184
-}
185
-
186
-static uint64_t pxa2xx_gpio_read(void *opaque, hwaddr offset,
187
- unsigned size)
188
-{
189
- PXA2xxGPIOInfo *s = (PXA2xxGPIOInfo *) opaque;
190
- uint32_t ret;
191
- int bank;
192
- if (offset >= 0x200)
193
- return 0;
194
-
195
- bank = pxa2xx_gpio_regs[offset].bank;
196
- switch (pxa2xx_gpio_regs[offset].reg) {
197
- case GPDR:        /* GPIO Pin-Direction registers */
198
- return s->dir[bank];
199
-
200
- case GPSR:        /* GPIO Pin-Output Set registers */
201
- qemu_log_mask(LOG_GUEST_ERROR,
202
- "pxa2xx GPIO: read from write only register GPSR\n");
203
- return 0;
204
-
205
- case GPCR:        /* GPIO Pin-Output Clear registers */
206
- qemu_log_mask(LOG_GUEST_ERROR,
207
- "pxa2xx GPIO: read from write only register GPCR\n");
208
- return 0;
209
-
210
- case GRER:        /* GPIO Rising-Edge Detect Enable registers */
211
- return s->rising[bank];
212
-
213
- case GFER:        /* GPIO Falling-Edge Detect Enable registers */
214
- return s->falling[bank];
215
-
216
- case GAFR_L:    /* GPIO Alternate Function registers */
217
- return s->gafr[bank * 2];
218
-
219
- case GAFR_U:    /* GPIO Alternate Function registers */
220
- return s->gafr[bank * 2 + 1];
221
-
222
- case GPLR:        /* GPIO Pin-Level registers */
223
- ret = (s->olevel[bank] & s->dir[bank]) |
224
- (s->ilevel[bank] & ~s->dir[bank]);
225
- qemu_irq_raise(s->read_notify);
226
- return ret;
227
-
228
- case GEDR:        /* GPIO Edge Detect Status registers */
229
- return s->status[bank];
230
-
231
- default:
232
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
233
- __func__, offset);
234
- }
235
-
236
- return 0;
237
-}
238
-
239
-static void pxa2xx_gpio_write(void *opaque, hwaddr offset,
240
- uint64_t value, unsigned size)
241
-{
242
- PXA2xxGPIOInfo *s = (PXA2xxGPIOInfo *) opaque;
243
- int bank;
244
- if (offset >= 0x200)
245
- return;
246
-
247
- bank = pxa2xx_gpio_regs[offset].bank;
248
- switch (pxa2xx_gpio_regs[offset].reg) {
249
- case GPDR:        /* GPIO Pin-Direction registers */
250
- s->dir[bank] = value;
251
- pxa2xx_gpio_handler_update(s);
252
- break;
253
-
254
- case GPSR:        /* GPIO Pin-Output Set registers */
255
- s->olevel[bank] |= value;
256
- pxa2xx_gpio_handler_update(s);
257
- break;
258
-
259
- case GPCR:        /* GPIO Pin-Output Clear registers */
260
- s->olevel[bank] &= ~value;
261
- pxa2xx_gpio_handler_update(s);
262
- break;
263
-
264
- case GRER:        /* GPIO Rising-Edge Detect Enable registers */
265
- s->rising[bank] = value;
266
- break;
267
-
268
- case GFER:        /* GPIO Falling-Edge Detect Enable registers */
269
- s->falling[bank] = value;
270
- break;
271
-
272
- case GAFR_L:    /* GPIO Alternate Function registers */
273
- s->gafr[bank * 2] = value;
274
- break;
275
-
276
- case GAFR_U:    /* GPIO Alternate Function registers */
277
- s->gafr[bank * 2 + 1] = value;
278
- break;
279
-
280
- case GEDR:        /* GPIO Edge Detect Status registers */
281
- s->status[bank] &= ~value;
282
- pxa2xx_gpio_irq_update(s);
283
- break;
284
-
285
- default:
286
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
287
- __func__, offset);
288
- }
289
-}
290
-
291
-static const MemoryRegionOps pxa_gpio_ops = {
292
- .read = pxa2xx_gpio_read,
293
- .write = pxa2xx_gpio_write,
294
- .endianness = DEVICE_NATIVE_ENDIAN,
295
-};
296
-
297
-DeviceState *pxa2xx_gpio_init(hwaddr base,
298
- ARMCPU *cpu, DeviceState *pic, int lines)
299
-{
300
- DeviceState *dev;
301
-
302
- dev = qdev_new(TYPE_PXA2XX_GPIO);
303
- qdev_prop_set_int32(dev, "lines", lines);
304
- object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort);
305
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
306
-
307
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
308
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
309
- qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_0));
310
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1,
311
- qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_1));
312
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2,
313
- qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_X));
314
-
315
- return dev;
316
-}
317
-
318
-static void pxa2xx_gpio_initfn(Object *obj)
319
-{
320
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
321
- DeviceState *dev = DEVICE(sbd);
322
- PXA2xxGPIOInfo *s = PXA2XX_GPIO(dev);
323
-
324
- memory_region_init_io(&s->iomem, obj, &pxa_gpio_ops,
325
- s, "pxa2xx-gpio", 0x1000);
326
- sysbus_init_mmio(sbd, &s->iomem);
327
- sysbus_init_irq(sbd, &s->irq0);
328
- sysbus_init_irq(sbd, &s->irq1);
329
- sysbus_init_irq(sbd, &s->irqX);
330
-}
331
-
332
-static void pxa2xx_gpio_realize(DeviceState *dev, Error **errp)
333
-{
334
- PXA2xxGPIOInfo *s = PXA2XX_GPIO(dev);
335
-
336
- qdev_init_gpio_in(dev, pxa2xx_gpio_set, s->lines);
337
- qdev_init_gpio_out(dev, s->handler, s->lines);
338
-}
339
-
340
-/*
341
- * Registers a callback to notify on GPLR reads. This normally
342
- * shouldn't be needed but it is used for the hack on Spitz machines.
343
- */
344
-void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler)
345
-{
346
- PXA2xxGPIOInfo *s = PXA2XX_GPIO(dev);
347
-
348
- s->read_notify = handler;
349
-}
350
-
351
-static const VMStateDescription vmstate_pxa2xx_gpio_regs = {
352
- .name = "pxa2xx-gpio",
353
- .version_id = 1,
354
- .minimum_version_id = 1,
355
- .fields = (const VMStateField[]) {
356
- VMSTATE_UINT32_ARRAY(ilevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
357
- VMSTATE_UINT32_ARRAY(olevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
358
- VMSTATE_UINT32_ARRAY(dir, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
359
- VMSTATE_UINT32_ARRAY(rising, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
360
- VMSTATE_UINT32_ARRAY(falling, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
361
- VMSTATE_UINT32_ARRAY(status, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
362
- VMSTATE_UINT32_ARRAY(gafr, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS * 2),
363
- VMSTATE_UINT32_ARRAY(prev_level, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
364
- VMSTATE_END_OF_LIST(),
365
- },
366
-};
367
-
368
-static Property pxa2xx_gpio_properties[] = {
369
- DEFINE_PROP_INT32("lines", PXA2xxGPIOInfo, lines, 0),
370
- DEFINE_PROP_LINK("cpu", PXA2xxGPIOInfo, cpu, TYPE_ARM_CPU, ARMCPU *),
371
- DEFINE_PROP_END_OF_LIST(),
372
-};
373
-
374
-static void pxa2xx_gpio_class_init(ObjectClass *klass, void *data)
375
-{
376
- DeviceClass *dc = DEVICE_CLASS(klass);
377
-
378
- dc->desc = "PXA2xx GPIO controller";
379
- device_class_set_props(dc, pxa2xx_gpio_properties);
380
- dc->vmsd = &vmstate_pxa2xx_gpio_regs;
381
- dc->realize = pxa2xx_gpio_realize;
382
-}
383
-
384
-static const TypeInfo pxa2xx_gpio_info = {
385
- .name = TYPE_PXA2XX_GPIO,
386
- .parent = TYPE_SYS_BUS_DEVICE,
387
- .instance_size = sizeof(PXA2xxGPIOInfo),
388
- .instance_init = pxa2xx_gpio_initfn,
389
- .class_init = pxa2xx_gpio_class_init,
390
-};
391
-
392
-static void pxa2xx_gpio_register_types(void)
393
-{
394
- type_register_static(&pxa2xx_gpio_info);
395
-}
396
-
397
-type_init(pxa2xx_gpio_register_types)
398
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
399
index XXXXXXX..XXXXXXX 100644
400
--- a/hw/arm/meson.build
401
+++ b/hw/arm/meson.build
402
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_SABRELITE', if_true: files('sabrelite.c'))
403
404
arm_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m.c'))
405
arm_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210.c'))
406
-arm_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_gpio.c', 'pxa2xx_pic.c'))
407
+arm_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_pic.c'))
408
arm_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic.c'))
409
arm_ss.add(when: 'CONFIG_OMAP', if_true: files('omap1.c'))
410
arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubieboard.c'))
411
--
23
--
412
2.34.1
24
2.34.1
413
414
diff view generated by jsdifflib
1
Remove the OMAP2 specific code from omap_intc.c.
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: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Message-id: 20240903160751.4100218-41-peter.maydell@linaro.org
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-41-peter.maydell@linaro.org
5
---
9
---
6
hw/intc/omap_intc.c | 276 --------------------------------------------
10
linux-user/arm/nwfpe/fpa11.c | 5 +++++
7
1 file changed, 276 deletions(-)
11
target/arm/cpu.c | 2 ++
12
2 files changed, 7 insertions(+)
8
13
9
diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c
14
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
10
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/intc/omap_intc.c
16
--- a/linux-user/arm/nwfpe/fpa11.c
12
+++ b/hw/intc/omap_intc.c
17
+++ b/linux-user/arm/nwfpe/fpa11.c
13
@@ -XXX,XX +XXX,XX @@ struct OMAPIntcState {
18
@@ -XXX,XX +XXX,XX @@ void resetFPA11(void)
14
int level_only;
19
* this late date.
15
uint32_t size;
20
*/
16
21
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
17
- uint8_t revision;
22
+ /*
18
-
23
+ * Use the same default NaN value as Arm VFP. This doesn't match
19
/* state */
24
+ * the Linux kernel's nwfpe emulation, which uses an all-1s value.
20
uint32_t new_agr[2];
25
+ */
21
int sir_intr[2];
26
+ set_float_default_nan_pattern(0b01000000, &fpa11->fp_status);
22
@@ -XXX,XX +XXX,XX @@ static void omap_set_intr(void *opaque, int irq, int req)
23
}
24
}
27
}
25
28
26
-/* Simplified version with no edge detection */
29
void SetRoundingMode(const unsigned int opcode)
27
-static void omap_set_intr_noedge(void *opaque, int irq, int req)
30
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
28
-{
31
index XXXXXXX..XXXXXXX 100644
29
- OMAPIntcState *ih = opaque;
32
--- a/target/arm/cpu.c
30
- uint32_t rise;
33
+++ b/target/arm/cpu.c
31
-
34
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
32
- struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
35
* the pseudocode function the arguments are in the order c, a, b.
33
- int n = irq & 31;
36
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
34
-
37
* and the input NaN if it is signalling
35
- if (req) {
38
+ * * Default NaN has sign bit clear, msb frac bit set
36
- rise = ~bank->inputs & (1 << n);
39
*/
37
- if (rise) {
40
static void arm_set_default_fp_behaviours(float_status *s)
38
- bank->irqs |= bank->inputs |= rise;
39
- omap_inth_update(ih, 0);
40
- omap_inth_update(ih, 1);
41
- }
42
- } else
43
- bank->irqs = (bank->inputs &= ~(1 << n)) | bank->swi;
44
-}
45
-
46
static uint64_t omap_inth_read(void *opaque, hwaddr addr,
47
unsigned size)
48
{
41
{
49
@@ -XXX,XX +XXX,XX @@ static const TypeInfo omap_intc_info = {
42
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
50
.class_init = omap_intc_class_init,
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
51
};
44
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
52
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
53
-static uint64_t omap2_inth_read(void *opaque, hwaddr addr,
46
+ set_float_default_nan_pattern(0b01000000, s);
54
- unsigned size)
55
-{
56
- OMAPIntcState *s = opaque;
57
- int offset = addr;
58
- int bank_no, line_no;
59
- struct omap_intr_handler_bank_s *bank = NULL;
60
-
61
- if ((offset & 0xf80) == 0x80) {
62
- bank_no = (offset & 0x60) >> 5;
63
- if (bank_no < s->nbanks) {
64
- offset &= ~0x60;
65
- bank = &s->bank[bank_no];
66
- } else {
67
- OMAP_BAD_REG(addr);
68
- return 0;
69
- }
70
- }
71
-
72
- switch (offset) {
73
- case 0x00:    /* INTC_REVISION */
74
- return s->revision;
75
-
76
- case 0x10:    /* INTC_SYSCONFIG */
77
- return (s->autoidle >> 2) & 1;
78
-
79
- case 0x14:    /* INTC_SYSSTATUS */
80
- return 1;                        /* RESETDONE */
81
-
82
- case 0x40:    /* INTC_SIR_IRQ */
83
- return s->sir_intr[0];
84
-
85
- case 0x44:    /* INTC_SIR_FIQ */
86
- return s->sir_intr[1];
87
-
88
- case 0x48:    /* INTC_CONTROL */
89
- return (!s->mask) << 2;                    /* GLOBALMASK */
90
-
91
- case 0x4c:    /* INTC_PROTECTION */
92
- return 0;
93
-
94
- case 0x50:    /* INTC_IDLE */
95
- return s->autoidle & 3;
96
-
97
- /* Per-bank registers */
98
- case 0x80:    /* INTC_ITR */
99
- return bank->inputs;
100
-
101
- case 0x84:    /* INTC_MIR */
102
- return bank->mask;
103
-
104
- case 0x88:    /* INTC_MIR_CLEAR */
105
- case 0x8c:    /* INTC_MIR_SET */
106
- return 0;
107
-
108
- case 0x90:    /* INTC_ISR_SET */
109
- return bank->swi;
110
-
111
- case 0x94:    /* INTC_ISR_CLEAR */
112
- return 0;
113
-
114
- case 0x98:    /* INTC_PENDING_IRQ */
115
- return bank->irqs & ~bank->mask & ~bank->fiq;
116
-
117
- case 0x9c:    /* INTC_PENDING_FIQ */
118
- return bank->irqs & ~bank->mask & bank->fiq;
119
-
120
- /* Per-line registers */
121
- case 0x100 ... 0x300:    /* INTC_ILR */
122
- bank_no = (offset - 0x100) >> 7;
123
- if (bank_no > s->nbanks)
124
- break;
125
- bank = &s->bank[bank_no];
126
- line_no = (offset & 0x7f) >> 2;
127
- return (bank->priority[line_no] << 2) |
128
- ((bank->fiq >> line_no) & 1);
129
- }
130
- OMAP_BAD_REG(addr);
131
- return 0;
132
-}
133
-
134
-static void omap2_inth_write(void *opaque, hwaddr addr,
135
- uint64_t value, unsigned size)
136
-{
137
- OMAPIntcState *s = opaque;
138
- int offset = addr;
139
- int bank_no, line_no;
140
- struct omap_intr_handler_bank_s *bank = NULL;
141
-
142
- if ((offset & 0xf80) == 0x80) {
143
- bank_no = (offset & 0x60) >> 5;
144
- if (bank_no < s->nbanks) {
145
- offset &= ~0x60;
146
- bank = &s->bank[bank_no];
147
- } else {
148
- OMAP_BAD_REG(addr);
149
- return;
150
- }
151
- }
152
-
153
- switch (offset) {
154
- case 0x10:    /* INTC_SYSCONFIG */
155
- s->autoidle &= 4;
156
- s->autoidle |= (value & 1) << 2;
157
- if (value & 2) { /* SOFTRESET */
158
- omap_inth_reset(DEVICE(s));
159
- }
160
- return;
161
-
162
- case 0x48:    /* INTC_CONTROL */
163
- s->mask = (value & 4) ? 0 : ~0;                /* GLOBALMASK */
164
- if (value & 2) {                    /* NEWFIQAGR */
165
- qemu_set_irq(s->parent_intr[1], 0);
166
- s->new_agr[1] = ~0;
167
- omap_inth_update(s, 1);
168
- }
169
- if (value & 1) {                    /* NEWIRQAGR */
170
- qemu_set_irq(s->parent_intr[0], 0);
171
- s->new_agr[0] = ~0;
172
- omap_inth_update(s, 0);
173
- }
174
- return;
175
-
176
- case 0x4c:    /* INTC_PROTECTION */
177
- /* TODO: Make a bitmap (or sizeof(char)map) of access privileges
178
- * for every register, see Chapter 3 and 4 for privileged mode. */
179
- if (value & 1)
180
- fprintf(stderr, "%s: protection mode enable attempt\n",
181
- __func__);
182
- return;
183
-
184
- case 0x50:    /* INTC_IDLE */
185
- s->autoidle &= ~3;
186
- s->autoidle |= value & 3;
187
- return;
188
-
189
- /* Per-bank registers */
190
- case 0x84:    /* INTC_MIR */
191
- bank->mask = value;
192
- omap_inth_update(s, 0);
193
- omap_inth_update(s, 1);
194
- return;
195
-
196
- case 0x88:    /* INTC_MIR_CLEAR */
197
- bank->mask &= ~value;
198
- omap_inth_update(s, 0);
199
- omap_inth_update(s, 1);
200
- return;
201
-
202
- case 0x8c:    /* INTC_MIR_SET */
203
- bank->mask |= value;
204
- return;
205
-
206
- case 0x90:    /* INTC_ISR_SET */
207
- bank->irqs |= bank->swi |= value;
208
- omap_inth_update(s, 0);
209
- omap_inth_update(s, 1);
210
- return;
211
-
212
- case 0x94:    /* INTC_ISR_CLEAR */
213
- bank->swi &= ~value;
214
- bank->irqs = bank->swi & bank->inputs;
215
- return;
216
-
217
- /* Per-line registers */
218
- case 0x100 ... 0x300:    /* INTC_ILR */
219
- bank_no = (offset - 0x100) >> 7;
220
- if (bank_no > s->nbanks)
221
- break;
222
- bank = &s->bank[bank_no];
223
- line_no = (offset & 0x7f) >> 2;
224
- bank->priority[line_no] = (value >> 2) & 0x3f;
225
- bank->fiq &= ~(1 << line_no);
226
- bank->fiq |= (value & 1) << line_no;
227
- return;
228
-
229
- case 0x00:    /* INTC_REVISION */
230
- case 0x14:    /* INTC_SYSSTATUS */
231
- case 0x40:    /* INTC_SIR_IRQ */
232
- case 0x44:    /* INTC_SIR_FIQ */
233
- case 0x80:    /* INTC_ITR */
234
- case 0x98:    /* INTC_PENDING_IRQ */
235
- case 0x9c:    /* INTC_PENDING_FIQ */
236
- OMAP_RO_REG(addr);
237
- return;
238
- }
239
- OMAP_BAD_REG(addr);
240
-}
241
-
242
-static const MemoryRegionOps omap2_inth_mem_ops = {
243
- .read = omap2_inth_read,
244
- .write = omap2_inth_write,
245
- .endianness = DEVICE_NATIVE_ENDIAN,
246
- .valid = {
247
- .min_access_size = 4,
248
- .max_access_size = 4,
249
- },
250
-};
251
-
252
-static void omap2_intc_init(Object *obj)
253
-{
254
- DeviceState *dev = DEVICE(obj);
255
- OMAPIntcState *s = OMAP_INTC(obj);
256
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
257
-
258
- s->level_only = 1;
259
- s->nbanks = 3;
260
- sysbus_init_irq(sbd, &s->parent_intr[0]);
261
- sysbus_init_irq(sbd, &s->parent_intr[1]);
262
- qdev_init_gpio_in(dev, omap_set_intr_noedge, s->nbanks * 32);
263
- memory_region_init_io(&s->mmio, obj, &omap2_inth_mem_ops, s,
264
- "omap2-intc", 0x1000);
265
- sysbus_init_mmio(sbd, &s->mmio);
266
-}
267
-
268
-static void omap2_intc_realize(DeviceState *dev, Error **errp)
269
-{
270
- OMAPIntcState *s = OMAP_INTC(dev);
271
-
272
- if (!s->iclk) {
273
- error_setg(errp, "omap2-intc: iclk not connected");
274
- return;
275
- }
276
- if (!s->fclk) {
277
- error_setg(errp, "omap2-intc: fclk not connected");
278
- return;
279
- }
280
-}
281
-
282
-static Property omap2_intc_properties[] = {
283
- DEFINE_PROP_UINT8("revision", OMAPIntcState,
284
- revision, 0x21),
285
- DEFINE_PROP_END_OF_LIST(),
286
-};
287
-
288
-static void omap2_intc_class_init(ObjectClass *klass, void *data)
289
-{
290
- DeviceClass *dc = DEVICE_CLASS(klass);
291
-
292
- device_class_set_legacy_reset(dc, omap_inth_reset);
293
- device_class_set_props(dc, omap2_intc_properties);
294
- /* Reason: pointer property "iclk", "fclk" */
295
- dc->user_creatable = false;
296
- dc->realize = omap2_intc_realize;
297
-}
298
-
299
-static const TypeInfo omap2_intc_info = {
300
- .name = "omap2-intc",
301
- .parent = TYPE_OMAP_INTC,
302
- .instance_init = omap2_intc_init,
303
- .class_init = omap2_intc_class_init,
304
-};
305
-
306
static const TypeInfo omap_intc_type_info = {
307
.name = TYPE_OMAP_INTC,
308
.parent = TYPE_SYS_BUS_DEVICE,
309
@@ -XXX,XX +XXX,XX @@ static void omap_intc_register_types(void)
310
{
311
type_register_static(&omap_intc_type_info);
312
type_register_static(&omap_intc_info);
313
- type_register_static(&omap2_intc_info);
314
}
47
}
315
48
316
type_init(omap_intc_register_types)
49
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
317
--
50
--
318
2.34.1
51
2.34.1
diff view generated by jsdifflib
1
The pxa27x-timer can be removed now we have removed the PXA2xx
1
Set the default NaN pattern explicitly for loongarch.
2
SoC models. The pxa25x-timer device must remain as it is still
3
used by strongarm.
4
2
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20240903160751.4100218-24-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
hw/timer/pxa2xx_timer.c | 24 ------------------------
7
target/loongarch/tcg/fpu_helper.c | 2 ++
9
1 file changed, 24 deletions(-)
8
1 file changed, 2 insertions(+)
10
9
11
diff --git a/hw/timer/pxa2xx_timer.c b/hw/timer/pxa2xx_timer.c
10
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/timer/pxa2xx_timer.c
12
--- a/target/loongarch/tcg/fpu_helper.c
14
+++ b/hw/timer/pxa2xx_timer.c
13
+++ b/target/loongarch/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
16
#define OSNR    0x20
15
*/
17
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
18
#define PXA25X_FREQ    3686400    /* 3.6864 MHz */
17
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
19
-#define PXA27X_FREQ    3250000    /* 3.25 MHz */
18
+ /* Default NaN: sign bit clear, msb frac bit set */
20
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
21
static int pxa2xx_timer4_freq[8] = {
22
[0] = 0,
23
@@ -XXX,XX +XXX,XX @@ static const TypeInfo pxa25x_timer_dev_info = {
24
.class_init = pxa25x_timer_dev_class_init,
25
};
26
27
-static Property pxa27x_timer_dev_properties[] = {
28
- DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ),
29
- DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
30
- PXA2XX_TIMER_HAVE_TM4, true),
31
- DEFINE_PROP_END_OF_LIST(),
32
-};
33
-
34
-static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data)
35
-{
36
- DeviceClass *dc = DEVICE_CLASS(klass);
37
-
38
- dc->desc = "PXA27x timer";
39
- device_class_set_props(dc, pxa27x_timer_dev_properties);
40
-}
41
-
42
-static const TypeInfo pxa27x_timer_dev_info = {
43
- .name = "pxa27x-timer",
44
- .parent = TYPE_PXA2XX_TIMER,
45
- .instance_size = sizeof(PXA2xxTimerInfo),
46
- .class_init = pxa27x_timer_dev_class_init,
47
-};
48
-
49
static void pxa2xx_timer_class_init(ObjectClass *oc, void *data)
50
{
51
DeviceClass *dc = DEVICE_CLASS(oc);
52
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_timer_register_types(void)
53
{
54
type_register_static(&pxa2xx_timer_type_info);
55
type_register_static(&pxa25x_timer_dev_info);
56
- type_register_static(&pxa27x_timer_dev_info);
57
}
20
}
58
21
59
type_init(pxa2xx_timer_register_types)
22
int ieee_ex_to_loongarch(int xcpt)
60
--
23
--
61
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
Remove the pxa2xx specific pcmcia device.
1
Set the default NaN pattern explicitly for m68k.
2
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20240903160751.4100218-21-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-43-peter.maydell@linaro.org
6
---
6
---
7
include/hw/arm/pxa.h | 8 --
7
target/m68k/cpu.c | 2 ++
8
hw/pcmcia/pxa2xx.c | 248 ------------------------------------------
8
fpu/softfloat-specialize.c.inc | 2 +-
9
hw/pcmcia/meson.build | 1 -
9
2 files changed, 3 insertions(+), 1 deletion(-)
10
3 files changed, 257 deletions(-)
11
delete mode 100644 hw/pcmcia/pxa2xx.c
12
10
13
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
11
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/pxa.h
13
--- a/target/m68k/cpu.c
16
+++ b/include/hw/arm/pxa.h
14
+++ b/target/m68k/cpu.c
17
@@ -XXX,XX +XXX,XX @@ DeviceState *pxa2xx_gpio_init(hwaddr base,
15
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
18
ARMCPU *cpu, DeviceState *pic, int lines);
16
* preceding paragraph for nonsignaling NaNs.
19
void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler);
17
*/
20
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
21
-/* pxa2xx_pcmcia.c */
19
+ /* Default NaN: sign bit clear, all frac bits set */
22
-#define TYPE_PXA2XX_PCMCIA "pxa2xx-pcmcia"
20
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
23
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxPCMCIAState, PXA2XX_PCMCIA)
21
24
-
22
nan = floatx80_default_nan(&env->fp_status);
25
-int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card);
23
for (i = 0; i < 8; i++) {
26
-int pxa2xx_pcmcia_detach(void *opaque);
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
27
-void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq);
28
-
29
#endif /* PXA_H */
30
diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
31
deleted file mode 100644
32
index XXXXXXX..XXXXXXX
33
--- a/hw/pcmcia/pxa2xx.c
34
+++ /dev/null
35
@@ -XXX,XX +XXX,XX @@
36
-/*
37
- * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
38
- *
39
- * Copyright (c) 2006 Openedhand Ltd.
40
- * Written by Andrzej Zaborowski <balrog@zabor.org>
41
- *
42
- * This code is licensed under the GPLv2.
43
- *
44
- * Contributions after 2012-01-13 are licensed under the terms of the
45
- * GNU GPL, version 2 or (at your option) any later version.
46
- */
47
-
48
-#include "qemu/osdep.h"
49
-#include "hw/irq.h"
50
-#include "hw/sysbus.h"
51
-#include "qapi/error.h"
52
-#include "qemu/module.h"
53
-#include "hw/pcmcia.h"
54
-#include "hw/arm/pxa.h"
55
-
56
-struct PXA2xxPCMCIAState {
57
- SysBusDevice parent_obj;
58
-
59
- PCMCIASocket slot;
60
- MemoryRegion container_mem;
61
- MemoryRegion common_iomem;
62
- MemoryRegion attr_iomem;
63
- MemoryRegion iomem;
64
-
65
- qemu_irq irq;
66
- qemu_irq cd_irq;
67
-
68
- PCMCIACardState *card;
69
-};
70
-
71
-static uint64_t pxa2xx_pcmcia_common_read(void *opaque,
72
- hwaddr offset, unsigned size)
73
-{
74
- PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
75
- PCMCIACardClass *pcc;
76
-
77
- if (s->slot.attached) {
78
- pcc = PCMCIA_CARD_GET_CLASS(s->card);
79
- return pcc->common_read(s->card, offset);
80
- }
81
-
82
- return 0;
83
-}
84
-
85
-static void pxa2xx_pcmcia_common_write(void *opaque, hwaddr offset,
86
- uint64_t value, unsigned size)
87
-{
88
- PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
89
- PCMCIACardClass *pcc;
90
-
91
- if (s->slot.attached) {
92
- pcc = PCMCIA_CARD_GET_CLASS(s->card);
93
- pcc->common_write(s->card, offset, value);
94
- }
95
-}
96
-
97
-static uint64_t pxa2xx_pcmcia_attr_read(void *opaque,
98
- hwaddr offset, unsigned size)
99
-{
100
- PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
101
- PCMCIACardClass *pcc;
102
-
103
- if (s->slot.attached) {
104
- pcc = PCMCIA_CARD_GET_CLASS(s->card);
105
- return pcc->attr_read(s->card, offset);
106
- }
107
-
108
- return 0;
109
-}
110
-
111
-static void pxa2xx_pcmcia_attr_write(void *opaque, hwaddr offset,
112
- uint64_t value, unsigned size)
113
-{
114
- PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
115
- PCMCIACardClass *pcc;
116
-
117
- if (s->slot.attached) {
118
- pcc = PCMCIA_CARD_GET_CLASS(s->card);
119
- pcc->attr_write(s->card, offset, value);
120
- }
121
-}
122
-
123
-static uint64_t pxa2xx_pcmcia_io_read(void *opaque,
124
- hwaddr offset, unsigned size)
125
-{
126
- PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
127
- PCMCIACardClass *pcc;
128
-
129
- if (s->slot.attached) {
130
- pcc = PCMCIA_CARD_GET_CLASS(s->card);
131
- return pcc->io_read(s->card, offset);
132
- }
133
-
134
- return 0;
135
-}
136
-
137
-static void pxa2xx_pcmcia_io_write(void *opaque, hwaddr offset,
138
- uint64_t value, unsigned size)
139
-{
140
- PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
141
- PCMCIACardClass *pcc;
142
-
143
- if (s->slot.attached) {
144
- pcc = PCMCIA_CARD_GET_CLASS(s->card);
145
- pcc->io_write(s->card, offset, value);
146
- }
147
-}
148
-
149
-static const MemoryRegionOps pxa2xx_pcmcia_common_ops = {
150
- .read = pxa2xx_pcmcia_common_read,
151
- .write = pxa2xx_pcmcia_common_write,
152
- .endianness = DEVICE_NATIVE_ENDIAN
153
-};
154
-
155
-static const MemoryRegionOps pxa2xx_pcmcia_attr_ops = {
156
- .read = pxa2xx_pcmcia_attr_read,
157
- .write = pxa2xx_pcmcia_attr_write,
158
- .endianness = DEVICE_NATIVE_ENDIAN
159
-};
160
-
161
-static const MemoryRegionOps pxa2xx_pcmcia_io_ops = {
162
- .read = pxa2xx_pcmcia_io_read,
163
- .write = pxa2xx_pcmcia_io_write,
164
- .endianness = DEVICE_NATIVE_ENDIAN
165
-};
166
-
167
-static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
168
-{
169
- PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
170
- if (!s->irq)
171
- return;
172
-
173
- qemu_set_irq(s->irq, level);
174
-}
175
-
176
-static void pxa2xx_pcmcia_initfn(Object *obj)
177
-{
178
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
179
- PXA2xxPCMCIAState *s = PXA2XX_PCMCIA(obj);
180
-
181
- memory_region_init(&s->container_mem, obj, "container", 0x10000000);
182
- sysbus_init_mmio(sbd, &s->container_mem);
183
-
184
- /* Socket I/O Memory Space */
185
- memory_region_init_io(&s->iomem, obj, &pxa2xx_pcmcia_io_ops, s,
186
- "pxa2xx-pcmcia-io", 0x04000000);
187
- memory_region_add_subregion(&s->container_mem, 0x00000000,
188
- &s->iomem);
189
-
190
- /* Then next 64 MB is reserved */
191
-
192
- /* Socket Attribute Memory Space */
193
- memory_region_init_io(&s->attr_iomem, obj, &pxa2xx_pcmcia_attr_ops, s,
194
- "pxa2xx-pcmcia-attribute", 0x04000000);
195
- memory_region_add_subregion(&s->container_mem, 0x08000000,
196
- &s->attr_iomem);
197
-
198
- /* Socket Common Memory Space */
199
- memory_region_init_io(&s->common_iomem, obj, &pxa2xx_pcmcia_common_ops, s,
200
- "pxa2xx-pcmcia-common", 0x04000000);
201
- memory_region_add_subregion(&s->container_mem, 0x0c000000,
202
- &s->common_iomem);
203
-
204
- s->slot.irq = qemu_allocate_irq(pxa2xx_pcmcia_set_irq, s, 0);
205
-
206
- object_property_add_link(obj, "card", TYPE_PCMCIA_CARD,
207
- (Object **)&s->card,
208
- NULL, /* read-only property */
209
- 0);
210
-}
211
-
212
-/* Insert a new card into a slot */
213
-int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
214
-{
215
- PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
216
- PCMCIACardClass *pcc;
217
-
218
- if (s->slot.attached) {
219
- return -EEXIST;
220
- }
221
-
222
- if (s->cd_irq) {
223
- qemu_irq_raise(s->cd_irq);
224
- }
225
-
226
- s->card = card;
227
- pcc = PCMCIA_CARD_GET_CLASS(s->card);
228
-
229
- s->slot.attached = true;
230
- s->card->slot = &s->slot;
231
- pcc->attach(s->card);
232
-
233
- return 0;
234
-}
235
-
236
-/* Eject card from the slot */
237
-int pxa2xx_pcmcia_detach(void *opaque)
238
-{
239
- PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
240
- PCMCIACardClass *pcc;
241
-
242
- if (!s->slot.attached) {
243
- return -ENOENT;
244
- }
245
-
246
- pcc = PCMCIA_CARD_GET_CLASS(s->card);
247
- pcc->detach(s->card);
248
- s->card->slot = NULL;
249
- s->card = NULL;
250
-
251
- s->slot.attached = false;
252
-
253
- if (s->irq) {
254
- qemu_irq_lower(s->irq);
255
- }
256
- if (s->cd_irq) {
257
- qemu_irq_lower(s->cd_irq);
258
- }
259
-
260
- return 0;
261
-}
262
-
263
-/* Who to notify on card events */
264
-void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
265
-{
266
- PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
267
- s->irq = irq;
268
- s->cd_irq = cd_irq;
269
-}
270
-
271
-static const TypeInfo pxa2xx_pcmcia_type_info = {
272
- .name = TYPE_PXA2XX_PCMCIA,
273
- .parent = TYPE_SYS_BUS_DEVICE,
274
- .instance_size = sizeof(PXA2xxPCMCIAState),
275
- .instance_init = pxa2xx_pcmcia_initfn,
276
-};
277
-
278
-static void pxa2xx_pcmcia_register_types(void)
279
-{
280
- type_register_static(&pxa2xx_pcmcia_type_info);
281
-}
282
-
283
-type_init(pxa2xx_pcmcia_register_types)
284
diff --git a/hw/pcmcia/meson.build b/hw/pcmcia/meson.build
285
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
286
--- a/hw/pcmcia/meson.build
26
--- a/fpu/softfloat-specialize.c.inc
287
+++ b/hw/pcmcia/meson.build
27
+++ b/fpu/softfloat-specialize.c.inc
288
@@ -1,2 +1 @@
28
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
289
system_ss.add(when: 'CONFIG_PCMCIA', if_true: files('pcmcia.c'))
29
uint8_t dnan_pattern = status->default_nan_pattern;
290
-system_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx.c'))
30
31
if (dnan_pattern == 0) {
32
-#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
+#if defined(TARGET_SPARC)
34
/* Sign bit clear, all frac bits set */
35
dnan_pattern = 0b01111111;
36
#elif defined(TARGET_HEXAGON)
291
--
37
--
292
2.34.1
38
2.34.1
293
294
diff view generated by jsdifflib
1
Remove the pxa2xx-specific pxa2xx_dma device.
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: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20240903160751.4100218-20-peter.maydell@linaro.org
8
Message-id: 20241202131347.498124-44-peter.maydell@linaro.org
6
---
9
---
7
include/hw/arm/pxa.h | 4 -
10
target/mips/fpu_helper.h | 7 +++++++
8
hw/dma/pxa2xx_dma.c | 591 -------------------------------------------
11
target/mips/msa.c | 3 +++
9
hw/dma/meson.build | 1 -
12
2 files changed, 10 insertions(+)
10
3 files changed, 596 deletions(-)
11
delete mode 100644 hw/dma/pxa2xx_dma.c
12
13
13
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
14
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/pxa.h
16
--- a/target/mips/fpu_helper.h
16
+++ b/include/hw/arm/pxa.h
17
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ DeviceState *pxa2xx_gpio_init(hwaddr base,
18
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
18
ARMCPU *cpu, DeviceState *pic, int lines);
19
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
19
void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler);
20
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
20
21
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
21
-/* pxa2xx_dma.c */
22
+ /*
22
-DeviceState *pxa255_dma_init(hwaddr base, qemu_irq irq);
23
+ * With nan2008, the default NaN value has the sign bit clear and the
23
-DeviceState *pxa27x_dma_init(hwaddr base, qemu_irq irq);
24
+ * frac msb set; with the older mode, the sign bit is clear, and all
24
-
25
+ * frac bits except the msb are set.
25
/* pxa2xx_pcmcia.c */
26
+ */
26
#define TYPE_PXA2XX_PCMCIA "pxa2xx-pcmcia"
27
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
27
OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxPCMCIAState, PXA2XX_PCMCIA)
28
+ &env->active_fpu.fp_status);
28
diff --git a/hw/dma/pxa2xx_dma.c b/hw/dma/pxa2xx_dma.c
29
29
deleted file mode 100644
30
}
30
index XXXXXXX..XXXXXXX
31
31
--- a/hw/dma/pxa2xx_dma.c
32
diff --git a/target/mips/msa.c b/target/mips/msa.c
32
+++ /dev/null
33
@@ -XXX,XX +XXX,XX @@
34
-/*
35
- * Intel XScale PXA255/270 DMA controller.
36
- *
37
- * Copyright (c) 2006 Openedhand Ltd.
38
- * Copyright (c) 2006 Thorsten Zitterell
39
- * Written by Andrzej Zaborowski <balrog@zabor.org>
40
- *
41
- * This code is licensed under the GPL.
42
- */
43
-
44
-#include "qemu/osdep.h"
45
-#include "qemu/log.h"
46
-#include "hw/hw.h"
47
-#include "hw/irq.h"
48
-#include "hw/qdev-properties.h"
49
-#include "hw/arm/pxa.h"
50
-#include "hw/sysbus.h"
51
-#include "migration/vmstate.h"
52
-#include "qapi/error.h"
53
-#include "qemu/module.h"
54
-#include "qom/object.h"
55
-
56
-#define PXA255_DMA_NUM_CHANNELS 16
57
-#define PXA27X_DMA_NUM_CHANNELS 32
58
-
59
-#define PXA2XX_DMA_NUM_REQUESTS 75
60
-
61
-typedef struct {
62
- uint32_t descr;
63
- uint32_t src;
64
- uint32_t dest;
65
- uint32_t cmd;
66
- uint32_t state;
67
- int request;
68
-} PXA2xxDMAChannel;
69
-
70
-#define TYPE_PXA2XX_DMA "pxa2xx-dma"
71
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxDMAState, PXA2XX_DMA)
72
-
73
-struct PXA2xxDMAState {
74
- SysBusDevice parent_obj;
75
-
76
- MemoryRegion iomem;
77
- qemu_irq irq;
78
-
79
- uint32_t stopintr;
80
- uint32_t eorintr;
81
- uint32_t rasintr;
82
- uint32_t startintr;
83
- uint32_t endintr;
84
-
85
- uint32_t align;
86
- uint32_t pio;
87
-
88
- int channels;
89
- PXA2xxDMAChannel *chan;
90
-
91
- uint8_t req[PXA2XX_DMA_NUM_REQUESTS];
92
-
93
- /* Flag to avoid recursive DMA invocations. */
94
- int running;
95
-};
96
-
97
-#define DCSR0    0x0000    /* DMA Control / Status register for Channel 0 */
98
-#define DCSR31    0x007c    /* DMA Control / Status register for Channel 31 */
99
-#define DALGN    0x00a0    /* DMA Alignment register */
100
-#define DPCSR    0x00a4    /* DMA Programmed I/O Control Status register */
101
-#define DRQSR0    0x00e0    /* DMA DREQ<0> Status register */
102
-#define DRQSR1    0x00e4    /* DMA DREQ<1> Status register */
103
-#define DRQSR2    0x00e8    /* DMA DREQ<2> Status register */
104
-#define DINT    0x00f0    /* DMA Interrupt register */
105
-#define DRCMR0    0x0100    /* Request to Channel Map register 0 */
106
-#define DRCMR63    0x01fc    /* Request to Channel Map register 63 */
107
-#define D_CH0    0x0200    /* Channel 0 Descriptor start */
108
-#define DRCMR64    0x1100    /* Request to Channel Map register 64 */
109
-#define DRCMR74    0x1128    /* Request to Channel Map register 74 */
110
-
111
-/* Per-channel register */
112
-#define DDADR    0x00
113
-#define DSADR    0x01
114
-#define DTADR    0x02
115
-#define DCMD    0x03
116
-
117
-/* Bit-field masks */
118
-#define DRCMR_CHLNUM        0x1f
119
-#define DRCMR_MAPVLD        (1 << 7)
120
-#define DDADR_STOP        (1 << 0)
121
-#define DDADR_BREN        (1 << 1)
122
-#define DCMD_LEN        0x1fff
123
-#define DCMD_WIDTH(x)        (1 << ((((x) >> 14) & 3) - 1))
124
-#define DCMD_SIZE(x)        (4 << (((x) >> 16) & 3))
125
-#define DCMD_FLYBYT        (1 << 19)
126
-#define DCMD_FLYBYS        (1 << 20)
127
-#define DCMD_ENDIRQEN        (1 << 21)
128
-#define DCMD_STARTIRQEN        (1 << 22)
129
-#define DCMD_CMPEN        (1 << 25)
130
-#define DCMD_FLOWTRG        (1 << 28)
131
-#define DCMD_FLOWSRC        (1 << 29)
132
-#define DCMD_INCTRGADDR        (1 << 30)
133
-#define DCMD_INCSRCADDR        (1 << 31)
134
-#define DCSR_BUSERRINTR        (1 << 0)
135
-#define DCSR_STARTINTR        (1 << 1)
136
-#define DCSR_ENDINTR        (1 << 2)
137
-#define DCSR_STOPINTR        (1 << 3)
138
-#define DCSR_RASINTR        (1 << 4)
139
-#define DCSR_REQPEND        (1 << 8)
140
-#define DCSR_EORINT        (1 << 9)
141
-#define DCSR_CMPST        (1 << 10)
142
-#define DCSR_MASKRUN        (1 << 22)
143
-#define DCSR_RASIRQEN        (1 << 23)
144
-#define DCSR_CLRCMPST        (1 << 24)
145
-#define DCSR_SETCMPST        (1 << 25)
146
-#define DCSR_EORSTOPEN        (1 << 26)
147
-#define DCSR_EORJMPEN        (1 << 27)
148
-#define DCSR_EORIRQEN        (1 << 28)
149
-#define DCSR_STOPIRQEN        (1 << 29)
150
-#define DCSR_NODESCFETCH    (1 << 30)
151
-#define DCSR_RUN        (1 << 31)
152
-
153
-static inline void pxa2xx_dma_update(PXA2xxDMAState *s, int ch)
154
-{
155
- if (ch >= 0) {
156
- if ((s->chan[ch].state & DCSR_STOPIRQEN) &&
157
- (s->chan[ch].state & DCSR_STOPINTR))
158
- s->stopintr |= 1 << ch;
159
- else
160
- s->stopintr &= ~(1 << ch);
161
-
162
- if ((s->chan[ch].state & DCSR_EORIRQEN) &&
163
- (s->chan[ch].state & DCSR_EORINT))
164
- s->eorintr |= 1 << ch;
165
- else
166
- s->eorintr &= ~(1 << ch);
167
-
168
- if ((s->chan[ch].state & DCSR_RASIRQEN) &&
169
- (s->chan[ch].state & DCSR_RASINTR))
170
- s->rasintr |= 1 << ch;
171
- else
172
- s->rasintr &= ~(1 << ch);
173
-
174
- if (s->chan[ch].state & DCSR_STARTINTR)
175
- s->startintr |= 1 << ch;
176
- else
177
- s->startintr &= ~(1 << ch);
178
-
179
- if (s->chan[ch].state & DCSR_ENDINTR)
180
- s->endintr |= 1 << ch;
181
- else
182
- s->endintr &= ~(1 << ch);
183
- }
184
-
185
- if (s->stopintr | s->eorintr | s->rasintr | s->startintr | s->endintr)
186
- qemu_irq_raise(s->irq);
187
- else
188
- qemu_irq_lower(s->irq);
189
-}
190
-
191
-static inline void pxa2xx_dma_descriptor_fetch(
192
- PXA2xxDMAState *s, int ch)
193
-{
194
- uint32_t desc[4];
195
- hwaddr daddr = s->chan[ch].descr & ~0xf;
196
- if ((s->chan[ch].descr & DDADR_BREN) && (s->chan[ch].state & DCSR_CMPST))
197
- daddr += 32;
198
-
199
- cpu_physical_memory_read(daddr, desc, 16);
200
- s->chan[ch].descr = desc[DDADR];
201
- s->chan[ch].src = desc[DSADR];
202
- s->chan[ch].dest = desc[DTADR];
203
- s->chan[ch].cmd = desc[DCMD];
204
-
205
- if (s->chan[ch].cmd & DCMD_FLOWSRC)
206
- s->chan[ch].src &= ~3;
207
- if (s->chan[ch].cmd & DCMD_FLOWTRG)
208
- s->chan[ch].dest &= ~3;
209
-
210
- if (s->chan[ch].cmd & (DCMD_CMPEN | DCMD_FLYBYS | DCMD_FLYBYT))
211
- printf("%s: unsupported mode in channel %i\n", __func__, ch);
212
-
213
- if (s->chan[ch].cmd & DCMD_STARTIRQEN)
214
- s->chan[ch].state |= DCSR_STARTINTR;
215
-}
216
-
217
-static void pxa2xx_dma_run(PXA2xxDMAState *s)
218
-{
219
- int c, srcinc, destinc;
220
- uint32_t n, size;
221
- uint32_t width;
222
- uint32_t length;
223
- uint8_t buffer[32];
224
- PXA2xxDMAChannel *ch;
225
-
226
- if (s->running ++)
227
- return;
228
-
229
- while (s->running) {
230
- s->running = 1;
231
- for (c = 0; c < s->channels; c ++) {
232
- ch = &s->chan[c];
233
-
234
- while ((ch->state & DCSR_RUN) && !(ch->state & DCSR_STOPINTR)) {
235
- /* Test for pending requests */
236
- if ((ch->cmd & (DCMD_FLOWSRC | DCMD_FLOWTRG)) && !ch->request)
237
- break;
238
-
239
- length = ch->cmd & DCMD_LEN;
240
- size = DCMD_SIZE(ch->cmd);
241
- width = DCMD_WIDTH(ch->cmd);
242
-
243
- srcinc = (ch->cmd & DCMD_INCSRCADDR) ? width : 0;
244
- destinc = (ch->cmd & DCMD_INCTRGADDR) ? width : 0;
245
-
246
- while (length) {
247
- size = MIN(length, size);
248
-
249
- for (n = 0; n < size; n += width) {
250
- cpu_physical_memory_read(ch->src, buffer + n, width);
251
- ch->src += srcinc;
252
- }
253
-
254
- for (n = 0; n < size; n += width) {
255
- cpu_physical_memory_write(ch->dest, buffer + n, width);
256
- ch->dest += destinc;
257
- }
258
-
259
- length -= size;
260
-
261
- if ((ch->cmd & (DCMD_FLOWSRC | DCMD_FLOWTRG)) &&
262
- !ch->request) {
263
- ch->state |= DCSR_EORINT;
264
- if (ch->state & DCSR_EORSTOPEN)
265
- ch->state |= DCSR_STOPINTR;
266
- if ((ch->state & DCSR_EORJMPEN) &&
267
- !(ch->state & DCSR_NODESCFETCH))
268
- pxa2xx_dma_descriptor_fetch(s, c);
269
- break;
270
- }
271
- }
272
-
273
- ch->cmd = (ch->cmd & ~DCMD_LEN) | length;
274
-
275
- /* Is the transfer complete now? */
276
- if (!length) {
277
- if (ch->cmd & DCMD_ENDIRQEN)
278
- ch->state |= DCSR_ENDINTR;
279
-
280
- if ((ch->state & DCSR_NODESCFETCH) ||
281
- (ch->descr & DDADR_STOP) ||
282
- (ch->state & DCSR_EORSTOPEN)) {
283
- ch->state |= DCSR_STOPINTR;
284
- ch->state &= ~DCSR_RUN;
285
-
286
- break;
287
- }
288
-
289
- ch->state |= DCSR_STOPINTR;
290
- break;
291
- }
292
- }
293
- }
294
-
295
- s->running --;
296
- }
297
-}
298
-
299
-static uint64_t pxa2xx_dma_read(void *opaque, hwaddr offset,
300
- unsigned size)
301
-{
302
- PXA2xxDMAState *s = (PXA2xxDMAState *) opaque;
303
- unsigned int channel;
304
-
305
- if (size != 4) {
306
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad access width %u\n",
307
- __func__, size);
308
- return 5;
309
- }
310
-
311
- switch (offset) {
312
- case DRCMR64 ... DRCMR74:
313
- offset -= DRCMR64 - DRCMR0 - (64 << 2);
314
- /* Fall through */
315
- case DRCMR0 ... DRCMR63:
316
- channel = (offset - DRCMR0) >> 2;
317
- return s->req[channel];
318
-
319
- case DRQSR0:
320
- case DRQSR1:
321
- case DRQSR2:
322
- return 0;
323
-
324
- case DCSR0 ... DCSR31:
325
- channel = offset >> 2;
326
- if (s->chan[channel].request)
327
- return s->chan[channel].state | DCSR_REQPEND;
328
- return s->chan[channel].state;
329
-
330
- case DINT:
331
- return s->stopintr | s->eorintr | s->rasintr |
332
- s->startintr | s->endintr;
333
-
334
- case DALGN:
335
- return s->align;
336
-
337
- case DPCSR:
338
- return s->pio;
339
- }
340
-
341
- if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) {
342
- channel = (offset - D_CH0) >> 4;
343
- switch ((offset & 0x0f) >> 2) {
344
- case DDADR:
345
- return s->chan[channel].descr;
346
- case DSADR:
347
- return s->chan[channel].src;
348
- case DTADR:
349
- return s->chan[channel].dest;
350
- case DCMD:
351
- return s->chan[channel].cmd;
352
- }
353
- }
354
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
355
- __func__, offset);
356
- return 7;
357
-}
358
-
359
-static void pxa2xx_dma_write(void *opaque, hwaddr offset,
360
- uint64_t value, unsigned size)
361
-{
362
- PXA2xxDMAState *s = (PXA2xxDMAState *) opaque;
363
- unsigned int channel;
364
-
365
- if (size != 4) {
366
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad access width %u\n",
367
- __func__, size);
368
- return;
369
- }
370
-
371
- switch (offset) {
372
- case DRCMR64 ... DRCMR74:
373
- offset -= DRCMR64 - DRCMR0 - (64 << 2);
374
- /* Fall through */
375
- case DRCMR0 ... DRCMR63:
376
- channel = (offset - DRCMR0) >> 2;
377
-
378
- if (value & DRCMR_MAPVLD)
379
- if ((value & DRCMR_CHLNUM) > s->channels)
380
- hw_error("%s: Bad DMA channel %i\n",
381
- __func__, (unsigned)value & DRCMR_CHLNUM);
382
-
383
- s->req[channel] = value;
384
- break;
385
-
386
- case DRQSR0:
387
- case DRQSR1:
388
- case DRQSR2:
389
- /* Nothing to do */
390
- break;
391
-
392
- case DCSR0 ... DCSR31:
393
- channel = offset >> 2;
394
- s->chan[channel].state &= 0x0000071f & ~(value &
395
- (DCSR_EORINT | DCSR_ENDINTR |
396
- DCSR_STARTINTR | DCSR_BUSERRINTR));
397
- s->chan[channel].state |= value & 0xfc800000;
398
-
399
- if (s->chan[channel].state & DCSR_STOPIRQEN)
400
- s->chan[channel].state &= ~DCSR_STOPINTR;
401
-
402
- if (value & DCSR_NODESCFETCH) {
403
- /* No-descriptor-fetch mode */
404
- if (value & DCSR_RUN) {
405
- s->chan[channel].state &= ~DCSR_STOPINTR;
406
- pxa2xx_dma_run(s);
407
- }
408
- } else {
409
- /* Descriptor-fetch mode */
410
- if (value & DCSR_RUN) {
411
- s->chan[channel].state &= ~DCSR_STOPINTR;
412
- pxa2xx_dma_descriptor_fetch(s, channel);
413
- pxa2xx_dma_run(s);
414
- }
415
- }
416
-
417
- /* Shouldn't matter as our DMA is synchronous. */
418
- if (!(value & (DCSR_RUN | DCSR_MASKRUN)))
419
- s->chan[channel].state |= DCSR_STOPINTR;
420
-
421
- if (value & DCSR_CLRCMPST)
422
- s->chan[channel].state &= ~DCSR_CMPST;
423
- if (value & DCSR_SETCMPST)
424
- s->chan[channel].state |= DCSR_CMPST;
425
-
426
- pxa2xx_dma_update(s, channel);
427
- break;
428
-
429
- case DALGN:
430
- s->align = value;
431
- break;
432
-
433
- case DPCSR:
434
- s->pio = value & 0x80000001;
435
- break;
436
-
437
- default:
438
- if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) {
439
- channel = (offset - D_CH0) >> 4;
440
- switch ((offset & 0x0f) >> 2) {
441
- case DDADR:
442
- s->chan[channel].descr = value;
443
- break;
444
- case DSADR:
445
- s->chan[channel].src = value;
446
- break;
447
- case DTADR:
448
- s->chan[channel].dest = value;
449
- break;
450
- case DCMD:
451
- s->chan[channel].cmd = value;
452
- break;
453
- default:
454
- goto fail;
455
- }
456
-
457
- break;
458
- }
459
- fail:
460
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
461
- __func__, offset);
462
- }
463
-}
464
-
465
-static const MemoryRegionOps pxa2xx_dma_ops = {
466
- .read = pxa2xx_dma_read,
467
- .write = pxa2xx_dma_write,
468
- .endianness = DEVICE_NATIVE_ENDIAN,
469
-};
470
-
471
-static void pxa2xx_dma_request(void *opaque, int req_num, int on)
472
-{
473
- PXA2xxDMAState *s = opaque;
474
- int ch;
475
- if (req_num < 0 || req_num >= PXA2XX_DMA_NUM_REQUESTS)
476
- hw_error("%s: Bad DMA request %i\n", __func__, req_num);
477
-
478
- if (!(s->req[req_num] & DRCMR_MAPVLD))
479
- return;
480
- ch = s->req[req_num] & DRCMR_CHLNUM;
481
-
482
- if (!s->chan[ch].request && on)
483
- s->chan[ch].state |= DCSR_RASINTR;
484
- else
485
- s->chan[ch].state &= ~DCSR_RASINTR;
486
- if (s->chan[ch].request && !on)
487
- s->chan[ch].state |= DCSR_EORINT;
488
-
489
- s->chan[ch].request = on;
490
- if (on) {
491
- pxa2xx_dma_run(s);
492
- pxa2xx_dma_update(s, ch);
493
- }
494
-}
495
-
496
-static void pxa2xx_dma_init(Object *obj)
497
-{
498
- DeviceState *dev = DEVICE(obj);
499
- PXA2xxDMAState *s = PXA2XX_DMA(obj);
500
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
501
-
502
- memset(s->req, 0, sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);
503
-
504
- qdev_init_gpio_in(dev, pxa2xx_dma_request, PXA2XX_DMA_NUM_REQUESTS);
505
-
506
- memory_region_init_io(&s->iomem, obj, &pxa2xx_dma_ops, s,
507
- "pxa2xx.dma", 0x00010000);
508
- sysbus_init_mmio(sbd, &s->iomem);
509
- sysbus_init_irq(sbd, &s->irq);
510
-}
511
-
512
-static void pxa2xx_dma_realize(DeviceState *dev, Error **errp)
513
-{
514
- PXA2xxDMAState *s = PXA2XX_DMA(dev);
515
- int i;
516
-
517
- if (s->channels <= 0) {
518
- error_setg(errp, "channels value invalid");
519
- return;
520
- }
521
-
522
- s->chan = g_new0(PXA2xxDMAChannel, s->channels);
523
-
524
- for (i = 0; i < s->channels; i ++)
525
- s->chan[i].state = DCSR_STOPINTR;
526
-}
527
-
528
-DeviceState *pxa27x_dma_init(hwaddr base, qemu_irq irq)
529
-{
530
- DeviceState *dev;
531
-
532
- dev = qdev_new("pxa2xx-dma");
533
- qdev_prop_set_int32(dev, "channels", PXA27X_DMA_NUM_CHANNELS);
534
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
535
-
536
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
537
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
538
-
539
- return dev;
540
-}
541
-
542
-DeviceState *pxa255_dma_init(hwaddr base, qemu_irq irq)
543
-{
544
- DeviceState *dev;
545
-
546
- dev = qdev_new("pxa2xx-dma");
547
- qdev_prop_set_int32(dev, "channels", PXA27X_DMA_NUM_CHANNELS);
548
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
549
-
550
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
551
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
552
-
553
- return dev;
554
-}
555
-
556
-static bool is_version_0(void *opaque, int version_id)
557
-{
558
- return version_id == 0;
559
-}
560
-
561
-static const VMStateDescription vmstate_pxa2xx_dma_chan = {
562
- .name = "pxa2xx_dma_chan",
563
- .version_id = 1,
564
- .minimum_version_id = 1,
565
- .fields = (const VMStateField[]) {
566
- VMSTATE_UINT32(descr, PXA2xxDMAChannel),
567
- VMSTATE_UINT32(src, PXA2xxDMAChannel),
568
- VMSTATE_UINT32(dest, PXA2xxDMAChannel),
569
- VMSTATE_UINT32(cmd, PXA2xxDMAChannel),
570
- VMSTATE_UINT32(state, PXA2xxDMAChannel),
571
- VMSTATE_INT32(request, PXA2xxDMAChannel),
572
- VMSTATE_END_OF_LIST(),
573
- },
574
-};
575
-
576
-static const VMStateDescription vmstate_pxa2xx_dma = {
577
- .name = "pxa2xx_dma",
578
- .version_id = 1,
579
- .minimum_version_id = 0,
580
- .fields = (const VMStateField[]) {
581
- VMSTATE_UNUSED_TEST(is_version_0, 4),
582
- VMSTATE_UINT32(stopintr, PXA2xxDMAState),
583
- VMSTATE_UINT32(eorintr, PXA2xxDMAState),
584
- VMSTATE_UINT32(rasintr, PXA2xxDMAState),
585
- VMSTATE_UINT32(startintr, PXA2xxDMAState),
586
- VMSTATE_UINT32(endintr, PXA2xxDMAState),
587
- VMSTATE_UINT32(align, PXA2xxDMAState),
588
- VMSTATE_UINT32(pio, PXA2xxDMAState),
589
- VMSTATE_BUFFER(req, PXA2xxDMAState),
590
- VMSTATE_STRUCT_VARRAY_POINTER_INT32(chan, PXA2xxDMAState, channels,
591
- vmstate_pxa2xx_dma_chan, PXA2xxDMAChannel),
592
- VMSTATE_END_OF_LIST(),
593
- },
594
-};
595
-
596
-static Property pxa2xx_dma_properties[] = {
597
- DEFINE_PROP_INT32("channels", PXA2xxDMAState, channels, -1),
598
- DEFINE_PROP_END_OF_LIST(),
599
-};
600
-
601
-static void pxa2xx_dma_class_init(ObjectClass *klass, void *data)
602
-{
603
- DeviceClass *dc = DEVICE_CLASS(klass);
604
-
605
- dc->desc = "PXA2xx DMA controller";
606
- dc->vmsd = &vmstate_pxa2xx_dma;
607
- device_class_set_props(dc, pxa2xx_dma_properties);
608
- dc->realize = pxa2xx_dma_realize;
609
-}
610
-
611
-static const TypeInfo pxa2xx_dma_info = {
612
- .name = TYPE_PXA2XX_DMA,
613
- .parent = TYPE_SYS_BUS_DEVICE,
614
- .instance_size = sizeof(PXA2xxDMAState),
615
- .instance_init = pxa2xx_dma_init,
616
- .class_init = pxa2xx_dma_class_init,
617
-};
618
-
619
-static void pxa2xx_dma_register_types(void)
620
-{
621
- type_register_static(&pxa2xx_dma_info);
622
-}
623
-
624
-type_init(pxa2xx_dma_register_types)
625
diff --git a/hw/dma/meson.build b/hw/dma/meson.build
626
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
627
--- a/hw/dma/meson.build
34
--- a/target/mips/msa.c
628
+++ b/hw/dma/meson.build
35
+++ b/target/mips/msa.c
629
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_STP2000', if_true: files('sparc32_dma.c'))
36
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
630
system_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx_dpdma.c'))
37
/* Inf * 0 + NaN returns the input NaN */
631
system_ss.add(when: 'CONFIG_XLNX_ZDMA', if_true: files('xlnx-zdma.c'))
38
set_float_infzeronan_rule(float_infzeronan_dnan_never,
632
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_dma.c', 'soc_dma.c'))
39
&env->active_tc.msa_fp_status);
633
-system_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_dma.c'))
40
+ /* Default NaN: sign bit clear, frac msb set */
634
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c'))
41
+ set_float_default_nan_pattern(0b01000000,
635
system_ss.add(when: 'CONFIG_SIFIVE_PDMA', if_true: files('sifive_pdma.c'))
42
+ &env->active_tc.msa_fp_status);
636
system_ss.add(when: 'CONFIG_XLNX_CSU_DMA', if_true: files('xlnx_csu_dma.c'))
43
}
637
--
44
--
638
2.34.1
45
2.34.1
639
640
diff view generated by jsdifflib
1
Remove the pxa2xx-specific pxa2xx_lcd device.
1
Set the default NaN pattern explicitly for openrisc.
2
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Message-id: 20240903160751.4100218-19-peter.maydell@linaro.org
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-45-peter.maydell@linaro.org
5
---
6
---
6
include/hw/arm/pxa.h | 6 -
7
target/openrisc/cpu.c | 2 ++
7
hw/display/pxa2xx_lcd.c | 1451 ---------------------------------------
8
1 file changed, 2 insertions(+)
8
hw/display/meson.build | 1 -
9
3 files changed, 1458 deletions(-)
10
delete mode 100644 hw/display/pxa2xx_lcd.c
11
9
12
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.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/include/hw/arm/pxa.h
12
--- a/target/openrisc/cpu.c
15
+++ b/include/hw/arm/pxa.h
13
+++ b/target/openrisc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler);
14
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
17
DeviceState *pxa255_dma_init(hwaddr base, qemu_irq irq);
15
*/
18
DeviceState *pxa27x_dma_init(hwaddr base, qemu_irq irq);
16
set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
19
17
20
-/* pxa2xx_lcd.c */
18
+ /* Default NaN: sign bit clear, frac msb set */
21
-typedef struct PXA2xxLCDState PXA2xxLCDState;
19
+ set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
22
-PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
20
23
- hwaddr base, qemu_irq irq);
21
#ifndef CONFIG_USER_ONLY
24
-void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler);
22
cpu->env.picmr = 0x00000000;
25
-
26
/* pxa2xx_pcmcia.c */
27
#define TYPE_PXA2XX_PCMCIA "pxa2xx-pcmcia"
28
OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxPCMCIAState, PXA2XX_PCMCIA)
29
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
30
deleted file mode 100644
31
index XXXXXXX..XXXXXXX
32
--- a/hw/display/pxa2xx_lcd.c
33
+++ /dev/null
34
@@ -XXX,XX +XXX,XX @@
35
-/*
36
- * Intel XScale PXA255/270 LCDC emulation.
37
- *
38
- * Copyright (c) 2006 Openedhand Ltd.
39
- * Written by Andrzej Zaborowski <balrog@zabor.org>
40
- *
41
- * This code is licensed under the GPLv2.
42
- *
43
- * Contributions after 2012-01-13 are licensed under the terms of the
44
- * GNU GPL, version 2 or (at your option) any later version.
45
- */
46
-
47
-#include "qemu/osdep.h"
48
-#include "qemu/log.h"
49
-#include "hw/irq.h"
50
-#include "migration/vmstate.h"
51
-#include "ui/console.h"
52
-#include "hw/arm/pxa.h"
53
-#include "ui/pixel_ops.h"
54
-#include "hw/boards.h"
55
-/* FIXME: For graphic_rotate. Should probably be done in common code. */
56
-#include "sysemu/sysemu.h"
57
-#include "framebuffer.h"
58
-
59
-struct DMAChannel {
60
- uint32_t branch;
61
- uint8_t up;
62
- uint8_t palette[1024];
63
- uint8_t pbuffer[1024];
64
- void (*redraw)(PXA2xxLCDState *s, hwaddr addr,
65
- int *miny, int *maxy);
66
-
67
- uint32_t descriptor;
68
- uint32_t source;
69
- uint32_t id;
70
- uint32_t command;
71
-};
72
-
73
-struct PXA2xxLCDState {
74
- MemoryRegion *sysmem;
75
- MemoryRegion iomem;
76
- MemoryRegionSection fbsection;
77
- qemu_irq irq;
78
- int irqlevel;
79
-
80
- int invalidated;
81
- QemuConsole *con;
82
- int dest_width;
83
- int xres, yres;
84
- int pal_for;
85
- int transp;
86
- enum {
87
- pxa_lcdc_2bpp = 1,
88
- pxa_lcdc_4bpp = 2,
89
- pxa_lcdc_8bpp = 3,
90
- pxa_lcdc_16bpp = 4,
91
- pxa_lcdc_18bpp = 5,
92
- pxa_lcdc_18pbpp = 6,
93
- pxa_lcdc_19bpp = 7,
94
- pxa_lcdc_19pbpp = 8,
95
- pxa_lcdc_24bpp = 9,
96
- pxa_lcdc_25bpp = 10,
97
- } bpp;
98
-
99
- uint32_t control[6];
100
- uint32_t status[2];
101
- uint32_t ovl1c[2];
102
- uint32_t ovl2c[2];
103
- uint32_t ccr;
104
- uint32_t cmdcr;
105
- uint32_t trgbr;
106
- uint32_t tcr;
107
- uint32_t liidr;
108
- uint8_t bscntr;
109
-
110
- struct DMAChannel dma_ch[7];
111
-
112
- qemu_irq vsync_cb;
113
- int orientation;
114
-};
115
-
116
-typedef struct QEMU_PACKED {
117
- uint32_t fdaddr;
118
- uint32_t fsaddr;
119
- uint32_t fidr;
120
- uint32_t ldcmd;
121
-} PXAFrameDescriptor;
122
-
123
-#define LCCR0 0x000 /* LCD Controller Control register 0 */
124
-#define LCCR1 0x004 /* LCD Controller Control register 1 */
125
-#define LCCR2 0x008 /* LCD Controller Control register 2 */
126
-#define LCCR3 0x00c /* LCD Controller Control register 3 */
127
-#define LCCR4 0x010 /* LCD Controller Control register 4 */
128
-#define LCCR5 0x014 /* LCD Controller Control register 5 */
129
-
130
-#define FBR0 0x020 /* DMA Channel 0 Frame Branch register */
131
-#define FBR1 0x024 /* DMA Channel 1 Frame Branch register */
132
-#define FBR2 0x028 /* DMA Channel 2 Frame Branch register */
133
-#define FBR3 0x02c /* DMA Channel 3 Frame Branch register */
134
-#define FBR4 0x030 /* DMA Channel 4 Frame Branch register */
135
-#define FBR5 0x110 /* DMA Channel 5 Frame Branch register */
136
-#define FBR6 0x114 /* DMA Channel 6 Frame Branch register */
137
-
138
-#define LCSR1 0x034 /* LCD Controller Status register 1 */
139
-#define LCSR0 0x038 /* LCD Controller Status register 0 */
140
-#define LIIDR 0x03c /* LCD Controller Interrupt ID register */
141
-
142
-#define TRGBR 0x040 /* TMED RGB Seed register */
143
-#define TCR 0x044 /* TMED Control register */
144
-
145
-#define OVL1C1 0x050 /* Overlay 1 Control register 1 */
146
-#define OVL1C2 0x060 /* Overlay 1 Control register 2 */
147
-#define OVL2C1 0x070 /* Overlay 2 Control register 1 */
148
-#define OVL2C2 0x080 /* Overlay 2 Control register 2 */
149
-#define CCR 0x090 /* Cursor Control register */
150
-
151
-#define CMDCR 0x100 /* Command Control register */
152
-#define PRSR 0x104 /* Panel Read Status register */
153
-
154
-#define PXA_LCDDMA_CHANS 7
155
-#define DMA_FDADR 0x00 /* Frame Descriptor Address register */
156
-#define DMA_FSADR 0x04 /* Frame Source Address register */
157
-#define DMA_FIDR 0x08 /* Frame ID register */
158
-#define DMA_LDCMD 0x0c /* Command register */
159
-
160
-/* LCD Buffer Strength Control register */
161
-#define BSCNTR 0x04000054
162
-
163
-/* Bitfield masks */
164
-#define LCCR0_ENB (1 << 0)
165
-#define LCCR0_CMS (1 << 1)
166
-#define LCCR0_SDS (1 << 2)
167
-#define LCCR0_LDM (1 << 3)
168
-#define LCCR0_SOFM0 (1 << 4)
169
-#define LCCR0_IUM (1 << 5)
170
-#define LCCR0_EOFM0 (1 << 6)
171
-#define LCCR0_PAS (1 << 7)
172
-#define LCCR0_DPD (1 << 9)
173
-#define LCCR0_DIS (1 << 10)
174
-#define LCCR0_QDM (1 << 11)
175
-#define LCCR0_PDD (0xff << 12)
176
-#define LCCR0_BSM0 (1 << 20)
177
-#define LCCR0_OUM (1 << 21)
178
-#define LCCR0_LCDT (1 << 22)
179
-#define LCCR0_RDSTM (1 << 23)
180
-#define LCCR0_CMDIM (1 << 24)
181
-#define LCCR0_OUC (1 << 25)
182
-#define LCCR0_LDDALT (1 << 26)
183
-#define LCCR1_PPL(x) ((x) & 0x3ff)
184
-#define LCCR2_LPP(x) ((x) & 0x3ff)
185
-#define LCCR3_API (15 << 16)
186
-#define LCCR3_BPP(x) ((((x) >> 24) & 7) | (((x) >> 26) & 8))
187
-#define LCCR3_PDFOR(x) (((x) >> 30) & 3)
188
-#define LCCR4_K1(x) (((x) >> 0) & 7)
189
-#define LCCR4_K2(x) (((x) >> 3) & 7)
190
-#define LCCR4_K3(x) (((x) >> 6) & 7)
191
-#define LCCR4_PALFOR(x) (((x) >> 15) & 3)
192
-#define LCCR5_SOFM(ch) (1 << (ch - 1))
193
-#define LCCR5_EOFM(ch) (1 << (ch + 7))
194
-#define LCCR5_BSM(ch) (1 << (ch + 15))
195
-#define LCCR5_IUM(ch) (1 << (ch + 23))
196
-#define OVLC1_EN (1 << 31)
197
-#define CCR_CEN (1 << 31)
198
-#define FBR_BRA (1 << 0)
199
-#define FBR_BINT (1 << 1)
200
-#define FBR_SRCADDR (0xfffffff << 4)
201
-#define LCSR0_LDD (1 << 0)
202
-#define LCSR0_SOF0 (1 << 1)
203
-#define LCSR0_BER (1 << 2)
204
-#define LCSR0_ABC (1 << 3)
205
-#define LCSR0_IU0 (1 << 4)
206
-#define LCSR0_IU1 (1 << 5)
207
-#define LCSR0_OU (1 << 6)
208
-#define LCSR0_QD (1 << 7)
209
-#define LCSR0_EOF0 (1 << 8)
210
-#define LCSR0_BS0 (1 << 9)
211
-#define LCSR0_SINT (1 << 10)
212
-#define LCSR0_RDST (1 << 11)
213
-#define LCSR0_CMDINT (1 << 12)
214
-#define LCSR0_BERCH(x) (((x) & 7) << 28)
215
-#define LCSR1_SOF(ch) (1 << (ch - 1))
216
-#define LCSR1_EOF(ch) (1 << (ch + 7))
217
-#define LCSR1_BS(ch) (1 << (ch + 15))
218
-#define LCSR1_IU(ch) (1 << (ch + 23))
219
-#define LDCMD_LENGTH(x) ((x) & 0x001ffffc)
220
-#define LDCMD_EOFINT (1 << 21)
221
-#define LDCMD_SOFINT (1 << 22)
222
-#define LDCMD_PAL (1 << 26)
223
-
224
-/* Size of a pixel in the QEMU UI output surface, in bytes */
225
-#define DEST_PIXEL_WIDTH 4
226
-
227
-/* Line drawing code to handle the various possible guest pixel formats */
228
-
229
-# define SKIP_PIXEL(to) do { to += deststep; } while (0)
230
-# define COPY_PIXEL(to, from) \
231
- do { \
232
- *(uint32_t *) to = from; \
233
- SKIP_PIXEL(to); \
234
- } while (0)
235
-
236
-#if HOST_BIG_ENDIAN
237
-# define SWAP_WORDS 1
238
-#endif
239
-
240
-#define FN_2(x) FN(x + 1) FN(x)
241
-#define FN_4(x) FN_2(x + 2) FN_2(x)
242
-
243
-static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src,
244
- int width, int deststep)
245
-{
246
- uint32_t *palette = opaque;
247
- uint32_t data;
248
- while (width > 0) {
249
- data = *(uint32_t *) src;
250
-#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
251
-#ifdef SWAP_WORDS
252
- FN_4(12)
253
- FN_4(8)
254
- FN_4(4)
255
- FN_4(0)
256
-#else
257
- FN_4(0)
258
- FN_4(4)
259
- FN_4(8)
260
- FN_4(12)
261
-#endif
262
-#undef FN
263
- width -= 16;
264
- src += 4;
265
- }
266
-}
267
-
268
-static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src,
269
- int width, int deststep)
270
-{
271
- uint32_t *palette = opaque;
272
- uint32_t data;
273
- while (width > 0) {
274
- data = *(uint32_t *) src;
275
-#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
276
-#ifdef SWAP_WORDS
277
- FN_2(6)
278
- FN_2(4)
279
- FN_2(2)
280
- FN_2(0)
281
-#else
282
- FN_2(0)
283
- FN_2(2)
284
- FN_2(4)
285
- FN_2(6)
286
-#endif
287
-#undef FN
288
- width -= 8;
289
- src += 4;
290
- }
291
-}
292
-
293
-static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src,
294
- int width, int deststep)
295
-{
296
- uint32_t *palette = opaque;
297
- uint32_t data;
298
- while (width > 0) {
299
- data = *(uint32_t *) src;
300
-#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
301
-#ifdef SWAP_WORDS
302
- FN(24)
303
- FN(16)
304
- FN(8)
305
- FN(0)
306
-#else
307
- FN(0)
308
- FN(8)
309
- FN(16)
310
- FN(24)
311
-#endif
312
-#undef FN
313
- width -= 4;
314
- src += 4;
315
- }
316
-}
317
-
318
-static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src,
319
- int width, int deststep)
320
-{
321
- uint32_t data;
322
- unsigned int r, g, b;
323
- while (width > 0) {
324
- data = *(uint32_t *) src;
325
-#ifdef SWAP_WORDS
326
- data = bswap32(data);
327
-#endif
328
- b = (data & 0x1f) << 3;
329
- data >>= 5;
330
- g = (data & 0x3f) << 2;
331
- data >>= 6;
332
- r = (data & 0x1f) << 3;
333
- data >>= 5;
334
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
335
- b = (data & 0x1f) << 3;
336
- data >>= 5;
337
- g = (data & 0x3f) << 2;
338
- data >>= 6;
339
- r = (data & 0x1f) << 3;
340
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
341
- width -= 2;
342
- src += 4;
343
- }
344
-}
345
-
346
-static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src,
347
- int width, int deststep)
348
-{
349
- uint32_t data;
350
- unsigned int r, g, b;
351
- while (width > 0) {
352
- data = *(uint32_t *) src;
353
-#ifdef SWAP_WORDS
354
- data = bswap32(data);
355
-#endif
356
- b = (data & 0x1f) << 3;
357
- data >>= 5;
358
- g = (data & 0x1f) << 3;
359
- data >>= 5;
360
- r = (data & 0x1f) << 3;
361
- data >>= 5;
362
- if (data & 1) {
363
- SKIP_PIXEL(dest);
364
- } else {
365
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
366
- }
367
- data >>= 1;
368
- b = (data & 0x1f) << 3;
369
- data >>= 5;
370
- g = (data & 0x1f) << 3;
371
- data >>= 5;
372
- r = (data & 0x1f) << 3;
373
- data >>= 5;
374
- if (data & 1) {
375
- SKIP_PIXEL(dest);
376
- } else {
377
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
378
- }
379
- width -= 2;
380
- src += 4;
381
- }
382
-}
383
-
384
-static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src,
385
- int width, int deststep)
386
-{
387
- uint32_t data;
388
- unsigned int r, g, b;
389
- while (width > 0) {
390
- data = *(uint32_t *) src;
391
-#ifdef SWAP_WORDS
392
- data = bswap32(data);
393
-#endif
394
- b = (data & 0x3f) << 2;
395
- data >>= 6;
396
- g = (data & 0x3f) << 2;
397
- data >>= 6;
398
- r = (data & 0x3f) << 2;
399
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
400
- width -= 1;
401
- src += 4;
402
- }
403
-}
404
-
405
-/* The wicked packed format */
406
-static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src,
407
- int width, int deststep)
408
-{
409
- uint32_t data[3];
410
- unsigned int r, g, b;
411
- while (width > 0) {
412
- data[0] = *(uint32_t *) src;
413
- src += 4;
414
- data[1] = *(uint32_t *) src;
415
- src += 4;
416
- data[2] = *(uint32_t *) src;
417
- src += 4;
418
-#ifdef SWAP_WORDS
419
- data[0] = bswap32(data[0]);
420
- data[1] = bswap32(data[1]);
421
- data[2] = bswap32(data[2]);
422
-#endif
423
- b = (data[0] & 0x3f) << 2;
424
- data[0] >>= 6;
425
- g = (data[0] & 0x3f) << 2;
426
- data[0] >>= 6;
427
- r = (data[0] & 0x3f) << 2;
428
- data[0] >>= 12;
429
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
430
- b = (data[0] & 0x3f) << 2;
431
- data[0] >>= 6;
432
- g = ((data[1] & 0xf) << 4) | (data[0] << 2);
433
- data[1] >>= 4;
434
- r = (data[1] & 0x3f) << 2;
435
- data[1] >>= 12;
436
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
437
- b = (data[1] & 0x3f) << 2;
438
- data[1] >>= 6;
439
- g = (data[1] & 0x3f) << 2;
440
- data[1] >>= 6;
441
- r = ((data[2] & 0x3) << 6) | (data[1] << 2);
442
- data[2] >>= 8;
443
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
444
- b = (data[2] & 0x3f) << 2;
445
- data[2] >>= 6;
446
- g = (data[2] & 0x3f) << 2;
447
- data[2] >>= 6;
448
- r = data[2] << 2;
449
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
450
- width -= 4;
451
- }
452
-}
453
-
454
-static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src,
455
- int width, int deststep)
456
-{
457
- uint32_t data;
458
- unsigned int r, g, b;
459
- while (width > 0) {
460
- data = *(uint32_t *) src;
461
-#ifdef SWAP_WORDS
462
- data = bswap32(data);
463
-#endif
464
- b = (data & 0x3f) << 2;
465
- data >>= 6;
466
- g = (data & 0x3f) << 2;
467
- data >>= 6;
468
- r = (data & 0x3f) << 2;
469
- data >>= 6;
470
- if (data & 1) {
471
- SKIP_PIXEL(dest);
472
- } else {
473
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
474
- }
475
- width -= 1;
476
- src += 4;
477
- }
478
-}
479
-
480
-/* The wicked packed format */
481
-static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src,
482
- int width, int deststep)
483
-{
484
- uint32_t data[3];
485
- unsigned int r, g, b;
486
- while (width > 0) {
487
- data[0] = *(uint32_t *) src;
488
- src += 4;
489
- data[1] = *(uint32_t *) src;
490
- src += 4;
491
- data[2] = *(uint32_t *) src;
492
- src += 4;
493
-# ifdef SWAP_WORDS
494
- data[0] = bswap32(data[0]);
495
- data[1] = bswap32(data[1]);
496
- data[2] = bswap32(data[2]);
497
-# endif
498
- b = (data[0] & 0x3f) << 2;
499
- data[0] >>= 6;
500
- g = (data[0] & 0x3f) << 2;
501
- data[0] >>= 6;
502
- r = (data[0] & 0x3f) << 2;
503
- data[0] >>= 6;
504
- if (data[0] & 1) {
505
- SKIP_PIXEL(dest);
506
- } else {
507
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
508
- }
509
- data[0] >>= 6;
510
- b = (data[0] & 0x3f) << 2;
511
- data[0] >>= 6;
512
- g = ((data[1] & 0xf) << 4) | (data[0] << 2);
513
- data[1] >>= 4;
514
- r = (data[1] & 0x3f) << 2;
515
- data[1] >>= 6;
516
- if (data[1] & 1) {
517
- SKIP_PIXEL(dest);
518
- } else {
519
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
520
- }
521
- data[1] >>= 6;
522
- b = (data[1] & 0x3f) << 2;
523
- data[1] >>= 6;
524
- g = (data[1] & 0x3f) << 2;
525
- data[1] >>= 6;
526
- r = ((data[2] & 0x3) << 6) | (data[1] << 2);
527
- data[2] >>= 2;
528
- if (data[2] & 1) {
529
- SKIP_PIXEL(dest);
530
- } else {
531
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
532
- }
533
- data[2] >>= 6;
534
- b = (data[2] & 0x3f) << 2;
535
- data[2] >>= 6;
536
- g = (data[2] & 0x3f) << 2;
537
- data[2] >>= 6;
538
- r = data[2] << 2;
539
- data[2] >>= 6;
540
- if (data[2] & 1) {
541
- SKIP_PIXEL(dest);
542
- } else {
543
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
544
- }
545
- width -= 4;
546
- }
547
-}
548
-
549
-static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src,
550
- int width, int deststep)
551
-{
552
- uint32_t data;
553
- unsigned int r, g, b;
554
- while (width > 0) {
555
- data = *(uint32_t *) src;
556
-#ifdef SWAP_WORDS
557
- data = bswap32(data);
558
-#endif
559
- b = data & 0xff;
560
- data >>= 8;
561
- g = data & 0xff;
562
- data >>= 8;
563
- r = data & 0xff;
564
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
565
- width -= 1;
566
- src += 4;
567
- }
568
-}
569
-
570
-static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src,
571
- int width, int deststep)
572
-{
573
- uint32_t data;
574
- unsigned int r, g, b;
575
- while (width > 0) {
576
- data = *(uint32_t *) src;
577
-#ifdef SWAP_WORDS
578
- data = bswap32(data);
579
-#endif
580
- b = (data & 0x7f) << 1;
581
- data >>= 7;
582
- g = data & 0xff;
583
- data >>= 8;
584
- r = data & 0xff;
585
- data >>= 8;
586
- if (data & 1) {
587
- SKIP_PIXEL(dest);
588
- } else {
589
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
590
- }
591
- width -= 1;
592
- src += 4;
593
- }
594
-}
595
-
596
-static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src,
597
- int width, int deststep)
598
-{
599
- uint32_t data;
600
- unsigned int r, g, b;
601
- while (width > 0) {
602
- data = *(uint32_t *) src;
603
-#ifdef SWAP_WORDS
604
- data = bswap32(data);
605
-#endif
606
- b = data & 0xff;
607
- data >>= 8;
608
- g = data & 0xff;
609
- data >>= 8;
610
- r = data & 0xff;
611
- data >>= 8;
612
- if (data & 1) {
613
- SKIP_PIXEL(dest);
614
- } else {
615
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
616
- }
617
- width -= 1;
618
- src += 4;
619
- }
620
-}
621
-
622
-/* Overlay planes disabled, no transparency */
623
-static drawfn pxa2xx_draw_fn_32[16] = {
624
- [0 ... 0xf] = NULL,
625
- [pxa_lcdc_2bpp] = pxa2xx_draw_line2,
626
- [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
627
- [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
628
- [pxa_lcdc_16bpp] = pxa2xx_draw_line16,
629
- [pxa_lcdc_18bpp] = pxa2xx_draw_line18,
630
- [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p,
631
- [pxa_lcdc_24bpp] = pxa2xx_draw_line24,
632
-};
633
-
634
-/* Overlay planes enabled, transparency used */
635
-static drawfn pxa2xx_draw_fn_32t[16] = {
636
- [0 ... 0xf] = NULL,
637
- [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
638
- [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
639
- [pxa_lcdc_16bpp] = pxa2xx_draw_line16t,
640
- [pxa_lcdc_19bpp] = pxa2xx_draw_line19,
641
- [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p,
642
- [pxa_lcdc_24bpp] = pxa2xx_draw_line24t,
643
- [pxa_lcdc_25bpp] = pxa2xx_draw_line25,
644
-};
645
-
646
-#undef COPY_PIXEL
647
-#undef SKIP_PIXEL
648
-
649
-#ifdef SWAP_WORDS
650
-# undef SWAP_WORDS
651
-#endif
652
-
653
-/* Route internal interrupt lines to the global IC */
654
-static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
655
-{
656
- int level = 0;
657
- level |= (s->status[0] & LCSR0_LDD) && !(s->control[0] & LCCR0_LDM);
658
- level |= (s->status[0] & LCSR0_SOF0) && !(s->control[0] & LCCR0_SOFM0);
659
- level |= (s->status[0] & LCSR0_IU0) && !(s->control[0] & LCCR0_IUM);
660
- level |= (s->status[0] & LCSR0_IU1) && !(s->control[5] & LCCR5_IUM(1));
661
- level |= (s->status[0] & LCSR0_OU) && !(s->control[0] & LCCR0_OUM);
662
- level |= (s->status[0] & LCSR0_QD) && !(s->control[0] & LCCR0_QDM);
663
- level |= (s->status[0] & LCSR0_EOF0) && !(s->control[0] & LCCR0_EOFM0);
664
- level |= (s->status[0] & LCSR0_BS0) && !(s->control[0] & LCCR0_BSM0);
665
- level |= (s->status[0] & LCSR0_RDST) && !(s->control[0] & LCCR0_RDSTM);
666
- level |= (s->status[0] & LCSR0_CMDINT) && !(s->control[0] & LCCR0_CMDIM);
667
- level |= (s->status[1] & ~s->control[5]);
668
-
669
- qemu_set_irq(s->irq, !!level);
670
- s->irqlevel = level;
671
-}
672
-
673
-/* Set Branch Status interrupt high and poke associated registers */
674
-static inline void pxa2xx_dma_bs_set(PXA2xxLCDState *s, int ch)
675
-{
676
- int unmasked;
677
- if (ch == 0) {
678
- s->status[0] |= LCSR0_BS0;
679
- unmasked = !(s->control[0] & LCCR0_BSM0);
680
- } else {
681
- s->status[1] |= LCSR1_BS(ch);
682
- unmasked = !(s->control[5] & LCCR5_BSM(ch));
683
- }
684
-
685
- if (unmasked) {
686
- if (s->irqlevel)
687
- s->status[0] |= LCSR0_SINT;
688
- else
689
- s->liidr = s->dma_ch[ch].id;
690
- }
691
-}
692
-
693
-/* Set Start Of Frame Status interrupt high and poke associated registers */
694
-static inline void pxa2xx_dma_sof_set(PXA2xxLCDState *s, int ch)
695
-{
696
- int unmasked;
697
- if (!(s->dma_ch[ch].command & LDCMD_SOFINT))
698
- return;
699
-
700
- if (ch == 0) {
701
- s->status[0] |= LCSR0_SOF0;
702
- unmasked = !(s->control[0] & LCCR0_SOFM0);
703
- } else {
704
- s->status[1] |= LCSR1_SOF(ch);
705
- unmasked = !(s->control[5] & LCCR5_SOFM(ch));
706
- }
707
-
708
- if (unmasked) {
709
- if (s->irqlevel)
710
- s->status[0] |= LCSR0_SINT;
711
- else
712
- s->liidr = s->dma_ch[ch].id;
713
- }
714
-}
715
-
716
-/* Set End Of Frame Status interrupt high and poke associated registers */
717
-static inline void pxa2xx_dma_eof_set(PXA2xxLCDState *s, int ch)
718
-{
719
- int unmasked;
720
- if (!(s->dma_ch[ch].command & LDCMD_EOFINT))
721
- return;
722
-
723
- if (ch == 0) {
724
- s->status[0] |= LCSR0_EOF0;
725
- unmasked = !(s->control[0] & LCCR0_EOFM0);
726
- } else {
727
- s->status[1] |= LCSR1_EOF(ch);
728
- unmasked = !(s->control[5] & LCCR5_EOFM(ch));
729
- }
730
-
731
- if (unmasked) {
732
- if (s->irqlevel)
733
- s->status[0] |= LCSR0_SINT;
734
- else
735
- s->liidr = s->dma_ch[ch].id;
736
- }
737
-}
738
-
739
-/* Set Bus Error Status interrupt high and poke associated registers */
740
-static inline void pxa2xx_dma_ber_set(PXA2xxLCDState *s, int ch)
741
-{
742
- s->status[0] |= LCSR0_BERCH(ch) | LCSR0_BER;
743
- if (s->irqlevel)
744
- s->status[0] |= LCSR0_SINT;
745
- else
746
- s->liidr = s->dma_ch[ch].id;
747
-}
748
-
749
-/* Load new Frame Descriptors from DMA */
750
-static void pxa2xx_descriptor_load(PXA2xxLCDState *s)
751
-{
752
- PXAFrameDescriptor desc;
753
- hwaddr descptr;
754
- int i;
755
-
756
- for (i = 0; i < PXA_LCDDMA_CHANS; i ++) {
757
- s->dma_ch[i].source = 0;
758
-
759
- if (!s->dma_ch[i].up)
760
- continue;
761
-
762
- if (s->dma_ch[i].branch & FBR_BRA) {
763
- descptr = s->dma_ch[i].branch & FBR_SRCADDR;
764
- if (s->dma_ch[i].branch & FBR_BINT)
765
- pxa2xx_dma_bs_set(s, i);
766
- s->dma_ch[i].branch &= ~FBR_BRA;
767
- } else
768
- descptr = s->dma_ch[i].descriptor;
769
-
770
- if (!((descptr >= PXA2XX_SDRAM_BASE && descptr +
771
- sizeof(desc) <= PXA2XX_SDRAM_BASE + current_machine->ram_size) ||
772
- (descptr >= PXA2XX_INTERNAL_BASE && descptr + sizeof(desc) <=
773
- PXA2XX_INTERNAL_BASE + PXA2XX_INTERNAL_SIZE))) {
774
- continue;
775
- }
776
-
777
- cpu_physical_memory_read(descptr, &desc, sizeof(desc));
778
- s->dma_ch[i].descriptor = le32_to_cpu(desc.fdaddr);
779
- s->dma_ch[i].source = le32_to_cpu(desc.fsaddr);
780
- s->dma_ch[i].id = le32_to_cpu(desc.fidr);
781
- s->dma_ch[i].command = le32_to_cpu(desc.ldcmd);
782
- }
783
-}
784
-
785
-static uint64_t pxa2xx_lcdc_read(void *opaque, hwaddr offset,
786
- unsigned size)
787
-{
788
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
789
- int ch;
790
-
791
- switch (offset) {
792
- case LCCR0:
793
- return s->control[0];
794
- case LCCR1:
795
- return s->control[1];
796
- case LCCR2:
797
- return s->control[2];
798
- case LCCR3:
799
- return s->control[3];
800
- case LCCR4:
801
- return s->control[4];
802
- case LCCR5:
803
- return s->control[5];
804
-
805
- case OVL1C1:
806
- return s->ovl1c[0];
807
- case OVL1C2:
808
- return s->ovl1c[1];
809
- case OVL2C1:
810
- return s->ovl2c[0];
811
- case OVL2C2:
812
- return s->ovl2c[1];
813
-
814
- case CCR:
815
- return s->ccr;
816
-
817
- case CMDCR:
818
- return s->cmdcr;
819
-
820
- case TRGBR:
821
- return s->trgbr;
822
- case TCR:
823
- return s->tcr;
824
-
825
- case 0x200 ... 0x1000: /* DMA per-channel registers */
826
- ch = (offset - 0x200) >> 4;
827
- if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS))
828
- goto fail;
829
-
830
- switch (offset & 0xf) {
831
- case DMA_FDADR:
832
- return s->dma_ch[ch].descriptor;
833
- case DMA_FSADR:
834
- return s->dma_ch[ch].source;
835
- case DMA_FIDR:
836
- return s->dma_ch[ch].id;
837
- case DMA_LDCMD:
838
- return s->dma_ch[ch].command;
839
- default:
840
- goto fail;
841
- }
842
-
843
- case FBR0:
844
- return s->dma_ch[0].branch;
845
- case FBR1:
846
- return s->dma_ch[1].branch;
847
- case FBR2:
848
- return s->dma_ch[2].branch;
849
- case FBR3:
850
- return s->dma_ch[3].branch;
851
- case FBR4:
852
- return s->dma_ch[4].branch;
853
- case FBR5:
854
- return s->dma_ch[5].branch;
855
- case FBR6:
856
- return s->dma_ch[6].branch;
857
-
858
- case BSCNTR:
859
- return s->bscntr;
860
-
861
- case PRSR:
862
- return 0;
863
-
864
- case LCSR0:
865
- return s->status[0];
866
- case LCSR1:
867
- return s->status[1];
868
- case LIIDR:
869
- return s->liidr;
870
-
871
- default:
872
- fail:
873
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
874
- __func__, offset);
875
- }
876
-
877
- return 0;
878
-}
879
-
880
-static void pxa2xx_lcdc_write(void *opaque, hwaddr offset,
881
- uint64_t value, unsigned size)
882
-{
883
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
884
- int ch;
885
-
886
- switch (offset) {
887
- case LCCR0:
888
- /* ACK Quick Disable done */
889
- if ((s->control[0] & LCCR0_ENB) && !(value & LCCR0_ENB))
890
- s->status[0] |= LCSR0_QD;
891
-
892
- if (!(s->control[0] & LCCR0_LCDT) && (value & LCCR0_LCDT)) {
893
- qemu_log_mask(LOG_UNIMP,
894
- "%s: internal frame buffer unsupported\n", __func__);
895
- }
896
- if ((s->control[3] & LCCR3_API) &&
897
- (value & LCCR0_ENB) && !(value & LCCR0_LCDT))
898
- s->status[0] |= LCSR0_ABC;
899
-
900
- s->control[0] = value & 0x07ffffff;
901
- pxa2xx_lcdc_int_update(s);
902
-
903
- s->dma_ch[0].up = !!(value & LCCR0_ENB);
904
- s->dma_ch[1].up = (s->ovl1c[0] & OVLC1_EN) || (value & LCCR0_SDS);
905
- break;
906
-
907
- case LCCR1:
908
- s->control[1] = value;
909
- break;
910
-
911
- case LCCR2:
912
- s->control[2] = value;
913
- break;
914
-
915
- case LCCR3:
916
- s->control[3] = value & 0xefffffff;
917
- s->bpp = LCCR3_BPP(value);
918
- break;
919
-
920
- case LCCR4:
921
- s->control[4] = value & 0x83ff81ff;
922
- break;
923
-
924
- case LCCR5:
925
- s->control[5] = value & 0x3f3f3f3f;
926
- break;
927
-
928
- case OVL1C1:
929
- if (!(s->ovl1c[0] & OVLC1_EN) && (value & OVLC1_EN)) {
930
- qemu_log_mask(LOG_UNIMP, "%s: Overlay 1 not supported\n", __func__);
931
- }
932
- s->ovl1c[0] = value & 0x80ffffff;
933
- s->dma_ch[1].up = (value & OVLC1_EN) || (s->control[0] & LCCR0_SDS);
934
- break;
935
-
936
- case OVL1C2:
937
- s->ovl1c[1] = value & 0x000fffff;
938
- break;
939
-
940
- case OVL2C1:
941
- if (!(s->ovl2c[0] & OVLC1_EN) && (value & OVLC1_EN)) {
942
- qemu_log_mask(LOG_UNIMP, "%s: Overlay 2 not supported\n", __func__);
943
- }
944
- s->ovl2c[0] = value & 0x80ffffff;
945
- s->dma_ch[2].up = !!(value & OVLC1_EN);
946
- s->dma_ch[3].up = !!(value & OVLC1_EN);
947
- s->dma_ch[4].up = !!(value & OVLC1_EN);
948
- break;
949
-
950
- case OVL2C2:
951
- s->ovl2c[1] = value & 0x007fffff;
952
- break;
953
-
954
- case CCR:
955
- if (!(s->ccr & CCR_CEN) && (value & CCR_CEN)) {
956
- qemu_log_mask(LOG_UNIMP,
957
- "%s: Hardware cursor unimplemented\n", __func__);
958
- }
959
- s->ccr = value & 0x81ffffe7;
960
- s->dma_ch[5].up = !!(value & CCR_CEN);
961
- break;
962
-
963
- case CMDCR:
964
- s->cmdcr = value & 0xff;
965
- break;
966
-
967
- case TRGBR:
968
- s->trgbr = value & 0x00ffffff;
969
- break;
970
-
971
- case TCR:
972
- s->tcr = value & 0x7fff;
973
- break;
974
-
975
- case 0x200 ... 0x1000: /* DMA per-channel registers */
976
- ch = (offset - 0x200) >> 4;
977
- if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS))
978
- goto fail;
979
-
980
- switch (offset & 0xf) {
981
- case DMA_FDADR:
982
- s->dma_ch[ch].descriptor = value & 0xfffffff0;
983
- break;
984
-
985
- default:
986
- goto fail;
987
- }
988
- break;
989
-
990
- case FBR0:
991
- s->dma_ch[0].branch = value & 0xfffffff3;
992
- break;
993
- case FBR1:
994
- s->dma_ch[1].branch = value & 0xfffffff3;
995
- break;
996
- case FBR2:
997
- s->dma_ch[2].branch = value & 0xfffffff3;
998
- break;
999
- case FBR3:
1000
- s->dma_ch[3].branch = value & 0xfffffff3;
1001
- break;
1002
- case FBR4:
1003
- s->dma_ch[4].branch = value & 0xfffffff3;
1004
- break;
1005
- case FBR5:
1006
- s->dma_ch[5].branch = value & 0xfffffff3;
1007
- break;
1008
- case FBR6:
1009
- s->dma_ch[6].branch = value & 0xfffffff3;
1010
- break;
1011
-
1012
- case BSCNTR:
1013
- s->bscntr = value & 0xf;
1014
- break;
1015
-
1016
- case PRSR:
1017
- break;
1018
-
1019
- case LCSR0:
1020
- s->status[0] &= ~(value & 0xfff);
1021
- if (value & LCSR0_BER)
1022
- s->status[0] &= ~LCSR0_BERCH(7);
1023
- break;
1024
-
1025
- case LCSR1:
1026
- s->status[1] &= ~(value & 0x3e3f3f);
1027
- break;
1028
-
1029
- default:
1030
- fail:
1031
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
1032
- __func__, offset);
1033
- }
1034
-}
1035
-
1036
-static const MemoryRegionOps pxa2xx_lcdc_ops = {
1037
- .read = pxa2xx_lcdc_read,
1038
- .write = pxa2xx_lcdc_write,
1039
- .endianness = DEVICE_NATIVE_ENDIAN,
1040
-};
1041
-
1042
-/* Load new palette for a given DMA channel, convert to internal format */
1043
-static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
1044
-{
1045
- DisplaySurface *surface = qemu_console_surface(s->con);
1046
- int i, n, format, r, g, b, alpha;
1047
- uint32_t *dest;
1048
- uint8_t *src;
1049
- s->pal_for = LCCR4_PALFOR(s->control[4]);
1050
- format = s->pal_for;
1051
-
1052
- switch (bpp) {
1053
- case pxa_lcdc_2bpp:
1054
- n = 4;
1055
- break;
1056
- case pxa_lcdc_4bpp:
1057
- n = 16;
1058
- break;
1059
- case pxa_lcdc_8bpp:
1060
- n = 256;
1061
- break;
1062
- default:
1063
- return;
1064
- }
1065
-
1066
- src = (uint8_t *) s->dma_ch[ch].pbuffer;
1067
- dest = (uint32_t *) s->dma_ch[ch].palette;
1068
- alpha = r = g = b = 0;
1069
-
1070
- for (i = 0; i < n; i ++) {
1071
- switch (format) {
1072
- case 0: /* 16 bpp, no transparency */
1073
- alpha = 0;
1074
- if (s->control[0] & LCCR0_CMS) {
1075
- r = g = b = *(uint16_t *) src & 0xff;
1076
- }
1077
- else {
1078
- r = (*(uint16_t *) src & 0xf800) >> 8;
1079
- g = (*(uint16_t *) src & 0x07e0) >> 3;
1080
- b = (*(uint16_t *) src & 0x001f) << 3;
1081
- }
1082
- src += 2;
1083
- break;
1084
- case 1: /* 16 bpp plus transparency */
1085
- alpha = *(uint32_t *) src & (1 << 24);
1086
- if (s->control[0] & LCCR0_CMS)
1087
- r = g = b = *(uint32_t *) src & 0xff;
1088
- else {
1089
- r = (*(uint32_t *) src & 0xf80000) >> 16;
1090
- g = (*(uint32_t *) src & 0x00fc00) >> 8;
1091
- b = (*(uint32_t *) src & 0x0000f8);
1092
- }
1093
- src += 4;
1094
- break;
1095
- case 2: /* 18 bpp plus transparency */
1096
- alpha = *(uint32_t *) src & (1 << 24);
1097
- if (s->control[0] & LCCR0_CMS)
1098
- r = g = b = *(uint32_t *) src & 0xff;
1099
- else {
1100
- r = (*(uint32_t *) src & 0xfc0000) >> 16;
1101
- g = (*(uint32_t *) src & 0x00fc00) >> 8;
1102
- b = (*(uint32_t *) src & 0x0000fc);
1103
- }
1104
- src += 4;
1105
- break;
1106
- case 3: /* 24 bpp plus transparency */
1107
- alpha = *(uint32_t *) src & (1 << 24);
1108
- if (s->control[0] & LCCR0_CMS)
1109
- r = g = b = *(uint32_t *) src & 0xff;
1110
- else {
1111
- r = (*(uint32_t *) src & 0xff0000) >> 16;
1112
- g = (*(uint32_t *) src & 0x00ff00) >> 8;
1113
- b = (*(uint32_t *) src & 0x0000ff);
1114
- }
1115
- src += 4;
1116
- break;
1117
- }
1118
- switch (surface_bits_per_pixel(surface)) {
1119
- case 8:
1120
- *dest = rgb_to_pixel8(r, g, b) | alpha;
1121
- break;
1122
- case 15:
1123
- *dest = rgb_to_pixel15(r, g, b) | alpha;
1124
- break;
1125
- case 16:
1126
- *dest = rgb_to_pixel16(r, g, b) | alpha;
1127
- break;
1128
- case 24:
1129
- *dest = rgb_to_pixel24(r, g, b) | alpha;
1130
- break;
1131
- case 32:
1132
- *dest = rgb_to_pixel32(r, g, b) | alpha;
1133
- break;
1134
- }
1135
- dest ++;
1136
- }
1137
-}
1138
-
1139
-static inline drawfn pxa2xx_drawfn(PXA2xxLCDState *s)
1140
-{
1141
- if (s->transp) {
1142
- return pxa2xx_draw_fn_32t[s->bpp];
1143
- } else {
1144
- return pxa2xx_draw_fn_32[s->bpp];
1145
- }
1146
-}
1147
-
1148
-static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
1149
- hwaddr addr, int *miny, int *maxy)
1150
-{
1151
- DisplaySurface *surface = qemu_console_surface(s->con);
1152
- int src_width, dest_width;
1153
- drawfn fn = pxa2xx_drawfn(s);
1154
- if (!fn)
1155
- return;
1156
-
1157
- src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
1158
- if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
1159
- src_width *= 3;
1160
- else if (s->bpp > pxa_lcdc_16bpp)
1161
- src_width *= 4;
1162
- else if (s->bpp > pxa_lcdc_8bpp)
1163
- src_width *= 2;
1164
-
1165
- dest_width = s->xres * DEST_PIXEL_WIDTH;
1166
- *miny = 0;
1167
- if (s->invalidated) {
1168
- framebuffer_update_memory_section(&s->fbsection, s->sysmem,
1169
- addr, s->yres, src_width);
1170
- }
1171
- framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
1172
- src_width, dest_width, DEST_PIXEL_WIDTH,
1173
- s->invalidated,
1174
- fn, s->dma_ch[0].palette, miny, maxy);
1175
-}
1176
-
1177
-static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
1178
- hwaddr addr, int *miny, int *maxy)
1179
-{
1180
- DisplaySurface *surface = qemu_console_surface(s->con);
1181
- int src_width, dest_width;
1182
- drawfn fn = pxa2xx_drawfn(s);
1183
- if (!fn)
1184
- return;
1185
-
1186
- src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
1187
- if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
1188
- src_width *= 3;
1189
- else if (s->bpp > pxa_lcdc_16bpp)
1190
- src_width *= 4;
1191
- else if (s->bpp > pxa_lcdc_8bpp)
1192
- src_width *= 2;
1193
-
1194
- dest_width = s->yres * DEST_PIXEL_WIDTH;
1195
- *miny = 0;
1196
- if (s->invalidated) {
1197
- framebuffer_update_memory_section(&s->fbsection, s->sysmem,
1198
- addr, s->yres, src_width);
1199
- }
1200
- framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
1201
- src_width, DEST_PIXEL_WIDTH, -dest_width,
1202
- s->invalidated,
1203
- fn, s->dma_ch[0].palette,
1204
- miny, maxy);
1205
-}
1206
-
1207
-static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
1208
- hwaddr addr, int *miny, int *maxy)
1209
-{
1210
- DisplaySurface *surface = qemu_console_surface(s->con);
1211
- int src_width, dest_width;
1212
- drawfn fn = pxa2xx_drawfn(s);
1213
- if (!fn) {
1214
- return;
1215
- }
1216
-
1217
- src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
1218
- if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) {
1219
- src_width *= 3;
1220
- } else if (s->bpp > pxa_lcdc_16bpp) {
1221
- src_width *= 4;
1222
- } else if (s->bpp > pxa_lcdc_8bpp) {
1223
- src_width *= 2;
1224
- }
1225
-
1226
- dest_width = s->xres * DEST_PIXEL_WIDTH;
1227
- *miny = 0;
1228
- if (s->invalidated) {
1229
- framebuffer_update_memory_section(&s->fbsection, s->sysmem,
1230
- addr, s->yres, src_width);
1231
- }
1232
- framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
1233
- src_width, -dest_width, -DEST_PIXEL_WIDTH,
1234
- s->invalidated,
1235
- fn, s->dma_ch[0].palette, miny, maxy);
1236
-}
1237
-
1238
-static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
1239
- hwaddr addr, int *miny, int *maxy)
1240
-{
1241
- DisplaySurface *surface = qemu_console_surface(s->con);
1242
- int src_width, dest_width;
1243
- drawfn fn = pxa2xx_drawfn(s);
1244
- if (!fn) {
1245
- return;
1246
- }
1247
-
1248
- src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
1249
- if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) {
1250
- src_width *= 3;
1251
- } else if (s->bpp > pxa_lcdc_16bpp) {
1252
- src_width *= 4;
1253
- } else if (s->bpp > pxa_lcdc_8bpp) {
1254
- src_width *= 2;
1255
- }
1256
-
1257
- dest_width = s->yres * DEST_PIXEL_WIDTH;
1258
- *miny = 0;
1259
- if (s->invalidated) {
1260
- framebuffer_update_memory_section(&s->fbsection, s->sysmem,
1261
- addr, s->yres, src_width);
1262
- }
1263
- framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
1264
- src_width, -DEST_PIXEL_WIDTH, dest_width,
1265
- s->invalidated,
1266
- fn, s->dma_ch[0].palette,
1267
- miny, maxy);
1268
-}
1269
-
1270
-static void pxa2xx_lcdc_resize(PXA2xxLCDState *s)
1271
-{
1272
- int width, height;
1273
- if (!(s->control[0] & LCCR0_ENB))
1274
- return;
1275
-
1276
- width = LCCR1_PPL(s->control[1]) + 1;
1277
- height = LCCR2_LPP(s->control[2]) + 1;
1278
-
1279
- if (width != s->xres || height != s->yres) {
1280
- if (s->orientation == 90 || s->orientation == 270) {
1281
- qemu_console_resize(s->con, height, width);
1282
- } else {
1283
- qemu_console_resize(s->con, width, height);
1284
- }
1285
- s->invalidated = 1;
1286
- s->xres = width;
1287
- s->yres = height;
1288
- }
1289
-}
1290
-
1291
-static void pxa2xx_update_display(void *opaque)
1292
-{
1293
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
1294
- hwaddr fbptr;
1295
- int miny, maxy;
1296
- int ch;
1297
- if (!(s->control[0] & LCCR0_ENB))
1298
- return;
1299
-
1300
- pxa2xx_descriptor_load(s);
1301
-
1302
- pxa2xx_lcdc_resize(s);
1303
- miny = s->yres;
1304
- maxy = 0;
1305
- s->transp = s->dma_ch[2].up || s->dma_ch[3].up;
1306
- /* Note: With overlay planes the order depends on LCCR0 bit 25. */
1307
- for (ch = 0; ch < PXA_LCDDMA_CHANS; ch ++)
1308
- if (s->dma_ch[ch].up) {
1309
- if (!s->dma_ch[ch].source) {
1310
- pxa2xx_dma_ber_set(s, ch);
1311
- continue;
1312
- }
1313
- fbptr = s->dma_ch[ch].source;
1314
- if (!((fbptr >= PXA2XX_SDRAM_BASE &&
1315
- fbptr <= PXA2XX_SDRAM_BASE + current_machine->ram_size) ||
1316
- (fbptr >= PXA2XX_INTERNAL_BASE &&
1317
- fbptr <= PXA2XX_INTERNAL_BASE + PXA2XX_INTERNAL_SIZE))) {
1318
- pxa2xx_dma_ber_set(s, ch);
1319
- continue;
1320
- }
1321
-
1322
- if (s->dma_ch[ch].command & LDCMD_PAL) {
1323
- cpu_physical_memory_read(fbptr, s->dma_ch[ch].pbuffer,
1324
- MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
1325
- sizeof(s->dma_ch[ch].pbuffer)));
1326
- pxa2xx_palette_parse(s, ch, s->bpp);
1327
- } else {
1328
- /* Do we need to reparse palette */
1329
- if (LCCR4_PALFOR(s->control[4]) != s->pal_for)
1330
- pxa2xx_palette_parse(s, ch, s->bpp);
1331
-
1332
- /* ACK frame start */
1333
- pxa2xx_dma_sof_set(s, ch);
1334
-
1335
- s->dma_ch[ch].redraw(s, fbptr, &miny, &maxy);
1336
- s->invalidated = 0;
1337
-
1338
- /* ACK frame completed */
1339
- pxa2xx_dma_eof_set(s, ch);
1340
- }
1341
- }
1342
-
1343
- if (s->control[0] & LCCR0_DIS) {
1344
- /* ACK last frame completed */
1345
- s->control[0] &= ~LCCR0_ENB;
1346
- s->status[0] |= LCSR0_LDD;
1347
- }
1348
-
1349
- if (miny >= 0) {
1350
- switch (s->orientation) {
1351
- case 0:
1352
- dpy_gfx_update(s->con, 0, miny, s->xres, maxy - miny + 1);
1353
- break;
1354
- case 90:
1355
- dpy_gfx_update(s->con, miny, 0, maxy - miny + 1, s->xres);
1356
- break;
1357
- case 180:
1358
- maxy = s->yres - maxy - 1;
1359
- miny = s->yres - miny - 1;
1360
- dpy_gfx_update(s->con, 0, maxy, s->xres, miny - maxy + 1);
1361
- break;
1362
- case 270:
1363
- maxy = s->yres - maxy - 1;
1364
- miny = s->yres - miny - 1;
1365
- dpy_gfx_update(s->con, maxy, 0, miny - maxy + 1, s->xres);
1366
- break;
1367
- }
1368
- }
1369
- pxa2xx_lcdc_int_update(s);
1370
-
1371
- qemu_irq_raise(s->vsync_cb);
1372
-}
1373
-
1374
-static void pxa2xx_invalidate_display(void *opaque)
1375
-{
1376
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
1377
- s->invalidated = 1;
1378
-}
1379
-
1380
-static void pxa2xx_lcdc_orientation(void *opaque, int angle)
1381
-{
1382
- PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
1383
-
1384
- switch (angle) {
1385
- case 0:
1386
- s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot0;
1387
- break;
1388
- case 90:
1389
- s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot90;
1390
- break;
1391
- case 180:
1392
- s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot180;
1393
- break;
1394
- case 270:
1395
- s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot270;
1396
- break;
1397
- }
1398
-
1399
- s->orientation = angle;
1400
- s->xres = s->yres = -1;
1401
- pxa2xx_lcdc_resize(s);
1402
-}
1403
-
1404
-static const VMStateDescription vmstate_dma_channel = {
1405
- .name = "dma_channel",
1406
- .version_id = 0,
1407
- .minimum_version_id = 0,
1408
- .fields = (const VMStateField[]) {
1409
- VMSTATE_UINT32(branch, struct DMAChannel),
1410
- VMSTATE_UINT8(up, struct DMAChannel),
1411
- VMSTATE_BUFFER(pbuffer, struct DMAChannel),
1412
- VMSTATE_UINT32(descriptor, struct DMAChannel),
1413
- VMSTATE_UINT32(source, struct DMAChannel),
1414
- VMSTATE_UINT32(id, struct DMAChannel),
1415
- VMSTATE_UINT32(command, struct DMAChannel),
1416
- VMSTATE_END_OF_LIST()
1417
- }
1418
-};
1419
-
1420
-static int pxa2xx_lcdc_post_load(void *opaque, int version_id)
1421
-{
1422
- PXA2xxLCDState *s = opaque;
1423
-
1424
- s->bpp = LCCR3_BPP(s->control[3]);
1425
- s->xres = s->yres = s->pal_for = -1;
1426
-
1427
- return 0;
1428
-}
1429
-
1430
-static const VMStateDescription vmstate_pxa2xx_lcdc = {
1431
- .name = "pxa2xx_lcdc",
1432
- .version_id = 0,
1433
- .minimum_version_id = 0,
1434
- .post_load = pxa2xx_lcdc_post_load,
1435
- .fields = (const VMStateField[]) {
1436
- VMSTATE_INT32(irqlevel, PXA2xxLCDState),
1437
- VMSTATE_INT32(transp, PXA2xxLCDState),
1438
- VMSTATE_UINT32_ARRAY(control, PXA2xxLCDState, 6),
1439
- VMSTATE_UINT32_ARRAY(status, PXA2xxLCDState, 2),
1440
- VMSTATE_UINT32_ARRAY(ovl1c, PXA2xxLCDState, 2),
1441
- VMSTATE_UINT32_ARRAY(ovl2c, PXA2xxLCDState, 2),
1442
- VMSTATE_UINT32(ccr, PXA2xxLCDState),
1443
- VMSTATE_UINT32(cmdcr, PXA2xxLCDState),
1444
- VMSTATE_UINT32(trgbr, PXA2xxLCDState),
1445
- VMSTATE_UINT32(tcr, PXA2xxLCDState),
1446
- VMSTATE_UINT32(liidr, PXA2xxLCDState),
1447
- VMSTATE_UINT8(bscntr, PXA2xxLCDState),
1448
- VMSTATE_STRUCT_ARRAY(dma_ch, PXA2xxLCDState, 7, 0,
1449
- vmstate_dma_channel, struct DMAChannel),
1450
- VMSTATE_END_OF_LIST()
1451
- }
1452
-};
1453
-
1454
-static const GraphicHwOps pxa2xx_ops = {
1455
- .invalidate = pxa2xx_invalidate_display,
1456
- .gfx_update = pxa2xx_update_display,
1457
-};
1458
-
1459
-PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
1460
- hwaddr base, qemu_irq irq)
1461
-{
1462
- PXA2xxLCDState *s;
1463
-
1464
- s = g_new0(PXA2xxLCDState, 1);
1465
- s->invalidated = 1;
1466
- s->irq = irq;
1467
- s->sysmem = sysmem;
1468
-
1469
- pxa2xx_lcdc_orientation(s, graphic_rotate);
1470
-
1471
- memory_region_init_io(&s->iomem, NULL, &pxa2xx_lcdc_ops, s,
1472
- "pxa2xx-lcd-controller", 0x00100000);
1473
- memory_region_add_subregion(sysmem, base, &s->iomem);
1474
-
1475
- s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
1476
-
1477
- vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
1478
-
1479
- return s;
1480
-}
1481
-
1482
-void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler)
1483
-{
1484
- s->vsync_cb = handler;
1485
-}
1486
diff --git a/hw/display/meson.build b/hw/display/meson.build
1487
index XXXXXXX..XXXXXXX 100644
1488
--- a/hw/display/meson.build
1489
+++ b/hw/display/meson.build
1490
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_fimd.c'))
1491
system_ss.add(when: 'CONFIG_FRAMEBUFFER', if_true: files('framebuffer.c'))
1492
1493
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_dss.c'))
1494
-system_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_lcd.c'))
1495
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_fb.c'))
1496
system_ss.add(when: 'CONFIG_SM501', if_true: files('sm501.c'))
1497
system_ss.add(when: 'CONFIG_TCX', if_true: files('tcx.c'))
1498
--
23
--
1499
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
Remove the TWL92230 RTC device, which was used only by the n800 and n810.
1
Set the default NaN pattern explicitly for ppc.
2
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20240903160751.4100218-31-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-46-peter.maydell@linaro.org
6
---
6
---
7
MAINTAINERS | 1 -
7
target/ppc/cpu_init.c | 4 ++++
8
hw/rtc/twl92230.c | 882 ---------------------------------------------
8
1 file changed, 4 insertions(+)
9
hw/rtc/Kconfig | 4 -
10
hw/rtc/meson.build | 1 -
11
4 files changed, 888 deletions(-)
12
delete mode 100644 hw/rtc/twl92230.c
13
9
14
diff --git a/MAINTAINERS b/MAINTAINERS
10
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/MAINTAINERS
12
--- a/target/ppc/cpu_init.c
17
+++ b/MAINTAINERS
13
+++ b/target/ppc/cpu_init.c
18
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
14
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
19
L: qemu-arm@nongnu.org
15
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
S: Odd Fixes
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
21
F: hw/input/lm832x.c
17
22
-F: hw/rtc/twl92230.c
18
+ /* Default NaN: sign bit clear, set frac msb */
23
F: include/hw/input/lm832x.h
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
24
20
+ set_float_default_nan_pattern(0b01000000, &env->vec_status);
25
Raspberry Pi
21
+
26
diff --git a/hw/rtc/twl92230.c b/hw/rtc/twl92230.c
22
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
27
deleted file mode 100644
23
ppc_spr_t *spr = &env->spr_cb[i];
28
index XXXXXXX..XXXXXXX
29
--- a/hw/rtc/twl92230.c
30
+++ /dev/null
31
@@ -XXX,XX +XXX,XX @@
32
-/*
33
- * TI TWL92230C energy-management companion device for the OMAP24xx.
34
- * Aka. Menelaus (N4200 MENELAUS1_V2.2)
35
- *
36
- * Copyright (C) 2008 Nokia Corporation
37
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
38
- *
39
- * This program is free software; you can redistribute it and/or
40
- * modify it under the terms of the GNU General Public License as
41
- * published by the Free Software Foundation; either version 2 or
42
- * (at your option) version 3 of the License.
43
- *
44
- * This program is distributed in the hope that it will be useful,
45
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
46
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47
- * GNU General Public License for more details.
48
- *
49
- * You should have received a copy of the GNU General Public License along
50
- * with this program; if not, see <http://www.gnu.org/licenses/>.
51
- */
52
-
53
-#include "qemu/osdep.h"
54
-#include "qemu/timer.h"
55
-#include "hw/i2c/i2c.h"
56
-#include "hw/irq.h"
57
-#include "migration/qemu-file-types.h"
58
-#include "migration/vmstate.h"
59
-#include "sysemu/sysemu.h"
60
-#include "sysemu/rtc.h"
61
-#include "qemu/bcd.h"
62
-#include "qemu/module.h"
63
-#include "qom/object.h"
64
-
65
-#define VERBOSE 1
66
-
67
-#define TYPE_TWL92230 "twl92230"
68
-OBJECT_DECLARE_SIMPLE_TYPE(MenelausState, TWL92230)
69
-
70
-struct MenelausState {
71
- I2CSlave parent_obj;
72
-
73
- int firstbyte;
74
- uint8_t reg;
75
-
76
- uint8_t vcore[5];
77
- uint8_t dcdc[3];
78
- uint8_t ldo[8];
79
- uint8_t sleep[2];
80
- uint8_t osc;
81
- uint8_t detect;
82
- uint16_t mask;
83
- uint16_t status;
84
- uint8_t dir;
85
- uint8_t inputs;
86
- uint8_t outputs;
87
- uint8_t bbsms;
88
- uint8_t pull[4];
89
- uint8_t mmc_ctrl[3];
90
- uint8_t mmc_debounce;
91
- struct {
92
- uint8_t ctrl;
93
- uint16_t comp;
94
- QEMUTimer *hz_tm;
95
- int64_t next;
96
- struct tm tm;
97
- struct tm new;
98
- struct tm alm;
99
- int64_t sec_offset;
100
- int64_t alm_sec;
101
- int next_comp;
102
- } rtc;
103
- uint16_t rtc_next_vmstate;
104
- qemu_irq out[4];
105
- uint8_t pwrbtn_state;
106
-};
107
-
108
-static inline void menelaus_update(MenelausState *s)
109
-{
110
- qemu_set_irq(s->out[3], s->status & ~s->mask);
111
-}
112
-
113
-static inline void menelaus_rtc_start(MenelausState *s)
114
-{
115
- s->rtc.next += qemu_clock_get_ms(rtc_clock);
116
- timer_mod(s->rtc.hz_tm, s->rtc.next);
117
-}
118
-
119
-static inline void menelaus_rtc_stop(MenelausState *s)
120
-{
121
- timer_del(s->rtc.hz_tm);
122
- s->rtc.next -= qemu_clock_get_ms(rtc_clock);
123
- if (s->rtc.next < 1)
124
- s->rtc.next = 1;
125
-}
126
-
127
-static void menelaus_rtc_update(MenelausState *s)
128
-{
129
- qemu_get_timedate(&s->rtc.tm, s->rtc.sec_offset);
130
-}
131
-
132
-static void menelaus_alm_update(MenelausState *s)
133
-{
134
- if ((s->rtc.ctrl & 3) == 3)
135
- s->rtc.alm_sec = qemu_timedate_diff(&s->rtc.alm) - s->rtc.sec_offset;
136
-}
137
-
138
-static void menelaus_rtc_hz(void *opaque)
139
-{
140
- MenelausState *s = (MenelausState *) opaque;
141
-
142
- s->rtc.next_comp --;
143
- s->rtc.alm_sec --;
144
- s->rtc.next += 1000;
145
- timer_mod(s->rtc.hz_tm, s->rtc.next);
146
- if ((s->rtc.ctrl >> 3) & 3) { /* EVERY */
147
- menelaus_rtc_update(s);
148
- if (((s->rtc.ctrl >> 3) & 3) == 1 && !s->rtc.tm.tm_sec)
149
- s->status |= 1 << 8; /* RTCTMR */
150
- else if (((s->rtc.ctrl >> 3) & 3) == 2 && !s->rtc.tm.tm_min)
151
- s->status |= 1 << 8; /* RTCTMR */
152
- else if (!s->rtc.tm.tm_hour)
153
- s->status |= 1 << 8; /* RTCTMR */
154
- } else
155
- s->status |= 1 << 8; /* RTCTMR */
156
- if ((s->rtc.ctrl >> 1) & 1) { /* RTC_AL_EN */
157
- if (s->rtc.alm_sec == 0)
158
- s->status |= 1 << 9; /* RTCALM */
159
- /* TODO: wake-up */
160
- }
161
- if (s->rtc.next_comp <= 0) {
162
- s->rtc.next -= muldiv64((int16_t) s->rtc.comp, 1000, 0x8000);
163
- s->rtc.next_comp = 3600;
164
- }
165
- menelaus_update(s);
166
-}
167
-
168
-static void menelaus_reset(I2CSlave *i2c)
169
-{
170
- MenelausState *s = TWL92230(i2c);
171
-
172
- s->reg = 0x00;
173
-
174
- s->vcore[0] = 0x0c; /* XXX: X-loader needs 0x8c? check! */
175
- s->vcore[1] = 0x05;
176
- s->vcore[2] = 0x02;
177
- s->vcore[3] = 0x0c;
178
- s->vcore[4] = 0x03;
179
- s->dcdc[0] = 0x33; /* Depends on wiring */
180
- s->dcdc[1] = 0x03;
181
- s->dcdc[2] = 0x00;
182
- s->ldo[0] = 0x95;
183
- s->ldo[1] = 0x7e;
184
- s->ldo[2] = 0x00;
185
- s->ldo[3] = 0x00; /* Depends on wiring */
186
- s->ldo[4] = 0x03; /* Depends on wiring */
187
- s->ldo[5] = 0x00;
188
- s->ldo[6] = 0x00;
189
- s->ldo[7] = 0x00;
190
- s->sleep[0] = 0x00;
191
- s->sleep[1] = 0x00;
192
- s->osc = 0x01;
193
- s->detect = 0x09;
194
- s->mask = 0x0fff;
195
- s->status = 0;
196
- s->dir = 0x07;
197
- s->outputs = 0x00;
198
- s->bbsms = 0x00;
199
- s->pull[0] = 0x00;
200
- s->pull[1] = 0x00;
201
- s->pull[2] = 0x00;
202
- s->pull[3] = 0x00;
203
- s->mmc_ctrl[0] = 0x03;
204
- s->mmc_ctrl[1] = 0xc0;
205
- s->mmc_ctrl[2] = 0x00;
206
- s->mmc_debounce = 0x05;
207
-
208
- if (s->rtc.ctrl & 1)
209
- menelaus_rtc_stop(s);
210
- s->rtc.ctrl = 0x00;
211
- s->rtc.comp = 0x0000;
212
- s->rtc.next = 1000;
213
- s->rtc.sec_offset = 0;
214
- s->rtc.next_comp = 1800;
215
- s->rtc.alm_sec = 1800;
216
- s->rtc.alm.tm_sec = 0x00;
217
- s->rtc.alm.tm_min = 0x00;
218
- s->rtc.alm.tm_hour = 0x00;
219
- s->rtc.alm.tm_mday = 0x01;
220
- s->rtc.alm.tm_mon = 0x00;
221
- s->rtc.alm.tm_year = 2004;
222
- menelaus_update(s);
223
-}
224
-
225
-static void menelaus_gpio_set(void *opaque, int line, int level)
226
-{
227
- MenelausState *s = (MenelausState *) opaque;
228
-
229
- if (line < 3) {
230
- /* No interrupt generated */
231
- s->inputs &= ~(1 << line);
232
- s->inputs |= level << line;
233
- return;
234
- }
235
-
236
- if (!s->pwrbtn_state && level) {
237
- s->status |= 1 << 11; /* PSHBTN */
238
- menelaus_update(s);
239
- }
240
- s->pwrbtn_state = level;
241
-}
242
-
243
-#define MENELAUS_REV 0x01
244
-#define MENELAUS_VCORE_CTRL1 0x02
245
-#define MENELAUS_VCORE_CTRL2 0x03
246
-#define MENELAUS_VCORE_CTRL3 0x04
247
-#define MENELAUS_VCORE_CTRL4 0x05
248
-#define MENELAUS_VCORE_CTRL5 0x06
249
-#define MENELAUS_DCDC_CTRL1 0x07
250
-#define MENELAUS_DCDC_CTRL2 0x08
251
-#define MENELAUS_DCDC_CTRL3 0x09
252
-#define MENELAUS_LDO_CTRL1 0x0a
253
-#define MENELAUS_LDO_CTRL2 0x0b
254
-#define MENELAUS_LDO_CTRL3 0x0c
255
-#define MENELAUS_LDO_CTRL4 0x0d
256
-#define MENELAUS_LDO_CTRL5 0x0e
257
-#define MENELAUS_LDO_CTRL6 0x0f
258
-#define MENELAUS_LDO_CTRL7 0x10
259
-#define MENELAUS_LDO_CTRL8 0x11
260
-#define MENELAUS_SLEEP_CTRL1 0x12
261
-#define MENELAUS_SLEEP_CTRL2 0x13
262
-#define MENELAUS_DEVICE_OFF 0x14
263
-#define MENELAUS_OSC_CTRL 0x15
264
-#define MENELAUS_DETECT_CTRL 0x16
265
-#define MENELAUS_INT_MASK1 0x17
266
-#define MENELAUS_INT_MASK2 0x18
267
-#define MENELAUS_INT_STATUS1 0x19
268
-#define MENELAUS_INT_STATUS2 0x1a
269
-#define MENELAUS_INT_ACK1 0x1b
270
-#define MENELAUS_INT_ACK2 0x1c
271
-#define MENELAUS_GPIO_CTRL 0x1d
272
-#define MENELAUS_GPIO_IN 0x1e
273
-#define MENELAUS_GPIO_OUT 0x1f
274
-#define MENELAUS_BBSMS 0x20
275
-#define MENELAUS_RTC_CTRL 0x21
276
-#define MENELAUS_RTC_UPDATE 0x22
277
-#define MENELAUS_RTC_SEC 0x23
278
-#define MENELAUS_RTC_MIN 0x24
279
-#define MENELAUS_RTC_HR 0x25
280
-#define MENELAUS_RTC_DAY 0x26
281
-#define MENELAUS_RTC_MON 0x27
282
-#define MENELAUS_RTC_YR 0x28
283
-#define MENELAUS_RTC_WKDAY 0x29
284
-#define MENELAUS_RTC_AL_SEC 0x2a
285
-#define MENELAUS_RTC_AL_MIN 0x2b
286
-#define MENELAUS_RTC_AL_HR 0x2c
287
-#define MENELAUS_RTC_AL_DAY 0x2d
288
-#define MENELAUS_RTC_AL_MON 0x2e
289
-#define MENELAUS_RTC_AL_YR 0x2f
290
-#define MENELAUS_RTC_COMP_MSB 0x30
291
-#define MENELAUS_RTC_COMP_LSB 0x31
292
-#define MENELAUS_S1_PULL_EN 0x32
293
-#define MENELAUS_S1_PULL_DIR 0x33
294
-#define MENELAUS_S2_PULL_EN 0x34
295
-#define MENELAUS_S2_PULL_DIR 0x35
296
-#define MENELAUS_MCT_CTRL1 0x36
297
-#define MENELAUS_MCT_CTRL2 0x37
298
-#define MENELAUS_MCT_CTRL3 0x38
299
-#define MENELAUS_MCT_PIN_ST 0x39
300
-#define MENELAUS_DEBOUNCE1 0x3a
301
-
302
-static uint8_t menelaus_read(void *opaque, uint8_t addr)
303
-{
304
- MenelausState *s = (MenelausState *) opaque;
305
-
306
- switch (addr) {
307
- case MENELAUS_REV:
308
- return 0x22;
309
-
310
- case MENELAUS_VCORE_CTRL1 ... MENELAUS_VCORE_CTRL5:
311
- return s->vcore[addr - MENELAUS_VCORE_CTRL1];
312
-
313
- case MENELAUS_DCDC_CTRL1 ... MENELAUS_DCDC_CTRL3:
314
- return s->dcdc[addr - MENELAUS_DCDC_CTRL1];
315
-
316
- case MENELAUS_LDO_CTRL1 ... MENELAUS_LDO_CTRL8:
317
- return s->ldo[addr - MENELAUS_LDO_CTRL1];
318
-
319
- case MENELAUS_SLEEP_CTRL1:
320
- case MENELAUS_SLEEP_CTRL2:
321
- return s->sleep[addr - MENELAUS_SLEEP_CTRL1];
322
-
323
- case MENELAUS_DEVICE_OFF:
324
- return 0;
325
-
326
- case MENELAUS_OSC_CTRL:
327
- return s->osc | (1 << 7); /* CLK32K_GOOD */
328
-
329
- case MENELAUS_DETECT_CTRL:
330
- return s->detect;
331
-
332
- case MENELAUS_INT_MASK1:
333
- return (s->mask >> 0) & 0xff;
334
- case MENELAUS_INT_MASK2:
335
- return (s->mask >> 8) & 0xff;
336
-
337
- case MENELAUS_INT_STATUS1:
338
- return (s->status >> 0) & 0xff;
339
- case MENELAUS_INT_STATUS2:
340
- return (s->status >> 8) & 0xff;
341
-
342
- case MENELAUS_INT_ACK1:
343
- case MENELAUS_INT_ACK2:
344
- return 0;
345
-
346
- case MENELAUS_GPIO_CTRL:
347
- return s->dir;
348
- case MENELAUS_GPIO_IN:
349
- return s->inputs | (~s->dir & s->outputs);
350
- case MENELAUS_GPIO_OUT:
351
- return s->outputs;
352
-
353
- case MENELAUS_BBSMS:
354
- return s->bbsms;
355
-
356
- case MENELAUS_RTC_CTRL:
357
- return s->rtc.ctrl;
358
- case MENELAUS_RTC_UPDATE:
359
- return 0x00;
360
- case MENELAUS_RTC_SEC:
361
- menelaus_rtc_update(s);
362
- return to_bcd(s->rtc.tm.tm_sec);
363
- case MENELAUS_RTC_MIN:
364
- menelaus_rtc_update(s);
365
- return to_bcd(s->rtc.tm.tm_min);
366
- case MENELAUS_RTC_HR:
367
- menelaus_rtc_update(s);
368
- if ((s->rtc.ctrl >> 2) & 1) /* MODE12_n24 */
369
- return to_bcd((s->rtc.tm.tm_hour % 12) + 1) |
370
- (!!(s->rtc.tm.tm_hour >= 12) << 7); /* PM_nAM */
371
- else
372
- return to_bcd(s->rtc.tm.tm_hour);
373
- case MENELAUS_RTC_DAY:
374
- menelaus_rtc_update(s);
375
- return to_bcd(s->rtc.tm.tm_mday);
376
- case MENELAUS_RTC_MON:
377
- menelaus_rtc_update(s);
378
- return to_bcd(s->rtc.tm.tm_mon + 1);
379
- case MENELAUS_RTC_YR:
380
- menelaus_rtc_update(s);
381
- return to_bcd(s->rtc.tm.tm_year - 2000);
382
- case MENELAUS_RTC_WKDAY:
383
- menelaus_rtc_update(s);
384
- return to_bcd(s->rtc.tm.tm_wday);
385
- case MENELAUS_RTC_AL_SEC:
386
- return to_bcd(s->rtc.alm.tm_sec);
387
- case MENELAUS_RTC_AL_MIN:
388
- return to_bcd(s->rtc.alm.tm_min);
389
- case MENELAUS_RTC_AL_HR:
390
- if ((s->rtc.ctrl >> 2) & 1) /* MODE12_n24 */
391
- return to_bcd((s->rtc.alm.tm_hour % 12) + 1) |
392
- (!!(s->rtc.alm.tm_hour >= 12) << 7);/* AL_PM_nAM */
393
- else
394
- return to_bcd(s->rtc.alm.tm_hour);
395
- case MENELAUS_RTC_AL_DAY:
396
- return to_bcd(s->rtc.alm.tm_mday);
397
- case MENELAUS_RTC_AL_MON:
398
- return to_bcd(s->rtc.alm.tm_mon + 1);
399
- case MENELAUS_RTC_AL_YR:
400
- return to_bcd(s->rtc.alm.tm_year - 2000);
401
- case MENELAUS_RTC_COMP_MSB:
402
- return (s->rtc.comp >> 8) & 0xff;
403
- case MENELAUS_RTC_COMP_LSB:
404
- return (s->rtc.comp >> 0) & 0xff;
405
-
406
- case MENELAUS_S1_PULL_EN:
407
- return s->pull[0];
408
- case MENELAUS_S1_PULL_DIR:
409
- return s->pull[1];
410
- case MENELAUS_S2_PULL_EN:
411
- return s->pull[2];
412
- case MENELAUS_S2_PULL_DIR:
413
- return s->pull[3];
414
-
415
- case MENELAUS_MCT_CTRL1 ... MENELAUS_MCT_CTRL3:
416
- return s->mmc_ctrl[addr - MENELAUS_MCT_CTRL1];
417
- case MENELAUS_MCT_PIN_ST:
418
- /* TODO: return the real Card Detect */
419
- return 0;
420
- case MENELAUS_DEBOUNCE1:
421
- return s->mmc_debounce;
422
-
423
- default:
424
-#ifdef VERBOSE
425
- printf("%s: unknown register %02x\n", __func__, addr);
426
-#endif
427
- break;
428
- }
429
- return 0;
430
-}
431
-
432
-static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
433
-{
434
- MenelausState *s = (MenelausState *) opaque;
435
- int line;
436
- struct tm tm;
437
-
438
- switch (addr) {
439
- case MENELAUS_VCORE_CTRL1:
440
- s->vcore[0] = (value & 0xe) | MIN(value & 0x1f, 0x12);
441
- break;
442
- case MENELAUS_VCORE_CTRL2:
443
- s->vcore[1] = value;
444
- break;
445
- case MENELAUS_VCORE_CTRL3:
446
- s->vcore[2] = MIN(value & 0x1f, 0x12);
447
- break;
448
- case MENELAUS_VCORE_CTRL4:
449
- s->vcore[3] = MIN(value & 0x1f, 0x12);
450
- break;
451
- case MENELAUS_VCORE_CTRL5:
452
- s->vcore[4] = value & 3;
453
- /* XXX
454
- * auto set to 3 on M_Active, nRESWARM
455
- * auto set to 0 on M_WaitOn, M_Backup
456
- */
457
- break;
458
-
459
- case MENELAUS_DCDC_CTRL1:
460
- s->dcdc[0] = value & 0x3f;
461
- break;
462
- case MENELAUS_DCDC_CTRL2:
463
- s->dcdc[1] = value & 0x07;
464
- /* XXX
465
- * auto set to 3 on M_Active, nRESWARM
466
- * auto set to 0 on M_WaitOn, M_Backup
467
- */
468
- break;
469
- case MENELAUS_DCDC_CTRL3:
470
- s->dcdc[2] = value & 0x07;
471
- break;
472
-
473
- case MENELAUS_LDO_CTRL1:
474
- s->ldo[0] = value;
475
- break;
476
- case MENELAUS_LDO_CTRL2:
477
- s->ldo[1] = value & 0x7f;
478
- /* XXX
479
- * auto set to 0x7e on M_WaitOn, M_Backup
480
- */
481
- break;
482
- case MENELAUS_LDO_CTRL3:
483
- s->ldo[2] = value & 3;
484
- /* XXX
485
- * auto set to 3 on M_Active, nRESWARM
486
- * auto set to 0 on M_WaitOn, M_Backup
487
- */
488
- break;
489
- case MENELAUS_LDO_CTRL4:
490
- s->ldo[3] = value & 3;
491
- /* XXX
492
- * auto set to 3 on M_Active, nRESWARM
493
- * auto set to 0 on M_WaitOn, M_Backup
494
- */
495
- break;
496
- case MENELAUS_LDO_CTRL5:
497
- s->ldo[4] = value & 3;
498
- /* XXX
499
- * auto set to 3 on M_Active, nRESWARM
500
- * auto set to 0 on M_WaitOn, M_Backup
501
- */
502
- break;
503
- case MENELAUS_LDO_CTRL6:
504
- s->ldo[5] = value & 3;
505
- break;
506
- case MENELAUS_LDO_CTRL7:
507
- s->ldo[6] = value & 3;
508
- break;
509
- case MENELAUS_LDO_CTRL8:
510
- s->ldo[7] = value & 3;
511
- break;
512
-
513
- case MENELAUS_SLEEP_CTRL1:
514
- case MENELAUS_SLEEP_CTRL2:
515
- s->sleep[addr - MENELAUS_SLEEP_CTRL1] = value;
516
- break;
517
-
518
- case MENELAUS_DEVICE_OFF:
519
- if (value & 1) {
520
- menelaus_reset(I2C_SLAVE(s));
521
- }
522
- break;
523
-
524
- case MENELAUS_OSC_CTRL:
525
- s->osc = value & 7;
526
- break;
527
-
528
- case MENELAUS_DETECT_CTRL:
529
- s->detect = value & 0x7f;
530
- break;
531
-
532
- case MENELAUS_INT_MASK1:
533
- s->mask &= 0xf00;
534
- s->mask |= value << 0;
535
- menelaus_update(s);
536
- break;
537
- case MENELAUS_INT_MASK2:
538
- s->mask &= 0x0ff;
539
- s->mask |= value << 8;
540
- menelaus_update(s);
541
- break;
542
-
543
- case MENELAUS_INT_ACK1:
544
- s->status &= ~(((uint16_t) value) << 0);
545
- menelaus_update(s);
546
- break;
547
- case MENELAUS_INT_ACK2:
548
- s->status &= ~(((uint16_t) value) << 8);
549
- menelaus_update(s);
550
- break;
551
-
552
- case MENELAUS_GPIO_CTRL:
553
- for (line = 0; line < 3; line ++) {
554
- if (((s->dir ^ value) >> line) & 1) {
555
- qemu_set_irq(s->out[line],
556
- ((s->outputs & ~s->dir) >> line) & 1);
557
- }
558
- }
559
- s->dir = value & 0x67;
560
- break;
561
- case MENELAUS_GPIO_OUT:
562
- for (line = 0; line < 3; line ++) {
563
- if ((((s->outputs ^ value) & ~s->dir) >> line) & 1) {
564
- qemu_set_irq(s->out[line], (s->outputs >> line) & 1);
565
- }
566
- }
567
- s->outputs = value & 0x07;
568
- break;
569
-
570
- case MENELAUS_BBSMS:
571
- s->bbsms = 0x0d;
572
- break;
573
-
574
- case MENELAUS_RTC_CTRL:
575
- if ((s->rtc.ctrl ^ value) & 1) { /* RTC_EN */
576
- if (value & 1)
577
- menelaus_rtc_start(s);
578
- else
579
- menelaus_rtc_stop(s);
580
- }
581
- s->rtc.ctrl = value & 0x1f;
582
- menelaus_alm_update(s);
583
- break;
584
- case MENELAUS_RTC_UPDATE:
585
- menelaus_rtc_update(s);
586
- memcpy(&tm, &s->rtc.tm, sizeof(tm));
587
- switch (value & 0xf) {
588
- case 0:
589
- break;
590
- case 1:
591
- tm.tm_sec = s->rtc.new.tm_sec;
592
- break;
593
- case 2:
594
- tm.tm_min = s->rtc.new.tm_min;
595
- break;
596
- case 3:
597
- if (s->rtc.new.tm_hour > 23)
598
- goto rtc_badness;
599
- tm.tm_hour = s->rtc.new.tm_hour;
600
- break;
601
- case 4:
602
- if (s->rtc.new.tm_mday < 1)
603
- goto rtc_badness;
604
- /* TODO check range */
605
- tm.tm_mday = s->rtc.new.tm_mday;
606
- break;
607
- case 5:
608
- if (s->rtc.new.tm_mon < 0 || s->rtc.new.tm_mon > 11)
609
- goto rtc_badness;
610
- tm.tm_mon = s->rtc.new.tm_mon;
611
- break;
612
- case 6:
613
- tm.tm_year = s->rtc.new.tm_year;
614
- break;
615
- case 7:
616
- /* TODO set .tm_mday instead */
617
- tm.tm_wday = s->rtc.new.tm_wday;
618
- break;
619
- case 8:
620
- if (s->rtc.new.tm_hour > 23)
621
- goto rtc_badness;
622
- if (s->rtc.new.tm_mday < 1)
623
- goto rtc_badness;
624
- if (s->rtc.new.tm_mon < 0 || s->rtc.new.tm_mon > 11)
625
- goto rtc_badness;
626
- tm.tm_sec = s->rtc.new.tm_sec;
627
- tm.tm_min = s->rtc.new.tm_min;
628
- tm.tm_hour = s->rtc.new.tm_hour;
629
- tm.tm_mday = s->rtc.new.tm_mday;
630
- tm.tm_mon = s->rtc.new.tm_mon;
631
- tm.tm_year = s->rtc.new.tm_year;
632
- break;
633
- rtc_badness:
634
- default:
635
- fprintf(stderr, "%s: bad RTC_UPDATE value %02x\n",
636
- __func__, value);
637
- s->status |= 1 << 10; /* RTCERR */
638
- menelaus_update(s);
639
- }
640
- s->rtc.sec_offset = qemu_timedate_diff(&tm);
641
- break;
642
- case MENELAUS_RTC_SEC:
643
- s->rtc.tm.tm_sec = from_bcd(value & 0x7f);
644
- break;
645
- case MENELAUS_RTC_MIN:
646
- s->rtc.tm.tm_min = from_bcd(value & 0x7f);
647
- break;
648
- case MENELAUS_RTC_HR:
649
- s->rtc.tm.tm_hour = (s->rtc.ctrl & (1 << 2)) ? /* MODE12_n24 */
650
- MIN(from_bcd(value & 0x3f), 12) + ((value >> 7) ? 11 : -1) :
651
- from_bcd(value & 0x3f);
652
- break;
653
- case MENELAUS_RTC_DAY:
654
- s->rtc.tm.tm_mday = from_bcd(value);
655
- break;
656
- case MENELAUS_RTC_MON:
657
- s->rtc.tm.tm_mon = MAX(1, from_bcd(value)) - 1;
658
- break;
659
- case MENELAUS_RTC_YR:
660
- s->rtc.tm.tm_year = 2000 + from_bcd(value);
661
- break;
662
- case MENELAUS_RTC_WKDAY:
663
- s->rtc.tm.tm_mday = from_bcd(value);
664
- break;
665
- case MENELAUS_RTC_AL_SEC:
666
- s->rtc.alm.tm_sec = from_bcd(value & 0x7f);
667
- menelaus_alm_update(s);
668
- break;
669
- case MENELAUS_RTC_AL_MIN:
670
- s->rtc.alm.tm_min = from_bcd(value & 0x7f);
671
- menelaus_alm_update(s);
672
- break;
673
- case MENELAUS_RTC_AL_HR:
674
- s->rtc.alm.tm_hour = (s->rtc.ctrl & (1 << 2)) ? /* MODE12_n24 */
675
- MIN(from_bcd(value & 0x3f), 12) + ((value >> 7) ? 11 : -1) :
676
- from_bcd(value & 0x3f);
677
- menelaus_alm_update(s);
678
- break;
679
- case MENELAUS_RTC_AL_DAY:
680
- s->rtc.alm.tm_mday = from_bcd(value);
681
- menelaus_alm_update(s);
682
- break;
683
- case MENELAUS_RTC_AL_MON:
684
- s->rtc.alm.tm_mon = MAX(1, from_bcd(value)) - 1;
685
- menelaus_alm_update(s);
686
- break;
687
- case MENELAUS_RTC_AL_YR:
688
- s->rtc.alm.tm_year = 2000 + from_bcd(value);
689
- menelaus_alm_update(s);
690
- break;
691
- case MENELAUS_RTC_COMP_MSB:
692
- s->rtc.comp &= 0xff;
693
- s->rtc.comp |= value << 8;
694
- break;
695
- case MENELAUS_RTC_COMP_LSB:
696
- s->rtc.comp &= 0xff << 8;
697
- s->rtc.comp |= value;
698
- break;
699
-
700
- case MENELAUS_S1_PULL_EN:
701
- s->pull[0] = value;
702
- break;
703
- case MENELAUS_S1_PULL_DIR:
704
- s->pull[1] = value & 0x1f;
705
- break;
706
- case MENELAUS_S2_PULL_EN:
707
- s->pull[2] = value;
708
- break;
709
- case MENELAUS_S2_PULL_DIR:
710
- s->pull[3] = value & 0x1f;
711
- break;
712
-
713
- case MENELAUS_MCT_CTRL1:
714
- s->mmc_ctrl[0] = value & 0x7f;
715
- break;
716
- case MENELAUS_MCT_CTRL2:
717
- s->mmc_ctrl[1] = value;
718
- /* TODO update Card Detect interrupts */
719
- break;
720
- case MENELAUS_MCT_CTRL3:
721
- s->mmc_ctrl[2] = value & 0xf;
722
- break;
723
- case MENELAUS_DEBOUNCE1:
724
- s->mmc_debounce = value & 0x3f;
725
- break;
726
-
727
- default:
728
-#ifdef VERBOSE
729
- printf("%s: unknown register %02x\n", __func__, addr);
730
-#endif
731
- break;
732
- }
733
-}
734
-
735
-static int menelaus_event(I2CSlave *i2c, enum i2c_event event)
736
-{
737
- MenelausState *s = TWL92230(i2c);
738
-
739
- if (event == I2C_START_SEND)
740
- s->firstbyte = 1;
741
-
742
- return 0;
743
-}
744
-
745
-static int menelaus_tx(I2CSlave *i2c, uint8_t data)
746
-{
747
- MenelausState *s = TWL92230(i2c);
748
-
749
- /* Interpret register address byte */
750
- if (s->firstbyte) {
751
- s->reg = data;
752
- s->firstbyte = 0;
753
- } else
754
- menelaus_write(s, s->reg ++, data);
755
-
756
- return 0;
757
-}
758
-
759
-static uint8_t menelaus_rx(I2CSlave *i2c)
760
-{
761
- MenelausState *s = TWL92230(i2c);
762
-
763
- return menelaus_read(s, s->reg ++);
764
-}
765
-
766
-/* Save restore 32 bit int as uint16_t
767
- This is a Big hack, but it is how the old state did it.
768
- Or we broke compatibility in the state, or we can't use struct tm
769
- */
770
-
771
-static int get_int32_as_uint16(QEMUFile *f, void *pv, size_t size,
772
- const VMStateField *field)
773
-{
774
- int *v = pv;
775
- *v = qemu_get_be16(f);
776
- return 0;
777
-}
778
-
779
-static int put_int32_as_uint16(QEMUFile *f, void *pv, size_t size,
780
- const VMStateField *field, JSONWriter *vmdesc)
781
-{
782
- int *v = pv;
783
- qemu_put_be16(f, *v);
784
-
785
- return 0;
786
-}
787
-
788
-static const VMStateInfo vmstate_hack_int32_as_uint16 = {
789
- .name = "int32_as_uint16",
790
- .get = get_int32_as_uint16,
791
- .put = put_int32_as_uint16,
792
-};
793
-
794
-#define VMSTATE_UINT16_HACK(_f, _s) \
795
- VMSTATE_SINGLE(_f, _s, 0, vmstate_hack_int32_as_uint16, int32_t)
796
-
797
-
798
-static const VMStateDescription vmstate_menelaus_tm = {
799
- .name = "menelaus_tm",
800
- .version_id = 0,
801
- .minimum_version_id = 0,
802
- .fields = (const VMStateField[]) {
803
- VMSTATE_UINT16_HACK(tm_sec, struct tm),
804
- VMSTATE_UINT16_HACK(tm_min, struct tm),
805
- VMSTATE_UINT16_HACK(tm_hour, struct tm),
806
- VMSTATE_UINT16_HACK(tm_mday, struct tm),
807
- VMSTATE_UINT16_HACK(tm_min, struct tm),
808
- VMSTATE_UINT16_HACK(tm_year, struct tm),
809
- VMSTATE_END_OF_LIST()
810
- }
811
-};
812
-
813
-static int menelaus_pre_save(void *opaque)
814
-{
815
- MenelausState *s = opaque;
816
- /* Should be <= 1000 */
817
- s->rtc_next_vmstate = s->rtc.next - qemu_clock_get_ms(rtc_clock);
818
-
819
- return 0;
820
-}
821
-
822
-static int menelaus_post_load(void *opaque, int version_id)
823
-{
824
- MenelausState *s = opaque;
825
-
826
- if (s->rtc.ctrl & 1) /* RTC_EN */
827
- menelaus_rtc_stop(s);
828
-
829
- s->rtc.next = s->rtc_next_vmstate;
830
-
831
- menelaus_alm_update(s);
832
- menelaus_update(s);
833
- if (s->rtc.ctrl & 1) /* RTC_EN */
834
- menelaus_rtc_start(s);
835
- return 0;
836
-}
837
-
838
-static const VMStateDescription vmstate_menelaus = {
839
- .name = "menelaus",
840
- .version_id = 0,
841
- .minimum_version_id = 0,
842
- .pre_save = menelaus_pre_save,
843
- .post_load = menelaus_post_load,
844
- .fields = (const VMStateField[]) {
845
- VMSTATE_INT32(firstbyte, MenelausState),
846
- VMSTATE_UINT8(reg, MenelausState),
847
- VMSTATE_UINT8_ARRAY(vcore, MenelausState, 5),
848
- VMSTATE_UINT8_ARRAY(dcdc, MenelausState, 3),
849
- VMSTATE_UINT8_ARRAY(ldo, MenelausState, 8),
850
- VMSTATE_UINT8_ARRAY(sleep, MenelausState, 2),
851
- VMSTATE_UINT8(osc, MenelausState),
852
- VMSTATE_UINT8(detect, MenelausState),
853
- VMSTATE_UINT16(mask, MenelausState),
854
- VMSTATE_UINT16(status, MenelausState),
855
- VMSTATE_UINT8(dir, MenelausState),
856
- VMSTATE_UINT8(inputs, MenelausState),
857
- VMSTATE_UINT8(outputs, MenelausState),
858
- VMSTATE_UINT8(bbsms, MenelausState),
859
- VMSTATE_UINT8_ARRAY(pull, MenelausState, 4),
860
- VMSTATE_UINT8_ARRAY(mmc_ctrl, MenelausState, 3),
861
- VMSTATE_UINT8(mmc_debounce, MenelausState),
862
- VMSTATE_UINT8(rtc.ctrl, MenelausState),
863
- VMSTATE_UINT16(rtc.comp, MenelausState),
864
- VMSTATE_UINT16(rtc_next_vmstate, MenelausState),
865
- VMSTATE_STRUCT(rtc.new, MenelausState, 0, vmstate_menelaus_tm,
866
- struct tm),
867
- VMSTATE_STRUCT(rtc.alm, MenelausState, 0, vmstate_menelaus_tm,
868
- struct tm),
869
- VMSTATE_UINT8(pwrbtn_state, MenelausState),
870
- VMSTATE_I2C_SLAVE(parent_obj, MenelausState),
871
- VMSTATE_END_OF_LIST()
872
- }
873
-};
874
-
875
-static void twl92230_realize(DeviceState *dev, Error **errp)
876
-{
877
- MenelausState *s = TWL92230(dev);
878
-
879
- s->rtc.hz_tm = timer_new_ms(rtc_clock, menelaus_rtc_hz, s);
880
- /* Three output pins plus one interrupt pin. */
881
- qdev_init_gpio_out(dev, s->out, 4);
882
-
883
- /* Three input pins plus one power-button pin. */
884
- qdev_init_gpio_in(dev, menelaus_gpio_set, 4);
885
-
886
- menelaus_reset(I2C_SLAVE(dev));
887
-}
888
-
889
-static void twl92230_class_init(ObjectClass *klass, void *data)
890
-{
891
- DeviceClass *dc = DEVICE_CLASS(klass);
892
- I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
893
-
894
- dc->realize = twl92230_realize;
895
- sc->event = menelaus_event;
896
- sc->recv = menelaus_rx;
897
- sc->send = menelaus_tx;
898
- dc->vmsd = &vmstate_menelaus;
899
-}
900
-
901
-static const TypeInfo twl92230_info = {
902
- .name = TYPE_TWL92230,
903
- .parent = TYPE_I2C_SLAVE,
904
- .instance_size = sizeof(MenelausState),
905
- .class_init = twl92230_class_init,
906
-};
907
-
908
-static void twl92230_register_types(void)
909
-{
910
- type_register_static(&twl92230_info);
911
-}
912
-
913
-type_init(twl92230_register_types)
914
diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
915
index XXXXXXX..XXXXXXX 100644
916
--- a/hw/rtc/Kconfig
917
+++ b/hw/rtc/Kconfig
918
@@ -XXX,XX +XXX,XX @@ config M48T59
919
config PL031
920
bool
921
922
-config TWL92230
923
- bool
924
- depends on I2C
925
-
926
config MC146818RTC
927
depends on ISA_BUS
928
bool
929
diff --git a/hw/rtc/meson.build b/hw/rtc/meson.build
930
index XXXXXXX..XXXXXXX 100644
931
--- a/hw/rtc/meson.build
932
+++ b/hw/rtc/meson.build
933
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_DS1338', if_true: files('ds1338.c'))
934
system_ss.add(when: 'CONFIG_M41T80', if_true: files('m41t80.c'))
935
system_ss.add(when: 'CONFIG_M48T59', if_true: files('m48t59.c'))
936
system_ss.add(when: 'CONFIG_PL031', if_true: files('pl031.c'))
937
-system_ss.add(when: 'CONFIG_TWL92230', if_true: files('twl92230.c'))
938
system_ss.add(when: ['CONFIG_ISA_BUS', 'CONFIG_M48T59'], if_true: files('m48t59-isa.c'))
939
system_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: files('xlnx-zynqmp-rtc.c'))
940
24
941
--
25
--
942
2.34.1
26
2.34.1
diff view generated by jsdifflib
1
Remove the pxa2xx-specific pxa2xx_keypad device.
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: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20241202131347.498124-47-peter.maydell@linaro.org
6
Message-id: 20240903160751.4100218-18-peter.maydell@linaro.org
7
---
8
---
8
include/hw/arm/pxa.h | 12 --
9
target/sh4/cpu.c | 2 ++
9
hw/input/pxa2xx_keypad.c | 331 ---------------------------------------
10
1 file changed, 2 insertions(+)
10
hw/input/meson.build | 1 -
11
3 files changed, 344 deletions(-)
12
delete mode 100644 hw/input/pxa2xx_keypad.c
13
11
14
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
12
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/pxa.h
14
--- a/target/sh4/cpu.c
17
+++ b/include/hw/arm/pxa.h
15
+++ b/target/sh4/cpu.c
18
@@ -XXX,XX +XXX,XX @@ int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card);
16
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_reset_hold(Object *obj, ResetType type)
19
int pxa2xx_pcmcia_detach(void *opaque);
17
set_flush_to_zero(1, &env->fp_status);
20
void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq);
18
#endif
21
19
set_default_nan_mode(1, &env->fp_status);
22
-/* pxa2xx_keypad.c */
20
+ /* sign bit clear, set all frac bits other than msb */
23
-struct keymap {
21
+ set_float_default_nan_pattern(0b00111111, &env->fp_status);
24
- int8_t column;
22
}
25
- int8_t row;
23
26
-};
24
static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
27
-typedef struct PXA2xxKeyPadState PXA2xxKeyPadState;
28
-PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem,
29
- hwaddr base,
30
- qemu_irq irq);
31
-void pxa27x_register_keypad(PXA2xxKeyPadState *kp,
32
- const struct keymap *map, int size);
33
-
34
#endif /* PXA_H */
35
diff --git a/hw/input/pxa2xx_keypad.c b/hw/input/pxa2xx_keypad.c
36
deleted file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- a/hw/input/pxa2xx_keypad.c
39
+++ /dev/null
40
@@ -XXX,XX +XXX,XX @@
41
-/*
42
- * Intel PXA27X Keypad Controller emulation.
43
- *
44
- * Copyright (c) 2007 MontaVista Software, Inc
45
- * Written by Armin Kuster <akuster@kama-aina.net>
46
- * or <Akuster@mvista.com>
47
- *
48
- * This code is licensed under the GPLv2.
49
- *
50
- * Contributions after 2012-01-13 are licensed under the terms of the
51
- * GNU GPL, version 2 or (at your option) any later version.
52
- */
53
-
54
-#include "qemu/osdep.h"
55
-#include "qemu/log.h"
56
-#include "hw/irq.h"
57
-#include "migration/vmstate.h"
58
-#include "hw/arm/pxa.h"
59
-#include "ui/console.h"
60
-
61
-/*
62
- * Keypad
63
- */
64
-#define KPC 0x00 /* Keypad Interface Control register */
65
-#define KPDK 0x08 /* Keypad Interface Direct Key register */
66
-#define KPREC 0x10 /* Keypad Interface Rotary Encoder register */
67
-#define KPMK 0x18 /* Keypad Interface Matrix Key register */
68
-#define KPAS 0x20 /* Keypad Interface Automatic Scan register */
69
-#define KPASMKP0 0x28 /* Keypad Interface Automatic Scan Multiple
70
- Key Presser register 0 */
71
-#define KPASMKP1 0x30 /* Keypad Interface Automatic Scan Multiple
72
- Key Presser register 1 */
73
-#define KPASMKP2 0x38 /* Keypad Interface Automatic Scan Multiple
74
- Key Presser register 2 */
75
-#define KPASMKP3 0x40 /* Keypad Interface Automatic Scan Multiple
76
- Key Presser register 3 */
77
-#define KPKDI 0x48 /* Keypad Interface Key Debounce Interval
78
- register */
79
-
80
-/* Keypad defines */
81
-#define KPC_AS (0x1 << 30) /* Automatic Scan bit */
82
-#define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */
83
-#define KPC_MI (0x1 << 22) /* Matrix interrupt bit */
84
-#define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */
85
-#define KPC_MS7 (0x1 << 20) /* Matrix scan line 7 */
86
-#define KPC_MS6 (0x1 << 19) /* Matrix scan line 6 */
87
-#define KPC_MS5 (0x1 << 18) /* Matrix scan line 5 */
88
-#define KPC_MS4 (0x1 << 17) /* Matrix scan line 4 */
89
-#define KPC_MS3 (0x1 << 16) /* Matrix scan line 3 */
90
-#define KPC_MS2 (0x1 << 15) /* Matrix scan line 2 */
91
-#define KPC_MS1 (0x1 << 14) /* Matrix scan line 1 */
92
-#define KPC_MS0 (0x1 << 13) /* Matrix scan line 0 */
93
-#define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */
94
-#define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */
95
-#define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Keypad Debounce Select */
96
-#define KPC_DI (0x1 << 5) /* Direct key interrupt bit */
97
-#define KPC_RE_ZERO_DEB (0x1 << 4) /* Rotary Encoder Zero Debounce */
98
-#define KPC_REE1 (0x1 << 3) /* Rotary Encoder1 Enable */
99
-#define KPC_REE0 (0x1 << 2) /* Rotary Encoder0 Enable */
100
-#define KPC_DE (0x1 << 1) /* Direct Keypad Enable */
101
-#define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */
102
-
103
-#define KPDK_DKP (0x1 << 31)
104
-#define KPDK_DK7 (0x1 << 7)
105
-#define KPDK_DK6 (0x1 << 6)
106
-#define KPDK_DK5 (0x1 << 5)
107
-#define KPDK_DK4 (0x1 << 4)
108
-#define KPDK_DK3 (0x1 << 3)
109
-#define KPDK_DK2 (0x1 << 2)
110
-#define KPDK_DK1 (0x1 << 1)
111
-#define KPDK_DK0 (0x1 << 0)
112
-
113
-#define KPREC_OF1 (0x1 << 31)
114
-#define KPREC_UF1 (0x1 << 30)
115
-#define KPREC_OF0 (0x1 << 15)
116
-#define KPREC_UF0 (0x1 << 14)
117
-
118
-#define KPMK_MKP (0x1 << 31)
119
-#define KPAS_SO (0x1 << 31)
120
-#define KPASMKPx_SO (0x1 << 31)
121
-
122
-
123
-#define KPASMKPx_MKC(row, col) (1 << (row + 16 * (col % 2)))
124
-
125
-#define PXAKBD_MAXROW 8
126
-#define PXAKBD_MAXCOL 8
127
-
128
-struct PXA2xxKeyPadState {
129
- MemoryRegion iomem;
130
- qemu_irq irq;
131
- const struct keymap *map;
132
- int pressed_cnt;
133
- int alt_code;
134
-
135
- uint32_t kpc;
136
- uint32_t kpdk;
137
- uint32_t kprec;
138
- uint32_t kpmk;
139
- uint32_t kpas;
140
- uint32_t kpasmkp[4];
141
- uint32_t kpkdi;
142
-};
143
-
144
-static void pxa27x_keypad_find_pressed_key(PXA2xxKeyPadState *kp, int *row, int *col)
145
-{
146
- int i;
147
- for (i = 0; i < 4; i++)
148
- {
149
- *col = i * 2;
150
- for (*row = 0; *row < 8; (*row)++) {
151
- if (kp->kpasmkp[i] & (1 << *row))
152
- return;
153
- }
154
- *col = i * 2 + 1;
155
- for (*row = 0; *row < 8; (*row)++) {
156
- if (kp->kpasmkp[i] & (1 << (*row + 16)))
157
- return;
158
- }
159
- }
160
-}
161
-
162
-static void pxa27x_keyboard_event (PXA2xxKeyPadState *kp, int keycode)
163
-{
164
- int row, col, rel, assert_irq = 0;
165
- uint32_t val;
166
-
167
- if (keycode == 0xe0) {
168
- kp->alt_code = 1;
169
- return;
170
- }
171
-
172
- if(!(kp->kpc & KPC_ME)) /* skip if not enabled */
173
- return;
174
-
175
- rel = (keycode & 0x80) ? 1 : 0; /* key release from qemu */
176
- keycode &= ~0x80; /* strip qemu key release bit */
177
- if (kp->alt_code) {
178
- keycode |= 0x80;
179
- kp->alt_code = 0;
180
- }
181
-
182
- row = kp->map[keycode].row;
183
- col = kp->map[keycode].column;
184
- if (row == -1 || col == -1) {
185
- return;
186
- }
187
-
188
- val = KPASMKPx_MKC(row, col);
189
- if (rel) {
190
- if (kp->kpasmkp[col / 2] & val) {
191
- kp->kpasmkp[col / 2] &= ~val;
192
- kp->pressed_cnt--;
193
- assert_irq = 1;
194
- }
195
- } else {
196
- if (!(kp->kpasmkp[col / 2] & val)) {
197
- kp->kpasmkp[col / 2] |= val;
198
- kp->pressed_cnt++;
199
- assert_irq = 1;
200
- }
201
- }
202
- kp->kpas = ((kp->pressed_cnt & 0x1f) << 26) | (0xf << 4) | 0xf;
203
- if (kp->pressed_cnt == 1) {
204
- kp->kpas &= ~((0xf << 4) | 0xf);
205
- if (rel) {
206
- pxa27x_keypad_find_pressed_key(kp, &row, &col);
207
- }
208
- kp->kpas |= ((row & 0xf) << 4) | (col & 0xf);
209
- }
210
-
211
- if (!(kp->kpc & (KPC_AS | KPC_ASACT)))
212
- assert_irq = 0;
213
-
214
- if (assert_irq && (kp->kpc & KPC_MIE)) {
215
- kp->kpc |= KPC_MI;
216
- qemu_irq_raise(kp->irq);
217
- }
218
-}
219
-
220
-static uint64_t pxa2xx_keypad_read(void *opaque, hwaddr offset,
221
- unsigned size)
222
-{
223
- PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque;
224
- uint32_t tmp;
225
-
226
- switch (offset) {
227
- case KPC:
228
- tmp = s->kpc;
229
- if(tmp & KPC_MI)
230
- s->kpc &= ~(KPC_MI);
231
- if(tmp & KPC_DI)
232
- s->kpc &= ~(KPC_DI);
233
- qemu_irq_lower(s->irq);
234
- return tmp;
235
- case KPDK:
236
- return s->kpdk;
237
- case KPREC:
238
- tmp = s->kprec;
239
- if(tmp & KPREC_OF1)
240
- s->kprec &= ~(KPREC_OF1);
241
- if(tmp & KPREC_UF1)
242
- s->kprec &= ~(KPREC_UF1);
243
- if(tmp & KPREC_OF0)
244
- s->kprec &= ~(KPREC_OF0);
245
- if(tmp & KPREC_UF0)
246
- s->kprec &= ~(KPREC_UF0);
247
- return tmp;
248
- case KPMK:
249
- tmp = s->kpmk;
250
- if(tmp & KPMK_MKP)
251
- s->kpmk &= ~(KPMK_MKP);
252
- return tmp;
253
- case KPAS:
254
- return s->kpas;
255
- case KPASMKP0:
256
- return s->kpasmkp[0];
257
- case KPASMKP1:
258
- return s->kpasmkp[1];
259
- case KPASMKP2:
260
- return s->kpasmkp[2];
261
- case KPASMKP3:
262
- return s->kpasmkp[3];
263
- case KPKDI:
264
- return s->kpkdi;
265
- default:
266
- qemu_log_mask(LOG_GUEST_ERROR,
267
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
268
- __func__, offset);
269
- }
270
-
271
- return 0;
272
-}
273
-
274
-static void pxa2xx_keypad_write(void *opaque, hwaddr offset,
275
- uint64_t value, unsigned size)
276
-{
277
- PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque;
278
-
279
- switch (offset) {
280
- case KPC:
281
- s->kpc = value;
282
- if (s->kpc & KPC_AS) {
283
- s->kpc &= ~(KPC_AS);
284
- }
285
- break;
286
- case KPDK:
287
- s->kpdk = value;
288
- break;
289
- case KPREC:
290
- s->kprec = value;
291
- break;
292
- case KPMK:
293
- s->kpmk = value;
294
- break;
295
- case KPAS:
296
- s->kpas = value;
297
- break;
298
- case KPASMKP0:
299
- s->kpasmkp[0] = value;
300
- break;
301
- case KPASMKP1:
302
- s->kpasmkp[1] = value;
303
- break;
304
- case KPASMKP2:
305
- s->kpasmkp[2] = value;
306
- break;
307
- case KPASMKP3:
308
- s->kpasmkp[3] = value;
309
- break;
310
- case KPKDI:
311
- s->kpkdi = value;
312
- break;
313
-
314
- default:
315
- qemu_log_mask(LOG_GUEST_ERROR,
316
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
317
- __func__, offset);
318
- }
319
-}
320
-
321
-static const MemoryRegionOps pxa2xx_keypad_ops = {
322
- .read = pxa2xx_keypad_read,
323
- .write = pxa2xx_keypad_write,
324
- .endianness = DEVICE_NATIVE_ENDIAN,
325
-};
326
-
327
-static const VMStateDescription vmstate_pxa2xx_keypad = {
328
- .name = "pxa2xx_keypad",
329
- .version_id = 0,
330
- .minimum_version_id = 0,
331
- .fields = (const VMStateField[]) {
332
- VMSTATE_UINT32(kpc, PXA2xxKeyPadState),
333
- VMSTATE_UINT32(kpdk, PXA2xxKeyPadState),
334
- VMSTATE_UINT32(kprec, PXA2xxKeyPadState),
335
- VMSTATE_UINT32(kpmk, PXA2xxKeyPadState),
336
- VMSTATE_UINT32(kpas, PXA2xxKeyPadState),
337
- VMSTATE_UINT32_ARRAY(kpasmkp, PXA2xxKeyPadState, 4),
338
- VMSTATE_UINT32(kpkdi, PXA2xxKeyPadState),
339
- VMSTATE_END_OF_LIST()
340
- }
341
-};
342
-
343
-PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem,
344
- hwaddr base,
345
- qemu_irq irq)
346
-{
347
- PXA2xxKeyPadState *s;
348
-
349
- s = g_new0(PXA2xxKeyPadState, 1);
350
- s->irq = irq;
351
-
352
- memory_region_init_io(&s->iomem, NULL, &pxa2xx_keypad_ops, s,
353
- "pxa2xx-keypad", 0x00100000);
354
- memory_region_add_subregion(sysmem, base, &s->iomem);
355
-
356
- vmstate_register(NULL, 0, &vmstate_pxa2xx_keypad, s);
357
-
358
- return s;
359
-}
360
-
361
-void pxa27x_register_keypad(PXA2xxKeyPadState *kp,
362
- const struct keymap *map, int size)
363
-{
364
- if(!map || size < 0x80) {
365
- fprintf(stderr, "%s - No PXA keypad map defined\n", __func__);
366
- exit(-1);
367
- }
368
-
369
- kp->map = map;
370
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
371
-}
372
diff --git a/hw/input/meson.build b/hw/input/meson.build
373
index XXXXXXX..XXXXXXX 100644
374
--- a/hw/input/meson.build
375
+++ b/hw/input/meson.build
376
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: files('virtio-input.c'))
377
system_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: files('virtio-input-hid.c'))
378
system_ss.add(when: 'CONFIG_VIRTIO_INPUT_HOST', if_true: files('virtio-input-host.c'))
379
380
-system_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_keypad.c'))
381
system_ss.add(when: 'CONFIG_TSC210X', if_true: files('tsc210x.c'))
382
system_ss.add(when: 'CONFIG_LASIPS2', if_true: files('lasips2.c'))
383
--
25
--
384
2.34.1
26
2.34.1
385
386
diff view generated by jsdifflib
1
pxa2xx_timer includes pxa.h, but it doesn't actually make
1
Set the default NaN pattern explicitly for rx.
2
use of any of the #defines, function prototypes or structs
3
defined there. Remove the unnecessary include (we will
4
shortly be removing the whole header file).
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20241202131347.498124-48-peter.maydell@linaro.org
9
Message-id: 20240903160751.4100218-15-peter.maydell@linaro.org
10
---
6
---
11
hw/timer/pxa2xx_timer.c | 1 -
7
target/rx/cpu.c | 2 ++
12
1 file changed, 1 deletion(-)
8
1 file changed, 2 insertions(+)
13
9
14
diff --git a/hw/timer/pxa2xx_timer.c b/hw/timer/pxa2xx_timer.c
10
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/timer/pxa2xx_timer.c
12
--- a/target/rx/cpu.c
17
+++ b/hw/timer/pxa2xx_timer.c
13
+++ b/target/rx/cpu.c
18
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_reset_hold(Object *obj, ResetType type)
19
#include "hw/qdev-properties.h"
15
* then prefer dest over source", which is float_2nan_prop_s_ab.
20
#include "qemu/timer.h"
16
*/
21
#include "sysemu/runstate.h"
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
22
-#include "hw/arm/pxa.h"
18
+ /* Default NaN value: sign bit clear, set frac msb */
23
#include "hw/sysbus.h"
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
24
#include "migration/vmstate.h"
20
}
25
#include "qemu/log.h"
21
22
static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
26
--
23
--
27
2.34.1
24
2.34.1
28
29
diff view generated by jsdifflib
1
Currently the STRONGARM KConfig symbol pulls in PXA2XX. Since we've now
1
Set the default NaN pattern explicitly for s390x.
2
removed all the true uses of PXA2XX, we'd like to remove the PXA2XX
3
symbol too. To permit that, make STRONGARM directly select the things
4
it truly depends on:
5
* pxa25x-timer
6
* SSI
7
2
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20241202131347.498124-49-peter.maydell@linaro.org
11
Message-id: 20240903160751.4100218-14-peter.maydell@linaro.org
12
---
6
---
13
hw/arm/Kconfig | 4 +++-
7
target/s390x/cpu.c | 2 ++
14
hw/timer/Kconfig | 3 +++
8
1 file changed, 2 insertions(+)
15
hw/timer/meson.build | 2 +-
16
3 files changed, 7 insertions(+), 2 deletions(-)
17
9
18
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
10
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
19
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/Kconfig
12
--- a/target/s390x/cpu.c
21
+++ b/hw/arm/Kconfig
13
+++ b/target/s390x/cpu.c
22
@@ -XXX,XX +XXX,XX @@ config PXA2XX
14
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
23
select SSI
15
set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
24
select USB_OHCI_SYSBUS
16
set_float_infzeronan_rule(float_infzeronan_dnan_always,
25
select PCMCIA
17
&env->fpu_status);
26
+ select PXA2XX_TIMER
18
+ /* Default NaN value: sign bit clear, frac msb set */
27
19
+ set_float_default_nan_pattern(0b01000000, &env->fpu_status);
28
config REALVIEW
20
/* fall through */
29
bool
21
case RESET_TYPE_S390_CPU_NORMAL:
30
@@ -XXX,XX +XXX,XX @@ config STM32VLDISCOVERY
22
env->psw.mask &= ~PSW_MASK_RI;
31
32
config STRONGARM
33
bool
34
- select PXA2XX
35
+ select PXA2XX_TIMER
36
+ select SSI
37
38
config COLLIE
39
bool
40
diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/timer/Kconfig
43
+++ b/hw/timer/Kconfig
44
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10_PIT
45
bool
46
select PTIMER
47
48
+config PXA2XX_TIMER
49
+ bool
50
+
51
config SIFIVE_PWM
52
bool
53
54
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/timer/meson.build
57
+++ b/hw/timer/meson.build
58
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_timer.c'))
59
system_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_timer.c'))
60
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_gptimer.c'))
61
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_synctimer.c'))
62
-system_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_timer.c'))
63
+system_ss.add(when: 'CONFIG_PXA2XX_TIMER', if_true: files('pxa2xx_timer.c'))
64
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_systmr.c'))
65
system_ss.add(when: 'CONFIG_SH_TIMER', if_true: files('sh_timer.c'))
66
system_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_timer.c'))
67
--
23
--
68
2.34.1
24
2.34.1
69
70
diff view generated by jsdifflib
1
The 'z2' machine was deprecated in 9.0, so we can remove it for
1
Set the default NaN pattern explicitly for SPARC, and remove
2
9.2.
2
the ifdef from parts64_default_nan.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20240903160751.4100218-13-peter.maydell@linaro.org
6
Message-id: 20241202131347.498124-50-peter.maydell@linaro.org
7
---
7
---
8
MAINTAINERS | 1 -
8
target/sparc/cpu.c | 2 ++
9
configs/devices/arm-softmmu/default.mak | 1 -
9
fpu/softfloat-specialize.c.inc | 5 +----
10
hw/arm/z2.c | 355 ------------------------
10
2 files changed, 3 insertions(+), 4 deletions(-)
11
hw/arm/Kconfig | 9 -
12
hw/arm/meson.build | 1 -
13
5 files changed, 367 deletions(-)
14
delete mode 100644 hw/arm/z2.c
15
11
16
diff --git a/MAINTAINERS b/MAINTAINERS
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/MAINTAINERS
14
--- a/target/sparc/cpu.c
19
+++ b/MAINTAINERS
15
+++ b/target/sparc/cpu.c
20
@@ -XXX,XX +XXX,XX @@ PXA2XX
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
21
M: Peter Maydell <peter.maydell@linaro.org>
17
set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
22
L: qemu-arm@nongnu.org
18
/* For inf * 0 + NaN, return the input NaN */
23
S: Odd Fixes
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
-F: hw/arm/z2.c
20
+ /* Default NaN value: sign bit clear, all frac bits set */
25
F: hw/*/pxa2xx*
21
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
26
F: hw/gpio/max7310.c
22
27
F: hw/adc/max111x.c
23
cpu_exec_realizefn(cs, &local_err);
28
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
24
if (local_err != NULL) {
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
29
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
30
--- a/configs/devices/arm-softmmu/default.mak
27
--- a/fpu/softfloat-specialize.c.inc
31
+++ b/configs/devices/arm-softmmu/default.mak
28
+++ b/fpu/softfloat-specialize.c.inc
32
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
33
# CONFIG_VERSATILE=n
30
uint8_t dnan_pattern = status->default_nan_pattern;
34
# CONFIG_VEXPRESS=n
31
35
# CONFIG_ZYNQ=n
32
if (dnan_pattern == 0) {
36
-# CONFIG_Z2=n
33
-#if defined(TARGET_SPARC)
37
# CONFIG_NPCM7XX=n
34
- /* Sign bit clear, all frac bits set */
38
# CONFIG_COLLIE=n
35
- dnan_pattern = 0b01111111;
39
# CONFIG_ASPEED_SOC=n
36
-#elif defined(TARGET_HEXAGON)
40
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
37
+#if defined(TARGET_HEXAGON)
41
deleted file mode 100644
38
/* Sign bit set, all frac bits set. */
42
index XXXXXXX..XXXXXXX
39
dnan_pattern = 0b11111111;
43
--- a/hw/arm/z2.c
40
#else
44
+++ /dev/null
45
@@ -XXX,XX +XXX,XX @@
46
-/*
47
- * PXA270-based Zipit Z2 device
48
- *
49
- * Copyright (c) 2011 by Vasily Khoruzhick <anarsoul@gmail.com>
50
- *
51
- * Code is based on mainstone platform.
52
- *
53
- * This code is licensed under the GNU GPL v2.
54
- *
55
- * Contributions after 2012-01-13 are licensed under the terms of the
56
- * GNU GPL, version 2 or (at your option) any later version.
57
- */
58
-
59
-#include "qemu/osdep.h"
60
-#include "qemu/units.h"
61
-#include "hw/arm/pxa.h"
62
-#include "hw/arm/boot.h"
63
-#include "hw/i2c/i2c.h"
64
-#include "hw/irq.h"
65
-#include "hw/ssi/ssi.h"
66
-#include "migration/vmstate.h"
67
-#include "hw/boards.h"
68
-#include "hw/block/flash.h"
69
-#include "ui/console.h"
70
-#include "hw/audio/wm8750.h"
71
-#include "audio/audio.h"
72
-#include "exec/address-spaces.h"
73
-#include "qom/object.h"
74
-#include "qapi/error.h"
75
-#include "trace.h"
76
-
77
-static const struct keymap map[0x100] = {
78
- [0 ... 0xff] = { -1, -1 },
79
- [0x3b] = {0, 0}, /* Option = F1 */
80
- [0xc8] = {0, 1}, /* Up */
81
- [0xd0] = {0, 2}, /* Down */
82
- [0xcb] = {0, 3}, /* Left */
83
- [0xcd] = {0, 4}, /* Right */
84
- [0xcf] = {0, 5}, /* End */
85
- [0x0d] = {0, 6}, /* KPPLUS */
86
- [0xc7] = {1, 0}, /* Home */
87
- [0x10] = {1, 1}, /* Q */
88
- [0x17] = {1, 2}, /* I */
89
- [0x22] = {1, 3}, /* G */
90
- [0x2d] = {1, 4}, /* X */
91
- [0x1c] = {1, 5}, /* Enter */
92
- [0x0c] = {1, 6}, /* KPMINUS */
93
- [0xc9] = {2, 0}, /* PageUp */
94
- [0x11] = {2, 1}, /* W */
95
- [0x18] = {2, 2}, /* O */
96
- [0x23] = {2, 3}, /* H */
97
- [0x2e] = {2, 4}, /* C */
98
- [0x38] = {2, 5}, /* LeftAlt */
99
- [0xd1] = {3, 0}, /* PageDown */
100
- [0x12] = {3, 1}, /* E */
101
- [0x19] = {3, 2}, /* P */
102
- [0x24] = {3, 3}, /* J */
103
- [0x2f] = {3, 4}, /* V */
104
- [0x2a] = {3, 5}, /* LeftShift */
105
- [0x01] = {4, 0}, /* Esc */
106
- [0x13] = {4, 1}, /* R */
107
- [0x1e] = {4, 2}, /* A */
108
- [0x25] = {4, 3}, /* K */
109
- [0x30] = {4, 4}, /* B */
110
- [0x1d] = {4, 5}, /* LeftCtrl */
111
- [0x0f] = {5, 0}, /* Tab */
112
- [0x14] = {5, 1}, /* T */
113
- [0x1f] = {5, 2}, /* S */
114
- [0x26] = {5, 3}, /* L */
115
- [0x31] = {5, 4}, /* N */
116
- [0x39] = {5, 5}, /* Space */
117
- [0x3c] = {6, 0}, /* Stop = F2 */
118
- [0x15] = {6, 1}, /* Y */
119
- [0x20] = {6, 2}, /* D */
120
- [0x0e] = {6, 3}, /* Backspace */
121
- [0x32] = {6, 4}, /* M */
122
- [0x33] = {6, 5}, /* Comma */
123
- [0x3d] = {7, 0}, /* Play = F3 */
124
- [0x16] = {7, 1}, /* U */
125
- [0x21] = {7, 2}, /* F */
126
- [0x2c] = {7, 3}, /* Z */
127
- [0x27] = {7, 4}, /* Semicolon */
128
- [0x34] = {7, 5}, /* Dot */
129
-};
130
-
131
-#define Z2_RAM_SIZE 0x02000000
132
-#define Z2_FLASH_BASE 0x00000000
133
-#define Z2_FLASH_SIZE 0x00800000
134
-
135
-static struct arm_boot_info z2_binfo = {
136
- .loader_start = PXA2XX_SDRAM_BASE,
137
- .ram_size = Z2_RAM_SIZE,
138
-};
139
-
140
-#define Z2_GPIO_SD_DETECT 96
141
-#define Z2_GPIO_AC_IN 0
142
-#define Z2_GPIO_KEY_ON 1
143
-#define Z2_GPIO_LCD_CS 88
144
-
145
-struct ZipitLCD {
146
- SSIPeripheral ssidev;
147
- int32_t selected;
148
- int32_t enabled;
149
- uint8_t buf[3];
150
- uint32_t cur_reg;
151
- int pos;
152
-};
153
-
154
-#define TYPE_ZIPIT_LCD "zipit-lcd"
155
-OBJECT_DECLARE_SIMPLE_TYPE(ZipitLCD, ZIPIT_LCD)
156
-
157
-static uint32_t zipit_lcd_transfer(SSIPeripheral *dev, uint32_t value)
158
-{
159
- ZipitLCD *z = ZIPIT_LCD(dev);
160
- uint16_t val;
161
-
162
- trace_z2_lcd_reg_update(z->cur_reg, z->buf[0], z->buf[1], z->buf[2], value);
163
- if (z->selected) {
164
- z->buf[z->pos] = value & 0xff;
165
- z->pos++;
166
- }
167
- if (z->pos == 3) {
168
- switch (z->buf[0]) {
169
- case 0x74:
170
- z->cur_reg = z->buf[2];
171
- break;
172
- case 0x76:
173
- val = z->buf[1] << 8 | z->buf[2];
174
- if (z->cur_reg == 0x22 && val == 0x0000) {
175
- z->enabled = 1;
176
- trace_z2_lcd_enable_disable_result("enabled");
177
- } else if (z->cur_reg == 0x10 && val == 0x0000) {
178
- z->enabled = 0;
179
- trace_z2_lcd_enable_disable_result("disabled");
180
- }
181
- break;
182
- default:
183
- break;
184
- }
185
- z->pos = 0;
186
- }
187
- return 0;
188
-}
189
-
190
-static void z2_lcd_cs(void *opaque, int line, int level)
191
-{
192
- ZipitLCD *z2_lcd = opaque;
193
- z2_lcd->selected = !level;
194
-}
195
-
196
-static void zipit_lcd_realize(SSIPeripheral *dev, Error **errp)
197
-{
198
- ZipitLCD *z = ZIPIT_LCD(dev);
199
- z->selected = 0;
200
- z->enabled = 0;
201
- z->pos = 0;
202
-}
203
-
204
-static const VMStateDescription vmstate_zipit_lcd_state = {
205
- .name = "zipit-lcd",
206
- .version_id = 2,
207
- .minimum_version_id = 2,
208
- .fields = (const VMStateField[]) {
209
- VMSTATE_SSI_PERIPHERAL(ssidev, ZipitLCD),
210
- VMSTATE_INT32(selected, ZipitLCD),
211
- VMSTATE_INT32(enabled, ZipitLCD),
212
- VMSTATE_BUFFER(buf, ZipitLCD),
213
- VMSTATE_UINT32(cur_reg, ZipitLCD),
214
- VMSTATE_INT32(pos, ZipitLCD),
215
- VMSTATE_END_OF_LIST(),
216
- }
217
-};
218
-
219
-static void zipit_lcd_class_init(ObjectClass *klass, void *data)
220
-{
221
- DeviceClass *dc = DEVICE_CLASS(klass);
222
- SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
223
-
224
- k->realize = zipit_lcd_realize;
225
- k->transfer = zipit_lcd_transfer;
226
- dc->vmsd = &vmstate_zipit_lcd_state;
227
-}
228
-
229
-static const TypeInfo zipit_lcd_info = {
230
- .name = TYPE_ZIPIT_LCD,
231
- .parent = TYPE_SSI_PERIPHERAL,
232
- .instance_size = sizeof(ZipitLCD),
233
- .class_init = zipit_lcd_class_init,
234
-};
235
-
236
-#define TYPE_AER915 "aer915"
237
-OBJECT_DECLARE_SIMPLE_TYPE(AER915State, AER915)
238
-
239
-struct AER915State {
240
- I2CSlave parent_obj;
241
-
242
- int len;
243
- uint8_t buf[3];
244
-};
245
-
246
-static int aer915_send(I2CSlave *i2c, uint8_t data)
247
-{
248
- AER915State *s = AER915(i2c);
249
-
250
- s->buf[s->len] = data;
251
- if (s->len++ > 2) {
252
- trace_z2_aer915_send_too_long(s->len);
253
- return 1;
254
- }
255
-
256
- if (s->len == 2) {
257
- trace_z2_aer915_send(s->buf[0], s->buf[1]);
258
- }
259
-
260
- return 0;
261
-}
262
-
263
-static int aer915_event(I2CSlave *i2c, enum i2c_event event)
264
-{
265
- AER915State *s = AER915(i2c);
266
-
267
- trace_z2_aer915_event(s->len, event);
268
- switch (event) {
269
- case I2C_START_SEND:
270
- s->len = 0;
271
- break;
272
- case I2C_START_RECV:
273
- break;
274
- case I2C_FINISH:
275
- break;
276
- default:
277
- break;
278
- }
279
-
280
- return 0;
281
-}
282
-
283
-static uint8_t aer915_recv(I2CSlave *slave)
284
-{
285
- AER915State *s = AER915(slave);
286
- int retval = 0x00;
287
-
288
- switch (s->buf[0]) {
289
- /* Return hardcoded battery voltage,
290
- * 0xf0 means ~4.1V
291
- */
292
- case 0x02:
293
- retval = 0xf0;
294
- break;
295
- /* Return 0x00 for other regs,
296
- * we don't know what they are for,
297
- * anyway they return 0x00 on real hardware.
298
- */
299
- default:
300
- break;
301
- }
302
-
303
- return retval;
304
-}
305
-
306
-static const VMStateDescription vmstate_aer915_state = {
307
- .name = "aer915",
308
- .version_id = 1,
309
- .minimum_version_id = 1,
310
- .fields = (const VMStateField[]) {
311
- VMSTATE_INT32(len, AER915State),
312
- VMSTATE_BUFFER(buf, AER915State),
313
- VMSTATE_END_OF_LIST(),
314
- }
315
-};
316
-
317
-static void aer915_class_init(ObjectClass *klass, void *data)
318
-{
319
- DeviceClass *dc = DEVICE_CLASS(klass);
320
- I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
321
-
322
- k->event = aer915_event;
323
- k->recv = aer915_recv;
324
- k->send = aer915_send;
325
- dc->vmsd = &vmstate_aer915_state;
326
-}
327
-
328
-static const TypeInfo aer915_info = {
329
- .name = TYPE_AER915,
330
- .parent = TYPE_I2C_SLAVE,
331
- .instance_size = sizeof(AER915State),
332
- .class_init = aer915_class_init,
333
-};
334
-
335
-#define FLASH_SECTOR_SIZE (64 * KiB)
336
-
337
-static void z2_init(MachineState *machine)
338
-{
339
- PXA2xxState *mpu;
340
- DriveInfo *dinfo;
341
- void *z2_lcd;
342
- I2CBus *bus;
343
- DeviceState *wm;
344
- I2CSlave *i2c_dev;
345
-
346
- /* Setup CPU & memory */
347
- mpu = pxa270_init(z2_binfo.ram_size, machine->cpu_type);
348
-
349
- dinfo = drive_get(IF_PFLASH, 0, 0);
350
- pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
351
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
352
- FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0);
353
-
354
- /* setup keypad */
355
- pxa27x_register_keypad(mpu->kp, map, 0x100);
356
-
357
- /* MMC/SD host */
358
- pxa2xx_mmci_handlers(mpu->mmc,
359
- NULL,
360
- qdev_get_gpio_in(mpu->gpio, Z2_GPIO_SD_DETECT));
361
-
362
- type_register_static(&zipit_lcd_info);
363
- type_register_static(&aer915_info);
364
- z2_lcd = ssi_create_peripheral(mpu->ssp[1], TYPE_ZIPIT_LCD);
365
- bus = pxa2xx_i2c_bus(mpu->i2c[0]);
366
-
367
- i2c_slave_create_simple(bus, TYPE_AER915, 0x55);
368
-
369
- i2c_dev = i2c_slave_new(TYPE_WM8750, 0x1b);
370
- wm = DEVICE(i2c_dev);
371
-
372
- if (machine->audiodev) {
373
- qdev_prop_set_string(wm, "audiodev", machine->audiodev);
374
- }
375
- i2c_slave_realize_and_unref(i2c_dev, bus, &error_abort);
376
-
377
- mpu->i2s->opaque = wm;
378
- mpu->i2s->codec_out = wm8750_dac_dat;
379
- mpu->i2s->codec_in = wm8750_adc_dat;
380
- wm8750_data_req_set(wm, mpu->i2s->data_req, mpu->i2s);
381
-
382
- qdev_connect_gpio_out(mpu->gpio, Z2_GPIO_LCD_CS,
383
- qemu_allocate_irq(z2_lcd_cs, z2_lcd, 0));
384
-
385
- z2_binfo.board_id = 0x6dd;
386
- arm_load_kernel(mpu->cpu, machine, &z2_binfo);
387
-}
388
-
389
-static void z2_machine_init(MachineClass *mc)
390
-{
391
- mc->desc = "Zipit Z2 (PXA27x)";
392
- mc->init = z2_init;
393
- mc->ignore_memory_transaction_failures = true;
394
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c5");
395
- mc->deprecation_reason = "machine is old and unmaintained";
396
-
397
- machine_add_audiodev_property(mc);
398
-}
399
-
400
-DEFINE_MACHINE("z2", z2_machine_init)
401
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
402
index XXXXXXX..XXXXXXX 100644
403
--- a/hw/arm/Kconfig
404
+++ b/hw/arm/Kconfig
405
@@ -XXX,XX +XXX,XX @@ config PXA2XX
406
select USB_OHCI_SYSBUS
407
select PCMCIA
408
409
-config Z2
410
- bool
411
- default y
412
- depends on TCG && ARM
413
- select PFLASH_CFI01
414
- select WM8750
415
- select PL011 # UART
416
- select PXA2XX
417
-
418
config REALVIEW
419
bool
420
default y
421
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
422
index XXXXXXX..XXXXXXX 100644
423
--- a/hw/arm/meson.build
424
+++ b/hw/arm/meson.build
425
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_STRONGARM', if_true: files('strongarm.c'))
426
system_ss.add(when: 'CONFIG_SX1', if_true: files('omap_sx1.c'))
427
system_ss.add(when: 'CONFIG_VERSATILE', if_true: files('versatilepb.c'))
428
system_ss.add(when: 'CONFIG_VEXPRESS', if_true: files('vexpress.c'))
429
-system_ss.add(when: 'CONFIG_Z2', if_true: files('z2.c'))
430
431
hw_arch += {'arm': arm_ss}
432
--
41
--
433
2.34.1
42
2.34.1
434
435
diff view generated by jsdifflib
1
Remove the tsc2005 touchscreen controller, which was only used
1
Set the default NaN pattern explicitly for xtensa.
2
by the n800 and n810 machines.
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: Thomas Huth <thuth@redhat.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20240903160751.4100218-29-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-51-peter.maydell@linaro.org
7
---
6
---
8
MAINTAINERS | 1 -
7
target/xtensa/cpu.c | 2 ++
9
include/hw/input/tsc2xxx.h | 5 -
8
1 file changed, 2 insertions(+)
10
hw/input/tsc2005.c | 571 -------------------------------------
11
hw/input/Kconfig | 3 -
12
hw/input/meson.build | 1 -
13
hw/input/trace-events | 3 -
14
6 files changed, 584 deletions(-)
15
delete mode 100644 hw/input/tsc2005.c
16
9
17
diff --git a/MAINTAINERS b/MAINTAINERS
10
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/MAINTAINERS
12
--- a/target/xtensa/cpu.c
20
+++ b/MAINTAINERS
13
+++ b/target/xtensa/cpu.c
21
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
14
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
22
L: qemu-arm@nongnu.org
15
/* For inf * 0 + NaN, return the input NaN */
23
S: Odd Fixes
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
F: hw/input/lm832x.c
17
set_no_signaling_nans(!dfpu, &env->fp_status);
25
-F: hw/input/tsc2005.c
18
+ /* Default NaN value: sign bit clear, set frac msb */
26
F: hw/input/tsc210x.c
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
27
F: hw/rtc/twl92230.c
20
xtensa_use_first_nan(env, !dfpu);
28
F: include/hw/input/lm832x.h
21
}
29
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/input/tsc2xxx.h
32
+++ b/include/hw/input/tsc2xxx.h
33
@@ -XXX,XX +XXX,XX @@ uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
34
void tsc210x_set_transform(uWireSlave *chip, const MouseTransformInfo *info);
35
void tsc210x_key_event(uWireSlave *chip, int key, int down);
36
37
-/* tsc2005.c */
38
-void *tsc2005_init(qemu_irq pintdav);
39
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
40
-void tsc2005_set_transform(void *opaque, const MouseTransformInfo *info);
41
-
42
#endif
43
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
44
deleted file mode 100644
45
index XXXXXXX..XXXXXXX
46
--- a/hw/input/tsc2005.c
47
+++ /dev/null
48
@@ -XXX,XX +XXX,XX @@
49
-/*
50
- * TI TSC2005 emulator.
51
- *
52
- * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
53
- * Copyright (C) 2008 Nokia Corporation
54
- *
55
- * This program is free software; you can redistribute it and/or
56
- * modify it under the terms of the GNU General Public License as
57
- * published by the Free Software Foundation; either version 2 or
58
- * (at your option) version 3 of the License.
59
- *
60
- * This program is distributed in the hope that it will be useful,
61
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
62
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63
- * GNU General Public License for more details.
64
- *
65
- * You should have received a copy of the GNU General Public License along
66
- * with this program; if not, see <http://www.gnu.org/licenses/>.
67
- */
68
-
69
-#include "qemu/osdep.h"
70
-#include "qemu/log.h"
71
-#include "qemu/timer.h"
72
-#include "sysemu/reset.h"
73
-#include "ui/console.h"
74
-#include "hw/input/tsc2xxx.h"
75
-#include "hw/irq.h"
76
-#include "migration/vmstate.h"
77
-#include "trace.h"
78
-
79
-#define TSC_CUT_RESOLUTION(value, p) ((value) >> (16 - (p ? 12 : 10)))
80
-
81
-typedef struct {
82
- qemu_irq pint; /* Combination of the nPENIRQ and DAV signals */
83
- QEMUTimer *timer;
84
- uint16_t model;
85
-
86
- int32_t x, y;
87
- bool pressure;
88
-
89
- uint8_t reg, state;
90
- bool irq, command;
91
- uint16_t data, dav;
92
-
93
- bool busy;
94
- bool enabled;
95
- bool host_mode;
96
- int8_t function;
97
- int8_t nextfunction;
98
- bool precision;
99
- bool nextprecision;
100
- uint16_t filter;
101
- uint8_t pin_func;
102
- uint16_t timing[2];
103
- uint8_t noise;
104
- bool reset;
105
- bool pdst;
106
- bool pnd0;
107
- uint16_t temp_thr[2];
108
- uint16_t aux_thr[2];
109
-
110
- int32_t tr[8];
111
-} TSC2005State;
112
-
113
-enum {
114
- TSC_MODE_XYZ_SCAN = 0x0,
115
- TSC_MODE_XY_SCAN,
116
- TSC_MODE_X,
117
- TSC_MODE_Y,
118
- TSC_MODE_Z,
119
- TSC_MODE_AUX,
120
- TSC_MODE_TEMP1,
121
- TSC_MODE_TEMP2,
122
- TSC_MODE_AUX_SCAN,
123
- TSC_MODE_X_TEST,
124
- TSC_MODE_Y_TEST,
125
- TSC_MODE_TS_TEST,
126
- TSC_MODE_RESERVED,
127
- TSC_MODE_XX_DRV,
128
- TSC_MODE_YY_DRV,
129
- TSC_MODE_YX_DRV,
130
-};
131
-
132
-static const uint16_t mode_regs[16] = {
133
- 0xf000, /* X, Y, Z scan */
134
- 0xc000, /* X, Y scan */
135
- 0x8000, /* X */
136
- 0x4000, /* Y */
137
- 0x3000, /* Z */
138
- 0x0800, /* AUX */
139
- 0x0400, /* TEMP1 */
140
- 0x0200, /* TEMP2 */
141
- 0x0800, /* AUX scan */
142
- 0x0040, /* X test */
143
- 0x0020, /* Y test */
144
- 0x0080, /* Short-circuit test */
145
- 0x0000, /* Reserved */
146
- 0x0000, /* X+, X- drivers */
147
- 0x0000, /* Y+, Y- drivers */
148
- 0x0000, /* Y+, X- drivers */
149
-};
150
-
151
-#define X_TRANSFORM(s) \
152
- ((s->y * s->tr[0] - s->x * s->tr[1]) / s->tr[2] + s->tr[3])
153
-#define Y_TRANSFORM(s) \
154
- ((s->y * s->tr[4] - s->x * s->tr[5]) / s->tr[6] + s->tr[7])
155
-#define Z1_TRANSFORM(s) \
156
- ((400 - ((s)->x >> 7) + ((s)->pressure << 10)) << 4)
157
-#define Z2_TRANSFORM(s) \
158
- ((4000 + ((s)->y >> 7) - ((s)->pressure << 10)) << 4)
159
-
160
-#define AUX_VAL (700 << 4) /* +/- 3 at 12-bit */
161
-#define TEMP1_VAL (1264 << 4) /* +/- 5 at 12-bit */
162
-#define TEMP2_VAL (1531 << 4) /* +/- 5 at 12-bit */
163
-
164
-static uint16_t tsc2005_read(TSC2005State *s, int reg)
165
-{
166
- uint16_t ret;
167
-
168
- switch (reg) {
169
- case 0x0: /* X */
170
- s->dav &= ~mode_regs[TSC_MODE_X];
171
- return TSC_CUT_RESOLUTION(X_TRANSFORM(s), s->precision) +
172
- (s->noise & 3);
173
- case 0x1: /* Y */
174
- s->dav &= ~mode_regs[TSC_MODE_Y];
175
- s->noise++;
176
- return TSC_CUT_RESOLUTION(Y_TRANSFORM(s), s->precision) ^
177
- (s->noise & 3);
178
- case 0x2: /* Z1 */
179
- s->dav &= 0xdfff;
180
- return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
181
- (s->noise & 3);
182
- case 0x3: /* Z2 */
183
- s->dav &= 0xefff;
184
- return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
185
- (s->noise & 3);
186
-
187
- case 0x4: /* AUX */
188
- s->dav &= ~mode_regs[TSC_MODE_AUX];
189
- return TSC_CUT_RESOLUTION(AUX_VAL, s->precision);
190
-
191
- case 0x5: /* TEMP1 */
192
- s->dav &= ~mode_regs[TSC_MODE_TEMP1];
193
- return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision) -
194
- (s->noise & 5);
195
- case 0x6: /* TEMP2 */
196
- s->dav &= 0xdfff;
197
- s->dav &= ~mode_regs[TSC_MODE_TEMP2];
198
- return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision) ^
199
- (s->noise & 3);
200
-
201
- case 0x7: /* Status */
202
- ret = s->dav | (s->reset << 7) | (s->pdst << 2) | 0x0;
203
- s->dav &= ~(mode_regs[TSC_MODE_X_TEST] | mode_regs[TSC_MODE_Y_TEST] |
204
- mode_regs[TSC_MODE_TS_TEST]);
205
- s->reset = true;
206
- return ret;
207
-
208
- case 0x8: /* AUX high threshold */
209
- return s->aux_thr[1];
210
- case 0x9: /* AUX low threshold */
211
- return s->aux_thr[0];
212
-
213
- case 0xa: /* TEMP high threshold */
214
- return s->temp_thr[1];
215
- case 0xb: /* TEMP low threshold */
216
- return s->temp_thr[0];
217
-
218
- case 0xc: /* CFR0 */
219
- return (s->pressure << 15) | ((!s->busy) << 14) |
220
- (s->nextprecision << 13) | s->timing[0];
221
- case 0xd: /* CFR1 */
222
- return s->timing[1];
223
- case 0xe: /* CFR2 */
224
- return (s->pin_func << 14) | s->filter;
225
-
226
- case 0xf: /* Function select status */
227
- return s->function >= 0 ? 1 << s->function : 0;
228
- }
229
-
230
- /* Never gets here */
231
- return 0xffff;
232
-}
233
-
234
-static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
235
-{
236
- switch (reg) {
237
- case 0x8: /* AUX high threshold */
238
- s->aux_thr[1] = data;
239
- break;
240
- case 0x9: /* AUX low threshold */
241
- s->aux_thr[0] = data;
242
- break;
243
-
244
- case 0xa: /* TEMP high threshold */
245
- s->temp_thr[1] = data;
246
- break;
247
- case 0xb: /* TEMP low threshold */
248
- s->temp_thr[0] = data;
249
- break;
250
-
251
- case 0xc: /* CFR0 */
252
- s->host_mode = (data >> 15) != 0;
253
- if (s->enabled != !(data & 0x4000)) {
254
- s->enabled = !(data & 0x4000);
255
- trace_tsc2005_sense(s->enabled ? "enabled" : "disabled");
256
- if (s->busy && !s->enabled) {
257
- timer_del(s->timer);
258
- }
259
- s->busy = s->busy && s->enabled;
260
- }
261
- s->nextprecision = (data >> 13) & 1;
262
- s->timing[0] = data & 0x1fff;
263
- if ((s->timing[0] >> 11) == 3) {
264
- qemu_log_mask(LOG_GUEST_ERROR,
265
- "tsc2005_write: illegal conversion clock setting\n");
266
- }
267
- break;
268
- case 0xd: /* CFR1 */
269
- s->timing[1] = data & 0xf07;
270
- break;
271
- case 0xe: /* CFR2 */
272
- s->pin_func = (data >> 14) & 3;
273
- s->filter = data & 0x3fff;
274
- break;
275
-
276
- default:
277
- qemu_log_mask(LOG_GUEST_ERROR,
278
- "%s: write into read-only register 0x%x\n",
279
- __func__, reg);
280
- }
281
-}
282
-
283
-/* This handles most of the chip's logic. */
284
-static void tsc2005_pin_update(TSC2005State *s)
285
-{
286
- int64_t expires;
287
- bool pin_state;
288
-
289
- switch (s->pin_func) {
290
- case 0:
291
- pin_state = !s->pressure && !!s->dav;
292
- break;
293
- case 1:
294
- case 3:
295
- default:
296
- pin_state = !s->dav;
297
- break;
298
- case 2:
299
- pin_state = !s->pressure;
300
- }
301
-
302
- if (pin_state != s->irq) {
303
- s->irq = pin_state;
304
- qemu_set_irq(s->pint, s->irq);
305
- }
306
-
307
- switch (s->nextfunction) {
308
- case TSC_MODE_XYZ_SCAN:
309
- case TSC_MODE_XY_SCAN:
310
- if (!s->host_mode && s->dav) {
311
- s->enabled = false;
312
- }
313
- if (!s->pressure) {
314
- return;
315
- }
316
- /* Fall through */
317
- case TSC_MODE_AUX_SCAN:
318
- break;
319
-
320
- case TSC_MODE_X:
321
- case TSC_MODE_Y:
322
- case TSC_MODE_Z:
323
- if (!s->pressure) {
324
- return;
325
- }
326
- /* Fall through */
327
- case TSC_MODE_AUX:
328
- case TSC_MODE_TEMP1:
329
- case TSC_MODE_TEMP2:
330
- case TSC_MODE_X_TEST:
331
- case TSC_MODE_Y_TEST:
332
- case TSC_MODE_TS_TEST:
333
- if (s->dav) {
334
- s->enabled = false;
335
- }
336
- break;
337
-
338
- case TSC_MODE_RESERVED:
339
- case TSC_MODE_XX_DRV:
340
- case TSC_MODE_YY_DRV:
341
- case TSC_MODE_YX_DRV:
342
- default:
343
- return;
344
- }
345
-
346
- if (!s->enabled || s->busy) {
347
- return;
348
- }
349
-
350
- s->busy = true;
351
- s->precision = s->nextprecision;
352
- s->function = s->nextfunction;
353
- s->pdst = !s->pnd0; /* Synchronised on internal clock */
354
- expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
355
- (NANOSECONDS_PER_SECOND >> 7);
356
- timer_mod(s->timer, expires);
357
-}
358
-
359
-static void tsc2005_reset(TSC2005State *s)
360
-{
361
- s->state = 0;
362
- s->pin_func = 0;
363
- s->enabled = false;
364
- s->busy = false;
365
- s->nextprecision = false;
366
- s->nextfunction = 0;
367
- s->timing[0] = 0;
368
- s->timing[1] = 0;
369
- s->irq = false;
370
- s->dav = 0;
371
- s->reset = false;
372
- s->pdst = true;
373
- s->pnd0 = false;
374
- s->function = -1;
375
- s->temp_thr[0] = 0x000;
376
- s->temp_thr[1] = 0xfff;
377
- s->aux_thr[0] = 0x000;
378
- s->aux_thr[1] = 0xfff;
379
-
380
- tsc2005_pin_update(s);
381
-}
382
-
383
-static uint8_t tsc2005_txrx_word(void *opaque, uint8_t value)
384
-{
385
- TSC2005State *s = opaque;
386
- uint32_t ret = 0;
387
-
388
- switch (s->state++) {
389
- case 0:
390
- if (value & 0x80) {
391
- /* Command */
392
- if (value & (1 << 1))
393
- tsc2005_reset(s);
394
- else {
395
- s->nextfunction = (value >> 3) & 0xf;
396
- s->nextprecision = (value >> 2) & 1;
397
- if (s->enabled != !(value & 1)) {
398
- s->enabled = !(value & 1);
399
- trace_tsc2005_sense(s->enabled ? "enabled" : "disabled");
400
- if (s->busy && !s->enabled) {
401
- timer_del(s->timer);
402
- }
403
- s->busy = s->busy && s->enabled;
404
- }
405
- tsc2005_pin_update(s);
406
- }
407
-
408
- s->state = 0;
409
- } else if (value) {
410
- /* Data transfer */
411
- s->reg = (value >> 3) & 0xf;
412
- s->pnd0 = (value >> 1) & 1;
413
- s->command = value & 1;
414
-
415
- if (s->command) {
416
- /* Read */
417
- s->data = tsc2005_read(s, s->reg);
418
- tsc2005_pin_update(s);
419
- } else
420
- s->data = 0;
421
- } else
422
- s->state = 0;
423
- break;
424
-
425
- case 1:
426
- if (s->command) {
427
- ret = (s->data >> 8) & 0xff;
428
- } else {
429
- s->data |= value << 8;
430
- }
431
- break;
432
-
433
- case 2:
434
- if (s->command)
435
- ret = s->data & 0xff;
436
- else {
437
- s->data |= value;
438
- tsc2005_write(s, s->reg, s->data);
439
- tsc2005_pin_update(s);
440
- }
441
-
442
- s->state = 0;
443
- break;
444
- }
445
-
446
- return ret;
447
-}
448
-
449
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len)
450
-{
451
- uint32_t ret = 0;
452
-
453
- len &= ~7;
454
- while (len > 0) {
455
- len -= 8;
456
- ret |= tsc2005_txrx_word(opaque, (value >> len) & 0xff) << len;
457
- }
458
-
459
- return ret;
460
-}
461
-
462
-static void tsc2005_timer_tick(void *opaque)
463
-{
464
- TSC2005State *s = opaque;
465
- unsigned int function = s->function;
466
-
467
- assert(function < ARRAY_SIZE(mode_regs));
468
-
469
- /* Timer ticked -- a set of conversions has been finished. */
470
-
471
- if (!s->busy) {
472
- return;
473
- }
474
-
475
- s->busy = false;
476
- s->dav |= mode_regs[function];
477
- s->function = -1;
478
- tsc2005_pin_update(s);
479
-}
480
-
481
-static void tsc2005_touchscreen_event(void *opaque,
482
- int x, int y, int z, int buttons_state)
483
-{
484
- TSC2005State *s = opaque;
485
- int p = s->pressure;
486
-
487
- if (buttons_state) {
488
- s->x = x;
489
- s->y = y;
490
- }
491
- s->pressure = !!buttons_state;
492
-
493
- /*
494
- * Note: We would get better responsiveness in the guest by
495
- * signaling TS events immediately, but for now we simulate
496
- * the first conversion delay for sake of correctness.
497
- */
498
- if (p != s->pressure) {
499
- tsc2005_pin_update(s);
500
- }
501
-}
502
-
503
-static int tsc2005_post_load(void *opaque, int version_id)
504
-{
505
- TSC2005State *s = (TSC2005State *) opaque;
506
-
507
- s->busy = timer_pending(s->timer);
508
- tsc2005_pin_update(s);
509
-
510
- return 0;
511
-}
512
-
513
-static const VMStateDescription vmstate_tsc2005 = {
514
- .name = "tsc2005",
515
- .version_id = 2,
516
- .minimum_version_id = 2,
517
- .post_load = tsc2005_post_load,
518
- .fields = (const VMStateField []) {
519
- VMSTATE_BOOL(pressure, TSC2005State),
520
- VMSTATE_BOOL(irq, TSC2005State),
521
- VMSTATE_BOOL(command, TSC2005State),
522
- VMSTATE_BOOL(enabled, TSC2005State),
523
- VMSTATE_BOOL(host_mode, TSC2005State),
524
- VMSTATE_BOOL(reset, TSC2005State),
525
- VMSTATE_BOOL(pdst, TSC2005State),
526
- VMSTATE_BOOL(pnd0, TSC2005State),
527
- VMSTATE_BOOL(precision, TSC2005State),
528
- VMSTATE_BOOL(nextprecision, TSC2005State),
529
- VMSTATE_UINT8(reg, TSC2005State),
530
- VMSTATE_UINT8(state, TSC2005State),
531
- VMSTATE_UINT16(data, TSC2005State),
532
- VMSTATE_UINT16(dav, TSC2005State),
533
- VMSTATE_UINT16(filter, TSC2005State),
534
- VMSTATE_INT8(nextfunction, TSC2005State),
535
- VMSTATE_INT8(function, TSC2005State),
536
- VMSTATE_INT32(x, TSC2005State),
537
- VMSTATE_INT32(y, TSC2005State),
538
- VMSTATE_TIMER_PTR(timer, TSC2005State),
539
- VMSTATE_UINT8(pin_func, TSC2005State),
540
- VMSTATE_UINT16_ARRAY(timing, TSC2005State, 2),
541
- VMSTATE_UINT8(noise, TSC2005State),
542
- VMSTATE_UINT16_ARRAY(temp_thr, TSC2005State, 2),
543
- VMSTATE_UINT16_ARRAY(aux_thr, TSC2005State, 2),
544
- VMSTATE_INT32_ARRAY(tr, TSC2005State, 8),
545
- VMSTATE_END_OF_LIST()
546
- }
547
-};
548
-
549
-void *tsc2005_init(qemu_irq pintdav)
550
-{
551
- TSC2005State *s;
552
-
553
- s = g_new0(TSC2005State, 1);
554
- s->x = 400;
555
- s->y = 240;
556
- s->pressure = false;
557
- s->precision = s->nextprecision = false;
558
- s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc2005_timer_tick, s);
559
- s->pint = pintdav;
560
- s->model = 0x2005;
561
-
562
- s->tr[0] = 0;
563
- s->tr[1] = 1;
564
- s->tr[2] = 1;
565
- s->tr[3] = 0;
566
- s->tr[4] = 1;
567
- s->tr[5] = 0;
568
- s->tr[6] = 1;
569
- s->tr[7] = 0;
570
-
571
- tsc2005_reset(s);
572
-
573
- qemu_add_mouse_event_handler(tsc2005_touchscreen_event, s, 1,
574
- "QEMU TSC2005-driven Touchscreen");
575
-
576
- qemu_register_reset((void *) tsc2005_reset, s);
577
- vmstate_register(NULL, 0, &vmstate_tsc2005, s);
578
-
579
- return s;
580
-}
581
-
582
-/*
583
- * Use tslib generated calibration data to generate ADC input values
584
- * from the touchscreen. Assuming 12-bit precision was used during
585
- * tslib calibration.
586
- */
587
-void tsc2005_set_transform(void *opaque, const MouseTransformInfo *info)
588
-{
589
- TSC2005State *s = (TSC2005State *) opaque;
590
-
591
- /* This version assumes touchscreen X & Y axis are parallel or
592
- * perpendicular to LCD's X & Y axis in some way. */
593
- if (abs(info->a[0]) > abs(info->a[1])) {
594
- s->tr[0] = 0;
595
- s->tr[1] = -info->a[6] * info->x;
596
- s->tr[2] = info->a[0];
597
- s->tr[3] = -info->a[2] / info->a[0];
598
- s->tr[4] = info->a[6] * info->y;
599
- s->tr[5] = 0;
600
- s->tr[6] = info->a[4];
601
- s->tr[7] = -info->a[5] / info->a[4];
602
- } else {
603
- s->tr[0] = info->a[6] * info->y;
604
- s->tr[1] = 0;
605
- s->tr[2] = info->a[1];
606
- s->tr[3] = -info->a[2] / info->a[1];
607
- s->tr[4] = 0;
608
- s->tr[5] = -info->a[6] * info->x;
609
- s->tr[6] = info->a[3];
610
- s->tr[7] = -info->a[5] / info->a[3];
611
- }
612
-
613
- s->tr[0] >>= 11;
614
- s->tr[1] >>= 11;
615
- s->tr[3] <<= 4;
616
- s->tr[4] >>= 11;
617
- s->tr[5] >>= 11;
618
- s->tr[7] <<= 4;
619
-}
620
diff --git a/hw/input/Kconfig b/hw/input/Kconfig
621
index XXXXXXX..XXXXXXX 100644
622
--- a/hw/input/Kconfig
623
+++ b/hw/input/Kconfig
624
@@ -XXX,XX +XXX,XX @@ config PS2
625
config STELLARIS_GAMEPAD
626
bool
627
628
-config TSC2005
629
- bool
630
-
631
config VIRTIO_INPUT
632
bool
633
default y
634
diff --git a/hw/input/meson.build b/hw/input/meson.build
635
index XXXXXXX..XXXXXXX 100644
636
--- a/hw/input/meson.build
637
+++ b/hw/input/meson.build
638
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_PCKBD', if_true: files('pckbd.c'))
639
system_ss.add(when: 'CONFIG_PL050', if_true: files('pl050.c'))
640
system_ss.add(when: 'CONFIG_PS2', if_true: files('ps2.c'))
641
system_ss.add(when: 'CONFIG_STELLARIS_GAMEPAD', if_true: files('stellaris_gamepad.c'))
642
-system_ss.add(when: 'CONFIG_TSC2005', if_true: files('tsc2005.c'))
643
644
system_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: files('virtio-input.c'))
645
system_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: files('virtio-input-hid.c'))
646
diff --git a/hw/input/trace-events b/hw/input/trace-events
647
index XXXXXXX..XXXXXXX 100644
648
--- a/hw/input/trace-events
649
+++ b/hw/input/trace-events
650
@@ -XXX,XX +XXX,XX @@ ps2_mouse_reset(void *opaque) "%p"
651
hid_kbd_queue_full(void) "queue full"
652
hid_kbd_queue_empty(void) "queue empty"
653
654
-# tsc2005.c
655
-tsc2005_sense(const char *state) "touchscreen sense %s"
656
-
657
# virtio-input.c
658
virtio_input_queue_full(void) "queue full"
659
22
660
--
23
--
661
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
Remove the blizzard display device, which was only used with the
1
Set the default NaN pattern explicitly for hexagon.
2
n800 and n810 machines.
2
Remove the ifdef from parts64_default_nan(); the only
3
remaining unconverted targets all use the default case.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20240903160751.4100218-28-peter.maydell@linaro.org
7
Message-id: 20241202131347.498124-52-peter.maydell@linaro.org
7
---
8
---
8
MAINTAINERS | 2 -
9
target/hexagon/cpu.c | 2 ++
9
include/hw/display/blizzard.h | 21 -
10
fpu/softfloat-specialize.c.inc | 5 -----
10
hw/display/blizzard.c | 1026 ---------------------------------
11
2 files changed, 2 insertions(+), 5 deletions(-)
11
hw/display/Kconfig | 3 -
12
hw/display/meson.build | 1 -
13
5 files changed, 1053 deletions(-)
14
delete mode 100644 include/hw/display/blizzard.h
15
delete mode 100644 hw/display/blizzard.c
16
12
17
diff --git a/MAINTAINERS b/MAINTAINERS
13
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/MAINTAINERS
15
--- a/target/hexagon/cpu.c
20
+++ b/MAINTAINERS
16
+++ b/target/hexagon/cpu.c
21
@@ -XXX,XX +XXX,XX @@ nSeries
17
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
22
M: Peter Maydell <peter.maydell@linaro.org>
18
23
L: qemu-arm@nongnu.org
19
set_default_nan_mode(1, &env->fp_status);
24
S: Odd Fixes
20
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
25
-F: hw/display/blizzard.c
21
+ /* Default NaN value: sign bit set, all frac bits set */
26
F: hw/input/lm832x.c
22
+ set_float_default_nan_pattern(0b11111111, &env->fp_status);
27
F: hw/input/tsc2005.c
23
}
28
F: hw/input/tsc210x.c
24
29
F: hw/rtc/twl92230.c
25
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
30
-F: include/hw/display/blizzard.h
26
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
31
F: include/hw/input/lm832x.h
27
index XXXXXXX..XXXXXXX 100644
32
F: include/hw/input/tsc2xxx.h
28
--- a/fpu/softfloat-specialize.c.inc
33
29
+++ b/fpu/softfloat-specialize.c.inc
34
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
30
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
35
deleted file mode 100644
31
uint8_t dnan_pattern = status->default_nan_pattern;
36
index XXXXXXX..XXXXXXX
32
37
--- a/include/hw/display/blizzard.h
33
if (dnan_pattern == 0) {
38
+++ /dev/null
34
-#if defined(TARGET_HEXAGON)
39
@@ -XXX,XX +XXX,XX @@
35
- /* Sign bit set, all frac bits set. */
40
-/*
36
- dnan_pattern = 0b11111111;
41
- * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
37
-#else
42
- *
38
/*
43
- * Copyright (C) 2008 Nokia Corporation
39
* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
44
- * Written by Andrzej Zaborowski
40
* S390, SH4, TriCore, and Xtensa. Our other supported targets
45
- *
41
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
46
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
42
/* sign bit clear, set frac msb */
47
- * See the COPYING file in the top-level directory.
43
dnan_pattern = 0b01000000;
48
- */
44
}
49
-
50
-#ifndef HW_DISPLAY_BLIZZARD_H
51
-#define HW_DISPLAY_BLIZZARD_H
52
-
53
-
54
-void *s1d13745_init(qemu_irq gpio_int);
55
-void s1d13745_write(void *opaque, int dc, uint16_t value);
56
-void s1d13745_write_block(void *opaque, int dc,
57
- void *buf, size_t len, int pitch);
58
-uint16_t s1d13745_read(void *opaque, int dc);
59
-
60
-#endif
45
-#endif
61
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
46
}
62
deleted file mode 100644
47
assert(dnan_pattern != 0);
63
index XXXXXXX..XXXXXXX
64
--- a/hw/display/blizzard.c
65
+++ /dev/null
66
@@ -XXX,XX +XXX,XX @@
67
-/*
68
- * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
69
- *
70
- * Copyright (C) 2008 Nokia Corporation
71
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
72
- *
73
- * This program is free software; you can redistribute it and/or
74
- * modify it under the terms of the GNU General Public License as
75
- * published by the Free Software Foundation; either version 2 or
76
- * (at your option) version 3 of the License.
77
- *
78
- * This program is distributed in the hope that it will be useful,
79
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
80
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81
- * GNU General Public License for more details.
82
- *
83
- * You should have received a copy of the GNU General Public License along
84
- * with this program; if not, see <http://www.gnu.org/licenses/>.
85
- */
86
-
87
-#include "qemu/osdep.h"
88
-#include "qemu/bitops.h"
89
-#include "ui/console.h"
90
-#include "hw/display/blizzard.h"
91
-#include "ui/pixel_ops.h"
92
-
93
-typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int);
94
-
95
-typedef struct {
96
- uint8_t reg;
97
- uint32_t addr;
98
- int swallow;
99
-
100
- int pll;
101
- int pll_range;
102
- int pll_ctrl;
103
- uint8_t pll_mode;
104
- uint8_t clksel;
105
- int memenable;
106
- int memrefresh;
107
- uint8_t timing[3];
108
- int priority;
109
-
110
- uint8_t lcd_config;
111
- int x;
112
- int y;
113
- int skipx;
114
- int skipy;
115
- uint8_t hndp;
116
- uint8_t vndp;
117
- uint8_t hsync;
118
- uint8_t vsync;
119
- uint8_t pclk;
120
- uint8_t u;
121
- uint8_t v;
122
- uint8_t yrc[2];
123
- int ix[2];
124
- int iy[2];
125
- int ox[2];
126
- int oy[2];
127
-
128
- int enable;
129
- int blank;
130
- int bpp;
131
- int invalidate;
132
- int mx[2];
133
- int my[2];
134
- uint8_t mode;
135
- uint8_t effect;
136
- uint8_t iformat;
137
- uint8_t source;
138
- QemuConsole *con;
139
- blizzard_fn_t *line_fn_tab[2];
140
- void *fb;
141
-
142
- uint8_t hssi_config[3];
143
- uint8_t tv_config;
144
- uint8_t tv_timing[4];
145
- uint8_t vbi;
146
- uint8_t tv_x;
147
- uint8_t tv_y;
148
- uint8_t tv_test;
149
- uint8_t tv_filter_config;
150
- uint8_t tv_filter_idx;
151
- uint8_t tv_filter_coeff[0x20];
152
- uint8_t border_r;
153
- uint8_t border_g;
154
- uint8_t border_b;
155
- uint8_t gamma_config;
156
- uint8_t gamma_idx;
157
- uint8_t gamma_lut[0x100];
158
- uint8_t matrix_ena;
159
- uint8_t matrix_coeff[0x12];
160
- uint8_t matrix_r;
161
- uint8_t matrix_g;
162
- uint8_t matrix_b;
163
- uint8_t pm;
164
- uint8_t status;
165
- uint8_t rgbgpio_dir;
166
- uint8_t rgbgpio;
167
- uint8_t gpio_dir;
168
- uint8_t gpio;
169
- uint8_t gpio_edge[2];
170
- uint8_t gpio_irq;
171
- uint8_t gpio_pdown;
172
-
173
- struct {
174
- int x;
175
- int y;
176
- int dx;
177
- int dy;
178
- int len;
179
- int buflen;
180
- void *buf;
181
- void *data;
182
- uint16_t *ptr;
183
- int angle;
184
- int pitch;
185
- blizzard_fn_t line_fn;
186
- } data;
187
-} BlizzardState;
188
-
189
-/* Bytes(!) per pixel */
190
-static const int blizzard_iformat_bpp[0x10] = {
191
- 0,
192
- 2, /* RGB 5:6:5*/
193
- 3, /* RGB 6:6:6 mode 1 */
194
- 3, /* RGB 8:8:8 mode 1 */
195
- 0, 0,
196
- 4, /* RGB 6:6:6 mode 2 */
197
- 4, /* RGB 8:8:8 mode 2 */
198
- 0, /* YUV 4:2:2 */
199
- 0, /* YUV 4:2:0 */
200
- 0, 0, 0, 0, 0, 0,
201
-};
202
-
203
-static void blizzard_window(BlizzardState *s)
204
-{
205
- DisplaySurface *surface = qemu_console_surface(s->con);
206
- uint8_t *src, *dst;
207
- int bypp[2];
208
- int bypl[3];
209
- int y;
210
- blizzard_fn_t fn = s->data.line_fn;
211
-
212
- if (!fn)
213
- return;
214
- if (s->mx[0] > s->data.x)
215
- s->mx[0] = s->data.x;
216
- if (s->my[0] > s->data.y)
217
- s->my[0] = s->data.y;
218
- if (s->mx[1] < s->data.x + s->data.dx)
219
- s->mx[1] = s->data.x + s->data.dx;
220
- if (s->my[1] < s->data.y + s->data.dy)
221
- s->my[1] = s->data.y + s->data.dy;
222
-
223
- bypp[0] = s->bpp;
224
- bypp[1] = surface_bytes_per_pixel(surface);
225
- bypl[0] = bypp[0] * s->data.pitch;
226
- bypl[1] = bypp[1] * s->x;
227
- bypl[2] = bypp[0] * s->data.dx;
228
-
229
- src = s->data.data;
230
- dst = s->fb + bypl[1] * s->data.y + bypp[1] * s->data.x;
231
- for (y = s->data.dy; y > 0; y --, src += bypl[0], dst += bypl[1])
232
- fn(dst, src, bypl[2]);
233
-}
234
-
235
-static int blizzard_transfer_setup(BlizzardState *s)
236
-{
237
- if (s->source > 3 || !s->bpp ||
238
- s->ix[1] < s->ix[0] || s->iy[1] < s->iy[0])
239
- return 0;
240
-
241
- s->data.angle = s->effect & 3;
242
- s->data.line_fn = s->line_fn_tab[!!s->data.angle][s->iformat];
243
- s->data.x = s->ix[0];
244
- s->data.y = s->iy[0];
245
- s->data.dx = s->ix[1] - s->ix[0] + 1;
246
- s->data.dy = s->iy[1] - s->iy[0] + 1;
247
- s->data.len = s->bpp * s->data.dx * s->data.dy;
248
- s->data.pitch = s->data.dx;
249
- if (s->data.len > s->data.buflen) {
250
- s->data.buf = g_realloc(s->data.buf, s->data.len);
251
- s->data.buflen = s->data.len;
252
- }
253
- s->data.ptr = s->data.buf;
254
- s->data.data = s->data.buf;
255
- s->data.len /= 2;
256
- return 1;
257
-}
258
-
259
-static void blizzard_reset(BlizzardState *s)
260
-{
261
- s->reg = 0;
262
- s->swallow = 0;
263
-
264
- s->pll = 9;
265
- s->pll_range = 1;
266
- s->pll_ctrl = 0x14;
267
- s->pll_mode = 0x32;
268
- s->clksel = 0x00;
269
- s->memenable = 0;
270
- s->memrefresh = 0x25c;
271
- s->timing[0] = 0x3f;
272
- s->timing[1] = 0x13;
273
- s->timing[2] = 0x21;
274
- s->priority = 0;
275
-
276
- s->lcd_config = 0x74;
277
- s->x = 8;
278
- s->y = 1;
279
- s->skipx = 0;
280
- s->skipy = 0;
281
- s->hndp = 3;
282
- s->vndp = 2;
283
- s->hsync = 1;
284
- s->vsync = 1;
285
- s->pclk = 0x80;
286
-
287
- s->ix[0] = 0;
288
- s->ix[1] = 0;
289
- s->iy[0] = 0;
290
- s->iy[1] = 0;
291
- s->ox[0] = 0;
292
- s->ox[1] = 0;
293
- s->oy[0] = 0;
294
- s->oy[1] = 0;
295
-
296
- s->yrc[0] = 0x00;
297
- s->yrc[1] = 0x30;
298
- s->u = 0;
299
- s->v = 0;
300
-
301
- s->iformat = 3;
302
- s->source = 0;
303
- s->bpp = blizzard_iformat_bpp[s->iformat];
304
-
305
- s->hssi_config[0] = 0x00;
306
- s->hssi_config[1] = 0x00;
307
- s->hssi_config[2] = 0x01;
308
- s->tv_config = 0x00;
309
- s->tv_timing[0] = 0x00;
310
- s->tv_timing[1] = 0x00;
311
- s->tv_timing[2] = 0x00;
312
- s->tv_timing[3] = 0x00;
313
- s->vbi = 0x10;
314
- s->tv_x = 0x14;
315
- s->tv_y = 0x03;
316
- s->tv_test = 0x00;
317
- s->tv_filter_config = 0x80;
318
- s->tv_filter_idx = 0x00;
319
- s->border_r = 0x10;
320
- s->border_g = 0x80;
321
- s->border_b = 0x80;
322
- s->gamma_config = 0x00;
323
- s->gamma_idx = 0x00;
324
- s->matrix_ena = 0x00;
325
- memset(&s->matrix_coeff, 0, sizeof(s->matrix_coeff));
326
- s->matrix_r = 0x00;
327
- s->matrix_g = 0x00;
328
- s->matrix_b = 0x00;
329
- s->pm = 0x02;
330
- s->status = 0x00;
331
- s->rgbgpio_dir = 0x00;
332
- s->gpio_dir = 0x00;
333
- s->gpio_edge[0] = 0x00;
334
- s->gpio_edge[1] = 0x00;
335
- s->gpio_irq = 0x00;
336
- s->gpio_pdown = 0xff;
337
-}
338
-
339
-static inline void blizzard_invalidate_display(void *opaque) {
340
- BlizzardState *s = (BlizzardState *) opaque;
341
-
342
- s->invalidate = 1;
343
-}
344
-
345
-static uint16_t blizzard_reg_read(void *opaque, uint8_t reg)
346
-{
347
- BlizzardState *s = (BlizzardState *) opaque;
348
-
349
- switch (reg) {
350
- case 0x00: /* Revision Code */
351
- return 0xa5;
352
-
353
- case 0x02: /* Configuration Readback */
354
- return 0x83; /* Macrovision OK, CNF[2:0] = 3 */
355
-
356
- case 0x04: /* PLL M-Divider */
357
- return (s->pll - 1) | (1 << 7);
358
- case 0x06: /* PLL Lock Range Control */
359
- return s->pll_range;
360
- case 0x08: /* PLL Lock Synthesis Control 0 */
361
- return s->pll_ctrl & 0xff;
362
- case 0x0a: /* PLL Lock Synthesis Control 1 */
363
- return s->pll_ctrl >> 8;
364
- case 0x0c: /* PLL Mode Control 0 */
365
- return s->pll_mode;
366
-
367
- case 0x0e: /* Clock-Source Select */
368
- return s->clksel;
369
-
370
- case 0x10: /* Memory Controller Activate */
371
- case 0x14: /* Memory Controller Bank 0 Status Flag */
372
- return s->memenable;
373
-
374
- case 0x18: /* Auto-Refresh Interval Setting 0 */
375
- return s->memrefresh & 0xff;
376
- case 0x1a: /* Auto-Refresh Interval Setting 1 */
377
- return s->memrefresh >> 8;
378
-
379
- case 0x1c: /* Power-On Sequence Timing Control */
380
- return s->timing[0];
381
- case 0x1e: /* Timing Control 0 */
382
- return s->timing[1];
383
- case 0x20: /* Timing Control 1 */
384
- return s->timing[2];
385
-
386
- case 0x24: /* Arbitration Priority Control */
387
- return s->priority;
388
-
389
- case 0x28: /* LCD Panel Configuration */
390
- return s->lcd_config;
391
-
392
- case 0x2a: /* LCD Horizontal Display Width */
393
- return s->x >> 3;
394
- case 0x2c: /* LCD Horizontal Non-display Period */
395
- return s->hndp;
396
- case 0x2e: /* LCD Vertical Display Height 0 */
397
- return s->y & 0xff;
398
- case 0x30: /* LCD Vertical Display Height 1 */
399
- return s->y >> 8;
400
- case 0x32: /* LCD Vertical Non-display Period */
401
- return s->vndp;
402
- case 0x34: /* LCD HS Pulse-width */
403
- return s->hsync;
404
- case 0x36: /* LCd HS Pulse Start Position */
405
- return s->skipx >> 3;
406
- case 0x38: /* LCD VS Pulse-width */
407
- return s->vsync;
408
- case 0x3a: /* LCD VS Pulse Start Position */
409
- return s->skipy;
410
-
411
- case 0x3c: /* PCLK Polarity */
412
- return s->pclk;
413
-
414
- case 0x3e: /* High-speed Serial Interface Tx Configuration Port 0 */
415
- return s->hssi_config[0];
416
- case 0x40: /* High-speed Serial Interface Tx Configuration Port 1 */
417
- return s->hssi_config[1];
418
- case 0x42: /* High-speed Serial Interface Tx Mode */
419
- return s->hssi_config[2];
420
- case 0x44: /* TV Display Configuration */
421
- return s->tv_config;
422
- case 0x46 ... 0x4c: /* TV Vertical Blanking Interval Data bits */
423
- return s->tv_timing[(reg - 0x46) >> 1];
424
- case 0x4e: /* VBI: Closed Caption / XDS Control / Status */
425
- return s->vbi;
426
- case 0x50: /* TV Horizontal Start Position */
427
- return s->tv_x;
428
- case 0x52: /* TV Vertical Start Position */
429
- return s->tv_y;
430
- case 0x54: /* TV Test Pattern Setting */
431
- return s->tv_test;
432
- case 0x56: /* TV Filter Setting */
433
- return s->tv_filter_config;
434
- case 0x58: /* TV Filter Coefficient Index */
435
- return s->tv_filter_idx;
436
- case 0x5a: /* TV Filter Coefficient Data */
437
- if (s->tv_filter_idx < 0x20)
438
- return s->tv_filter_coeff[s->tv_filter_idx ++];
439
- return 0;
440
-
441
- case 0x60: /* Input YUV/RGB Translate Mode 0 */
442
- return s->yrc[0];
443
- case 0x62: /* Input YUV/RGB Translate Mode 1 */
444
- return s->yrc[1];
445
- case 0x64: /* U Data Fix */
446
- return s->u;
447
- case 0x66: /* V Data Fix */
448
- return s->v;
449
-
450
- case 0x68: /* Display Mode */
451
- return s->mode;
452
-
453
- case 0x6a: /* Special Effects */
454
- return s->effect;
455
-
456
- case 0x6c: /* Input Window X Start Position 0 */
457
- return s->ix[0] & 0xff;
458
- case 0x6e: /* Input Window X Start Position 1 */
459
- return s->ix[0] >> 3;
460
- case 0x70: /* Input Window Y Start Position 0 */
461
- return s->ix[0] & 0xff;
462
- case 0x72: /* Input Window Y Start Position 1 */
463
- return s->ix[0] >> 3;
464
- case 0x74: /* Input Window X End Position 0 */
465
- return s->ix[1] & 0xff;
466
- case 0x76: /* Input Window X End Position 1 */
467
- return s->ix[1] >> 3;
468
- case 0x78: /* Input Window Y End Position 0 */
469
- return s->ix[1] & 0xff;
470
- case 0x7a: /* Input Window Y End Position 1 */
471
- return s->ix[1] >> 3;
472
- case 0x7c: /* Output Window X Start Position 0 */
473
- return s->ox[0] & 0xff;
474
- case 0x7e: /* Output Window X Start Position 1 */
475
- return s->ox[0] >> 3;
476
- case 0x80: /* Output Window Y Start Position 0 */
477
- return s->oy[0] & 0xff;
478
- case 0x82: /* Output Window Y Start Position 1 */
479
- return s->oy[0] >> 3;
480
- case 0x84: /* Output Window X End Position 0 */
481
- return s->ox[1] & 0xff;
482
- case 0x86: /* Output Window X End Position 1 */
483
- return s->ox[1] >> 3;
484
- case 0x88: /* Output Window Y End Position 0 */
485
- return s->oy[1] & 0xff;
486
- case 0x8a: /* Output Window Y End Position 1 */
487
- return s->oy[1] >> 3;
488
-
489
- case 0x8c: /* Input Data Format */
490
- return s->iformat;
491
- case 0x8e: /* Data Source Select */
492
- return s->source;
493
- case 0x90: /* Display Memory Data Port */
494
- return 0;
495
-
496
- case 0xa8: /* Border Color 0 */
497
- return s->border_r;
498
- case 0xaa: /* Border Color 1 */
499
- return s->border_g;
500
- case 0xac: /* Border Color 2 */
501
- return s->border_b;
502
-
503
- case 0xb4: /* Gamma Correction Enable */
504
- return s->gamma_config;
505
- case 0xb6: /* Gamma Correction Table Index */
506
- return s->gamma_idx;
507
- case 0xb8: /* Gamma Correction Table Data */
508
- return s->gamma_lut[s->gamma_idx ++];
509
-
510
- case 0xba: /* 3x3 Matrix Enable */
511
- return s->matrix_ena;
512
- case 0xbc ... 0xde: /* Coefficient Registers */
513
- return s->matrix_coeff[(reg - 0xbc) >> 1];
514
- case 0xe0: /* 3x3 Matrix Red Offset */
515
- return s->matrix_r;
516
- case 0xe2: /* 3x3 Matrix Green Offset */
517
- return s->matrix_g;
518
- case 0xe4: /* 3x3 Matrix Blue Offset */
519
- return s->matrix_b;
520
-
521
- case 0xe6: /* Power-save */
522
- return s->pm;
523
- case 0xe8: /* Non-display Period Control / Status */
524
- return s->status | (1 << 5);
525
- case 0xea: /* RGB Interface Control */
526
- return s->rgbgpio_dir;
527
- case 0xec: /* RGB Interface Status */
528
- return s->rgbgpio;
529
- case 0xee: /* General-purpose IO Pins Configuration */
530
- return s->gpio_dir;
531
- case 0xf0: /* General-purpose IO Pins Status / Control */
532
- return s->gpio;
533
- case 0xf2: /* GPIO Positive Edge Interrupt Trigger */
534
- return s->gpio_edge[0];
535
- case 0xf4: /* GPIO Negative Edge Interrupt Trigger */
536
- return s->gpio_edge[1];
537
- case 0xf6: /* GPIO Interrupt Status */
538
- return s->gpio_irq;
539
- case 0xf8: /* GPIO Pull-down Control */
540
- return s->gpio_pdown;
541
-
542
- default:
543
- fprintf(stderr, "%s: unknown register %02x\n", __func__, reg);
544
- return 0;
545
- }
546
-}
547
-
548
-static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value)
549
-{
550
- BlizzardState *s = (BlizzardState *) opaque;
551
-
552
- switch (reg) {
553
- case 0x04: /* PLL M-Divider */
554
- s->pll = (value & 0x3f) + 1;
555
- break;
556
- case 0x06: /* PLL Lock Range Control */
557
- s->pll_range = value & 3;
558
- break;
559
- case 0x08: /* PLL Lock Synthesis Control 0 */
560
- s->pll_ctrl &= 0xf00;
561
- s->pll_ctrl |= (value << 0) & 0x0ff;
562
- break;
563
- case 0x0a: /* PLL Lock Synthesis Control 1 */
564
- s->pll_ctrl &= 0x0ff;
565
- s->pll_ctrl |= (value << 8) & 0xf00;
566
- break;
567
- case 0x0c: /* PLL Mode Control 0 */
568
- s->pll_mode = value & 0x77;
569
- if ((value & 3) == 0 || (value & 3) == 3)
570
- fprintf(stderr, "%s: wrong PLL Control bits (%i)\n",
571
- __func__, value & 3);
572
- break;
573
-
574
- case 0x0e: /* Clock-Source Select */
575
- s->clksel = value & 0xff;
576
- break;
577
-
578
- case 0x10: /* Memory Controller Activate */
579
- s->memenable = value & 1;
580
- break;
581
- case 0x14: /* Memory Controller Bank 0 Status Flag */
582
- break;
583
-
584
- case 0x18: /* Auto-Refresh Interval Setting 0 */
585
- s->memrefresh &= 0xf00;
586
- s->memrefresh |= (value << 0) & 0x0ff;
587
- break;
588
- case 0x1a: /* Auto-Refresh Interval Setting 1 */
589
- s->memrefresh &= 0x0ff;
590
- s->memrefresh |= (value << 8) & 0xf00;
591
- break;
592
-
593
- case 0x1c: /* Power-On Sequence Timing Control */
594
- s->timing[0] = value & 0x7f;
595
- break;
596
- case 0x1e: /* Timing Control 0 */
597
- s->timing[1] = value & 0x17;
598
- break;
599
- case 0x20: /* Timing Control 1 */
600
- s->timing[2] = value & 0x35;
601
- break;
602
-
603
- case 0x24: /* Arbitration Priority Control */
604
- s->priority = value & 1;
605
- break;
606
-
607
- case 0x28: /* LCD Panel Configuration */
608
- s->lcd_config = value & 0xff;
609
- if (value & (1 << 7))
610
- fprintf(stderr, "%s: data swap not supported!\n", __func__);
611
- break;
612
-
613
- case 0x2a: /* LCD Horizontal Display Width */
614
- s->x = value << 3;
615
- break;
616
- case 0x2c: /* LCD Horizontal Non-display Period */
617
- s->hndp = value & 0xff;
618
- break;
619
- case 0x2e: /* LCD Vertical Display Height 0 */
620
- s->y &= 0x300;
621
- s->y |= (value << 0) & 0x0ff;
622
- break;
623
- case 0x30: /* LCD Vertical Display Height 1 */
624
- s->y &= 0x0ff;
625
- s->y |= (value << 8) & 0x300;
626
- break;
627
- case 0x32: /* LCD Vertical Non-display Period */
628
- s->vndp = value & 0xff;
629
- break;
630
- case 0x34: /* LCD HS Pulse-width */
631
- s->hsync = value & 0xff;
632
- break;
633
- case 0x36: /* LCD HS Pulse Start Position */
634
- s->skipx = value & 0xff;
635
- break;
636
- case 0x38: /* LCD VS Pulse-width */
637
- s->vsync = value & 0xbf;
638
- break;
639
- case 0x3a: /* LCD VS Pulse Start Position */
640
- s->skipy = value & 0xff;
641
- break;
642
-
643
- case 0x3c: /* PCLK Polarity */
644
- s->pclk = value & 0x82;
645
- /* Affects calculation of s->hndp, s->hsync and s->skipx. */
646
- break;
647
-
648
- case 0x3e: /* High-speed Serial Interface Tx Configuration Port 0 */
649
- s->hssi_config[0] = value;
650
- break;
651
- case 0x40: /* High-speed Serial Interface Tx Configuration Port 1 */
652
- s->hssi_config[1] = value;
653
- if (((value >> 4) & 3) == 3)
654
- fprintf(stderr, "%s: Illegal active-data-links value\n",
655
- __func__);
656
- break;
657
- case 0x42: /* High-speed Serial Interface Tx Mode */
658
- s->hssi_config[2] = value & 0xbd;
659
- break;
660
-
661
- case 0x44: /* TV Display Configuration */
662
- s->tv_config = value & 0xfe;
663
- break;
664
- case 0x46 ... 0x4c: /* TV Vertical Blanking Interval Data bits 0 */
665
- s->tv_timing[(reg - 0x46) >> 1] = value;
666
- break;
667
- case 0x4e: /* VBI: Closed Caption / XDS Control / Status */
668
- s->vbi = value;
669
- break;
670
- case 0x50: /* TV Horizontal Start Position */
671
- s->tv_x = value;
672
- break;
673
- case 0x52: /* TV Vertical Start Position */
674
- s->tv_y = value & 0x7f;
675
- break;
676
- case 0x54: /* TV Test Pattern Setting */
677
- s->tv_test = value;
678
- break;
679
- case 0x56: /* TV Filter Setting */
680
- s->tv_filter_config = value & 0xbf;
681
- break;
682
- case 0x58: /* TV Filter Coefficient Index */
683
- s->tv_filter_idx = value & 0x1f;
684
- break;
685
- case 0x5a: /* TV Filter Coefficient Data */
686
- if (s->tv_filter_idx < 0x20)
687
- s->tv_filter_coeff[s->tv_filter_idx ++] = value;
688
- break;
689
-
690
- case 0x60: /* Input YUV/RGB Translate Mode 0 */
691
- s->yrc[0] = value & 0xb0;
692
- break;
693
- case 0x62: /* Input YUV/RGB Translate Mode 1 */
694
- s->yrc[1] = value & 0x30;
695
- break;
696
- case 0x64: /* U Data Fix */
697
- s->u = value & 0xff;
698
- break;
699
- case 0x66: /* V Data Fix */
700
- s->v = value & 0xff;
701
- break;
702
-
703
- case 0x68: /* Display Mode */
704
- if ((s->mode ^ value) & 3)
705
- s->invalidate = 1;
706
- s->mode = value & 0xb7;
707
- s->enable = value & 1;
708
- s->blank = (value >> 1) & 1;
709
- if (value & (1 << 4))
710
- fprintf(stderr, "%s: Macrovision enable attempt!\n", __func__);
711
- break;
712
-
713
- case 0x6a: /* Special Effects */
714
- s->effect = value & 0xfb;
715
- break;
716
-
717
- case 0x6c: /* Input Window X Start Position 0 */
718
- s->ix[0] &= 0x300;
719
- s->ix[0] |= (value << 0) & 0x0ff;
720
- break;
721
- case 0x6e: /* Input Window X Start Position 1 */
722
- s->ix[0] &= 0x0ff;
723
- s->ix[0] |= (value << 8) & 0x300;
724
- break;
725
- case 0x70: /* Input Window Y Start Position 0 */
726
- s->iy[0] &= 0x300;
727
- s->iy[0] |= (value << 0) & 0x0ff;
728
- break;
729
- case 0x72: /* Input Window Y Start Position 1 */
730
- s->iy[0] &= 0x0ff;
731
- s->iy[0] |= (value << 8) & 0x300;
732
- break;
733
- case 0x74: /* Input Window X End Position 0 */
734
- s->ix[1] &= 0x300;
735
- s->ix[1] |= (value << 0) & 0x0ff;
736
- break;
737
- case 0x76: /* Input Window X End Position 1 */
738
- s->ix[1] &= 0x0ff;
739
- s->ix[1] |= (value << 8) & 0x300;
740
- break;
741
- case 0x78: /* Input Window Y End Position 0 */
742
- s->iy[1] &= 0x300;
743
- s->iy[1] |= (value << 0) & 0x0ff;
744
- break;
745
- case 0x7a: /* Input Window Y End Position 1 */
746
- s->iy[1] &= 0x0ff;
747
- s->iy[1] |= (value << 8) & 0x300;
748
- break;
749
- case 0x7c: /* Output Window X Start Position 0 */
750
- s->ox[0] &= 0x300;
751
- s->ox[0] |= (value << 0) & 0x0ff;
752
- break;
753
- case 0x7e: /* Output Window X Start Position 1 */
754
- s->ox[0] &= 0x0ff;
755
- s->ox[0] |= (value << 8) & 0x300;
756
- break;
757
- case 0x80: /* Output Window Y Start Position 0 */
758
- s->oy[0] &= 0x300;
759
- s->oy[0] |= (value << 0) & 0x0ff;
760
- break;
761
- case 0x82: /* Output Window Y Start Position 1 */
762
- s->oy[0] &= 0x0ff;
763
- s->oy[0] |= (value << 8) & 0x300;
764
- break;
765
- case 0x84: /* Output Window X End Position 0 */
766
- s->ox[1] &= 0x300;
767
- s->ox[1] |= (value << 0) & 0x0ff;
768
- break;
769
- case 0x86: /* Output Window X End Position 1 */
770
- s->ox[1] &= 0x0ff;
771
- s->ox[1] |= (value << 8) & 0x300;
772
- break;
773
- case 0x88: /* Output Window Y End Position 0 */
774
- s->oy[1] &= 0x300;
775
- s->oy[1] |= (value << 0) & 0x0ff;
776
- break;
777
- case 0x8a: /* Output Window Y End Position 1 */
778
- s->oy[1] &= 0x0ff;
779
- s->oy[1] |= (value << 8) & 0x300;
780
- break;
781
-
782
- case 0x8c: /* Input Data Format */
783
- s->iformat = value & 0xf;
784
- s->bpp = blizzard_iformat_bpp[s->iformat];
785
- if (!s->bpp)
786
- fprintf(stderr, "%s: Illegal or unsupported input format %x\n",
787
- __func__, s->iformat);
788
- break;
789
- case 0x8e: /* Data Source Select */
790
- s->source = value & 7;
791
- /* Currently all windows will be "destructive overlays". */
792
- if ((!(s->effect & (1 << 3)) && (s->ix[0] != s->ox[0] ||
793
- s->iy[0] != s->oy[0] ||
794
- s->ix[1] != s->ox[1] ||
795
- s->iy[1] != s->oy[1])) ||
796
- !((s->ix[1] - s->ix[0]) & (s->iy[1] - s->iy[0]) &
797
- (s->ox[1] - s->ox[0]) & (s->oy[1] - s->oy[0]) & 1))
798
- fprintf(stderr, "%s: Illegal input/output window positions\n",
799
- __func__);
800
-
801
- blizzard_transfer_setup(s);
802
- break;
803
-
804
- case 0x90: /* Display Memory Data Port */
805
- if (!s->data.len && !blizzard_transfer_setup(s))
806
- break;
807
-
808
- *s->data.ptr ++ = value;
809
- if (-- s->data.len == 0)
810
- blizzard_window(s);
811
- break;
812
-
813
- case 0xa8: /* Border Color 0 */
814
- s->border_r = value;
815
- break;
816
- case 0xaa: /* Border Color 1 */
817
- s->border_g = value;
818
- break;
819
- case 0xac: /* Border Color 2 */
820
- s->border_b = value;
821
- break;
822
-
823
- case 0xb4: /* Gamma Correction Enable */
824
- s->gamma_config = value & 0x87;
825
- break;
826
- case 0xb6: /* Gamma Correction Table Index */
827
- s->gamma_idx = value;
828
- break;
829
- case 0xb8: /* Gamma Correction Table Data */
830
- s->gamma_lut[s->gamma_idx ++] = value;
831
- break;
832
-
833
- case 0xba: /* 3x3 Matrix Enable */
834
- s->matrix_ena = value & 1;
835
- break;
836
- case 0xbc ... 0xde: /* Coefficient Registers */
837
- s->matrix_coeff[(reg - 0xbc) >> 1] = value & ((reg & 2) ? 0x80 : 0xff);
838
- break;
839
- case 0xe0: /* 3x3 Matrix Red Offset */
840
- s->matrix_r = value;
841
- break;
842
- case 0xe2: /* 3x3 Matrix Green Offset */
843
- s->matrix_g = value;
844
- break;
845
- case 0xe4: /* 3x3 Matrix Blue Offset */
846
- s->matrix_b = value;
847
- break;
848
-
849
- case 0xe6: /* Power-save */
850
- s->pm = value & 0x83;
851
- if (value & s->mode & 1)
852
- fprintf(stderr, "%s: The display must be disabled before entering "
853
- "Standby Mode\n", __func__);
854
- break;
855
- case 0xe8: /* Non-display Period Control / Status */
856
- s->status = value & 0x1b;
857
- break;
858
- case 0xea: /* RGB Interface Control */
859
- s->rgbgpio_dir = value & 0x8f;
860
- break;
861
- case 0xec: /* RGB Interface Status */
862
- s->rgbgpio = value & 0xcf;
863
- break;
864
- case 0xee: /* General-purpose IO Pins Configuration */
865
- s->gpio_dir = value;
866
- break;
867
- case 0xf0: /* General-purpose IO Pins Status / Control */
868
- s->gpio = value;
869
- break;
870
- case 0xf2: /* GPIO Positive Edge Interrupt Trigger */
871
- s->gpio_edge[0] = value;
872
- break;
873
- case 0xf4: /* GPIO Negative Edge Interrupt Trigger */
874
- s->gpio_edge[1] = value;
875
- break;
876
- case 0xf6: /* GPIO Interrupt Status */
877
- s->gpio_irq &= value;
878
- break;
879
- case 0xf8: /* GPIO Pull-down Control */
880
- s->gpio_pdown = value;
881
- break;
882
-
883
- default:
884
- fprintf(stderr, "%s: unknown register %02x\n", __func__, reg);
885
- break;
886
- }
887
-}
888
-
889
-uint16_t s1d13745_read(void *opaque, int dc)
890
-{
891
- BlizzardState *s = (BlizzardState *) opaque;
892
- uint16_t value = blizzard_reg_read(s, s->reg);
893
-
894
- if (s->swallow -- > 0)
895
- return 0;
896
- if (dc)
897
- s->reg ++;
898
-
899
- return value;
900
-}
901
-
902
-void s1d13745_write(void *opaque, int dc, uint16_t value)
903
-{
904
- BlizzardState *s = (BlizzardState *) opaque;
905
-
906
- if (s->swallow -- > 0)
907
- return;
908
- if (dc) {
909
- blizzard_reg_write(s, s->reg, value);
910
-
911
- if (s->reg != 0x90 && s->reg != 0x5a && s->reg != 0xb8)
912
- s->reg += 2;
913
- } else
914
- s->reg = value & 0xff;
915
-}
916
-
917
-void s1d13745_write_block(void *opaque, int dc,
918
- void *buf, size_t len, int pitch)
919
-{
920
- BlizzardState *s = (BlizzardState *) opaque;
921
-
922
- while (len > 0) {
923
- if (s->reg == 0x90 && dc &&
924
- (s->data.len || blizzard_transfer_setup(s)) &&
925
- len >= (s->data.len << 1)) {
926
- len -= s->data.len << 1;
927
- s->data.len = 0;
928
- s->data.data = buf;
929
- if (pitch)
930
- s->data.pitch = pitch;
931
- blizzard_window(s);
932
- s->data.data = s->data.buf;
933
- continue;
934
- }
935
-
936
- s1d13745_write(opaque, dc, *(uint16_t *) buf);
937
- len -= 2;
938
- buf += 2;
939
- }
940
-}
941
-
942
-static void blizzard_update_display(void *opaque)
943
-{
944
- BlizzardState *s = (BlizzardState *) opaque;
945
- DisplaySurface *surface = qemu_console_surface(s->con);
946
- int y, bypp, bypl, bwidth;
947
- uint8_t *src, *dst;
948
-
949
- if (!s->enable)
950
- return;
951
-
952
- if (s->x != surface_width(surface) || s->y != surface_height(surface)) {
953
- s->invalidate = 1;
954
- qemu_console_resize(s->con, s->x, s->y);
955
- surface = qemu_console_surface(s->con);
956
- }
957
-
958
- if (s->invalidate) {
959
- s->invalidate = 0;
960
-
961
- if (s->blank) {
962
- bypp = surface_bytes_per_pixel(surface);
963
- memset(surface_data(surface), 0, bypp * s->x * s->y);
964
- return;
965
- }
966
-
967
- s->mx[0] = 0;
968
- s->mx[1] = s->x;
969
- s->my[0] = 0;
970
- s->my[1] = s->y;
971
- }
972
-
973
- if (s->mx[1] <= s->mx[0])
974
- return;
975
-
976
- bypp = surface_bytes_per_pixel(surface);
977
- bypl = bypp * s->x;
978
- bwidth = bypp * (s->mx[1] - s->mx[0]);
979
- y = s->my[0];
980
- src = s->fb + bypl * y + bypp * s->mx[0];
981
- dst = surface_data(surface) + bypl * y + bypp * s->mx[0];
982
- for (; y < s->my[1]; y ++, src += bypl, dst += bypl)
983
- memcpy(dst, src, bwidth);
984
-
985
- dpy_gfx_update(s->con, s->mx[0], s->my[0],
986
- s->mx[1] - s->mx[0], y - s->my[0]);
987
-
988
- s->mx[0] = s->x;
989
- s->mx[1] = 0;
990
- s->my[0] = s->y;
991
- s->my[1] = 0;
992
-}
993
-
994
-static void blizzard_draw_line16_32(uint32_t *dest,
995
- const uint16_t *src, unsigned int width)
996
-{
997
- uint16_t data;
998
- unsigned int r, g, b;
999
- const uint16_t *end = (const void *) src + width;
1000
- while (src < end) {
1001
- data = *src ++;
1002
- b = extract16(data, 0, 5) << 3;
1003
- g = extract16(data, 5, 6) << 2;
1004
- r = extract16(data, 11, 5) << 3;
1005
- *dest++ = rgb_to_pixel32(r, g, b);
1006
- }
1007
-}
1008
-
1009
-static void blizzard_draw_line24mode1_32(uint32_t *dest,
1010
- const uint8_t *src, unsigned int width)
1011
-{
1012
- /* TODO: check if SDL 24-bit planes are not in the same format and
1013
- * if so, use memcpy */
1014
- unsigned int r[2], g[2], b[2];
1015
- const uint8_t *end = src + width;
1016
- while (src < end) {
1017
- g[0] = *src ++;
1018
- r[0] = *src ++;
1019
- r[1] = *src ++;
1020
- b[0] = *src ++;
1021
- *dest++ = rgb_to_pixel32(r[0], g[0], b[0]);
1022
- b[1] = *src ++;
1023
- g[1] = *src ++;
1024
- *dest++ = rgb_to_pixel32(r[1], g[1], b[1]);
1025
- }
1026
-}
1027
-
1028
-static void blizzard_draw_line24mode2_32(uint32_t *dest,
1029
- const uint8_t *src, unsigned int width)
1030
-{
1031
- unsigned int r, g, b;
1032
- const uint8_t *end = src + width;
1033
- while (src < end) {
1034
- r = *src ++;
1035
- src ++;
1036
- b = *src ++;
1037
- g = *src ++;
1038
- *dest++ = rgb_to_pixel32(r, g, b);
1039
- }
1040
-}
1041
-
1042
-/* No rotation */
1043
-static blizzard_fn_t blizzard_draw_fn_32[0x10] = {
1044
- NULL,
1045
- /* RGB 5:6:5*/
1046
- (blizzard_fn_t) blizzard_draw_line16_32,
1047
- /* RGB 6:6:6 mode 1 */
1048
- (blizzard_fn_t) blizzard_draw_line24mode1_32,
1049
- /* RGB 8:8:8 mode 1 */
1050
- (blizzard_fn_t) blizzard_draw_line24mode1_32,
1051
- NULL, NULL,
1052
- /* RGB 6:6:6 mode 2 */
1053
- (blizzard_fn_t) blizzard_draw_line24mode2_32,
1054
- /* RGB 8:8:8 mode 2 */
1055
- (blizzard_fn_t) blizzard_draw_line24mode2_32,
1056
- /* YUV 4:2:2 */
1057
- NULL,
1058
- /* YUV 4:2:0 */
1059
- NULL,
1060
- NULL, NULL, NULL, NULL, NULL, NULL,
1061
-};
1062
-
1063
-/* 90deg, 180deg and 270deg rotation */
1064
-static blizzard_fn_t blizzard_draw_fn_r_32[0x10] = {
1065
- /* TODO */
1066
- [0 ... 0xf] = NULL,
1067
-};
1068
-
1069
-static const GraphicHwOps blizzard_ops = {
1070
- .invalidate = blizzard_invalidate_display,
1071
- .gfx_update = blizzard_update_display,
1072
-};
1073
-
1074
-void *s1d13745_init(qemu_irq gpio_int)
1075
-{
1076
- BlizzardState *s = g_malloc0(sizeof(*s));
1077
- DisplaySurface *surface;
1078
-
1079
- s->fb = g_malloc(0x180000);
1080
-
1081
- s->con = graphic_console_init(NULL, 0, &blizzard_ops, s);
1082
- surface = qemu_console_surface(s->con);
1083
-
1084
- assert(surface_bits_per_pixel(surface) == 32);
1085
-
1086
- s->line_fn_tab[0] = blizzard_draw_fn_32;
1087
- s->line_fn_tab[1] = blizzard_draw_fn_r_32;
1088
-
1089
- blizzard_reset(s);
1090
-
1091
- return s;
1092
-}
1093
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
1094
index XXXXXXX..XXXXXXX 100644
1095
--- a/hw/display/Kconfig
1096
+++ b/hw/display/Kconfig
1097
@@ -XXX,XX +XXX,XX @@ config BOCHS_DISPLAY
1098
select VGA
1099
select EDID
1100
1101
-config BLIZZARD
1102
- bool
1103
-
1104
config FRAMEBUFFER
1105
bool
1106
1107
diff --git a/hw/display/meson.build b/hw/display/meson.build
1108
index XXXXXXX..XXXXXXX 100644
1109
--- a/hw/display/meson.build
1110
+++ b/hw/display/meson.build
1111
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VGA_MMIO', if_true: files('vga-mmio.c'))
1112
system_ss.add(when: 'CONFIG_VMWARE_VGA', if_true: files('vmware_vga.c'))
1113
system_ss.add(when: 'CONFIG_BOCHS_DISPLAY', if_true: files('bochs-display.c'))
1114
1115
-system_ss.add(when: 'CONFIG_BLIZZARD', if_true: files('blizzard.c'))
1116
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_fimd.c'))
1117
system_ss.add(when: 'CONFIG_FRAMEBUFFER', if_true: files('framebuffer.c'))
1118
48
1119
--
49
--
1120
2.34.1
50
2.34.1
diff view generated by jsdifflib
1
The MAINSTONE_FPGA device was used only by the 'mainstone' machine
1
Set the default NaN pattern explicitly for riscv.
2
type, so we can remove it now.
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: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20240903160751.4100218-12-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-53-peter.maydell@linaro.org
7
---
6
---
8
MAINTAINERS | 1 -
7
target/riscv/cpu.c | 2 ++
9
hw/misc/mst_fpga.c | 269 --------------------------------------------
8
1 file changed, 2 insertions(+)
10
hw/misc/meson.build | 1 -
11
3 files changed, 271 deletions(-)
12
delete mode 100644 hw/misc/mst_fpga.c
13
9
14
diff --git a/MAINTAINERS b/MAINTAINERS
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/MAINTAINERS
12
--- a/target/riscv/cpu.c
17
+++ b/MAINTAINERS
13
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ S: Odd Fixes
14
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
19
F: hw/arm/z2.c
15
cs->exception_index = RISCV_EXCP_NONE;
20
F: hw/*/pxa2xx*
16
env->load_res = -1;
21
F: hw/gpio/max7310.c
17
set_default_nan_mode(1, &env->fp_status);
22
-F: hw/misc/mst_fpga.c
18
+ /* Default NaN value: sign bit clear, frac msb set */
23
F: hw/adc/max111x.c
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
24
F: include/hw/adc/max111x.h
20
env->vill = true;
25
F: include/hw/arm/pxa.h
21
26
diff --git a/hw/misc/mst_fpga.c b/hw/misc/mst_fpga.c
22
#ifndef CONFIG_USER_ONLY
27
deleted file mode 100644
28
index XXXXXXX..XXXXXXX
29
--- a/hw/misc/mst_fpga.c
30
+++ /dev/null
31
@@ -XXX,XX +XXX,XX @@
32
-/*
33
- * PXA270-based Intel Mainstone platforms.
34
- * FPGA driver
35
- *
36
- * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or
37
- * <akuster@mvista.com>
38
- *
39
- * This code is licensed under the GNU GPL v2.
40
- *
41
- * Contributions after 2012-01-13 are licensed under the terms of the
42
- * GNU GPL, version 2 or (at your option) any later version.
43
- */
44
-
45
-#include "qemu/osdep.h"
46
-#include "hw/irq.h"
47
-#include "hw/sysbus.h"
48
-#include "migration/vmstate.h"
49
-#include "qemu/module.h"
50
-#include "qom/object.h"
51
-
52
-/* Mainstone FPGA for extern irqs */
53
-#define FPGA_GPIO_PIN    0
54
-#define MST_NUM_IRQS    16
55
-#define MST_LEDDAT1        0x10
56
-#define MST_LEDDAT2        0x14
57
-#define MST_LEDCTRL        0x40
58
-#define MST_GPSWR        0x60
59
-#define MST_MSCWR1        0x80
60
-#define MST_MSCWR2        0x84
61
-#define MST_MSCWR3        0x88
62
-#define MST_MSCRD        0x90
63
-#define MST_INTMSKENA    0xc0
64
-#define MST_INTSETCLR    0xd0
65
-#define MST_PCMCIA0        0xe0
66
-#define MST_PCMCIA1        0xe4
67
-
68
-#define MST_PCMCIAx_READY    (1 << 10)
69
-#define MST_PCMCIAx_nCD        (1 << 5)
70
-
71
-#define MST_PCMCIA_CD0_IRQ    9
72
-#define MST_PCMCIA_CD1_IRQ    13
73
-
74
-#define TYPE_MAINSTONE_FPGA "mainstone-fpga"
75
-OBJECT_DECLARE_SIMPLE_TYPE(mst_irq_state, MAINSTONE_FPGA)
76
-
77
-struct mst_irq_state {
78
- SysBusDevice parent_obj;
79
-
80
- MemoryRegion iomem;
81
-
82
- qemu_irq parent;
83
-
84
- uint32_t prev_level;
85
- uint32_t leddat1;
86
- uint32_t leddat2;
87
- uint32_t ledctrl;
88
- uint32_t gpswr;
89
- uint32_t mscwr1;
90
- uint32_t mscwr2;
91
- uint32_t mscwr3;
92
- uint32_t mscrd;
93
- uint32_t intmskena;
94
- uint32_t intsetclr;
95
- uint32_t pcmcia0;
96
- uint32_t pcmcia1;
97
-};
98
-
99
-static void
100
-mst_fpga_set_irq(void *opaque, int irq, int level)
101
-{
102
-    mst_irq_state *s = (mst_irq_state *)opaque;
103
-    uint32_t oldint = s->intsetclr & s->intmskena;
104
-
105
-    if (level)
106
-        s->prev_level |= 1u << irq;
107
-    else
108
-        s->prev_level &= ~(1u << irq);
109
-
110
-    switch(irq) {
111
-    case MST_PCMCIA_CD0_IRQ:
112
-        if (level)
113
-            s->pcmcia0 &= ~MST_PCMCIAx_nCD;
114
-        else
115
-            s->pcmcia0 |= MST_PCMCIAx_nCD;
116
-        break;
117
-    case MST_PCMCIA_CD1_IRQ:
118
-        if (level)
119
-            s->pcmcia1 &= ~MST_PCMCIAx_nCD;
120
-        else
121
-            s->pcmcia1 |= MST_PCMCIAx_nCD;
122
-        break;
123
-    }
124
-
125
-    if ((s->intmskena & (1u << irq)) && level)
126
-        s->intsetclr |= 1u << irq;
127
-
128
-    if (oldint != (s->intsetclr & s->intmskena))
129
-        qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
130
-}
131
-
132
-
133
-static uint64_t
134
-mst_fpga_readb(void *opaque, hwaddr addr, unsigned size)
135
-{
136
-    mst_irq_state *s = (mst_irq_state *) opaque;
137
-
138
-    switch (addr) {
139
-    case MST_LEDDAT1:
140
-        return s->leddat1;
141
-    case MST_LEDDAT2:
142
-        return s->leddat2;
143
-    case MST_LEDCTRL:
144
-        return s->ledctrl;
145
-    case MST_GPSWR:
146
-        return s->gpswr;
147
-    case MST_MSCWR1:
148
-        return s->mscwr1;
149
-    case MST_MSCWR2:
150
-        return s->mscwr2;
151
-    case MST_MSCWR3:
152
-        return s->mscwr3;
153
-    case MST_MSCRD:
154
-        return s->mscrd;
155
-    case MST_INTMSKENA:
156
-        return s->intmskena;
157
-    case MST_INTSETCLR:
158
-        return s->intsetclr;
159
-    case MST_PCMCIA0:
160
-        return s->pcmcia0;
161
-    case MST_PCMCIA1:
162
-        return s->pcmcia1;
163
-    default:
164
-        printf("Mainstone - mst_fpga_readb: Bad register offset "
165
-            "0x" HWADDR_FMT_plx "\n", addr);
166
-    }
167
-    return 0;
168
-}
169
-
170
-static void
171
-mst_fpga_writeb(void *opaque, hwaddr addr, uint64_t value,
172
-        unsigned size)
173
-{
174
-    mst_irq_state *s = (mst_irq_state *) opaque;
175
-    value &= 0xffffffff;
176
-
177
-    switch (addr) {
178
-    case MST_LEDDAT1:
179
-        s->leddat1 = value;
180
-        break;
181
-    case MST_LEDDAT2:
182
-        s->leddat2 = value;
183
-        break;
184
-    case MST_LEDCTRL:
185
-        s->ledctrl = value;
186
-        break;
187
-    case MST_GPSWR:
188
-        s->gpswr = value;
189
-        break;
190
-    case MST_MSCWR1:
191
-        s->mscwr1 = value;
192
-        break;
193
-    case MST_MSCWR2:
194
-        s->mscwr2 = value;
195
-        break;
196
-    case MST_MSCWR3:
197
-        s->mscwr3 = value;
198
-        break;
199
-    case MST_MSCRD:
200
-        s->mscrd = value;
201
-        break;
202
-    case MST_INTMSKENA:    /* Mask interrupt */
203
-        s->intmskena = (value & 0xFEEFF);
204
-        qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
205
-        break;
206
-    case MST_INTSETCLR:    /* clear or set interrupt */
207
-        s->intsetclr = (value & 0xFEEFF);
208
-        qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
209
-        break;
210
-        /* For PCMCIAx allow the to change only power and reset */
211
-    case MST_PCMCIA0:
212
-        s->pcmcia0 = (value & 0x1f) | (s->pcmcia0 & ~0x1f);
213
-        break;
214
-    case MST_PCMCIA1:
215
-        s->pcmcia1 = (value & 0x1f) | (s->pcmcia1 & ~0x1f);
216
-        break;
217
-    default:
218
-        printf("Mainstone - mst_fpga_writeb: Bad register offset "
219
-            "0x" HWADDR_FMT_plx "\n", addr);
220
-    }
221
-}
222
-
223
-static const MemoryRegionOps mst_fpga_ops = {
224
-    .read = mst_fpga_readb,
225
-    .write = mst_fpga_writeb,
226
-    .endianness = DEVICE_NATIVE_ENDIAN,
227
-};
228
-
229
-static int mst_fpga_post_load(void *opaque, int version_id)
230
-{
231
-    mst_irq_state *s = (mst_irq_state *) opaque;
232
-
233
-    qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
234
-    return 0;
235
-}
236
-
237
-static void mst_fpga_init(Object *obj)
238
-{
239
- DeviceState *dev = DEVICE(obj);
240
- mst_irq_state *s = MAINSTONE_FPGA(obj);
241
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
242
-
243
- s->pcmcia0 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
244
- s->pcmcia1 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
245
-
246
- sysbus_init_irq(sbd, &s->parent);
247
-
248
- /* alloc the external 16 irqs */
249
- qdev_init_gpio_in(dev, mst_fpga_set_irq, MST_NUM_IRQS);
250
-
251
- memory_region_init_io(&s->iomem, obj, &mst_fpga_ops, s,
252
- "fpga", 0x00100000);
253
- sysbus_init_mmio(sbd, &s->iomem);
254
-}
255
-
256
-static const VMStateDescription vmstate_mst_fpga_regs = {
257
- .name = "mainstone_fpga",
258
- .version_id = 0,
259
- .minimum_version_id = 0,
260
- .post_load = mst_fpga_post_load,
261
- .fields = (const VMStateField[]) {
262
-        VMSTATE_UINT32(prev_level, mst_irq_state),
263
-        VMSTATE_UINT32(leddat1, mst_irq_state),
264
-        VMSTATE_UINT32(leddat2, mst_irq_state),
265
-        VMSTATE_UINT32(ledctrl, mst_irq_state),
266
-        VMSTATE_UINT32(gpswr, mst_irq_state),
267
-        VMSTATE_UINT32(mscwr1, mst_irq_state),
268
-        VMSTATE_UINT32(mscwr2, mst_irq_state),
269
-        VMSTATE_UINT32(mscwr3, mst_irq_state),
270
-        VMSTATE_UINT32(mscrd, mst_irq_state),
271
-        VMSTATE_UINT32(intmskena, mst_irq_state),
272
-        VMSTATE_UINT32(intsetclr, mst_irq_state),
273
-        VMSTATE_UINT32(pcmcia0, mst_irq_state),
274
-        VMSTATE_UINT32(pcmcia1, mst_irq_state),
275
-        VMSTATE_END_OF_LIST(),
276
-    },
277
-};
278
-
279
-static void mst_fpga_class_init(ObjectClass *klass, void *data)
280
-{
281
- DeviceClass *dc = DEVICE_CLASS(klass);
282
-
283
- dc->desc = "Mainstone II FPGA";
284
- dc->vmsd = &vmstate_mst_fpga_regs;
285
-}
286
-
287
-static const TypeInfo mst_fpga_info = {
288
- .name = TYPE_MAINSTONE_FPGA,
289
- .parent = TYPE_SYS_BUS_DEVICE,
290
- .instance_size = sizeof(mst_irq_state),
291
- .instance_init = mst_fpga_init,
292
- .class_init = mst_fpga_class_init,
293
-};
294
-
295
-static void mst_fpga_register_types(void)
296
-{
297
- type_register_static(&mst_fpga_info);
298
-}
299
-
300
-type_init(mst_fpga_register_types)
301
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
302
index XXXXXXX..XXXXXXX 100644
303
--- a/hw/misc/meson.build
304
+++ b/hw/misc/meson.build
305
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_IMX', if_true: files(
306
'imx_ccm.c',
307
'imx_rngc.c',
308
))
309
-system_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mst_fpga.c'))
310
system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
311
'npcm7xx_clk.c',
312
'npcm7xx_gcr.c',
313
--
23
--
314
2.34.1
24
2.34.1
315
316
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ardb@kernel.org>
1
Set the default NaN pattern explicitly for tricore.
2
2
3
target_ulong is typedef'ed as a 32-bit integer when building the
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
qemu-system-arm target, and this is smaller than the size of an
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
intermediate physical address when LPAE is being used.
5
Message-id: 20241202131347.498124-54-peter.maydell@linaro.org
6
---
7
target/tricore/helper.c | 2 ++
8
1 file changed, 2 insertions(+)
6
9
7
Given that Linux may place leaf level user page tables in high memory
10
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
8
when built for LPAE, the kernel will crash with an external abort as
9
soon as it enters user space when running with more than ~3 GiB of
10
system RAM.
11
12
So replace target_ulong with vaddr in places where it may carry an
13
address value that is not representable in 32 bits.
14
15
Fixes: f3639a64f602ea ("target/arm: Use softmmu tlbs for page table walking")
16
Cc: qemu-stable@nongnu.org
17
Reported-by: Arnd Bergmann <arnd@arndb.de>
18
Tested-by: Arnd Bergmann <arnd@arndb.de>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
21
Message-id: 20240927071051.1444768-1-ardb+git@google.com
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
24
target/arm/internals.h | 4 ++--
25
target/arm/ptw.c | 16 ++++++++--------
26
2 files changed, 10 insertions(+), 10 deletions(-)
27
28
diff --git a/target/arm/internals.h b/target/arm/internals.h
29
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/internals.h
12
--- a/target/tricore/helper.c
31
+++ b/target/arm/internals.h
13
+++ b/target/tricore/helper.c
32
@@ -XXX,XX +XXX,XX @@ typedef struct GetPhysAddrResult {
14
@@ -XXX,XX +XXX,XX @@ void fpu_set_state(CPUTriCoreState *env)
33
* * for PSMAv5 based systems we don't bother to return a full FSR format
15
set_flush_to_zero(1, &env->fp_status);
34
* value.
16
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
35
*/
17
set_default_nan_mode(1, &env->fp_status);
36
-bool get_phys_addr(CPUARMState *env, target_ulong address,
18
+ /* Default NaN pattern: sign bit clear, frac msb set */
37
+bool get_phys_addr(CPUARMState *env, vaddr address,
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
38
MMUAccessType access_type, ARMMMUIdx mmu_idx,
39
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
40
__attribute__((nonnull));
41
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
42
* Similar to get_phys_addr, but use the given security space and don't perform
43
* a Granule Protection Check on the resulting address.
44
*/
45
-bool get_phys_addr_with_space_nogpc(CPUARMState *env, target_ulong address,
46
+bool get_phys_addr_with_space_nogpc(CPUARMState *env, vaddr address,
47
MMUAccessType access_type,
48
ARMMMUIdx mmu_idx, ARMSecuritySpace space,
49
GetPhysAddrResult *result,
50
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/ptw.c
53
+++ b/target/arm/ptw.c
54
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
55
} S1Translate;
56
57
static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
58
- target_ulong address,
59
+ vaddr address,
60
MMUAccessType access_type,
61
GetPhysAddrResult *result,
62
ARMMMUFaultInfo *fi);
63
64
static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
65
- target_ulong address,
66
+ vaddr address,
67
MMUAccessType access_type,
68
GetPhysAddrResult *result,
69
ARMMMUFaultInfo *fi);
70
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
71
*/
72
static bool get_phys_addr_disabled(CPUARMState *env,
73
S1Translate *ptw,
74
- target_ulong address,
75
+ vaddr address,
76
MMUAccessType access_type,
77
GetPhysAddrResult *result,
78
ARMMMUFaultInfo *fi)
79
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env,
80
}
20
}
81
21
82
static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
22
uint32_t psw_read(CPUTriCoreState *env)
83
- target_ulong address,
84
+ vaddr address,
85
MMUAccessType access_type,
86
GetPhysAddrResult *result,
87
ARMMMUFaultInfo *fi)
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
89
}
90
91
static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
92
- target_ulong address,
93
+ vaddr address,
94
MMUAccessType access_type,
95
GetPhysAddrResult *result,
96
ARMMMUFaultInfo *fi)
97
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
98
}
99
100
static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
101
- target_ulong address,
102
+ vaddr address,
103
MMUAccessType access_type,
104
GetPhysAddrResult *result,
105
ARMMMUFaultInfo *fi)
106
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
107
return false;
108
}
109
110
-bool get_phys_addr_with_space_nogpc(CPUARMState *env, target_ulong address,
111
+bool get_phys_addr_with_space_nogpc(CPUARMState *env, vaddr address,
112
MMUAccessType access_type,
113
ARMMMUIdx mmu_idx, ARMSecuritySpace space,
114
GetPhysAddrResult *result,
115
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_space_nogpc(CPUARMState *env, target_ulong address,
116
return get_phys_addr_nogpc(env, &ptw, address, access_type, result, fi);
117
}
118
119
-bool get_phys_addr(CPUARMState *env, target_ulong address,
120
+bool get_phys_addr(CPUARMState *env, vaddr address,
121
MMUAccessType access_type, ARMMMUIdx mmu_idx,
122
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
123
{
124
--
23
--
125
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
The tc6393xb was used only by the XScale-based Zaurus machine types.
1
Now that all our targets have bene converted to explicitly specify
2
Now they have been removed we can remove this device too.
2
their pattern for the default NaN value we can remove the remaining
3
fallback code in parts64_default_nan().
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240903160751.4100218-7-peter.maydell@linaro.org
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-55-peter.maydell@linaro.org
6
---
8
---
7
MAINTAINERS | 2 -
9
fpu/softfloat-specialize.c.inc | 14 --------------
8
include/hw/display/tc6393xb.h | 21 --
10
1 file changed, 14 deletions(-)
9
hw/display/tc6393xb.c | 568 ----------------------------------
10
hw/display/meson.build | 1 -
11
4 files changed, 592 deletions(-)
12
delete mode 100644 include/hw/display/tc6393xb.h
13
delete mode 100644 hw/display/tc6393xb.c
14
11
15
diff --git a/MAINTAINERS b/MAINTAINERS
12
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
14
--- a/fpu/softfloat-specialize.c.inc
18
+++ b/MAINTAINERS
15
+++ b/fpu/softfloat-specialize.c.inc
19
@@ -XXX,XX +XXX,XX @@ S: Odd Fixes
16
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
20
F: hw/arm/mainstone.c
17
uint64_t frac;
21
F: hw/arm/z2.c
18
uint8_t dnan_pattern = status->default_nan_pattern;
22
F: hw/*/pxa2xx*
19
23
-F: hw/display/tc6393xb.c
20
- if (dnan_pattern == 0) {
24
F: hw/gpio/max7310.c
21
- /*
25
F: hw/gpio/zaurus.c
22
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
26
F: hw/misc/mst_fpga.c
23
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
27
@@ -XXX,XX +XXX,XX @@ F: hw/adc/max111x.c
24
- * do not have floating-point.
28
F: include/hw/adc/max111x.h
25
- */
29
F: include/hw/arm/pxa.h
26
- if (snan_bit_is_one(status)) {
30
F: include/hw/arm/sharpsl.h
27
- /* sign bit clear, set all frac bits other than msb */
31
-F: include/hw/display/tc6393xb.h
28
- dnan_pattern = 0b00111111;
32
F: docs/system/arm/mainstone.rst
29
- } else {
33
30
- /* sign bit clear, set frac msb */
34
SABRELITE / i.MX6
31
- dnan_pattern = 0b01000000;
35
diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h
36
deleted file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- a/include/hw/display/tc6393xb.h
39
+++ /dev/null
40
@@ -XXX,XX +XXX,XX @@
41
-/*
42
- * Toshiba TC6393XB I/O Controller.
43
- * Found in Sharp Zaurus SL-6000 (tosa) or some
44
- * Toshiba e-Series PDAs.
45
- *
46
- * Copyright (c) 2007 Hervé Poussineau
47
- *
48
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
49
- * See the COPYING file in the top-level directory.
50
- */
51
-
52
-#ifndef HW_DISPLAY_TC6393XB_H
53
-#define HW_DISPLAY_TC6393XB_H
54
-
55
-typedef struct TC6393xbState TC6393xbState;
56
-
57
-TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
58
- uint32_t base, qemu_irq irq);
59
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
60
-
61
-#endif
62
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
63
deleted file mode 100644
64
index XXXXXXX..XXXXXXX
65
--- a/hw/display/tc6393xb.c
66
+++ /dev/null
67
@@ -XXX,XX +XXX,XX @@
68
-/*
69
- * Toshiba TC6393XB I/O Controller.
70
- * Found in Sharp Zaurus SL-6000 (tosa) or some
71
- * Toshiba e-Series PDAs.
72
- *
73
- * Most features are currently unsupported!!!
74
- *
75
- * This code is licensed under the GNU GPL v2.
76
- *
77
- * Contributions after 2012-01-13 are licensed under the terms of the
78
- * GNU GPL, version 2 or (at your option) any later version.
79
- */
80
-
81
-#include "qemu/osdep.h"
82
-#include "qapi/error.h"
83
-#include "qemu/host-utils.h"
84
-#include "hw/irq.h"
85
-#include "hw/display/tc6393xb.h"
86
-#include "exec/memory.h"
87
-#include "hw/block/flash.h"
88
-#include "ui/console.h"
89
-#include "ui/pixel_ops.h"
90
-#include "sysemu/blockdev.h"
91
-
92
-#define IRQ_TC6393_NAND        0
93
-#define IRQ_TC6393_MMC        1
94
-#define IRQ_TC6393_OHCI        2
95
-#define IRQ_TC6393_SERIAL    3
96
-#define IRQ_TC6393_FB        4
97
-
98
-#define    TC6393XB_NR_IRQS    8
99
-
100
-#define TC6393XB_GPIOS 16
101
-
102
-#define SCR_REVID    0x08        /* b Revision ID    */
103
-#define SCR_ISR        0x50        /* b Interrupt Status    */
104
-#define SCR_IMR        0x52        /* b Interrupt Mask    */
105
-#define SCR_IRR        0x54        /* b Interrupt Routing    */
106
-#define SCR_GPER    0x60        /* w GP Enable        */
107
-#define SCR_GPI_SR(i)    (0x64 + (i))    /* b3 GPI Status    */
108
-#define SCR_GPI_IMR(i)    (0x68 + (i))    /* b3 GPI INT Mask    */
109
-#define SCR_GPI_EDER(i)    (0x6c + (i))    /* b3 GPI Edge Detect Enable */
110
-#define SCR_GPI_LIR(i)    (0x70 + (i))    /* b3 GPI Level Invert    */
111
-#define SCR_GPO_DSR(i)    (0x78 + (i))    /* b3 GPO Data Set    */
112
-#define SCR_GPO_DOECR(i) (0x7c + (i))    /* b3 GPO Data OE Control */
113
-#define SCR_GP_IARCR(i)    (0x80 + (i))    /* b3 GP Internal Active Register Control */
114
-#define SCR_GP_IARLCR(i) (0x84 + (i))    /* b3 GP INTERNAL Active Register Level Control */
115
-#define SCR_GPI_BCR(i)    (0x88 + (i))    /* b3 GPI Buffer Control */
116
-#define SCR_GPA_IARCR    0x8c        /* w GPa Internal Active Register Control */
117
-#define SCR_GPA_IARLCR    0x90        /* w GPa Internal Active Register Level Control */
118
-#define SCR_GPA_BCR    0x94        /* w GPa Buffer Control */
119
-#define SCR_CCR        0x98        /* w Clock Control    */
120
-#define SCR_PLL2CR    0x9a        /* w PLL2 Control    */
121
-#define SCR_PLL1CR    0x9c        /* l PLL1 Control    */
122
-#define SCR_DIARCR    0xa0        /* b Device Internal Active Register Control */
123
-#define SCR_DBOCR    0xa1        /* b Device Buffer Off Control */
124
-#define SCR_FER        0xe0        /* b Function Enable    */
125
-#define SCR_MCR        0xe4        /* w Mode Control    */
126
-#define SCR_CONFIG    0xfc        /* b Configuration Control */
127
-#define SCR_DEBUG    0xff        /* b Debug        */
128
-
129
-#define NAND_CFG_COMMAND 0x04 /* w Command */
130
-#define NAND_CFG_BASE 0x10 /* l Control Base Address */
131
-#define NAND_CFG_INTP 0x3d /* b Interrupt Pin */
132
-#define NAND_CFG_INTE 0x48 /* b Int Enable */
133
-#define NAND_CFG_EC 0x4a /* b Event Control */
134
-#define NAND_CFG_ICC 0x4c /* b Internal Clock Control */
135
-#define NAND_CFG_ECCC 0x5b /* b ECC Control */
136
-#define NAND_CFG_NFTC 0x60 /* b NAND Flash Transaction Control */
137
-#define NAND_CFG_NFM 0x61 /* b NAND Flash Monitor */
138
-#define NAND_CFG_NFPSC 0x62 /* b NAND Flash Power Supply Control */
139
-#define NAND_CFG_NFDC 0x63 /* b NAND Flash Detect Control */
140
-
141
-#define NAND_DATA 0x00 /* l Data */
142
-#define NAND_MODE 0x04 /* b Mode */
143
-#define NAND_STATUS 0x05 /* b Status */
144
-#define NAND_ISR 0x06 /* b Interrupt Status */
145
-#define NAND_IMR 0x07 /* b Interrupt Mask */
146
-
147
-#define NAND_MODE_WP 0x80
148
-#define NAND_MODE_CE 0x10
149
-#define NAND_MODE_ALE 0x02
150
-#define NAND_MODE_CLE 0x01
151
-#define NAND_MODE_ECC_MASK 0x60
152
-#define NAND_MODE_ECC_EN 0x20
153
-#define NAND_MODE_ECC_READ 0x40
154
-#define NAND_MODE_ECC_RST 0x60
155
-
156
-struct TC6393xbState {
157
- MemoryRegion iomem;
158
- qemu_irq irq;
159
- qemu_irq *sub_irqs;
160
- struct {
161
- uint8_t ISR;
162
- uint8_t IMR;
163
- uint8_t IRR;
164
- uint16_t GPER;
165
- uint8_t GPI_SR[3];
166
- uint8_t GPI_IMR[3];
167
- uint8_t GPI_EDER[3];
168
- uint8_t GPI_LIR[3];
169
- uint8_t GP_IARCR[3];
170
- uint8_t GP_IARLCR[3];
171
- uint8_t GPI_BCR[3];
172
- uint16_t GPA_IARCR;
173
- uint16_t GPA_IARLCR;
174
- uint16_t CCR;
175
- uint16_t PLL2CR;
176
- uint32_t PLL1CR;
177
- uint8_t DIARCR;
178
- uint8_t DBOCR;
179
- uint8_t FER;
180
- uint16_t MCR;
181
- uint8_t CONFIG;
182
- uint8_t DEBUG;
183
- } scr;
184
- uint32_t gpio_dir;
185
- uint32_t gpio_level;
186
- uint32_t prev_level;
187
- qemu_irq handler[TC6393XB_GPIOS];
188
- qemu_irq *gpio_in;
189
-
190
- struct {
191
- uint8_t mode;
192
- uint8_t isr;
193
- uint8_t imr;
194
- } nand;
195
- int nand_enable;
196
- uint32_t nand_phys;
197
- DeviceState *flash;
198
- ECCState ecc;
199
-
200
- QemuConsole *con;
201
- MemoryRegion vram;
202
- uint16_t *vram_ptr;
203
- uint32_t scr_width, scr_height; /* in pixels */
204
- qemu_irq l3v;
205
- unsigned blank : 1,
206
- blanked : 1;
207
-};
208
-
209
-static void tc6393xb_gpio_set(void *opaque, int line, int level)
210
-{
211
-// TC6393xbState *s = opaque;
212
-
213
- if (line > TC6393XB_GPIOS) {
214
- printf("%s: No GPIO pin %i\n", __func__, line);
215
- return;
216
- }
217
-
218
- // FIXME: how does the chip reflect the GPIO input level change?
219
-}
220
-
221
-static void tc6393xb_gpio_handler_update(TC6393xbState *s)
222
-{
223
- uint32_t level, diff;
224
- int bit;
225
-
226
- level = s->gpio_level & s->gpio_dir;
227
- level &= MAKE_64BIT_MASK(0, TC6393XB_GPIOS);
228
-
229
- for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
230
- bit = ctz32(diff);
231
- qemu_set_irq(s->handler[bit], (level >> bit) & 1);
232
- }
233
-
234
- s->prev_level = level;
235
-}
236
-
237
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s)
238
-{
239
- return s->l3v;
240
-}
241
-
242
-static void tc6393xb_l3v(void *opaque, int line, int level)
243
-{
244
- TC6393xbState *s = opaque;
245
- s->blank = !level;
246
- fprintf(stderr, "L3V: %d\n", level);
247
-}
248
-
249
-static void tc6393xb_sub_irq(void *opaque, int line, int level) {
250
- TC6393xbState *s = opaque;
251
- uint8_t isr = s->scr.ISR;
252
- if (level)
253
- isr |= 1 << line;
254
- else
255
- isr &= ~(1 << line);
256
- s->scr.ISR = isr;
257
- qemu_set_irq(s->irq, isr & s->scr.IMR);
258
-}
259
-
260
-#define SCR_REG_B(N) \
261
- case SCR_ ##N: return s->scr.N
262
-#define SCR_REG_W(N) \
263
- case SCR_ ##N: return s->scr.N; \
264
- case SCR_ ##N + 1: return s->scr.N >> 8;
265
-#define SCR_REG_L(N) \
266
- case SCR_ ##N: return s->scr.N; \
267
- case SCR_ ##N + 1: return s->scr.N >> 8; \
268
- case SCR_ ##N + 2: return s->scr.N >> 16; \
269
- case SCR_ ##N + 3: return s->scr.N >> 24;
270
-#define SCR_REG_A(N) \
271
- case SCR_ ##N(0): return s->scr.N[0]; \
272
- case SCR_ ##N(1): return s->scr.N[1]; \
273
- case SCR_ ##N(2): return s->scr.N[2]
274
-
275
-static uint32_t tc6393xb_scr_readb(TC6393xbState *s, hwaddr addr)
276
-{
277
- switch (addr) {
278
- case SCR_REVID:
279
- return 3;
280
- case SCR_REVID+1:
281
- return 0;
282
- SCR_REG_B(ISR);
283
- SCR_REG_B(IMR);
284
- SCR_REG_B(IRR);
285
- SCR_REG_W(GPER);
286
- SCR_REG_A(GPI_SR);
287
- SCR_REG_A(GPI_IMR);
288
- SCR_REG_A(GPI_EDER);
289
- SCR_REG_A(GPI_LIR);
290
- case SCR_GPO_DSR(0):
291
- case SCR_GPO_DSR(1):
292
- case SCR_GPO_DSR(2):
293
- return (s->gpio_level >> ((addr - SCR_GPO_DSR(0)) * 8)) & 0xff;
294
- case SCR_GPO_DOECR(0):
295
- case SCR_GPO_DOECR(1):
296
- case SCR_GPO_DOECR(2):
297
- return (s->gpio_dir >> ((addr - SCR_GPO_DOECR(0)) * 8)) & 0xff;
298
- SCR_REG_A(GP_IARCR);
299
- SCR_REG_A(GP_IARLCR);
300
- SCR_REG_A(GPI_BCR);
301
- SCR_REG_W(GPA_IARCR);
302
- SCR_REG_W(GPA_IARLCR);
303
- SCR_REG_W(CCR);
304
- SCR_REG_W(PLL2CR);
305
- SCR_REG_L(PLL1CR);
306
- SCR_REG_B(DIARCR);
307
- SCR_REG_B(DBOCR);
308
- SCR_REG_B(FER);
309
- SCR_REG_W(MCR);
310
- SCR_REG_B(CONFIG);
311
- SCR_REG_B(DEBUG);
312
- }
313
- fprintf(stderr, "tc6393xb_scr: unhandled read at %08x\n", (uint32_t) addr);
314
- return 0;
315
-}
316
-#undef SCR_REG_B
317
-#undef SCR_REG_W
318
-#undef SCR_REG_L
319
-#undef SCR_REG_A
320
-
321
-#define SCR_REG_B(N) \
322
- case SCR_ ##N: s->scr.N = value; return;
323
-#define SCR_REG_W(N) \
324
- case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); return; \
325
- case SCR_ ##N + 1: s->scr.N = (s->scr.N & 0xff) | (value << 8); return
326
-#define SCR_REG_L(N) \
327
- case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); return; \
328
- case SCR_ ##N + 1: s->scr.N = (s->scr.N & ~(0xff << 8)) | (value & (0xff << 8)); return; \
329
- case SCR_ ##N + 2: s->scr.N = (s->scr.N & ~(0xff << 16)) | (value & (0xff << 16)); return; \
330
- case SCR_ ##N + 3: s->scr.N = (s->scr.N & ~(0xff << 24)) | (value & (0xff << 24)); return;
331
-#define SCR_REG_A(N) \
332
- case SCR_ ##N(0): s->scr.N[0] = value; return; \
333
- case SCR_ ##N(1): s->scr.N[1] = value; return; \
334
- case SCR_ ##N(2): s->scr.N[2] = value; return
335
-
336
-static void tc6393xb_scr_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
337
-{
338
- switch (addr) {
339
- SCR_REG_B(ISR);
340
- SCR_REG_B(IMR);
341
- SCR_REG_B(IRR);
342
- SCR_REG_W(GPER);
343
- SCR_REG_A(GPI_SR);
344
- SCR_REG_A(GPI_IMR);
345
- SCR_REG_A(GPI_EDER);
346
- SCR_REG_A(GPI_LIR);
347
- case SCR_GPO_DSR(0):
348
- case SCR_GPO_DSR(1):
349
- case SCR_GPO_DSR(2):
350
- s->gpio_level = (s->gpio_level & ~(0xff << ((addr - SCR_GPO_DSR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DSR(0))*8));
351
- tc6393xb_gpio_handler_update(s);
352
- return;
353
- case SCR_GPO_DOECR(0):
354
- case SCR_GPO_DOECR(1):
355
- case SCR_GPO_DOECR(2):
356
- s->gpio_dir = (s->gpio_dir & ~(0xff << ((addr - SCR_GPO_DOECR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DOECR(0))*8));
357
- tc6393xb_gpio_handler_update(s);
358
- return;
359
- SCR_REG_A(GP_IARCR);
360
- SCR_REG_A(GP_IARLCR);
361
- SCR_REG_A(GPI_BCR);
362
- SCR_REG_W(GPA_IARCR);
363
- SCR_REG_W(GPA_IARLCR);
364
- SCR_REG_W(CCR);
365
- SCR_REG_W(PLL2CR);
366
- SCR_REG_L(PLL1CR);
367
- SCR_REG_B(DIARCR);
368
- SCR_REG_B(DBOCR);
369
- SCR_REG_B(FER);
370
- SCR_REG_W(MCR);
371
- SCR_REG_B(CONFIG);
372
- SCR_REG_B(DEBUG);
373
- }
374
- fprintf(stderr, "tc6393xb_scr: unhandled write at %08x: %02x\n",
375
- (uint32_t) addr, value & 0xff);
376
-}
377
-#undef SCR_REG_B
378
-#undef SCR_REG_W
379
-#undef SCR_REG_L
380
-#undef SCR_REG_A
381
-
382
-static void tc6393xb_nand_irq(TC6393xbState *s) {
383
- qemu_set_irq(s->sub_irqs[IRQ_TC6393_NAND],
384
- (s->nand.imr & 0x80) && (s->nand.imr & s->nand.isr));
385
-}
386
-
387
-static uint32_t tc6393xb_nand_cfg_readb(TC6393xbState *s, hwaddr addr) {
388
- switch (addr) {
389
- case NAND_CFG_COMMAND:
390
- return s->nand_enable ? 2 : 0;
391
- case NAND_CFG_BASE:
392
- case NAND_CFG_BASE + 1:
393
- case NAND_CFG_BASE + 2:
394
- case NAND_CFG_BASE + 3:
395
- return s->nand_phys >> (addr - NAND_CFG_BASE);
396
- }
397
- fprintf(stderr, "tc6393xb_nand_cfg: unhandled read at %08x\n", (uint32_t) addr);
398
- return 0;
399
-}
400
-static void tc6393xb_nand_cfg_writeb(TC6393xbState *s, hwaddr addr, uint32_t value) {
401
- switch (addr) {
402
- case NAND_CFG_COMMAND:
403
- s->nand_enable = (value & 0x2);
404
- return;
405
- case NAND_CFG_BASE:
406
- case NAND_CFG_BASE + 1:
407
- case NAND_CFG_BASE + 2:
408
- case NAND_CFG_BASE + 3:
409
- s->nand_phys &= ~(0xff << ((addr - NAND_CFG_BASE) * 8));
410
- s->nand_phys |= (value & 0xff) << ((addr - NAND_CFG_BASE) * 8);
411
- return;
412
- }
413
- fprintf(stderr, "tc6393xb_nand_cfg: unhandled write at %08x: %02x\n",
414
- (uint32_t) addr, value & 0xff);
415
-}
416
-
417
-static uint32_t tc6393xb_nand_readb(TC6393xbState *s, hwaddr addr) {
418
- switch (addr) {
419
- case NAND_DATA + 0:
420
- case NAND_DATA + 1:
421
- case NAND_DATA + 2:
422
- case NAND_DATA + 3:
423
- return nand_getio(s->flash);
424
- case NAND_MODE:
425
- return s->nand.mode;
426
- case NAND_STATUS:
427
- return 0x14;
428
- case NAND_ISR:
429
- return s->nand.isr;
430
- case NAND_IMR:
431
- return s->nand.imr;
432
- }
433
- fprintf(stderr, "tc6393xb_nand: unhandled read at %08x\n", (uint32_t) addr);
434
- return 0;
435
-}
436
-static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value) {
437
-// fprintf(stderr, "tc6393xb_nand: write at %08x: %02x\n",
438
-//                    (uint32_t) addr, value & 0xff);
439
- switch (addr) {
440
- case NAND_DATA + 0:
441
- case NAND_DATA + 1:
442
- case NAND_DATA + 2:
443
- case NAND_DATA + 3:
444
- nand_setio(s->flash, value);
445
- s->nand.isr |= 1;
446
- tc6393xb_nand_irq(s);
447
- return;
448
- case NAND_MODE:
449
- s->nand.mode = value;
450
- nand_setpins(s->flash,
451
- value & NAND_MODE_CLE,
452
- value & NAND_MODE_ALE,
453
- !(value & NAND_MODE_CE),
454
- value & NAND_MODE_WP,
455
- 0); // FIXME: gnd
456
- switch (value & NAND_MODE_ECC_MASK) {
457
- case NAND_MODE_ECC_RST:
458
- ecc_reset(&s->ecc);
459
- break;
460
- case NAND_MODE_ECC_READ:
461
- // FIXME
462
- break;
463
- case NAND_MODE_ECC_EN:
464
- ecc_reset(&s->ecc);
465
- }
466
- return;
467
- case NAND_ISR:
468
- s->nand.isr = value;
469
- tc6393xb_nand_irq(s);
470
- return;
471
- case NAND_IMR:
472
- s->nand.imr = value;
473
- tc6393xb_nand_irq(s);
474
- return;
475
- }
476
- fprintf(stderr, "tc6393xb_nand: unhandled write at %08x: %02x\n",
477
- (uint32_t) addr, value & 0xff);
478
-}
479
-
480
-static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
481
-{
482
- DisplaySurface *surface = qemu_console_surface(s->con);
483
- int i;
484
- uint16_t *data_buffer;
485
- uint8_t *data_display;
486
-
487
- data_buffer = s->vram_ptr;
488
- data_display = surface_data(surface);
489
- for (i = 0; i < s->scr_height; i++) {
490
- int j;
491
- for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
492
- uint16_t color = *data_buffer;
493
- uint32_t dest_color = rgb_to_pixel32(
494
- ((color & 0xf800) * 0x108) >> 11,
495
- ((color & 0x7e0) * 0x41) >> 9,
496
- ((color & 0x1f) * 0x21) >> 2
497
- );
498
- *(uint32_t *)data_display = dest_color;
499
- }
32
- }
500
- }
33
- }
501
- dpy_gfx_update_full(s->con);
34
assert(dnan_pattern != 0);
502
-}
35
503
-
36
sign = dnan_pattern >> 7;
504
-static void tc6393xb_draw_blank(TC6393xbState *s, int full_update)
505
-{
506
- DisplaySurface *surface = qemu_console_surface(s->con);
507
- int i, w;
508
- uint8_t *d;
509
-
510
- if (!full_update)
511
- return;
512
-
513
- w = s->scr_width * surface_bytes_per_pixel(surface);
514
- d = surface_data(surface);
515
- for(i = 0; i < s->scr_height; i++) {
516
- memset(d, 0, w);
517
- d += surface_stride(surface);
518
- }
519
-
520
- dpy_gfx_update_full(s->con);
521
-}
522
-
523
-static void tc6393xb_update_display(void *opaque)
524
-{
525
- TC6393xbState *s = opaque;
526
- DisplaySurface *surface = qemu_console_surface(s->con);
527
- int full_update;
528
-
529
- if (s->scr_width == 0 || s->scr_height == 0)
530
- return;
531
-
532
- full_update = 0;
533
- if (s->blanked != s->blank) {
534
- s->blanked = s->blank;
535
- full_update = 1;
536
- }
537
- if (s->scr_width != surface_width(surface) ||
538
- s->scr_height != surface_height(surface)) {
539
- qemu_console_resize(s->con, s->scr_width, s->scr_height);
540
- full_update = 1;
541
- }
542
- if (s->blanked)
543
- tc6393xb_draw_blank(s, full_update);
544
- else
545
- tc6393xb_draw_graphic(s, full_update);
546
-}
547
-
548
-
549
-static uint64_t tc6393xb_readb(void *opaque, hwaddr addr,
550
- unsigned size)
551
-{
552
- TC6393xbState *s = opaque;
553
-
554
- switch (addr >> 8) {
555
- case 0:
556
- return tc6393xb_scr_readb(s, addr & 0xff);
557
- case 1:
558
- return tc6393xb_nand_cfg_readb(s, addr & 0xff);
559
- };
560
-
561
- if ((addr &~0xff) == s->nand_phys && s->nand_enable) {
562
-// return tc6393xb_nand_readb(s, addr & 0xff);
563
- uint8_t d = tc6393xb_nand_readb(s, addr & 0xff);
564
-// fprintf(stderr, "tc6393xb_nand: read at %08x: %02hhx\n", (uint32_t) addr, d);
565
- return d;
566
- }
567
-
568
-// fprintf(stderr, "tc6393xb: unhandled read at %08x\n", (uint32_t) addr);
569
- return 0;
570
-}
571
-
572
-static void tc6393xb_writeb(void *opaque, hwaddr addr,
573
- uint64_t value, unsigned size) {
574
- TC6393xbState *s = opaque;
575
-
576
- switch (addr >> 8) {
577
- case 0:
578
- tc6393xb_scr_writeb(s, addr & 0xff, value);
579
- return;
580
- case 1:
581
- tc6393xb_nand_cfg_writeb(s, addr & 0xff, value);
582
- return;
583
- };
584
-
585
- if ((addr &~0xff) == s->nand_phys && s->nand_enable)
586
- tc6393xb_nand_writeb(s, addr & 0xff, value);
587
- else
588
- fprintf(stderr, "tc6393xb: unhandled write at %08x: %02x\n",
589
- (uint32_t) addr, (int)value & 0xff);
590
-}
591
-
592
-static const GraphicHwOps tc6393xb_gfx_ops = {
593
- .gfx_update = tc6393xb_update_display,
594
-};
595
-
596
-TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
597
-{
598
- TC6393xbState *s;
599
- DriveInfo *nand;
600
- static const MemoryRegionOps tc6393xb_ops = {
601
- .read = tc6393xb_readb,
602
- .write = tc6393xb_writeb,
603
- .endianness = DEVICE_NATIVE_ENDIAN,
604
- .impl = {
605
- .min_access_size = 1,
606
- .max_access_size = 1,
607
- },
608
- };
609
-
610
- s = g_new0(TC6393xbState, 1);
611
- s->irq = irq;
612
- s->gpio_in = qemu_allocate_irqs(tc6393xb_gpio_set, s, TC6393XB_GPIOS);
613
-
614
- s->l3v = qemu_allocate_irq(tc6393xb_l3v, s, 0);
615
- s->blanked = 1;
616
-
617
- s->sub_irqs = qemu_allocate_irqs(tc6393xb_sub_irq, s, TC6393XB_NR_IRQS);
618
-
619
- nand = drive_get(IF_MTD, 0, 0);
620
- s->flash = nand_init(nand ? blk_by_legacy_dinfo(nand) : NULL,
621
- NAND_MFR_TOSHIBA, 0x76);
622
-
623
- memory_region_init_io(&s->iomem, NULL, &tc6393xb_ops, s, "tc6393xb", 0x10000);
624
- memory_region_add_subregion(sysmem, base, &s->iomem);
625
-
626
- memory_region_init_ram(&s->vram, NULL, "tc6393xb.vram", 0x100000,
627
- &error_fatal);
628
- s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
629
- memory_region_add_subregion(sysmem, base + 0x100000, &s->vram);
630
- s->scr_width = 480;
631
- s->scr_height = 640;
632
- s->con = graphic_console_init(NULL, 0, &tc6393xb_gfx_ops, s);
633
-
634
- return s;
635
-}
636
diff --git a/hw/display/meson.build b/hw/display/meson.build
637
index XXXXXXX..XXXXXXX 100644
638
--- a/hw/display/meson.build
639
+++ b/hw/display/meson.build
640
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_BOCHS_DISPLAY', if_true: files('bochs-display.c'))
641
system_ss.add(when: 'CONFIG_BLIZZARD', if_true: files('blizzard.c'))
642
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_fimd.c'))
643
system_ss.add(when: 'CONFIG_FRAMEBUFFER', if_true: files('framebuffer.c'))
644
-system_ss.add(when: 'CONFIG_ZAURUS', if_true: files('tc6393xb.c'))
645
646
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_dss.c'))
647
system_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_lcd.c'))
648
--
37
--
649
2.34.1
38
2.34.1
650
651
diff view generated by jsdifflib
1
The 'cheetah' machine has been deprecated since 9.0, so we can
1
From: Richard Henderson <richard.henderson@linaro.org>
2
remove it for the 9.2 release.
3
2
4
(tsc210x.c is also used by nseries, so move its MAINTAINER file
3
Inline pickNaNMulAdd into its only caller. This makes
5
line there; the nseries boards are also about to be removed.)
4
one assert redundant with the immediately preceding IF.
6
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]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20240903160751.4100218-9-peter.maydell@linaro.org
9
---
11
---
10
MAINTAINERS | 10 +-
12
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
11
docs/system/arm/palm.rst | 23 --
13
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
12
docs/system/target-arm.rst | 1 -
14
2 files changed, 40 insertions(+), 55 deletions(-)
13
configs/devices/arm-softmmu/default.mak | 1 -
14
hw/arm/palm.c | 324 ------------------------
15
hw/arm/Kconfig | 7 -
16
hw/arm/meson.build | 1 -
17
7 files changed, 1 insertion(+), 366 deletions(-)
18
delete mode 100644 docs/system/arm/palm.rst
19
delete mode 100644 hw/arm/palm.c
20
15
21
diff --git a/MAINTAINERS b/MAINTAINERS
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/MAINTAINERS
18
--- a/fpu/softfloat-parts.c.inc
24
+++ b/MAINTAINERS
19
+++ b/fpu/softfloat-parts.c.inc
25
@@ -XXX,XX +XXX,XX @@ F: hw/arm/nseries.c
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
26
F: hw/display/blizzard.c
21
}
27
F: hw/input/lm832x.c
22
28
F: hw/input/tsc2005.c
23
if (s->default_nan_mode) {
29
+F: hw/input/tsc210x.c
24
+ /*
30
F: hw/misc/cbus.c
25
+ * We guarantee not to require the target to tell us how to
31
F: hw/rtc/twl92230.c
26
+ * pick a NaN if we're always returning the default NaN.
32
F: include/hw/display/blizzard.h
27
+ * But if we're not in default-NaN mode then the target must
33
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/cbus.h
28
+ * specify.
34
F: tests/avocado/machine_arm_n8x0.py
29
+ */
35
F: docs/system/arm/nseries.rst
30
which = 3;
36
31
+ } else if (infzero) {
37
-Palm
32
+ /*
38
-M: Peter Maydell <peter.maydell@linaro.org>
33
+ * Inf * 0 + NaN -- some implementations return the
39
-L: qemu-arm@nongnu.org
34
+ * default NaN here, and some return the input NaN.
40
-S: Odd Fixes
35
+ */
41
-F: hw/arm/palm.c
36
+ switch (s->float_infzeronan_rule) {
42
-F: hw/input/tsc210x.c
37
+ case float_infzeronan_dnan_never:
43
-F: include/hw/input/tsc2xxx.h
38
+ which = 2;
44
-F: docs/system/arm/palm.rst
39
+ break;
40
+ case float_infzeronan_dnan_always:
41
+ which = 3;
42
+ break;
43
+ case float_infzeronan_dnan_if_qnan:
44
+ which = is_qnan(c->cls) ? 3 : 2;
45
+ break;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
} else {
50
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
51
+ FloatClass cls[3] = { a->cls, b->cls, c->cls };
52
+ Float3NaNPropRule rule = s->float_3nan_prop_rule;
53
+
54
+ assert(rule != float_3nan_prop_none);
55
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
56
+ /* We have at least one SNaN input and should prefer it */
57
+ do {
58
+ which = rule & R_3NAN_1ST_MASK;
59
+ rule >>= R_3NAN_1ST_LENGTH;
60
+ } while (!is_snan(cls[which]));
61
+ } else {
62
+ do {
63
+ which = rule & R_3NAN_1ST_MASK;
64
+ rule >>= R_3NAN_1ST_LENGTH;
65
+ } while (!is_nan(cls[which]));
66
+ }
67
}
68
69
if (which == 3) {
70
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
71
index XXXXXXX..XXXXXXX 100644
72
--- a/fpu/softfloat-specialize.c.inc
73
+++ b/fpu/softfloat-specialize.c.inc
74
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
75
}
76
}
77
78
-/*----------------------------------------------------------------------------
79
-| Select which NaN to propagate for a three-input operation.
80
-| For the moment we assume that no CPU needs the 'larger significand'
81
-| information.
82
-| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
83
-*----------------------------------------------------------------------------*/
84
-static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
85
- bool infzero, bool have_snan, float_status *status)
86
-{
87
- FloatClass cls[3] = { a_cls, b_cls, c_cls };
88
- Float3NaNPropRule rule = status->float_3nan_prop_rule;
89
- int which;
45
-
90
-
46
Raspberry Pi
91
- /*
47
M: Peter Maydell <peter.maydell@linaro.org>
92
- * We guarantee not to require the target to tell us how to
48
R: Philippe Mathieu-Daudé <philmd@linaro.org>
93
- * pick a NaN if we're always returning the default NaN.
49
diff --git a/docs/system/arm/palm.rst b/docs/system/arm/palm.rst
94
- * But if we're not in default-NaN mode then the target must
50
deleted file mode 100644
95
- * specify.
51
index XXXXXXX..XXXXXXX
96
- */
52
--- a/docs/system/arm/palm.rst
97
- assert(!status->default_nan_mode);
53
+++ /dev/null
54
@@ -XXX,XX +XXX,XX @@
55
-Palm Tungsten|E PDA (``cheetah``)
56
-=================================
57
-
98
-
58
-The Palm Tungsten|E PDA (codename \"Cheetah\") emulation includes the
99
- if (infzero) {
59
-following elements:
100
- /*
60
-
101
- * Inf * 0 + NaN -- some implementations return the default NaN here,
61
-- Texas Instruments OMAP310 System-on-chip (ARM925T core)
102
- * and some return the input NaN.
62
-
103
- */
63
-- ROM and RAM memories (ROM firmware image can be loaded with
104
- switch (status->float_infzeronan_rule) {
64
- -option-rom)
105
- case float_infzeronan_dnan_never:
65
-
106
- return 2;
66
-- On-chip LCD controller
107
- case float_infzeronan_dnan_always:
67
-
108
- return 3;
68
-- On-chip Real Time Clock
109
- case float_infzeronan_dnan_if_qnan:
69
-
110
- return is_qnan(c_cls) ? 3 : 2;
70
-- TI TSC2102i touchscreen controller / analog-digital converter /
111
- default:
71
- Audio CODEC, connected through MicroWire and |I2S| buses
112
- g_assert_not_reached();
72
-
73
-- GPIO-connected matrix keypad
74
-
75
-- Secure Digital card connected to OMAP MMC/SD host
76
-
77
-- Three on-chip UARTs
78
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
79
index XXXXXXX..XXXXXXX 100644
80
--- a/docs/system/target-arm.rst
81
+++ b/docs/system/target-arm.rst
82
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
83
arm/nuvoton
84
arm/imx25-pdk
85
arm/orangepi
86
- arm/palm
87
arm/raspi
88
arm/collie
89
arm/sx1
90
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
91
index XXXXXXX..XXXXXXX 100644
92
--- a/configs/devices/arm-softmmu/default.mak
93
+++ b/configs/devices/arm-softmmu/default.mak
94
@@ -XXX,XX +XXX,XX @@
95
# CONFIG_MUSICPAL=n
96
# CONFIG_MPS3R=n
97
# CONFIG_MUSCA=n
98
-# CONFIG_CHEETAH=n
99
# CONFIG_SX1=n
100
# CONFIG_NSERIES=n
101
# CONFIG_STELLARIS=n
102
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
103
deleted file mode 100644
104
index XXXXXXX..XXXXXXX
105
--- a/hw/arm/palm.c
106
+++ /dev/null
107
@@ -XXX,XX +XXX,XX @@
108
-/*
109
- * PalmOne's (TM) PDAs.
110
- *
111
- * Copyright (C) 2006-2007 Andrzej Zaborowski <balrog@zabor.org>
112
- *
113
- * This program is free software; you can redistribute it and/or
114
- * modify it under the terms of the GNU General Public License as
115
- * published by the Free Software Foundation; either version 2 or
116
- * (at your option) version 3 of the License.
117
- *
118
- * This program is distributed in the hope that it will be useful,
119
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
120
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
121
- * GNU General Public License for more details.
122
- *
123
- * You should have received a copy of the GNU General Public License along
124
- * with this program; if not, see <http://www.gnu.org/licenses/>.
125
- */
126
-
127
-#include "qemu/osdep.h"
128
-#include "qapi/error.h"
129
-#include "audio/audio.h"
130
-#include "sysemu/sysemu.h"
131
-#include "sysemu/qtest.h"
132
-#include "ui/console.h"
133
-#include "hw/arm/omap.h"
134
-#include "hw/boards.h"
135
-#include "hw/arm/boot.h"
136
-#include "hw/input/tsc2xxx.h"
137
-#include "hw/irq.h"
138
-#include "hw/loader.h"
139
-#include "qemu/cutils.h"
140
-#include "qom/object.h"
141
-#include "qemu/error-report.h"
142
-
143
-
144
-static uint64_t static_read(void *opaque, hwaddr offset, unsigned size)
145
-{
146
- uint32_t *val = (uint32_t *)opaque;
147
- uint32_t sizemask = 7 >> size;
148
-
149
- return *val >> ((offset & sizemask) << 3);
150
-}
151
-
152
-static void static_write(void *opaque, hwaddr offset, uint64_t value,
153
- unsigned size)
154
-{
155
-#ifdef SPY
156
- printf("%s: value %08lx written at " PA_FMT "\n",
157
- __func__, value, offset);
158
-#endif
159
-}
160
-
161
-static const MemoryRegionOps static_ops = {
162
- .read = static_read,
163
- .write = static_write,
164
- .valid.min_access_size = 1,
165
- .valid.max_access_size = 4,
166
- .endianness = DEVICE_NATIVE_ENDIAN,
167
-};
168
-
169
-/* Palm Tunsgten|E support */
170
-
171
-/* Shared GPIOs */
172
-#define PALMTE_USBDETECT_GPIO 0
173
-#define PALMTE_USB_OR_DC_GPIO 1
174
-#define PALMTE_TSC_GPIO 4
175
-#define PALMTE_PINTDAV_GPIO 6
176
-#define PALMTE_MMC_WP_GPIO 8
177
-#define PALMTE_MMC_POWER_GPIO 9
178
-#define PALMTE_HDQ_GPIO 11
179
-#define PALMTE_HEADPHONES_GPIO 14
180
-#define PALMTE_SPEAKER_GPIO 15
181
-/* MPU private GPIOs */
182
-#define PALMTE_DC_GPIO 2
183
-#define PALMTE_MMC_SWITCH_GPIO 4
184
-#define PALMTE_MMC1_GPIO 6
185
-#define PALMTE_MMC2_GPIO 7
186
-#define PALMTE_MMC3_GPIO 11
187
-
188
-static MouseTransformInfo palmte_pointercal = {
189
- .x = 320,
190
- .y = 320,
191
- .a = { -5909, 8, 22465308, 104, 7644, -1219972, 65536 },
192
-};
193
-
194
-static void palmte_microwire_setup(struct omap_mpu_state_s *cpu)
195
-{
196
- uWireSlave *tsc;
197
-
198
- tsc = tsc2102_init(qdev_get_gpio_in(cpu->gpio, PALMTE_PINTDAV_GPIO));
199
-
200
- omap_uwire_attach(cpu->microwire, tsc, 0);
201
- omap_mcbsp_i2s_attach(cpu->mcbsp1, tsc210x_codec(tsc));
202
-
203
- tsc210x_set_transform(tsc, &palmte_pointercal);
204
-}
205
-
206
-static struct {
207
- int row;
208
- int column;
209
-} palmte_keymap[0x80] = {
210
- [0 ... 0x7f] = { -1, -1 },
211
- [0x3b] = { 0, 0 }, /* F1 -> Calendar */
212
- [0x3c] = { 1, 0 }, /* F2 -> Contacts */
213
- [0x3d] = { 2, 0 }, /* F3 -> Tasks List */
214
- [0x3e] = { 3, 0 }, /* F4 -> Note Pad */
215
- [0x01] = { 4, 0 }, /* Esc -> Power */
216
- [0x4b] = { 0, 1 }, /* Left */
217
- [0x50] = { 1, 1 }, /* Down */
218
- [0x48] = { 2, 1 }, /* Up */
219
- [0x4d] = { 3, 1 }, /* Right */
220
- [0x4c] = { 4, 1 }, /* Centre */
221
- [0x39] = { 4, 1 }, /* Spc -> Centre */
222
-};
223
-
224
-static void palmte_button_event(void *opaque, int keycode)
225
-{
226
- struct omap_mpu_state_s *cpu = opaque;
227
-
228
- if (palmte_keymap[keycode & 0x7f].row != -1)
229
- omap_mpuio_key(cpu->mpuio,
230
- palmte_keymap[keycode & 0x7f].row,
231
- palmte_keymap[keycode & 0x7f].column,
232
- !(keycode & 0x80));
233
-}
234
-
235
-/*
236
- * Encapsulation of some GPIO line behaviour for the Palm board
237
- *
238
- * QEMU interface:
239
- * + unnamed GPIO inputs 0..6: for the various miscellaneous input lines
240
- */
241
-
242
-#define TYPE_PALM_MISC_GPIO "palm-misc-gpio"
243
-OBJECT_DECLARE_SIMPLE_TYPE(PalmMiscGPIOState, PALM_MISC_GPIO)
244
-
245
-struct PalmMiscGPIOState {
246
- SysBusDevice parent_obj;
247
-};
248
-
249
-static void palmte_onoff_gpios(void *opaque, int line, int level)
250
-{
251
- switch (line) {
252
- case 0:
253
- printf("%s: current to MMC/SD card %sabled.\n",
254
- __func__, level ? "dis" : "en");
255
- break;
256
- case 1:
257
- printf("%s: internal speaker amplifier %s.\n",
258
- __func__, level ? "down" : "on");
259
- break;
260
-
261
- /* These LCD & Audio output signals have not been identified yet. */
262
- case 2:
263
- case 3:
264
- case 4:
265
- printf("%s: LCD GPIO%i %s.\n",
266
- __func__, line - 1, level ? "high" : "low");
267
- break;
268
- case 5:
269
- case 6:
270
- printf("%s: Audio GPIO%i %s.\n",
271
- __func__, line - 4, level ? "high" : "low");
272
- break;
273
- }
274
-}
275
-
276
-static void palm_misc_gpio_init(Object *obj)
277
-{
278
- DeviceState *dev = DEVICE(obj);
279
-
280
- qdev_init_gpio_in(dev, palmte_onoff_gpios, 7);
281
-}
282
-
283
-static const TypeInfo palm_misc_gpio_info = {
284
- .name = TYPE_PALM_MISC_GPIO,
285
- .parent = TYPE_SYS_BUS_DEVICE,
286
- .instance_size = sizeof(PalmMiscGPIOState),
287
- .instance_init = palm_misc_gpio_init,
288
- /*
289
- * No class init required: device has no internal state so does not
290
- * need to set up reset or vmstate, and has no realize method.
291
- */
292
-};
293
-
294
-static void palmte_gpio_setup(struct omap_mpu_state_s *cpu)
295
-{
296
- DeviceState *misc_gpio;
297
-
298
- misc_gpio = sysbus_create_simple(TYPE_PALM_MISC_GPIO, -1, NULL);
299
-
300
- omap_mmc_handlers(cpu->mmc,
301
- qdev_get_gpio_in(cpu->gpio, PALMTE_MMC_WP_GPIO),
302
- qemu_irq_invert(omap_mpuio_in_get(cpu->mpuio)
303
- [PALMTE_MMC_SWITCH_GPIO]));
304
-
305
- qdev_connect_gpio_out(cpu->gpio, PALMTE_MMC_POWER_GPIO,
306
- qdev_get_gpio_in(misc_gpio, 0));
307
- qdev_connect_gpio_out(cpu->gpio, PALMTE_SPEAKER_GPIO,
308
- qdev_get_gpio_in(misc_gpio, 1));
309
- qdev_connect_gpio_out(cpu->gpio, 11, qdev_get_gpio_in(misc_gpio, 2));
310
- qdev_connect_gpio_out(cpu->gpio, 12, qdev_get_gpio_in(misc_gpio, 3));
311
- qdev_connect_gpio_out(cpu->gpio, 13, qdev_get_gpio_in(misc_gpio, 4));
312
- omap_mpuio_out_set(cpu->mpuio, 1, qdev_get_gpio_in(misc_gpio, 5));
313
- omap_mpuio_out_set(cpu->mpuio, 3, qdev_get_gpio_in(misc_gpio, 6));
314
-
315
- /* Reset some inputs to initial state. */
316
- qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_USBDETECT_GPIO));
317
- qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_USB_OR_DC_GPIO));
318
- qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, 4));
319
- qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_HEADPHONES_GPIO));
320
- qemu_irq_lower(omap_mpuio_in_get(cpu->mpuio)[PALMTE_DC_GPIO]);
321
- qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[6]);
322
- qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[7]);
323
- qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[11]);
324
-}
325
-
326
-static struct arm_boot_info palmte_binfo = {
327
- .loader_start = OMAP_EMIFF_BASE,
328
- .ram_size = 0x02000000,
329
- .board_id = 0x331,
330
-};
331
-
332
-static void palmte_init(MachineState *machine)
333
-{
334
- MemoryRegion *address_space_mem = get_system_memory();
335
- struct omap_mpu_state_s *mpu;
336
- int flash_size = 0x00800000;
337
- static uint32_t cs0val = 0xffffffff;
338
- static uint32_t cs1val = 0x0000e1a0;
339
- static uint32_t cs2val = 0x0000e1a0;
340
- static uint32_t cs3val = 0xe1a0e1a0;
341
- int rom_size, rom_loaded = 0;
342
- MachineClass *mc = MACHINE_GET_CLASS(machine);
343
- MemoryRegion *flash = g_new(MemoryRegion, 1);
344
- MemoryRegion *cs = g_new(MemoryRegion, 4);
345
-
346
- if (machine->ram_size != mc->default_ram_size) {
347
- char *sz = size_to_str(mc->default_ram_size);
348
- error_report("Invalid RAM size, should be %s", sz);
349
- g_free(sz);
350
- exit(EXIT_FAILURE);
351
- }
352
-
353
- memory_region_add_subregion(address_space_mem, OMAP_EMIFF_BASE,
354
- machine->ram);
355
-
356
- mpu = omap310_mpu_init(machine->ram, machine->cpu_type);
357
-
358
- /* External Flash (EMIFS) */
359
- memory_region_init_rom(flash, NULL, "palmte.flash", flash_size,
360
- &error_fatal);
361
- memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash);
362
-
363
- memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val, "palmte-cs0",
364
- OMAP_CS0_SIZE - flash_size);
365
- memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE + flash_size,
366
- &cs[0]);
367
- memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val, "palmte-cs1",
368
- OMAP_CS1_SIZE);
369
- memory_region_add_subregion(address_space_mem, OMAP_CS1_BASE, &cs[1]);
370
- memory_region_init_io(&cs[2], NULL, &static_ops, &cs2val, "palmte-cs2",
371
- OMAP_CS2_SIZE);
372
- memory_region_add_subregion(address_space_mem, OMAP_CS2_BASE, &cs[2]);
373
- memory_region_init_io(&cs[3], NULL, &static_ops, &cs3val, "palmte-cs3",
374
- OMAP_CS3_SIZE);
375
- memory_region_add_subregion(address_space_mem, OMAP_CS3_BASE, &cs[3]);
376
-
377
- palmte_microwire_setup(mpu);
378
-
379
- qemu_add_kbd_event_handler(palmte_button_event, mpu);
380
-
381
- palmte_gpio_setup(mpu);
382
-
383
- /* Setup initial (reset) machine state */
384
- if (nb_option_roms) {
385
- rom_size = get_image_size(option_rom[0].name);
386
- if (rom_size > flash_size) {
387
- fprintf(stderr, "%s: ROM image too big (%x > %x)\n",
388
- __func__, rom_size, flash_size);
389
- rom_size = 0;
390
- }
391
- if (rom_size > 0) {
392
- rom_size = load_image_targphys(option_rom[0].name, OMAP_CS0_BASE,
393
- flash_size);
394
- rom_loaded = 1;
395
- }
396
- if (rom_size < 0) {
397
- fprintf(stderr, "%s: error loading '%s'\n",
398
- __func__, option_rom[0].name);
399
- }
113
- }
400
- }
114
- }
401
-
115
-
402
- if (!rom_loaded && !machine->kernel_filename && !qtest_enabled()) {
116
- assert(rule != float_3nan_prop_none);
403
- fprintf(stderr, "Kernel or ROM image must be specified\n");
117
- if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
404
- exit(1);
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]));
405
- }
128
- }
406
-
129
- return which;
407
- /* Load the kernel. */
408
- arm_load_kernel(mpu->cpu, machine, &palmte_binfo);
409
-}
130
-}
410
-
131
-
411
-static void palmte_machine_init(MachineClass *mc)
132
/*----------------------------------------------------------------------------
412
-{
133
| Returns 1 if the double-precision floating-point value `a' is a quiet
413
- mc->desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)";
134
| NaN; otherwise returns 0.
414
- mc->init = palmte_init;
415
- mc->ignore_memory_transaction_failures = true;
416
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("ti925t");
417
- mc->default_ram_size = 0x02000000;
418
- mc->default_ram_id = "omap1.dram";
419
- mc->deprecation_reason = "machine is old and unmaintained";
420
-
421
- machine_add_audiodev_property(mc);
422
-}
423
-
424
-DEFINE_MACHINE("cheetah", palmte_machine_init)
425
-
426
-static void palm_register_types(void)
427
-{
428
- type_register_static(&palm_misc_gpio_info);
429
-}
430
-
431
-type_init(palm_register_types)
432
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
433
index XXXXXXX..XXXXXXX 100644
434
--- a/hw/arm/Kconfig
435
+++ b/hw/arm/Kconfig
436
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
437
select ACPI_CXL
438
select ACPI_HMAT
439
440
-config CHEETAH
441
- bool
442
- default y
443
- depends on TCG && ARM
444
- select OMAP
445
- select TSC210X
446
-
447
config CUBIEBOARD
448
bool
449
default y
450
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
451
index XXXXXXX..XXXXXXX 100644
452
--- a/hw/arm/meson.build
453
+++ b/hw/arm/meson.build
454
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_XEN', if_true: files(
455
))
456
457
system_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c'))
458
-system_ss.add(when: 'CONFIG_CHEETAH', if_true: files('palm.c'))
459
system_ss.add(when: 'CONFIG_COLLIE', if_true: files('collie.c'))
460
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4_boards.c'))
461
system_ss.add(when: 'CONFIG_GUMSTIX', if_true: files('gumstix.c'))
462
--
135
--
463
2.34.1
136
2.34.1
464
137
465
138
diff view generated by jsdifflib
1
The 'mainstone' machine has been deprecated since 9.0, and
1
From: Richard Henderson <richard.henderson@linaro.org>
2
so we can remove it for the 9.2 release.
3
2
3
Remove "3" as a special case for which and simply
4
branch to return the desired value.
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-4-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20240903160751.4100218-11-peter.maydell@linaro.org
7
---
10
---
8
MAINTAINERS | 2 -
11
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
9
docs/system/arm/mainstone.rst | 25 ----
12
1 file changed, 10 insertions(+), 10 deletions(-)
10
docs/system/target-arm.rst | 1 -
11
configs/devices/arm-softmmu/default.mak | 1 -
12
hw/arm/mainstone.c | 175 ------------------------
13
hw/arm/Kconfig | 8 --
14
hw/arm/meson.build | 1 -
15
7 files changed, 213 deletions(-)
16
delete mode 100644 docs/system/arm/mainstone.rst
17
delete mode 100644 hw/arm/mainstone.c
18
13
19
diff --git a/MAINTAINERS b/MAINTAINERS
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/MAINTAINERS
16
--- a/fpu/softfloat-parts.c.inc
22
+++ b/MAINTAINERS
17
+++ b/fpu/softfloat-parts.c.inc
23
@@ -XXX,XX +XXX,XX @@ PXA2XX
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
24
M: Peter Maydell <peter.maydell@linaro.org>
19
* But if we're not in default-NaN mode then the target must
25
L: qemu-arm@nongnu.org
20
* specify.
26
S: Odd Fixes
21
*/
27
-F: hw/arm/mainstone.c
22
- which = 3;
28
F: hw/arm/z2.c
23
+ goto default_nan;
29
F: hw/*/pxa2xx*
24
} else if (infzero) {
30
F: hw/gpio/max7310.c
25
/*
31
@@ -XXX,XX +XXX,XX @@ F: hw/misc/mst_fpga.c
26
* Inf * 0 + NaN -- some implementations return the
32
F: hw/adc/max111x.c
27
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
33
F: include/hw/adc/max111x.h
28
*/
34
F: include/hw/arm/pxa.h
29
switch (s->float_infzeronan_rule) {
35
-F: docs/system/arm/mainstone.rst
30
case float_infzeronan_dnan_never:
36
31
- which = 2;
37
SABRELITE / i.MX6
32
break;
38
M: Peter Maydell <peter.maydell@linaro.org>
33
case float_infzeronan_dnan_always:
39
diff --git a/docs/system/arm/mainstone.rst b/docs/system/arm/mainstone.rst
34
- which = 3;
40
deleted file mode 100644
35
- break;
41
index XXXXXXX..XXXXXXX
36
+ goto default_nan;
42
--- a/docs/system/arm/mainstone.rst
37
case float_infzeronan_dnan_if_qnan:
43
+++ /dev/null
38
- which = is_qnan(c->cls) ? 3 : 2;
44
@@ -XXX,XX +XXX,XX @@
39
+ if (is_qnan(c->cls)) {
45
-Intel Mainstone II board (``mainstone``)
40
+ goto default_nan;
46
-========================================
41
+ }
47
-
42
break;
48
-The ``mainstone`` board emulates the Intel Mainstone II development
43
default:
49
-board, which uses a PXA270 CPU.
44
g_assert_not_reached();
50
-
45
}
51
-Emulated devices:
46
+ which = 2;
52
-
47
} else {
53
-- Flash memory
48
FloatClass cls[3] = { a->cls, b->cls, c->cls };
54
-- Keypad
49
Float3NaNPropRule rule = s->float_3nan_prop_rule;
55
-- MMC controller
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
56
-- 91C111 ethernet
51
}
57
-- PIC
52
}
58
-- Timer
53
59
-- DMA
54
- if (which == 3) {
60
-- GPIO
55
- parts_default_nan(a, s);
61
-- FIR
56
- return a;
62
-- Serial
63
-- LCD controller
64
-- SSP
65
-- USB controller
66
-- RTC
67
-- PCMCIA
68
-- I2C
69
-- I2S
70
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
71
index XXXXXXX..XXXXXXX 100644
72
--- a/docs/system/target-arm.rst
73
+++ b/docs/system/target-arm.rst
74
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
75
arm/cubieboard
76
arm/emcraft-sf2
77
arm/musicpal
78
- arm/mainstone
79
arm/kzm
80
arm/nseries
81
arm/nrf
82
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
83
index XXXXXXX..XXXXXXX 100644
84
--- a/configs/devices/arm-softmmu/default.mak
85
+++ b/configs/devices/arm-softmmu/default.mak
86
@@ -XXX,XX +XXX,XX @@
87
# CONFIG_VERSATILE=n
88
# CONFIG_VEXPRESS=n
89
# CONFIG_ZYNQ=n
90
-# CONFIG_MAINSTONE=n
91
# CONFIG_Z2=n
92
# CONFIG_NPCM7XX=n
93
# CONFIG_COLLIE=n
94
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
95
deleted file mode 100644
96
index XXXXXXX..XXXXXXX
97
--- a/hw/arm/mainstone.c
98
+++ /dev/null
99
@@ -XXX,XX +XXX,XX @@
100
-/*
101
- * PXA270-based Intel Mainstone platforms.
102
- *
103
- * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or
104
- * <akuster@mvista.com>
105
- *
106
- * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org>
107
- *
108
- * This code is licensed under the GNU GPL v2.
109
- *
110
- * Contributions after 2012-01-13 are licensed under the terms of the
111
- * GNU GPL, version 2 or (at your option) any later version.
112
- */
113
-#include "qemu/osdep.h"
114
-#include "qemu/units.h"
115
-#include "qemu/error-report.h"
116
-#include "qapi/error.h"
117
-#include "hw/arm/pxa.h"
118
-#include "hw/arm/boot.h"
119
-#include "net/net.h"
120
-#include "hw/net/smc91c111.h"
121
-#include "hw/boards.h"
122
-#include "hw/block/flash.h"
123
-#include "hw/sysbus.h"
124
-#include "exec/address-spaces.h"
125
-
126
-/* Device addresses */
127
-#define MST_FPGA_PHYS    0x08000000
128
-#define MST_ETH_PHYS    0x10000300
129
-#define MST_FLASH_0        0x00000000
130
-#define MST_FLASH_1        0x04000000
131
-
132
-/* IRQ definitions */
133
-#define MMC_IRQ 0
134
-#define USIM_IRQ 1
135
-#define USBC_IRQ 2
136
-#define ETHERNET_IRQ 3
137
-#define AC97_IRQ 4
138
-#define PEN_IRQ 5
139
-#define MSINS_IRQ 6
140
-#define EXBRD_IRQ 7
141
-#define S0_CD_IRQ 9
142
-#define S0_STSCHG_IRQ 10
143
-#define S0_IRQ 11
144
-#define S1_CD_IRQ 13
145
-#define S1_STSCHG_IRQ 14
146
-#define S1_IRQ 15
147
-
148
-static const struct keymap map[0xE0] = {
149
- [0 ... 0xDF] = { -1, -1 },
150
- [0x1e] = {0,0}, /* a */
151
- [0x30] = {0,1}, /* b */
152
- [0x2e] = {0,2}, /* c */
153
- [0x20] = {0,3}, /* d */
154
- [0x12] = {0,4}, /* e */
155
- [0x21] = {0,5}, /* f */
156
- [0x22] = {1,0}, /* g */
157
- [0x23] = {1,1}, /* h */
158
- [0x17] = {1,2}, /* i */
159
- [0x24] = {1,3}, /* j */
160
- [0x25] = {1,4}, /* k */
161
- [0x26] = {1,5}, /* l */
162
- [0x32] = {2,0}, /* m */
163
- [0x31] = {2,1}, /* n */
164
- [0x18] = {2,2}, /* o */
165
- [0x19] = {2,3}, /* p */
166
- [0x10] = {2,4}, /* q */
167
- [0x13] = {2,5}, /* r */
168
- [0x1f] = {3,0}, /* s */
169
- [0x14] = {3,1}, /* t */
170
- [0x16] = {3,2}, /* u */
171
- [0x2f] = {3,3}, /* v */
172
- [0x11] = {3,4}, /* w */
173
- [0x2d] = {3,5}, /* x */
174
- [0x34] = {4,0}, /* . */
175
- [0x15] = {4,2}, /* y */
176
- [0x2c] = {4,3}, /* z */
177
- [0x35] = {4,4}, /* / */
178
- [0xc7] = {5,0}, /* Home */
179
- [0x2a] = {5,1}, /* shift */
180
- /*
181
- * There are two matrix positions which map to space,
182
- * but QEMU can only use one of them for the reverse
183
- * mapping, so simply use the second one.
184
- */
185
- /* [0x39] = {5,2}, space */
186
- [0x39] = {5,3}, /* space */
187
- /*
188
- * Matrix position {5,4} and other keys are missing here.
189
- * TODO: Compare with Linux code and test real hardware.
190
- */
191
- [0x1c] = {5,4}, /* enter */
192
- [0x0e] = {5,5}, /* backspace */
193
- [0xc8] = {6,0}, /* up */
194
- [0xd0] = {6,1}, /* down */
195
- [0xcb] = {6,2}, /* left */
196
- [0xcd] = {6,3}, /* right */
197
-};
198
-
199
-enum mainstone_model_e { mainstone };
200
-
201
-#define MAINSTONE_RAM_SIZE (64 * MiB)
202
-#define MAINSTONE_ROM_SIZE (8 * MiB)
203
-#define MAINSTONE_FLASH_SIZE (32 * MiB)
204
-
205
-static struct arm_boot_info mainstone_binfo = {
206
- .loader_start = PXA2XX_SDRAM_BASE,
207
- .ram_size = MAINSTONE_RAM_SIZE,
208
-};
209
-
210
-#define FLASH_SECTOR_SIZE (256 * KiB)
211
-
212
-static void mainstone_common_init(MachineState *machine,
213
- enum mainstone_model_e model, int arm_id)
214
-{
215
- hwaddr mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 };
216
- PXA2xxState *mpu;
217
- DeviceState *mst_irq;
218
- DriveInfo *dinfo;
219
- int i;
220
- MemoryRegion *rom = g_new(MemoryRegion, 1);
221
-
222
- /* Setup CPU & memory */
223
- mpu = pxa270_init(mainstone_binfo.ram_size, machine->cpu_type);
224
- memory_region_init_rom(rom, NULL, "mainstone.rom", MAINSTONE_ROM_SIZE,
225
- &error_fatal);
226
- memory_region_add_subregion(get_system_memory(), 0x00000000, rom);
227
-
228
- /* There are two 32MiB flash devices on the board */
229
- for (i = 0; i < 2; i ++) {
230
- dinfo = drive_get(IF_PFLASH, 0, i);
231
- pflash_cfi01_register(mainstone_flash_base[i],
232
- i ? "mainstone.flash1" : "mainstone.flash0",
233
- MAINSTONE_FLASH_SIZE,
234
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
235
- FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0);
236
- }
57
- }
237
-
58
-
238
- mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS,
59
switch (which) {
239
- qdev_get_gpio_in(mpu->gpio, 0));
60
case 0:
240
-
61
break;
241
- /* setup keypad */
62
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
242
- pxa27x_register_keypad(mpu->kp, map, 0xe0);
63
parts_silence_nan(a, s);
243
-
64
}
244
- /* MMC/SD host */
65
return a;
245
- pxa2xx_mmci_handlers(mpu->mmc, NULL, qdev_get_gpio_in(mst_irq, MMC_IRQ));
66
+
246
-
67
+ default_nan:
247
- pxa2xx_pcmcia_set_irq_cb(mpu->pcmcia[0],
68
+ parts_default_nan(a, s);
248
- qdev_get_gpio_in(mst_irq, S0_IRQ),
69
+ return a;
249
- qdev_get_gpio_in(mst_irq, S0_CD_IRQ));
70
}
250
- pxa2xx_pcmcia_set_irq_cb(mpu->pcmcia[1],
71
251
- qdev_get_gpio_in(mst_irq, S1_IRQ),
72
/*
252
- qdev_get_gpio_in(mst_irq, S1_CD_IRQ));
253
-
254
- smc91c111_init(MST_ETH_PHYS, qdev_get_gpio_in(mst_irq, ETHERNET_IRQ));
255
-
256
- mainstone_binfo.board_id = arm_id;
257
- arm_load_kernel(mpu->cpu, machine, &mainstone_binfo);
258
-}
259
-
260
-static void mainstone_init(MachineState *machine)
261
-{
262
- mainstone_common_init(machine, mainstone, 0x196);
263
-}
264
-
265
-static void mainstone2_machine_init(MachineClass *mc)
266
-{
267
- mc->desc = "Mainstone II (PXA27x)";
268
- mc->init = mainstone_init;
269
- mc->ignore_memory_transaction_failures = true;
270
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c5");
271
- mc->deprecation_reason = "machine is old and unmaintained";
272
-}
273
-
274
-DEFINE_MACHINE("mainstone", mainstone2_machine_init)
275
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
276
index XXXXXXX..XXXXXXX 100644
277
--- a/hw/arm/Kconfig
278
+++ b/hw/arm/Kconfig
279
@@ -XXX,XX +XXX,XX @@ config INTEGRATOR
280
select PL181 # display
281
select SMC91C111
282
283
-config MAINSTONE
284
- bool
285
- default y
286
- depends on TCG && ARM
287
- select PXA2XX
288
- select PFLASH_CFI01
289
- select SMC91C111
290
-
291
config MPS3R
292
bool
293
default y
294
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
295
index XXXXXXX..XXXXXXX 100644
296
--- a/hw/arm/meson.build
297
+++ b/hw/arm/meson.build
298
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic_boards.c'))
299
arm_ss.add(when: 'CONFIG_EMCRAFT_SF2', if_true: files('msf2-som.c'))
300
arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
301
arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
302
-arm_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mainstone.c'))
303
arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
304
arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c'))
305
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
306
--
73
--
307
2.34.1
74
2.34.1
308
75
309
76
diff view generated by jsdifflib
1
The users of the OMAP2 SoC emulation have been removed, so we can
1
From: Richard Henderson <richard.henderson@linaro.org>
2
delete omap2.c.
3
2
3
Assign the pointer return value to 'a' directly,
4
rather than going through an intermediary index.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240903160751.4100218-38-peter.maydell@linaro.org
8
---
10
---
9
include/hw/arm/omap.h | 8 -
11
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
10
hw/arm/omap2.c | 2715 -----------------------------------------
12
1 file changed, 10 insertions(+), 22 deletions(-)
11
hw/arm/meson.build | 1 -
12
3 files changed, 2724 deletions(-)
13
delete mode 100644 hw/arm/omap2.c
14
13
15
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/omap.h
16
--- a/fpu/softfloat-parts.c.inc
18
+++ b/include/hw/arm/omap.h
17
+++ b/fpu/softfloat-parts.c.inc
19
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s {
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
20
struct omap_gp_timer_s *gptimer[12];
19
FloatPartsN *c, float_status *s,
21
struct omap_synctimer_s *synctimer;
20
int ab_mask, int abc_mask)
22
21
{
23
- struct omap_prcm_s *prcm;
22
- int which;
24
struct omap_sdrc_s *sdrc;
23
bool infzero = (ab_mask == float_cmask_infzero);
25
struct omap_gpmc_s *gpmc;
24
bool have_snan = (abc_mask & float_cmask_snan);
26
- struct omap_sysctl_s *sysc;
25
+ FloatPartsN *ret;
27
26
28
struct omap_mcspi_s *mcspi[2];
27
if (unlikely(have_snan)) {
29
28
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
30
struct omap_dss_s *dss;
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
31
-
30
default:
32
- struct omap_eac_s *eac;
31
g_assert_not_reached();
33
};
32
}
34
33
- which = 2;
35
/* omap1.c */
34
+ ret = c;
36
struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *sdram,
35
} else {
37
const char *core);
36
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
38
37
+ FloatPartsN *val[3] = { a, b, c };
39
-/* omap2.c */
38
Float3NaNPropRule rule = s->float_3nan_prop_rule;
40
-struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sdram,
39
41
- const char *core);
40
assert(rule != float_3nan_prop_none);
42
-
41
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
43
uint32_t omap_badwidth_read8(void *opaque, hwaddr addr);
42
/* We have at least one SNaN input and should prefer it */
44
void omap_badwidth_write8(void *opaque, hwaddr addr,
43
do {
45
uint32_t value);
44
- which = rule & R_3NAN_1ST_MASK;
46
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
45
+ ret = val[rule & R_3NAN_1ST_MASK];
47
deleted file mode 100644
46
rule >>= R_3NAN_1ST_LENGTH;
48
index XXXXXXX..XXXXXXX
47
- } while (!is_snan(cls[which]));
49
--- a/hw/arm/omap2.c
48
+ } while (!is_snan(ret->cls));
50
+++ /dev/null
49
} else {
51
@@ -XXX,XX +XXX,XX @@
50
do {
52
-/*
51
- which = rule & R_3NAN_1ST_MASK;
53
- * TI OMAP processors emulation.
52
+ ret = val[rule & R_3NAN_1ST_MASK];
54
- *
53
rule >>= R_3NAN_1ST_LENGTH;
55
- * Copyright (C) 2007-2008 Nokia Corporation
54
- } while (!is_nan(cls[which]));
56
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
55
+ } while (!is_nan(ret->cls));
57
- *
56
}
58
- * This program is free software; you can redistribute it and/or
57
}
59
- * modify it under the terms of the GNU General Public License as
58
60
- * published by the Free Software Foundation; either version 2 or
59
- switch (which) {
61
- * (at your option) version 3 of the License.
62
- *
63
- * This program is distributed in the hope that it will be useful,
64
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
65
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
66
- * GNU General Public License for more details.
67
- *
68
- * You should have received a copy of the GNU General Public License along
69
- * with this program; if not, see <http://www.gnu.org/licenses/>.
70
- */
71
-
72
-#include "qemu/osdep.h"
73
-#include "qemu/error-report.h"
74
-#include "qapi/error.h"
75
-#include "exec/address-spaces.h"
76
-#include "sysemu/blockdev.h"
77
-#include "sysemu/qtest.h"
78
-#include "sysemu/reset.h"
79
-#include "sysemu/runstate.h"
80
-#include "hw/irq.h"
81
-#include "hw/qdev-properties.h"
82
-#include "hw/arm/boot.h"
83
-#include "hw/arm/omap.h"
84
-#include "sysemu/sysemu.h"
85
-#include "qemu/timer.h"
86
-#include "chardev/char-fe.h"
87
-#include "hw/block/flash.h"
88
-#include "hw/arm/soc_dma.h"
89
-#include "hw/sysbus.h"
90
-#include "hw/boards.h"
91
-#include "audio/audio.h"
92
-#include "target/arm/cpu-qom.h"
93
-
94
-/* Enhanced Audio Controller (CODEC only) */
95
-struct omap_eac_s {
96
- qemu_irq irq;
97
- MemoryRegion iomem;
98
-
99
- uint16_t sysconfig;
100
- uint8_t config[4];
101
- uint8_t control;
102
- uint8_t address;
103
- uint16_t data;
104
- uint8_t vtol;
105
- uint8_t vtsl;
106
- uint16_t mixer;
107
- uint16_t gain[4];
108
- uint8_t att;
109
- uint16_t max[7];
110
-
111
- struct {
112
- qemu_irq txdrq;
113
- qemu_irq rxdrq;
114
- uint32_t (*txrx)(void *opaque, uint32_t, int);
115
- void *opaque;
116
-
117
-#define EAC_BUF_LEN 1024
118
- uint32_t rxbuf[EAC_BUF_LEN];
119
- int rxoff;
120
- int rxlen;
121
- int rxavail;
122
- uint32_t txbuf[EAC_BUF_LEN];
123
- int txlen;
124
- int txavail;
125
-
126
- int enable;
127
- int rate;
128
-
129
- uint16_t config[4];
130
-
131
- /* These need to be moved to the actual codec */
132
- QEMUSoundCard card;
133
- SWVoiceIn *in_voice;
134
- SWVoiceOut *out_voice;
135
- int hw_enable;
136
- } codec;
137
-
138
- struct {
139
- uint8_t control;
140
- uint16_t config;
141
- } modem, bt;
142
-};
143
-
144
-static inline void omap_eac_interrupt_update(struct omap_eac_s *s)
145
-{
146
- qemu_set_irq(s->irq, (s->codec.config[1] >> 14) & 1);    /* AURDI */
147
-}
148
-
149
-static inline void omap_eac_in_dmarequest_update(struct omap_eac_s *s)
150
-{
151
- qemu_set_irq(s->codec.rxdrq, (s->codec.rxavail || s->codec.rxlen) &&
152
- ((s->codec.config[1] >> 12) & 1));        /* DMAREN */
153
-}
154
-
155
-static inline void omap_eac_out_dmarequest_update(struct omap_eac_s *s)
156
-{
157
- qemu_set_irq(s->codec.txdrq, s->codec.txlen < s->codec.txavail &&
158
- ((s->codec.config[1] >> 11) & 1));        /* DMAWEN */
159
-}
160
-
161
-static inline void omap_eac_in_refill(struct omap_eac_s *s)
162
-{
163
- int left = MIN(EAC_BUF_LEN - s->codec.rxlen, s->codec.rxavail) << 2;
164
- int start = ((s->codec.rxoff + s->codec.rxlen) & (EAC_BUF_LEN - 1)) << 2;
165
- int leftwrap = MIN(left, (EAC_BUF_LEN << 2) - start);
166
- int recv = 1;
167
- uint8_t *buf = (uint8_t *) s->codec.rxbuf + start;
168
-
169
- left -= leftwrap;
170
- start = 0;
171
- while (leftwrap && (recv = AUD_read(s->codec.in_voice, buf + start,
172
- leftwrap)) > 0) {    /* Be defensive */
173
- start += recv;
174
- leftwrap -= recv;
175
- }
176
- if (recv <= 0)
177
- s->codec.rxavail = 0;
178
- else
179
- s->codec.rxavail -= start >> 2;
180
- s->codec.rxlen += start >> 2;
181
-
182
- if (recv > 0 && left > 0) {
183
- start = 0;
184
- while (left && (recv = AUD_read(s->codec.in_voice,
185
- (uint8_t *) s->codec.rxbuf + start,
186
- left)) > 0) {    /* Be defensive */
187
- start += recv;
188
- left -= recv;
189
- }
190
- if (recv <= 0)
191
- s->codec.rxavail = 0;
192
- else
193
- s->codec.rxavail -= start >> 2;
194
- s->codec.rxlen += start >> 2;
195
- }
196
-}
197
-
198
-static inline void omap_eac_out_empty(struct omap_eac_s *s)
199
-{
200
- int left = s->codec.txlen << 2;
201
- int start = 0;
202
- int sent = 1;
203
-
204
- while (left && (sent = AUD_write(s->codec.out_voice,
205
- (uint8_t *) s->codec.txbuf + start,
206
- left)) > 0) {    /* Be defensive */
207
- start += sent;
208
- left -= sent;
209
- }
210
-
211
- if (!sent) {
212
- s->codec.txavail = 0;
213
- omap_eac_out_dmarequest_update(s);
214
- }
215
-
216
- if (start)
217
- s->codec.txlen = 0;
218
-}
219
-
220
-static void omap_eac_in_cb(void *opaque, int avail_b)
221
-{
222
- struct omap_eac_s *s = opaque;
223
-
224
- s->codec.rxavail = avail_b >> 2;
225
- omap_eac_in_refill(s);
226
- /* TODO: possibly discard current buffer if overrun */
227
- omap_eac_in_dmarequest_update(s);
228
-}
229
-
230
-static void omap_eac_out_cb(void *opaque, int free_b)
231
-{
232
- struct omap_eac_s *s = opaque;
233
-
234
- s->codec.txavail = free_b >> 2;
235
- if (s->codec.txlen)
236
- omap_eac_out_empty(s);
237
- else
238
- omap_eac_out_dmarequest_update(s);
239
-}
240
-
241
-static void omap_eac_enable_update(struct omap_eac_s *s)
242
-{
243
- s->codec.enable = !(s->codec.config[1] & 1) &&        /* EACPWD */
244
- (s->codec.config[1] & 2) &&                /* AUDEN */
245
- s->codec.hw_enable;
246
-}
247
-
248
-static const int omap_eac_fsint[4] = {
249
- 8000,
250
- 11025,
251
- 22050,
252
- 44100,
253
-};
254
-
255
-static const int omap_eac_fsint2[8] = {
256
- 8000,
257
- 11025,
258
- 22050,
259
- 44100,
260
- 48000,
261
- 0, 0, 0,
262
-};
263
-
264
-static const int omap_eac_fsint3[16] = {
265
- 8000,
266
- 11025,
267
- 16000,
268
- 22050,
269
- 24000,
270
- 32000,
271
- 44100,
272
- 48000,
273
- 0, 0, 0, 0, 0, 0, 0, 0,
274
-};
275
-
276
-static void omap_eac_rate_update(struct omap_eac_s *s)
277
-{
278
- int fsint[3];
279
-
280
- fsint[2] = (s->codec.config[3] >> 9) & 0xf;
281
- fsint[1] = (s->codec.config[2] >> 0) & 0x7;
282
- fsint[0] = (s->codec.config[0] >> 6) & 0x3;
283
- if (fsint[2] < 0xf)
284
- s->codec.rate = omap_eac_fsint3[fsint[2]];
285
- else if (fsint[1] < 0x7)
286
- s->codec.rate = omap_eac_fsint2[fsint[1]];
287
- else
288
- s->codec.rate = omap_eac_fsint[fsint[0]];
289
-}
290
-
291
-static void omap_eac_volume_update(struct omap_eac_s *s)
292
-{
293
- /* TODO */
294
-}
295
-
296
-static void omap_eac_format_update(struct omap_eac_s *s)
297
-{
298
- struct audsettings fmt;
299
-
300
- /* The hardware buffers at most one sample */
301
- if (s->codec.rxlen)
302
- s->codec.rxlen = 1;
303
-
304
- if (s->codec.in_voice) {
305
- AUD_set_active_in(s->codec.in_voice, 0);
306
- AUD_close_in(&s->codec.card, s->codec.in_voice);
307
- s->codec.in_voice = NULL;
308
- }
309
- if (s->codec.out_voice) {
310
- omap_eac_out_empty(s);
311
- AUD_set_active_out(s->codec.out_voice, 0);
312
- AUD_close_out(&s->codec.card, s->codec.out_voice);
313
- s->codec.out_voice = NULL;
314
- s->codec.txavail = 0;
315
- }
316
- /* Discard what couldn't be written */
317
- s->codec.txlen = 0;
318
-
319
- omap_eac_enable_update(s);
320
- if (!s->codec.enable)
321
- return;
322
-
323
- omap_eac_rate_update(s);
324
- fmt.endianness = ((s->codec.config[0] >> 8) & 1);        /* LI_BI */
325
- fmt.nchannels = ((s->codec.config[0] >> 10) & 1) ? 2 : 1;    /* MN_ST */
326
- fmt.freq = s->codec.rate;
327
- /* TODO: signedness possibly depends on the CODEC hardware - or
328
- * does I2S specify it? */
329
- /* All register writes are 16 bits so we store 16-bit samples
330
- * in the buffers regardless of AGCFR[B8_16] value. */
331
- fmt.fmt = AUDIO_FORMAT_U16;
332
-
333
- s->codec.in_voice = AUD_open_in(&s->codec.card, s->codec.in_voice,
334
- "eac.codec.in", s, omap_eac_in_cb, &fmt);
335
- s->codec.out_voice = AUD_open_out(&s->codec.card, s->codec.out_voice,
336
- "eac.codec.out", s, omap_eac_out_cb, &fmt);
337
-
338
- omap_eac_volume_update(s);
339
-
340
- AUD_set_active_in(s->codec.in_voice, 1);
341
- AUD_set_active_out(s->codec.out_voice, 1);
342
-}
343
-
344
-static void omap_eac_reset(struct omap_eac_s *s)
345
-{
346
- s->sysconfig = 0;
347
- s->config[0] = 0x0c;
348
- s->config[1] = 0x09;
349
- s->config[2] = 0xab;
350
- s->config[3] = 0x03;
351
- s->control = 0x00;
352
- s->address = 0x00;
353
- s->data = 0x0000;
354
- s->vtol = 0x00;
355
- s->vtsl = 0x00;
356
- s->mixer = 0x0000;
357
- s->gain[0] = 0xe7e7;
358
- s->gain[1] = 0x6767;
359
- s->gain[2] = 0x6767;
360
- s->gain[3] = 0x6767;
361
- s->att = 0xce;
362
- s->max[0] = 0;
363
- s->max[1] = 0;
364
- s->max[2] = 0;
365
- s->max[3] = 0;
366
- s->max[4] = 0;
367
- s->max[5] = 0;
368
- s->max[6] = 0;
369
-
370
- s->modem.control = 0x00;
371
- s->modem.config = 0x0000;
372
- s->bt.control = 0x00;
373
- s->bt.config = 0x0000;
374
- s->codec.config[0] = 0x0649;
375
- s->codec.config[1] = 0x0000;
376
- s->codec.config[2] = 0x0007;
377
- s->codec.config[3] = 0x1ffc;
378
- s->codec.rxoff = 0;
379
- s->codec.rxlen = 0;
380
- s->codec.txlen = 0;
381
- s->codec.rxavail = 0;
382
- s->codec.txavail = 0;
383
-
384
- omap_eac_format_update(s);
385
- omap_eac_interrupt_update(s);
386
-}
387
-
388
-static uint64_t omap_eac_read(void *opaque, hwaddr addr, unsigned size)
389
-{
390
- struct omap_eac_s *s = opaque;
391
- uint32_t ret;
392
-
393
- if (size != 2) {
394
- return omap_badwidth_read16(opaque, addr);
395
- }
396
-
397
- switch (addr) {
398
- case 0x000:    /* CPCFR1 */
399
- return s->config[0];
400
- case 0x004:    /* CPCFR2 */
401
- return s->config[1];
402
- case 0x008:    /* CPCFR3 */
403
- return s->config[2];
404
- case 0x00c:    /* CPCFR4 */
405
- return s->config[3];
406
-
407
- case 0x010:    /* CPTCTL */
408
- return s->control | ((s->codec.rxavail + s->codec.rxlen > 0) << 7) |
409
- ((s->codec.txlen < s->codec.txavail) << 5);
410
-
411
- case 0x014:    /* CPTTADR */
412
- return s->address;
413
- case 0x018:    /* CPTDATL */
414
- return s->data & 0xff;
415
- case 0x01c:    /* CPTDATH */
416
- return s->data >> 8;
417
- case 0x020:    /* CPTVSLL */
418
- return s->vtol;
419
- case 0x024:    /* CPTVSLH */
420
- return s->vtsl | (3 << 5);    /* CRDY1 | CRDY2 */
421
- case 0x040:    /* MPCTR */
422
- return s->modem.control;
423
- case 0x044:    /* MPMCCFR */
424
- return s->modem.config;
425
- case 0x060:    /* BPCTR */
426
- return s->bt.control;
427
- case 0x064:    /* BPMCCFR */
428
- return s->bt.config;
429
- case 0x080:    /* AMSCFR */
430
- return s->mixer;
431
- case 0x084:    /* AMVCTR */
432
- return s->gain[0];
433
- case 0x088:    /* AM1VCTR */
434
- return s->gain[1];
435
- case 0x08c:    /* AM2VCTR */
436
- return s->gain[2];
437
- case 0x090:    /* AM3VCTR */
438
- return s->gain[3];
439
- case 0x094:    /* ASTCTR */
440
- return s->att;
441
- case 0x098:    /* APD1LCR */
442
- return s->max[0];
443
- case 0x09c:    /* APD1RCR */
444
- return s->max[1];
445
- case 0x0a0:    /* APD2LCR */
446
- return s->max[2];
447
- case 0x0a4:    /* APD2RCR */
448
- return s->max[3];
449
- case 0x0a8:    /* APD3LCR */
450
- return s->max[4];
451
- case 0x0ac:    /* APD3RCR */
452
- return s->max[5];
453
- case 0x0b0:    /* APD4R */
454
- return s->max[6];
455
- case 0x0b4:    /* ADWR */
456
- /* This should be write-only? Docs list it as read-only. */
457
- return 0x0000;
458
- case 0x0b8:    /* ADRDR */
459
- if (likely(s->codec.rxlen > 1)) {
460
- ret = s->codec.rxbuf[s->codec.rxoff ++];
461
- s->codec.rxlen --;
462
- s->codec.rxoff &= EAC_BUF_LEN - 1;
463
- return ret;
464
- } else if (s->codec.rxlen) {
465
- ret = s->codec.rxbuf[s->codec.rxoff ++];
466
- s->codec.rxlen --;
467
- s->codec.rxoff &= EAC_BUF_LEN - 1;
468
- if (s->codec.rxavail)
469
- omap_eac_in_refill(s);
470
- omap_eac_in_dmarequest_update(s);
471
- return ret;
472
- }
473
- return 0x0000;
474
- case 0x0bc:    /* AGCFR */
475
- return s->codec.config[0];
476
- case 0x0c0:    /* AGCTR */
477
- return s->codec.config[1] | ((s->codec.config[1] & 2) << 14);
478
- case 0x0c4:    /* AGCFR2 */
479
- return s->codec.config[2];
480
- case 0x0c8:    /* AGCFR3 */
481
- return s->codec.config[3];
482
- case 0x0cc:    /* MBPDMACTR */
483
- case 0x0d0:    /* MPDDMARR */
484
- case 0x0d8:    /* MPUDMARR */
485
- case 0x0e4:    /* BPDDMARR */
486
- case 0x0ec:    /* BPUDMARR */
487
- return 0x0000;
488
-
489
- case 0x100:    /* VERSION_NUMBER */
490
- return 0x0010;
491
-
492
- case 0x104:    /* SYSCONFIG */
493
- return s->sysconfig;
494
-
495
- case 0x108:    /* SYSSTATUS */
496
- return 1 | 0xe;                    /* RESETDONE | stuff */
497
- }
498
-
499
- OMAP_BAD_REG(addr);
500
- return 0;
501
-}
502
-
503
-static void omap_eac_write(void *opaque, hwaddr addr,
504
- uint64_t value, unsigned size)
505
-{
506
- struct omap_eac_s *s = opaque;
507
-
508
- if (size != 2) {
509
- omap_badwidth_write16(opaque, addr, value);
510
- return;
511
- }
512
-
513
- switch (addr) {
514
- case 0x098:    /* APD1LCR */
515
- case 0x09c:    /* APD1RCR */
516
- case 0x0a0:    /* APD2LCR */
517
- case 0x0a4:    /* APD2RCR */
518
- case 0x0a8:    /* APD3LCR */
519
- case 0x0ac:    /* APD3RCR */
520
- case 0x0b0:    /* APD4R */
521
- case 0x0b8:    /* ADRDR */
522
- case 0x0d0:    /* MPDDMARR */
523
- case 0x0d8:    /* MPUDMARR */
524
- case 0x0e4:    /* BPDDMARR */
525
- case 0x0ec:    /* BPUDMARR */
526
- case 0x100:    /* VERSION_NUMBER */
527
- case 0x108:    /* SYSSTATUS */
528
- OMAP_RO_REG(addr);
529
- return;
530
-
531
- case 0x000:    /* CPCFR1 */
532
- s->config[0] = value & 0xff;
533
- omap_eac_format_update(s);
534
- break;
535
- case 0x004:    /* CPCFR2 */
536
- s->config[1] = value & 0xff;
537
- omap_eac_format_update(s);
538
- break;
539
- case 0x008:    /* CPCFR3 */
540
- s->config[2] = value & 0xff;
541
- omap_eac_format_update(s);
542
- break;
543
- case 0x00c:    /* CPCFR4 */
544
- s->config[3] = value & 0xff;
545
- omap_eac_format_update(s);
546
- break;
547
-
548
- case 0x010:    /* CPTCTL */
549
- /* Assuming TXF and TXE bits are read-only... */
550
- s->control = value & 0x5f;
551
- omap_eac_interrupt_update(s);
552
- break;
553
-
554
- case 0x014:    /* CPTTADR */
555
- s->address = value & 0xff;
556
- break;
557
- case 0x018:    /* CPTDATL */
558
- s->data &= 0xff00;
559
- s->data |= value & 0xff;
560
- break;
561
- case 0x01c:    /* CPTDATH */
562
- s->data &= 0x00ff;
563
- s->data |= value << 8;
564
- break;
565
- case 0x020:    /* CPTVSLL */
566
- s->vtol = value & 0xf8;
567
- break;
568
- case 0x024:    /* CPTVSLH */
569
- s->vtsl = value & 0x9f;
570
- break;
571
- case 0x040:    /* MPCTR */
572
- s->modem.control = value & 0x8f;
573
- break;
574
- case 0x044:    /* MPMCCFR */
575
- s->modem.config = value & 0x7fff;
576
- break;
577
- case 0x060:    /* BPCTR */
578
- s->bt.control = value & 0x8f;
579
- break;
580
- case 0x064:    /* BPMCCFR */
581
- s->bt.config = value & 0x7fff;
582
- break;
583
- case 0x080:    /* AMSCFR */
584
- s->mixer = value & 0x0fff;
585
- break;
586
- case 0x084:    /* AMVCTR */
587
- s->gain[0] = value & 0xffff;
588
- break;
589
- case 0x088:    /* AM1VCTR */
590
- s->gain[1] = value & 0xff7f;
591
- break;
592
- case 0x08c:    /* AM2VCTR */
593
- s->gain[2] = value & 0xff7f;
594
- break;
595
- case 0x090:    /* AM3VCTR */
596
- s->gain[3] = value & 0xff7f;
597
- break;
598
- case 0x094:    /* ASTCTR */
599
- s->att = value & 0xff;
600
- break;
601
-
602
- case 0x0b4:    /* ADWR */
603
- s->codec.txbuf[s->codec.txlen ++] = value;
604
- if (unlikely(s->codec.txlen == EAC_BUF_LEN ||
605
- s->codec.txlen == s->codec.txavail)) {
606
- if (s->codec.txavail)
607
- omap_eac_out_empty(s);
608
- /* Discard what couldn't be written */
609
- s->codec.txlen = 0;
610
- }
611
- break;
612
-
613
- case 0x0bc:    /* AGCFR */
614
- s->codec.config[0] = value & 0x07ff;
615
- omap_eac_format_update(s);
616
- break;
617
- case 0x0c0:    /* AGCTR */
618
- s->codec.config[1] = value & 0x780f;
619
- omap_eac_format_update(s);
620
- break;
621
- case 0x0c4:    /* AGCFR2 */
622
- s->codec.config[2] = value & 0x003f;
623
- omap_eac_format_update(s);
624
- break;
625
- case 0x0c8:    /* AGCFR3 */
626
- s->codec.config[3] = value & 0xffff;
627
- omap_eac_format_update(s);
628
- break;
629
- case 0x0cc:    /* MBPDMACTR */
630
- case 0x0d4:    /* MPDDMAWR */
631
- case 0x0e0:    /* MPUDMAWR */
632
- case 0x0e8:    /* BPDDMAWR */
633
- case 0x0f0:    /* BPUDMAWR */
634
- break;
635
-
636
- case 0x104:    /* SYSCONFIG */
637
- if (value & (1 << 1))                /* SOFTRESET */
638
- omap_eac_reset(s);
639
- s->sysconfig = value & 0x31d;
640
- break;
641
-
642
- default:
643
- OMAP_BAD_REG(addr);
644
- return;
645
- }
646
-}
647
-
648
-static const MemoryRegionOps omap_eac_ops = {
649
- .read = omap_eac_read,
650
- .write = omap_eac_write,
651
- .endianness = DEVICE_NATIVE_ENDIAN,
652
-};
653
-
654
-static struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
655
- qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
656
-{
657
- struct omap_eac_s *s = g_new0(struct omap_eac_s, 1);
658
-
659
- s->irq = irq;
660
- s->codec.rxdrq = *drq ++;
661
- s->codec.txdrq = *drq;
662
- omap_eac_reset(s);
663
-
664
- if (current_machine->audiodev) {
665
- s->codec.card.name = g_strdup(current_machine->audiodev);
666
- s->codec.card.state = audio_state_by_name(s->codec.card.name, &error_fatal);
667
- }
668
- AUD_register_card("OMAP EAC", &s->codec.card, &error_fatal);
669
-
670
- memory_region_init_io(&s->iomem, NULL, &omap_eac_ops, s, "omap.eac",
671
- omap_l4_region_size(ta, 0));
672
- omap_l4_attach(ta, 0, &s->iomem);
673
-
674
- return s;
675
-}
676
-
677
-/* STI/XTI (emulation interface) console - reverse engineered only */
678
-struct omap_sti_s {
679
- qemu_irq irq;
680
- MemoryRegion iomem;
681
- MemoryRegion iomem_fifo;
682
- CharBackend chr;
683
-
684
- uint32_t sysconfig;
685
- uint32_t systest;
686
- uint32_t irqst;
687
- uint32_t irqen;
688
- uint32_t clkcontrol;
689
- uint32_t serial_config;
690
-};
691
-
692
-#define STI_TRACE_CONSOLE_CHANNEL    239
693
-#define STI_TRACE_CONTROL_CHANNEL    253
694
-
695
-static inline void omap_sti_interrupt_update(struct omap_sti_s *s)
696
-{
697
- qemu_set_irq(s->irq, s->irqst & s->irqen);
698
-}
699
-
700
-static void omap_sti_reset(struct omap_sti_s *s)
701
-{
702
- s->sysconfig = 0;
703
- s->irqst = 0;
704
- s->irqen = 0;
705
- s->clkcontrol = 0;
706
- s->serial_config = 0;
707
-
708
- omap_sti_interrupt_update(s);
709
-}
710
-
711
-static uint64_t omap_sti_read(void *opaque, hwaddr addr,
712
- unsigned size)
713
-{
714
- struct omap_sti_s *s = opaque;
715
-
716
- if (size != 4) {
717
- return omap_badwidth_read32(opaque, addr);
718
- }
719
-
720
- switch (addr) {
721
- case 0x00:    /* STI_REVISION */
722
- return 0x10;
723
-
724
- case 0x10:    /* STI_SYSCONFIG */
725
- return s->sysconfig;
726
-
727
- case 0x14:    /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
728
- return 0x00;
729
-
730
- case 0x18:    /* STI_IRQSTATUS */
731
- return s->irqst;
732
-
733
- case 0x1c:    /* STI_IRQSETEN / STI_IRQCLREN */
734
- return s->irqen;
735
-
736
- case 0x24:    /* STI_ER / STI_DR / XTI_TRACESELECT */
737
- case 0x28:    /* STI_RX_DR / XTI_RXDATA */
738
- /* TODO */
739
- return 0;
740
-
741
- case 0x2c:    /* STI_CLK_CTRL / XTI_SCLKCRTL */
742
- return s->clkcontrol;
743
-
744
- case 0x30:    /* STI_SERIAL_CFG / XTI_SCONFIG */
745
- return s->serial_config;
746
- }
747
-
748
- OMAP_BAD_REG(addr);
749
- return 0;
750
-}
751
-
752
-static void omap_sti_write(void *opaque, hwaddr addr,
753
- uint64_t value, unsigned size)
754
-{
755
- struct omap_sti_s *s = opaque;
756
-
757
- if (size != 4) {
758
- omap_badwidth_write32(opaque, addr, value);
759
- return;
760
- }
761
-
762
- switch (addr) {
763
- case 0x00:    /* STI_REVISION */
764
- case 0x14:    /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
765
- OMAP_RO_REG(addr);
766
- return;
767
-
768
- case 0x10:    /* STI_SYSCONFIG */
769
- if (value & (1 << 1))                /* SOFTRESET */
770
- omap_sti_reset(s);
771
- s->sysconfig = value & 0xfe;
772
- break;
773
-
774
- case 0x18:    /* STI_IRQSTATUS */
775
- s->irqst &= ~value;
776
- omap_sti_interrupt_update(s);
777
- break;
778
-
779
- case 0x1c:    /* STI_IRQSETEN / STI_IRQCLREN */
780
- s->irqen = value & 0xffff;
781
- omap_sti_interrupt_update(s);
782
- break;
783
-
784
- case 0x2c:    /* STI_CLK_CTRL / XTI_SCLKCRTL */
785
- s->clkcontrol = value & 0xff;
786
- break;
787
-
788
- case 0x30:    /* STI_SERIAL_CFG / XTI_SCONFIG */
789
- s->serial_config = value & 0xff;
790
- break;
791
-
792
- case 0x24:    /* STI_ER / STI_DR / XTI_TRACESELECT */
793
- case 0x28:    /* STI_RX_DR / XTI_RXDATA */
794
- /* TODO */
795
- return;
796
-
797
- default:
798
- OMAP_BAD_REG(addr);
799
- return;
800
- }
801
-}
802
-
803
-static const MemoryRegionOps omap_sti_ops = {
804
- .read = omap_sti_read,
805
- .write = omap_sti_write,
806
- .endianness = DEVICE_NATIVE_ENDIAN,
807
-};
808
-
809
-static uint64_t omap_sti_fifo_read(void *opaque, hwaddr addr, unsigned size)
810
-{
811
- OMAP_BAD_REG(addr);
812
- return 0;
813
-}
814
-
815
-static void omap_sti_fifo_write(void *opaque, hwaddr addr,
816
- uint64_t value, unsigned size)
817
-{
818
- struct omap_sti_s *s = opaque;
819
- int ch = addr >> 6;
820
- uint8_t byte = value;
821
-
822
- if (size != 1) {
823
- omap_badwidth_write8(opaque, addr, size);
824
- return;
825
- }
826
-
827
- if (ch == STI_TRACE_CONTROL_CHANNEL) {
828
- /* Flush channel <i>value</i>. */
829
- /* XXX this blocks entire thread. Rewrite to use
830
- * qemu_chr_fe_write and background I/O callbacks */
831
- qemu_chr_fe_write_all(&s->chr, (const uint8_t *) "\r", 1);
832
- } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
833
- if (value == 0xc0 || value == 0xc3) {
834
- /* Open channel <i>ch</i>. */
835
- } else if (value == 0x00) {
836
- qemu_chr_fe_write_all(&s->chr, (const uint8_t *) "\n", 1);
837
- } else {
838
- qemu_chr_fe_write_all(&s->chr, &byte, 1);
839
- }
840
- }
841
-}
842
-
843
-static const MemoryRegionOps omap_sti_fifo_ops = {
844
- .read = omap_sti_fifo_read,
845
- .write = omap_sti_fifo_write,
846
- .endianness = DEVICE_NATIVE_ENDIAN,
847
-};
848
-
849
-static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
850
- MemoryRegion *sysmem,
851
- hwaddr channel_base, qemu_irq irq, omap_clk clk,
852
- Chardev *chr)
853
-{
854
- struct omap_sti_s *s = g_new0(struct omap_sti_s, 1);
855
-
856
- s->irq = irq;
857
- omap_sti_reset(s);
858
-
859
- qemu_chr_fe_init(&s->chr, chr ?: qemu_chr_new("null", "null", NULL),
860
- &error_abort);
861
-
862
- memory_region_init_io(&s->iomem, NULL, &omap_sti_ops, s, "omap.sti",
863
- omap_l4_region_size(ta, 0));
864
- omap_l4_attach(ta, 0, &s->iomem);
865
-
866
- memory_region_init_io(&s->iomem_fifo, NULL, &omap_sti_fifo_ops, s,
867
- "omap.sti.fifo", 0x10000);
868
- memory_region_add_subregion(sysmem, channel_base, &s->iomem_fifo);
869
-
870
- return s;
871
-}
872
-
873
-/* L4 Interconnect */
874
-#define L4TA(n)        (n)
875
-#define L4TAO(n)    ((n) + 39)
876
-
877
-static const struct omap_l4_region_s omap_l4_region[125] = {
878
- [ 1] = { 0x40800, 0x800, 32 }, /* Initiator agent */
879
- [ 2] = { 0x41000, 0x1000, 32 }, /* Link agent */
880
- [ 0] = { 0x40000, 0x800, 32 }, /* Address and protection */
881
- [ 3] = { 0x00000, 0x1000, 32 | 16 | 8 }, /* System Control and Pinout */
882
- [ 4] = { 0x01000, 0x1000, 32 | 16 | 8 }, /* L4TAO1 */
883
- [ 5] = { 0x04000, 0x1000, 32 | 16 }, /* 32K Timer */
884
- [ 6] = { 0x05000, 0x1000, 32 | 16 | 8 }, /* L4TAO2 */
885
- [ 7] = { 0x08000, 0x800, 32 }, /* PRCM Region A */
886
- [ 8] = { 0x08800, 0x800, 32 }, /* PRCM Region B */
887
- [ 9] = { 0x09000, 0x1000, 32 | 16 | 8 }, /* L4TAO */
888
- [ 10] = { 0x12000, 0x1000, 32 | 16 | 8 }, /* Test (BCM) */
889
- [ 11] = { 0x13000, 0x1000, 32 | 16 | 8 }, /* L4TA1 */
890
- [ 12] = { 0x14000, 0x1000, 32 }, /* Test/emulation (TAP) */
891
- [ 13] = { 0x15000, 0x1000, 32 | 16 | 8 }, /* L4TA2 */
892
- [ 14] = { 0x18000, 0x1000, 32 | 16 | 8 }, /* GPIO1 */
893
- [ 16] = { 0x1a000, 0x1000, 32 | 16 | 8 }, /* GPIO2 */
894
- [ 18] = { 0x1c000, 0x1000, 32 | 16 | 8 }, /* GPIO3 */
895
- [ 19] = { 0x1e000, 0x1000, 32 | 16 | 8 }, /* GPIO4 */
896
- [ 15] = { 0x19000, 0x1000, 32 | 16 | 8 }, /* Quad GPIO TOP */
897
- [ 17] = { 0x1b000, 0x1000, 32 | 16 | 8 }, /* L4TA3 */
898
- [ 20] = { 0x20000, 0x1000, 32 | 16 | 8 }, /* WD Timer 1 (Secure) */
899
- [ 22] = { 0x22000, 0x1000, 32 | 16 | 8 }, /* WD Timer 2 (OMAP) */
900
- [ 21] = { 0x21000, 0x1000, 32 | 16 | 8 }, /* Dual WD timer TOP */
901
- [ 23] = { 0x23000, 0x1000, 32 | 16 | 8 }, /* L4TA4 */
902
- [ 24] = { 0x28000, 0x1000, 32 | 16 | 8 }, /* GP Timer 1 */
903
- [ 25] = { 0x29000, 0x1000, 32 | 16 | 8 }, /* L4TA7 */
904
- [ 26] = { 0x48000, 0x2000, 32 | 16 | 8 }, /* Emulation (ARM11ETB) */
905
- [ 27] = { 0x4a000, 0x1000, 32 | 16 | 8 }, /* L4TA9 */
906
- [ 28] = { 0x50000, 0x400, 32 | 16 | 8 }, /* Display top */
907
- [ 29] = { 0x50400, 0x400, 32 | 16 | 8 }, /* Display control */
908
- [ 30] = { 0x50800, 0x400, 32 | 16 | 8 }, /* Display RFBI */
909
- [ 31] = { 0x50c00, 0x400, 32 | 16 | 8 }, /* Display encoder */
910
- [ 32] = { 0x51000, 0x1000, 32 | 16 | 8 }, /* L4TA10 */
911
- [ 33] = { 0x52000, 0x400, 32 | 16 | 8 }, /* Camera top */
912
- [ 34] = { 0x52400, 0x400, 32 | 16 | 8 }, /* Camera core */
913
- [ 35] = { 0x52800, 0x400, 32 | 16 | 8 }, /* Camera DMA */
914
- [ 36] = { 0x52c00, 0x400, 32 | 16 | 8 }, /* Camera MMU */
915
- [ 37] = { 0x53000, 0x1000, 32 | 16 | 8 }, /* L4TA11 */
916
- [ 38] = { 0x56000, 0x1000, 32 | 16 | 8 }, /* sDMA */
917
- [ 39] = { 0x57000, 0x1000, 32 | 16 | 8 }, /* L4TA12 */
918
- [ 40] = { 0x58000, 0x1000, 32 | 16 | 8 }, /* SSI top */
919
- [ 41] = { 0x59000, 0x1000, 32 | 16 | 8 }, /* SSI GDD */
920
- [ 42] = { 0x5a000, 0x1000, 32 | 16 | 8 }, /* SSI Port1 */
921
- [ 43] = { 0x5b000, 0x1000, 32 | 16 | 8 }, /* SSI Port2 */
922
- [ 44] = { 0x5c000, 0x1000, 32 | 16 | 8 }, /* L4TA13 */
923
- [ 45] = { 0x5e000, 0x1000, 32 | 16 | 8 }, /* USB OTG */
924
- [ 46] = { 0x5f000, 0x1000, 32 | 16 | 8 }, /* L4TAO4 */
925
- [ 47] = { 0x60000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER1SDRC) */
926
- [ 48] = { 0x61000, 0x1000, 32 | 16 | 8 }, /* L4TA14 */
927
- [ 49] = { 0x62000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER2GPMC) */
928
- [ 50] = { 0x63000, 0x1000, 32 | 16 | 8 }, /* L4TA15 */
929
- [ 51] = { 0x64000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER3OCM) */
930
- [ 52] = { 0x65000, 0x1000, 32 | 16 | 8 }, /* L4TA16 */
931
- [ 53] = { 0x66000, 0x300, 32 | 16 | 8 }, /* Emulation (WIN_TRACER4L4) */
932
- [ 54] = { 0x67000, 0x1000, 32 | 16 | 8 }, /* L4TA17 */
933
- [ 55] = { 0x68000, 0x1000, 32 | 16 | 8 }, /* Emulation (XTI) */
934
- [ 56] = { 0x69000, 0x1000, 32 | 16 | 8 }, /* L4TA18 */
935
- [ 57] = { 0x6a000, 0x1000, 16 | 8 }, /* UART1 */
936
- [ 58] = { 0x6b000, 0x1000, 32 | 16 | 8 }, /* L4TA19 */
937
- [ 59] = { 0x6c000, 0x1000, 16 | 8 }, /* UART2 */
938
- [ 60] = { 0x6d000, 0x1000, 32 | 16 | 8 }, /* L4TA20 */
939
- [ 61] = { 0x6e000, 0x1000, 16 | 8 }, /* UART3 */
940
- [ 62] = { 0x6f000, 0x1000, 32 | 16 | 8 }, /* L4TA21 */
941
- [ 63] = { 0x70000, 0x1000, 16 }, /* I2C1 */
942
- [ 64] = { 0x71000, 0x1000, 32 | 16 | 8 }, /* L4TAO5 */
943
- [ 65] = { 0x72000, 0x1000, 16 }, /* I2C2 */
944
- [ 66] = { 0x73000, 0x1000, 32 | 16 | 8 }, /* L4TAO6 */
945
- [ 67] = { 0x74000, 0x1000, 16 }, /* McBSP1 */
946
- [ 68] = { 0x75000, 0x1000, 32 | 16 | 8 }, /* L4TAO7 */
947
- [ 69] = { 0x76000, 0x1000, 16 }, /* McBSP2 */
948
- [ 70] = { 0x77000, 0x1000, 32 | 16 | 8 }, /* L4TAO8 */
949
- [ 71] = { 0x24000, 0x1000, 32 | 16 | 8 }, /* WD Timer 3 (DSP) */
950
- [ 72] = { 0x25000, 0x1000, 32 | 16 | 8 }, /* L4TA5 */
951
- [ 73] = { 0x26000, 0x1000, 32 | 16 | 8 }, /* WD Timer 4 (IVA) */
952
- [ 74] = { 0x27000, 0x1000, 32 | 16 | 8 }, /* L4TA6 */
953
- [ 75] = { 0x2a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 2 */
954
- [ 76] = { 0x2b000, 0x1000, 32 | 16 | 8 }, /* L4TA8 */
955
- [ 77] = { 0x78000, 0x1000, 32 | 16 | 8 }, /* GP Timer 3 */
956
- [ 78] = { 0x79000, 0x1000, 32 | 16 | 8 }, /* L4TA22 */
957
- [ 79] = { 0x7a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 4 */
958
- [ 80] = { 0x7b000, 0x1000, 32 | 16 | 8 }, /* L4TA23 */
959
- [ 81] = { 0x7c000, 0x1000, 32 | 16 | 8 }, /* GP Timer 5 */
960
- [ 82] = { 0x7d000, 0x1000, 32 | 16 | 8 }, /* L4TA24 */
961
- [ 83] = { 0x7e000, 0x1000, 32 | 16 | 8 }, /* GP Timer 6 */
962
- [ 84] = { 0x7f000, 0x1000, 32 | 16 | 8 }, /* L4TA25 */
963
- [ 85] = { 0x80000, 0x1000, 32 | 16 | 8 }, /* GP Timer 7 */
964
- [ 86] = { 0x81000, 0x1000, 32 | 16 | 8 }, /* L4TA26 */
965
- [ 87] = { 0x82000, 0x1000, 32 | 16 | 8 }, /* GP Timer 8 */
966
- [ 88] = { 0x83000, 0x1000, 32 | 16 | 8 }, /* L4TA27 */
967
- [ 89] = { 0x84000, 0x1000, 32 | 16 | 8 }, /* GP Timer 9 */
968
- [ 90] = { 0x85000, 0x1000, 32 | 16 | 8 }, /* L4TA28 */
969
- [ 91] = { 0x86000, 0x1000, 32 | 16 | 8 }, /* GP Timer 10 */
970
- [ 92] = { 0x87000, 0x1000, 32 | 16 | 8 }, /* L4TA29 */
971
- [ 93] = { 0x88000, 0x1000, 32 | 16 | 8 }, /* GP Timer 11 */
972
- [ 94] = { 0x89000, 0x1000, 32 | 16 | 8 }, /* L4TA30 */
973
- [ 95] = { 0x8a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 12 */
974
- [ 96] = { 0x8b000, 0x1000, 32 | 16 | 8 }, /* L4TA31 */
975
- [ 97] = { 0x90000, 0x1000, 16 }, /* EAC */
976
- [ 98] = { 0x91000, 0x1000, 32 | 16 | 8 }, /* L4TA32 */
977
- [ 99] = { 0x92000, 0x1000, 16 }, /* FAC */
978
- [100] = { 0x93000, 0x1000, 32 | 16 | 8 }, /* L4TA33 */
979
- [101] = { 0x94000, 0x1000, 32 | 16 | 8 }, /* IPC (MAILBOX) */
980
- [102] = { 0x95000, 0x1000, 32 | 16 | 8 }, /* L4TA34 */
981
- [103] = { 0x98000, 0x1000, 32 | 16 | 8 }, /* SPI1 */
982
- [104] = { 0x99000, 0x1000, 32 | 16 | 8 }, /* L4TA35 */
983
- [105] = { 0x9a000, 0x1000, 32 | 16 | 8 }, /* SPI2 */
984
- [106] = { 0x9b000, 0x1000, 32 | 16 | 8 }, /* L4TA36 */
985
- [107] = { 0x9c000, 0x1000, 16 | 8 }, /* MMC SDIO */
986
- [108] = { 0x9d000, 0x1000, 32 | 16 | 8 }, /* L4TAO9 */
987
- [109] = { 0x9e000, 0x1000, 32 | 16 | 8 }, /* MS_PRO */
988
- [110] = { 0x9f000, 0x1000, 32 | 16 | 8 }, /* L4TAO10 */
989
- [111] = { 0xa0000, 0x1000, 32 }, /* RNG */
990
- [112] = { 0xa1000, 0x1000, 32 | 16 | 8 }, /* L4TAO11 */
991
- [113] = { 0xa2000, 0x1000, 32 }, /* DES3DES */
992
- [114] = { 0xa3000, 0x1000, 32 | 16 | 8 }, /* L4TAO12 */
993
- [115] = { 0xa4000, 0x1000, 32 }, /* SHA1MD5 */
994
- [116] = { 0xa5000, 0x1000, 32 | 16 | 8 }, /* L4TAO13 */
995
- [117] = { 0xa6000, 0x1000, 32 }, /* AES */
996
- [118] = { 0xa7000, 0x1000, 32 | 16 | 8 }, /* L4TA37 */
997
- [119] = { 0xa8000, 0x2000, 32 }, /* PKA */
998
- [120] = { 0xaa000, 0x1000, 32 | 16 | 8 }, /* L4TA38 */
999
- [121] = { 0xb0000, 0x1000, 32 }, /* MG */
1000
- [122] = { 0xb1000, 0x1000, 32 | 16 | 8 },
1001
- [123] = { 0xb2000, 0x1000, 32 }, /* HDQ/1-Wire */
1002
- [124] = { 0xb3000, 0x1000, 32 | 16 | 8 }, /* L4TA39 */
1003
-};
1004
-
1005
-static const struct omap_l4_agent_info_s omap_l4_agent_info[54] = {
1006
- { 0, 0, 3, 2 }, /* L4IA initiatior agent */
1007
- { L4TAO(1), 3, 2, 1 }, /* Control and pinout module */
1008
- { L4TAO(2), 5, 2, 1 }, /* 32K timer */
1009
- { L4TAO(3), 7, 3, 2 }, /* PRCM */
1010
- { L4TA(1), 10, 2, 1 }, /* BCM */
1011
- { L4TA(2), 12, 2, 1 }, /* Test JTAG */
1012
- { L4TA(3), 14, 6, 3 }, /* Quad GPIO */
1013
- { L4TA(4), 20, 4, 3 }, /* WD timer 1/2 */
1014
- { L4TA(7), 24, 2, 1 }, /* GP timer 1 */
1015
- { L4TA(9), 26, 2, 1 }, /* ATM11 ETB */
1016
- { L4TA(10), 28, 5, 4 }, /* Display subsystem */
1017
- { L4TA(11), 33, 5, 4 }, /* Camera subsystem */
1018
- { L4TA(12), 38, 2, 1 }, /* sDMA */
1019
- { L4TA(13), 40, 5, 4 }, /* SSI */
1020
- { L4TAO(4), 45, 2, 1 }, /* USB */
1021
- { L4TA(14), 47, 2, 1 }, /* Win Tracer1 */
1022
- { L4TA(15), 49, 2, 1 }, /* Win Tracer2 */
1023
- { L4TA(16), 51, 2, 1 }, /* Win Tracer3 */
1024
- { L4TA(17), 53, 2, 1 }, /* Win Tracer4 */
1025
- { L4TA(18), 55, 2, 1 }, /* XTI */
1026
- { L4TA(19), 57, 2, 1 }, /* UART1 */
1027
- { L4TA(20), 59, 2, 1 }, /* UART2 */
1028
- { L4TA(21), 61, 2, 1 }, /* UART3 */
1029
- { L4TAO(5), 63, 2, 1 }, /* I2C1 */
1030
- { L4TAO(6), 65, 2, 1 }, /* I2C2 */
1031
- { L4TAO(7), 67, 2, 1 }, /* McBSP1 */
1032
- { L4TAO(8), 69, 2, 1 }, /* McBSP2 */
1033
- { L4TA(5), 71, 2, 1 }, /* WD Timer 3 (DSP) */
1034
- { L4TA(6), 73, 2, 1 }, /* WD Timer 4 (IVA) */
1035
- { L4TA(8), 75, 2, 1 }, /* GP Timer 2 */
1036
- { L4TA(22), 77, 2, 1 }, /* GP Timer 3 */
1037
- { L4TA(23), 79, 2, 1 }, /* GP Timer 4 */
1038
- { L4TA(24), 81, 2, 1 }, /* GP Timer 5 */
1039
- { L4TA(25), 83, 2, 1 }, /* GP Timer 6 */
1040
- { L4TA(26), 85, 2, 1 }, /* GP Timer 7 */
1041
- { L4TA(27), 87, 2, 1 }, /* GP Timer 8 */
1042
- { L4TA(28), 89, 2, 1 }, /* GP Timer 9 */
1043
- { L4TA(29), 91, 2, 1 }, /* GP Timer 10 */
1044
- { L4TA(30), 93, 2, 1 }, /* GP Timer 11 */
1045
- { L4TA(31), 95, 2, 1 }, /* GP Timer 12 */
1046
- { L4TA(32), 97, 2, 1 }, /* EAC */
1047
- { L4TA(33), 99, 2, 1 }, /* FAC */
1048
- { L4TA(34), 101, 2, 1 }, /* IPC */
1049
- { L4TA(35), 103, 2, 1 }, /* SPI1 */
1050
- { L4TA(36), 105, 2, 1 }, /* SPI2 */
1051
- { L4TAO(9), 107, 2, 1 }, /* MMC SDIO */
1052
- { L4TAO(10), 109, 2, 1 },
1053
- { L4TAO(11), 111, 2, 1 }, /* RNG */
1054
- { L4TAO(12), 113, 2, 1 }, /* DES3DES */
1055
- { L4TAO(13), 115, 2, 1 }, /* SHA1MD5 */
1056
- { L4TA(37), 117, 2, 1 }, /* AES */
1057
- { L4TA(38), 119, 2, 1 }, /* PKA */
1058
- { -1, 121, 2, 1 },
1059
- { L4TA(39), 123, 2, 1 }, /* HDQ/1-Wire */
1060
-};
1061
-
1062
-#define omap_l4ta(bus, cs)    \
1063
- omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TA(cs))
1064
-#define omap_l4tao(bus, cs)    \
1065
- omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TAO(cs))
1066
-
1067
-/* Power, Reset, and Clock Management */
1068
-struct omap_prcm_s {
1069
- qemu_irq irq[3];
1070
- struct omap_mpu_state_s *mpu;
1071
- MemoryRegion iomem0;
1072
- MemoryRegion iomem1;
1073
-
1074
- uint32_t irqst[3];
1075
- uint32_t irqen[3];
1076
-
1077
- uint32_t sysconfig;
1078
- uint32_t voltctrl;
1079
- uint32_t scratch[20];
1080
-
1081
- uint32_t clksrc[1];
1082
- uint32_t clkout[1];
1083
- uint32_t clkemul[1];
1084
- uint32_t clkpol[1];
1085
- uint32_t clksel[8];
1086
- uint32_t clken[12];
1087
- uint32_t clkctrl[4];
1088
- uint32_t clkidle[7];
1089
- uint32_t setuptime[2];
1090
-
1091
- uint32_t wkup[3];
1092
- uint32_t wken[3];
1093
- uint32_t wkst[3];
1094
- uint32_t rst[4];
1095
- uint32_t rstctrl[1];
1096
- uint32_t power[4];
1097
- uint32_t rsttime_wkup;
1098
-
1099
- uint32_t ev;
1100
- uint32_t evtime[2];
1101
-
1102
- int dpll_lock, apll_lock[2];
1103
-};
1104
-
1105
-static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
1106
-{
1107
- qemu_set_irq(s->irq[dom], s->irqst[dom] & s->irqen[dom]);
1108
- /* XXX or is the mask applied before PRCM_IRQSTATUS_* ? */
1109
-}
1110
-
1111
-static uint64_t omap_prcm_read(void *opaque, hwaddr addr,
1112
- unsigned size)
1113
-{
1114
- struct omap_prcm_s *s = opaque;
1115
- uint32_t ret;
1116
-
1117
- if (size != 4) {
1118
- return omap_badwidth_read32(opaque, addr);
1119
- }
1120
-
1121
- switch (addr) {
1122
- case 0x000:    /* PRCM_REVISION */
1123
- return 0x10;
1124
-
1125
- case 0x010:    /* PRCM_SYSCONFIG */
1126
- return s->sysconfig;
1127
-
1128
- case 0x018:    /* PRCM_IRQSTATUS_MPU */
1129
- return s->irqst[0];
1130
-
1131
- case 0x01c:    /* PRCM_IRQENABLE_MPU */
1132
- return s->irqen[0];
1133
-
1134
- case 0x050:    /* PRCM_VOLTCTRL */
1135
- return s->voltctrl;
1136
- case 0x054:    /* PRCM_VOLTST */
1137
- return s->voltctrl & 3;
1138
-
1139
- case 0x060:    /* PRCM_CLKSRC_CTRL */
1140
- return s->clksrc[0];
1141
- case 0x070:    /* PRCM_CLKOUT_CTRL */
1142
- return s->clkout[0];
1143
- case 0x078:    /* PRCM_CLKEMUL_CTRL */
1144
- return s->clkemul[0];
1145
- case 0x080:    /* PRCM_CLKCFG_CTRL */
1146
- case 0x084:    /* PRCM_CLKCFG_STATUS */
1147
- return 0;
1148
-
1149
- case 0x090:    /* PRCM_VOLTSETUP */
1150
- return s->setuptime[0];
1151
-
1152
- case 0x094:    /* PRCM_CLKSSETUP */
1153
- return s->setuptime[1];
1154
-
1155
- case 0x098:    /* PRCM_POLCTRL */
1156
- return s->clkpol[0];
1157
-
1158
- case 0x0b0:    /* GENERAL_PURPOSE1 */
1159
- case 0x0b4:    /* GENERAL_PURPOSE2 */
1160
- case 0x0b8:    /* GENERAL_PURPOSE3 */
1161
- case 0x0bc:    /* GENERAL_PURPOSE4 */
1162
- case 0x0c0:    /* GENERAL_PURPOSE5 */
1163
- case 0x0c4:    /* GENERAL_PURPOSE6 */
1164
- case 0x0c8:    /* GENERAL_PURPOSE7 */
1165
- case 0x0cc:    /* GENERAL_PURPOSE8 */
1166
- case 0x0d0:    /* GENERAL_PURPOSE9 */
1167
- case 0x0d4:    /* GENERAL_PURPOSE10 */
1168
- case 0x0d8:    /* GENERAL_PURPOSE11 */
1169
- case 0x0dc:    /* GENERAL_PURPOSE12 */
1170
- case 0x0e0:    /* GENERAL_PURPOSE13 */
1171
- case 0x0e4:    /* GENERAL_PURPOSE14 */
1172
- case 0x0e8:    /* GENERAL_PURPOSE15 */
1173
- case 0x0ec:    /* GENERAL_PURPOSE16 */
1174
- case 0x0f0:    /* GENERAL_PURPOSE17 */
1175
- case 0x0f4:    /* GENERAL_PURPOSE18 */
1176
- case 0x0f8:    /* GENERAL_PURPOSE19 */
1177
- case 0x0fc:    /* GENERAL_PURPOSE20 */
1178
- return s->scratch[(addr - 0xb0) >> 2];
1179
-
1180
- case 0x140:    /* CM_CLKSEL_MPU */
1181
- return s->clksel[0];
1182
- case 0x148:    /* CM_CLKSTCTRL_MPU */
1183
- return s->clkctrl[0];
1184
-
1185
- case 0x158:    /* RM_RSTST_MPU */
1186
- return s->rst[0];
1187
- case 0x1c8:    /* PM_WKDEP_MPU */
1188
- return s->wkup[0];
1189
- case 0x1d4:    /* PM_EVGENCTRL_MPU */
1190
- return s->ev;
1191
- case 0x1d8:    /* PM_EVEGENONTIM_MPU */
1192
- return s->evtime[0];
1193
- case 0x1dc:    /* PM_EVEGENOFFTIM_MPU */
1194
- return s->evtime[1];
1195
- case 0x1e0:    /* PM_PWSTCTRL_MPU */
1196
- return s->power[0];
1197
- case 0x1e4:    /* PM_PWSTST_MPU */
1198
- return 0;
1199
-
1200
- case 0x200:    /* CM_FCLKEN1_CORE */
1201
- return s->clken[0];
1202
- case 0x204:    /* CM_FCLKEN2_CORE */
1203
- return s->clken[1];
1204
- case 0x210:    /* CM_ICLKEN1_CORE */
1205
- return s->clken[2];
1206
- case 0x214:    /* CM_ICLKEN2_CORE */
1207
- return s->clken[3];
1208
- case 0x21c:    /* CM_ICLKEN4_CORE */
1209
- return s->clken[4];
1210
-
1211
- case 0x220:    /* CM_IDLEST1_CORE */
1212
- /* TODO: check the actual iclk status */
1213
- return 0x7ffffff9;
1214
- case 0x224:    /* CM_IDLEST2_CORE */
1215
- /* TODO: check the actual iclk status */
1216
- return 0x00000007;
1217
- case 0x22c:    /* CM_IDLEST4_CORE */
1218
- /* TODO: check the actual iclk status */
1219
- return 0x0000001f;
1220
-
1221
- case 0x230:    /* CM_AUTOIDLE1_CORE */
1222
- return s->clkidle[0];
1223
- case 0x234:    /* CM_AUTOIDLE2_CORE */
1224
- return s->clkidle[1];
1225
- case 0x238:    /* CM_AUTOIDLE3_CORE */
1226
- return s->clkidle[2];
1227
- case 0x23c:    /* CM_AUTOIDLE4_CORE */
1228
- return s->clkidle[3];
1229
-
1230
- case 0x240:    /* CM_CLKSEL1_CORE */
1231
- return s->clksel[1];
1232
- case 0x244:    /* CM_CLKSEL2_CORE */
1233
- return s->clksel[2];
1234
-
1235
- case 0x248:    /* CM_CLKSTCTRL_CORE */
1236
- return s->clkctrl[1];
1237
-
1238
- case 0x2a0:    /* PM_WKEN1_CORE */
1239
- return s->wken[0];
1240
- case 0x2a4:    /* PM_WKEN2_CORE */
1241
- return s->wken[1];
1242
-
1243
- case 0x2b0:    /* PM_WKST1_CORE */
1244
- return s->wkst[0];
1245
- case 0x2b4:    /* PM_WKST2_CORE */
1246
- return s->wkst[1];
1247
- case 0x2c8:    /* PM_WKDEP_CORE */
1248
- return 0x1e;
1249
-
1250
- case 0x2e0:    /* PM_PWSTCTRL_CORE */
1251
- return s->power[1];
1252
- case 0x2e4:    /* PM_PWSTST_CORE */
1253
- return 0x000030 | (s->power[1] & 0xfc00);
1254
-
1255
- case 0x300:    /* CM_FCLKEN_GFX */
1256
- return s->clken[5];
1257
- case 0x310:    /* CM_ICLKEN_GFX */
1258
- return s->clken[6];
1259
- case 0x320:    /* CM_IDLEST_GFX */
1260
- /* TODO: check the actual iclk status */
1261
- return 0x00000001;
1262
- case 0x340:    /* CM_CLKSEL_GFX */
1263
- return s->clksel[3];
1264
- case 0x348:    /* CM_CLKSTCTRL_GFX */
1265
- return s->clkctrl[2];
1266
- case 0x350:    /* RM_RSTCTRL_GFX */
1267
- return s->rstctrl[0];
1268
- case 0x358:    /* RM_RSTST_GFX */
1269
- return s->rst[1];
1270
- case 0x3c8:    /* PM_WKDEP_GFX */
1271
- return s->wkup[1];
1272
-
1273
- case 0x3e0:    /* PM_PWSTCTRL_GFX */
1274
- return s->power[2];
1275
- case 0x3e4:    /* PM_PWSTST_GFX */
1276
- return s->power[2] & 3;
1277
-
1278
- case 0x400:    /* CM_FCLKEN_WKUP */
1279
- return s->clken[7];
1280
- case 0x410:    /* CM_ICLKEN_WKUP */
1281
- return s->clken[8];
1282
- case 0x420:    /* CM_IDLEST_WKUP */
1283
- /* TODO: check the actual iclk status */
1284
- return 0x0000003f;
1285
- case 0x430:    /* CM_AUTOIDLE_WKUP */
1286
- return s->clkidle[4];
1287
- case 0x440:    /* CM_CLKSEL_WKUP */
1288
- return s->clksel[4];
1289
- case 0x450:    /* RM_RSTCTRL_WKUP */
1290
- return 0;
1291
- case 0x454:    /* RM_RSTTIME_WKUP */
1292
- return s->rsttime_wkup;
1293
- case 0x458:    /* RM_RSTST_WKUP */
1294
- return s->rst[2];
1295
- case 0x4a0:    /* PM_WKEN_WKUP */
1296
- return s->wken[2];
1297
- case 0x4b0:    /* PM_WKST_WKUP */
1298
- return s->wkst[2];
1299
-
1300
- case 0x500:    /* CM_CLKEN_PLL */
1301
- return s->clken[9];
1302
- case 0x520:    /* CM_IDLEST_CKGEN */
1303
- ret = 0x0000070 | (s->apll_lock[0] << 9) | (s->apll_lock[1] << 8);
1304
- if (!(s->clksel[6] & 3))
1305
- /* Core uses 32-kHz clock */
1306
- ret |= 3 << 0;
1307
- else if (!s->dpll_lock)
1308
- /* DPLL not locked, core uses ref_clk */
1309
- ret |= 1 << 0;
1310
- else
1311
- /* Core uses DPLL */
1312
- ret |= 2 << 0;
1313
- return ret;
1314
- case 0x530:    /* CM_AUTOIDLE_PLL */
1315
- return s->clkidle[5];
1316
- case 0x540:    /* CM_CLKSEL1_PLL */
1317
- return s->clksel[5];
1318
- case 0x544:    /* CM_CLKSEL2_PLL */
1319
- return s->clksel[6];
1320
-
1321
- case 0x800:    /* CM_FCLKEN_DSP */
1322
- return s->clken[10];
1323
- case 0x810:    /* CM_ICLKEN_DSP */
1324
- return s->clken[11];
1325
- case 0x820:    /* CM_IDLEST_DSP */
1326
- /* TODO: check the actual iclk status */
1327
- return 0x00000103;
1328
- case 0x830:    /* CM_AUTOIDLE_DSP */
1329
- return s->clkidle[6];
1330
- case 0x840:    /* CM_CLKSEL_DSP */
1331
- return s->clksel[7];
1332
- case 0x848:    /* CM_CLKSTCTRL_DSP */
1333
- return s->clkctrl[3];
1334
- case 0x850:    /* RM_RSTCTRL_DSP */
1335
- return 0;
1336
- case 0x858:    /* RM_RSTST_DSP */
1337
- return s->rst[3];
1338
- case 0x8c8:    /* PM_WKDEP_DSP */
1339
- return s->wkup[2];
1340
- case 0x8e0:    /* PM_PWSTCTRL_DSP */
1341
- return s->power[3];
1342
- case 0x8e4:    /* PM_PWSTST_DSP */
1343
- return 0x008030 | (s->power[3] & 0x3003);
1344
-
1345
- case 0x8f0:    /* PRCM_IRQSTATUS_DSP */
1346
- return s->irqst[1];
1347
- case 0x8f4:    /* PRCM_IRQENABLE_DSP */
1348
- return s->irqen[1];
1349
-
1350
- case 0x8f8:    /* PRCM_IRQSTATUS_IVA */
1351
- return s->irqst[2];
1352
- case 0x8fc:    /* PRCM_IRQENABLE_IVA */
1353
- return s->irqen[2];
1354
- }
1355
-
1356
- OMAP_BAD_REG(addr);
1357
- return 0;
1358
-}
1359
-
1360
-static void omap_prcm_apll_update(struct omap_prcm_s *s)
1361
-{
1362
- int mode[2];
1363
-
1364
- mode[0] = (s->clken[9] >> 6) & 3;
1365
- s->apll_lock[0] = (mode[0] == 3);
1366
- mode[1] = (s->clken[9] >> 2) & 3;
1367
- s->apll_lock[1] = (mode[1] == 3);
1368
- /* TODO: update clocks */
1369
-
1370
- if (mode[0] == 1 || mode[0] == 2 || mode[1] == 1 || mode[1] == 2)
1371
- fprintf(stderr, "%s: bad EN_54M_PLL or bad EN_96M_PLL\n",
1372
- __func__);
1373
-}
1374
-
1375
-static void omap_prcm_dpll_update(struct omap_prcm_s *s)
1376
-{
1377
- omap_clk dpll = omap_findclk(s->mpu, "dpll");
1378
- omap_clk dpll_x2 = omap_findclk(s->mpu, "dpll");
1379
- omap_clk core = omap_findclk(s->mpu, "core_clk");
1380
- int mode = (s->clken[9] >> 0) & 3;
1381
- int mult, div;
1382
-
1383
- mult = (s->clksel[5] >> 12) & 0x3ff;
1384
- div = (s->clksel[5] >> 8) & 0xf;
1385
- if (mult == 0 || mult == 1)
1386
- mode = 1;    /* Bypass */
1387
-
1388
- s->dpll_lock = 0;
1389
- switch (mode) {
1390
- case 0:
60
- case 0:
1391
- fprintf(stderr, "%s: bad EN_DPLL\n", __func__);
1392
- break;
1393
- case 1:    /* Low-power bypass mode (Default) */
1394
- case 2:    /* Fast-relock bypass mode */
1395
- omap_clk_setrate(dpll, 1, 1);
1396
- omap_clk_setrate(dpll_x2, 1, 1);
1397
- break;
1398
- case 3:    /* Lock mode */
1399
- s->dpll_lock = 1; /* After 20 FINT cycles (ref_clk / (div + 1)). */
1400
-
1401
- omap_clk_setrate(dpll, div + 1, mult);
1402
- omap_clk_setrate(dpll_x2, div + 1, mult * 2);
1403
- break;
1404
- }
1405
-
1406
- switch ((s->clksel[6] >> 0) & 3) {
1407
- case 0:
1408
- omap_clk_reparent(core, omap_findclk(s->mpu, "clk32-kHz"));
1409
- break;
61
- break;
1410
- case 1:
62
- case 1:
1411
- omap_clk_reparent(core, dpll);
63
- a = b;
1412
- break;
64
- break;
1413
- case 2:
65
- case 2:
1414
- /* Default */
66
- a = c;
1415
- omap_clk_reparent(core, dpll_x2);
1416
- break;
1417
- case 3:
1418
- fprintf(stderr, "%s: bad CORE_CLK_SRC\n", __func__);
1419
- break;
1420
- }
1421
-}
1422
-
1423
-static void omap_prcm_write(void *opaque, hwaddr addr,
1424
- uint64_t value, unsigned size)
1425
-{
1426
- struct omap_prcm_s *s = opaque;
1427
-
1428
- if (size != 4) {
1429
- omap_badwidth_write32(opaque, addr, value);
1430
- return;
1431
- }
1432
-
1433
- switch (addr) {
1434
- case 0x000:    /* PRCM_REVISION */
1435
- case 0x054:    /* PRCM_VOLTST */
1436
- case 0x084:    /* PRCM_CLKCFG_STATUS */
1437
- case 0x1e4:    /* PM_PWSTST_MPU */
1438
- case 0x220:    /* CM_IDLEST1_CORE */
1439
- case 0x224:    /* CM_IDLEST2_CORE */
1440
- case 0x22c:    /* CM_IDLEST4_CORE */
1441
- case 0x2c8:    /* PM_WKDEP_CORE */
1442
- case 0x2e4:    /* PM_PWSTST_CORE */
1443
- case 0x320:    /* CM_IDLEST_GFX */
1444
- case 0x3e4:    /* PM_PWSTST_GFX */
1445
- case 0x420:    /* CM_IDLEST_WKUP */
1446
- case 0x520:    /* CM_IDLEST_CKGEN */
1447
- case 0x820:    /* CM_IDLEST_DSP */
1448
- case 0x8e4:    /* PM_PWSTST_DSP */
1449
- OMAP_RO_REG(addr);
1450
- return;
1451
-
1452
- case 0x010:    /* PRCM_SYSCONFIG */
1453
- s->sysconfig = value & 1;
1454
- break;
1455
-
1456
- case 0x018:    /* PRCM_IRQSTATUS_MPU */
1457
- s->irqst[0] &= ~value;
1458
- omap_prcm_int_update(s, 0);
1459
- break;
1460
- case 0x01c:    /* PRCM_IRQENABLE_MPU */
1461
- s->irqen[0] = value & 0x3f;
1462
- omap_prcm_int_update(s, 0);
1463
- break;
1464
-
1465
- case 0x050:    /* PRCM_VOLTCTRL */
1466
- s->voltctrl = value & 0xf1c3;
1467
- break;
1468
-
1469
- case 0x060:    /* PRCM_CLKSRC_CTRL */
1470
- s->clksrc[0] = value & 0xdb;
1471
- /* TODO update clocks */
1472
- break;
1473
-
1474
- case 0x070:    /* PRCM_CLKOUT_CTRL */
1475
- s->clkout[0] = value & 0xbbbb;
1476
- /* TODO update clocks */
1477
- break;
1478
-
1479
- case 0x078:    /* PRCM_CLKEMUL_CTRL */
1480
- s->clkemul[0] = value & 1;
1481
- /* TODO update clocks */
1482
- break;
1483
-
1484
- case 0x080:    /* PRCM_CLKCFG_CTRL */
1485
- break;
1486
-
1487
- case 0x090:    /* PRCM_VOLTSETUP */
1488
- s->setuptime[0] = value & 0xffff;
1489
- break;
1490
- case 0x094:    /* PRCM_CLKSSETUP */
1491
- s->setuptime[1] = value & 0xffff;
1492
- break;
1493
-
1494
- case 0x098:    /* PRCM_POLCTRL */
1495
- s->clkpol[0] = value & 0x701;
1496
- break;
1497
-
1498
- case 0x0b0:    /* GENERAL_PURPOSE1 */
1499
- case 0x0b4:    /* GENERAL_PURPOSE2 */
1500
- case 0x0b8:    /* GENERAL_PURPOSE3 */
1501
- case 0x0bc:    /* GENERAL_PURPOSE4 */
1502
- case 0x0c0:    /* GENERAL_PURPOSE5 */
1503
- case 0x0c4:    /* GENERAL_PURPOSE6 */
1504
- case 0x0c8:    /* GENERAL_PURPOSE7 */
1505
- case 0x0cc:    /* GENERAL_PURPOSE8 */
1506
- case 0x0d0:    /* GENERAL_PURPOSE9 */
1507
- case 0x0d4:    /* GENERAL_PURPOSE10 */
1508
- case 0x0d8:    /* GENERAL_PURPOSE11 */
1509
- case 0x0dc:    /* GENERAL_PURPOSE12 */
1510
- case 0x0e0:    /* GENERAL_PURPOSE13 */
1511
- case 0x0e4:    /* GENERAL_PURPOSE14 */
1512
- case 0x0e8:    /* GENERAL_PURPOSE15 */
1513
- case 0x0ec:    /* GENERAL_PURPOSE16 */
1514
- case 0x0f0:    /* GENERAL_PURPOSE17 */
1515
- case 0x0f4:    /* GENERAL_PURPOSE18 */
1516
- case 0x0f8:    /* GENERAL_PURPOSE19 */
1517
- case 0x0fc:    /* GENERAL_PURPOSE20 */
1518
- s->scratch[(addr - 0xb0) >> 2] = value;
1519
- break;
1520
-
1521
- case 0x140:    /* CM_CLKSEL_MPU */
1522
- s->clksel[0] = value & 0x1f;
1523
- /* TODO update clocks */
1524
- break;
1525
- case 0x148:    /* CM_CLKSTCTRL_MPU */
1526
- s->clkctrl[0] = value & 0x1f;
1527
- break;
1528
-
1529
- case 0x158:    /* RM_RSTST_MPU */
1530
- s->rst[0] &= ~value;
1531
- break;
1532
- case 0x1c8:    /* PM_WKDEP_MPU */
1533
- s->wkup[0] = value & 0x15;
1534
- break;
1535
-
1536
- case 0x1d4:    /* PM_EVGENCTRL_MPU */
1537
- s->ev = value & 0x1f;
1538
- break;
1539
- case 0x1d8:    /* PM_EVEGENONTIM_MPU */
1540
- s->evtime[0] = value;
1541
- break;
1542
- case 0x1dc:    /* PM_EVEGENOFFTIM_MPU */
1543
- s->evtime[1] = value;
1544
- break;
1545
-
1546
- case 0x1e0:    /* PM_PWSTCTRL_MPU */
1547
- s->power[0] = value & 0xc0f;
1548
- break;
1549
-
1550
- case 0x200:    /* CM_FCLKEN1_CORE */
1551
- s->clken[0] = value & 0xbfffffff;
1552
- /* TODO update clocks */
1553
- /* The EN_EAC bit only gets/puts func_96m_clk. */
1554
- break;
1555
- case 0x204:    /* CM_FCLKEN2_CORE */
1556
- s->clken[1] = value & 0x00000007;
1557
- /* TODO update clocks */
1558
- break;
1559
- case 0x210:    /* CM_ICLKEN1_CORE */
1560
- s->clken[2] = value & 0xfffffff9;
1561
- /* TODO update clocks */
1562
- /* The EN_EAC bit only gets/puts core_l4_iclk. */
1563
- break;
1564
- case 0x214:    /* CM_ICLKEN2_CORE */
1565
- s->clken[3] = value & 0x00000007;
1566
- /* TODO update clocks */
1567
- break;
1568
- case 0x21c:    /* CM_ICLKEN4_CORE */
1569
- s->clken[4] = value & 0x0000001f;
1570
- /* TODO update clocks */
1571
- break;
1572
-
1573
- case 0x230:    /* CM_AUTOIDLE1_CORE */
1574
- s->clkidle[0] = value & 0xfffffff9;
1575
- /* TODO update clocks */
1576
- break;
1577
- case 0x234:    /* CM_AUTOIDLE2_CORE */
1578
- s->clkidle[1] = value & 0x00000007;
1579
- /* TODO update clocks */
1580
- break;
1581
- case 0x238:    /* CM_AUTOIDLE3_CORE */
1582
- s->clkidle[2] = value & 0x00000007;
1583
- /* TODO update clocks */
1584
- break;
1585
- case 0x23c:    /* CM_AUTOIDLE4_CORE */
1586
- s->clkidle[3] = value & 0x0000001f;
1587
- /* TODO update clocks */
1588
- break;
1589
-
1590
- case 0x240:    /* CM_CLKSEL1_CORE */
1591
- s->clksel[1] = value & 0x0fffbf7f;
1592
- /* TODO update clocks */
1593
- break;
1594
-
1595
- case 0x244:    /* CM_CLKSEL2_CORE */
1596
- s->clksel[2] = value & 0x00fffffc;
1597
- /* TODO update clocks */
1598
- break;
1599
-
1600
- case 0x248:    /* CM_CLKSTCTRL_CORE */
1601
- s->clkctrl[1] = value & 0x7;
1602
- break;
1603
-
1604
- case 0x2a0:    /* PM_WKEN1_CORE */
1605
- s->wken[0] = value & 0x04667ff8;
1606
- break;
1607
- case 0x2a4:    /* PM_WKEN2_CORE */
1608
- s->wken[1] = value & 0x00000005;
1609
- break;
1610
-
1611
- case 0x2b0:    /* PM_WKST1_CORE */
1612
- s->wkst[0] &= ~value;
1613
- break;
1614
- case 0x2b4:    /* PM_WKST2_CORE */
1615
- s->wkst[1] &= ~value;
1616
- break;
1617
-
1618
- case 0x2e0:    /* PM_PWSTCTRL_CORE */
1619
- s->power[1] = (value & 0x00fc3f) | (1 << 2);
1620
- break;
1621
-
1622
- case 0x300:    /* CM_FCLKEN_GFX */
1623
- s->clken[5] = value & 6;
1624
- /* TODO update clocks */
1625
- break;
1626
- case 0x310:    /* CM_ICLKEN_GFX */
1627
- s->clken[6] = value & 1;
1628
- /* TODO update clocks */
1629
- break;
1630
- case 0x340:    /* CM_CLKSEL_GFX */
1631
- s->clksel[3] = value & 7;
1632
- /* TODO update clocks */
1633
- break;
1634
- case 0x348:    /* CM_CLKSTCTRL_GFX */
1635
- s->clkctrl[2] = value & 1;
1636
- break;
1637
- case 0x350:    /* RM_RSTCTRL_GFX */
1638
- s->rstctrl[0] = value & 1;
1639
- /* TODO: reset */
1640
- break;
1641
- case 0x358:    /* RM_RSTST_GFX */
1642
- s->rst[1] &= ~value;
1643
- break;
1644
- case 0x3c8:    /* PM_WKDEP_GFX */
1645
- s->wkup[1] = value & 0x13;
1646
- break;
1647
- case 0x3e0:    /* PM_PWSTCTRL_GFX */
1648
- s->power[2] = (value & 0x00c0f) | (3 << 2);
1649
- break;
1650
-
1651
- case 0x400:    /* CM_FCLKEN_WKUP */
1652
- s->clken[7] = value & 0xd;
1653
- /* TODO update clocks */
1654
- break;
1655
- case 0x410:    /* CM_ICLKEN_WKUP */
1656
- s->clken[8] = value & 0x3f;
1657
- /* TODO update clocks */
1658
- break;
1659
- case 0x430:    /* CM_AUTOIDLE_WKUP */
1660
- s->clkidle[4] = value & 0x0000003f;
1661
- /* TODO update clocks */
1662
- break;
1663
- case 0x440:    /* CM_CLKSEL_WKUP */
1664
- s->clksel[4] = value & 3;
1665
- /* TODO update clocks */
1666
- break;
1667
- case 0x450:    /* RM_RSTCTRL_WKUP */
1668
- /* TODO: reset */
1669
- if (value & 2)
1670
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
1671
- break;
1672
- case 0x454:    /* RM_RSTTIME_WKUP */
1673
- s->rsttime_wkup = value & 0x1fff;
1674
- break;
1675
- case 0x458:    /* RM_RSTST_WKUP */
1676
- s->rst[2] &= ~value;
1677
- break;
1678
- case 0x4a0:    /* PM_WKEN_WKUP */
1679
- s->wken[2] = value & 0x00000005;
1680
- break;
1681
- case 0x4b0:    /* PM_WKST_WKUP */
1682
- s->wkst[2] &= ~value;
1683
- break;
1684
-
1685
- case 0x500:    /* CM_CLKEN_PLL */
1686
- if (value & 0xffffff30)
1687
- fprintf(stderr, "%s: write 0s in CM_CLKEN_PLL for "
1688
- "future compatibility\n", __func__);
1689
- if ((s->clken[9] ^ value) & 0xcc) {
1690
- s->clken[9] &= ~0xcc;
1691
- s->clken[9] |= value & 0xcc;
1692
- omap_prcm_apll_update(s);
1693
- }
1694
- if ((s->clken[9] ^ value) & 3) {
1695
- s->clken[9] &= ~3;
1696
- s->clken[9] |= value & 3;
1697
- omap_prcm_dpll_update(s);
1698
- }
1699
- break;
1700
- case 0x530:    /* CM_AUTOIDLE_PLL */
1701
- s->clkidle[5] = value & 0x000000cf;
1702
- /* TODO update clocks */
1703
- break;
1704
- case 0x540:    /* CM_CLKSEL1_PLL */
1705
- if (value & 0xfc4000d7)
1706
- fprintf(stderr, "%s: write 0s in CM_CLKSEL1_PLL for "
1707
- "future compatibility\n", __func__);
1708
- if ((s->clksel[5] ^ value) & 0x003fff00) {
1709
- s->clksel[5] = value & 0x03bfff28;
1710
- omap_prcm_dpll_update(s);
1711
- }
1712
- /* TODO update the other clocks */
1713
-
1714
- s->clksel[5] = value & 0x03bfff28;
1715
- break;
1716
- case 0x544:    /* CM_CLKSEL2_PLL */
1717
- if (value & ~3)
1718
- fprintf(stderr, "%s: write 0s in CM_CLKSEL2_PLL[31:2] for "
1719
- "future compatibility\n", __func__);
1720
- if (s->clksel[6] != (value & 3)) {
1721
- s->clksel[6] = value & 3;
1722
- omap_prcm_dpll_update(s);
1723
- }
1724
- break;
1725
-
1726
- case 0x800:    /* CM_FCLKEN_DSP */
1727
- s->clken[10] = value & 0x501;
1728
- /* TODO update clocks */
1729
- break;
1730
- case 0x810:    /* CM_ICLKEN_DSP */
1731
- s->clken[11] = value & 0x2;
1732
- /* TODO update clocks */
1733
- break;
1734
- case 0x830:    /* CM_AUTOIDLE_DSP */
1735
- s->clkidle[6] = value & 0x2;
1736
- /* TODO update clocks */
1737
- break;
1738
- case 0x840:    /* CM_CLKSEL_DSP */
1739
- s->clksel[7] = value & 0x3fff;
1740
- /* TODO update clocks */
1741
- break;
1742
- case 0x848:    /* CM_CLKSTCTRL_DSP */
1743
- s->clkctrl[3] = value & 0x101;
1744
- break;
1745
- case 0x850:    /* RM_RSTCTRL_DSP */
1746
- /* TODO: reset */
1747
- break;
1748
- case 0x858:    /* RM_RSTST_DSP */
1749
- s->rst[3] &= ~value;
1750
- break;
1751
- case 0x8c8:    /* PM_WKDEP_DSP */
1752
- s->wkup[2] = value & 0x13;
1753
- break;
1754
- case 0x8e0:    /* PM_PWSTCTRL_DSP */
1755
- s->power[3] = (value & 0x03017) | (3 << 2);
1756
- break;
1757
-
1758
- case 0x8f0:    /* PRCM_IRQSTATUS_DSP */
1759
- s->irqst[1] &= ~value;
1760
- omap_prcm_int_update(s, 1);
1761
- break;
1762
- case 0x8f4:    /* PRCM_IRQENABLE_DSP */
1763
- s->irqen[1] = value & 0x7;
1764
- omap_prcm_int_update(s, 1);
1765
- break;
1766
-
1767
- case 0x8f8:    /* PRCM_IRQSTATUS_IVA */
1768
- s->irqst[2] &= ~value;
1769
- omap_prcm_int_update(s, 2);
1770
- break;
1771
- case 0x8fc:    /* PRCM_IRQENABLE_IVA */
1772
- s->irqen[2] = value & 0x7;
1773
- omap_prcm_int_update(s, 2);
1774
- break;
1775
-
1776
- default:
1777
- OMAP_BAD_REG(addr);
1778
- return;
1779
- }
1780
-}
1781
-
1782
-static const MemoryRegionOps omap_prcm_ops = {
1783
- .read = omap_prcm_read,
1784
- .write = omap_prcm_write,
1785
- .endianness = DEVICE_NATIVE_ENDIAN,
1786
-};
1787
-
1788
-static void omap_prcm_reset(struct omap_prcm_s *s)
1789
-{
1790
- s->sysconfig = 0;
1791
- s->irqst[0] = 0;
1792
- s->irqst[1] = 0;
1793
- s->irqst[2] = 0;
1794
- s->irqen[0] = 0;
1795
- s->irqen[1] = 0;
1796
- s->irqen[2] = 0;
1797
- s->voltctrl = 0x1040;
1798
- s->ev = 0x14;
1799
- s->evtime[0] = 0;
1800
- s->evtime[1] = 0;
1801
- s->clkctrl[0] = 0;
1802
- s->clkctrl[1] = 0;
1803
- s->clkctrl[2] = 0;
1804
- s->clkctrl[3] = 0;
1805
- s->clken[1] = 7;
1806
- s->clken[3] = 7;
1807
- s->clken[4] = 0;
1808
- s->clken[5] = 0;
1809
- s->clken[6] = 0;
1810
- s->clken[7] = 0xc;
1811
- s->clken[8] = 0x3e;
1812
- s->clken[9] = 0x0d;
1813
- s->clken[10] = 0;
1814
- s->clken[11] = 0;
1815
- s->clkidle[0] = 0;
1816
- s->clkidle[2] = 7;
1817
- s->clkidle[3] = 0;
1818
- s->clkidle[4] = 0;
1819
- s->clkidle[5] = 0x0c;
1820
- s->clkidle[6] = 0;
1821
- s->clksel[0] = 0x01;
1822
- s->clksel[1] = 0x02100121;
1823
- s->clksel[2] = 0x00000000;
1824
- s->clksel[3] = 0x01;
1825
- s->clksel[4] = 0;
1826
- s->clksel[7] = 0x0121;
1827
- s->wkup[0] = 0x15;
1828
- s->wkup[1] = 0x13;
1829
- s->wkup[2] = 0x13;
1830
- s->wken[0] = 0x04667ff8;
1831
- s->wken[1] = 0x00000005;
1832
- s->wken[2] = 5;
1833
- s->wkst[0] = 0;
1834
- s->wkst[1] = 0;
1835
- s->wkst[2] = 0;
1836
- s->power[0] = 0x00c;
1837
- s->power[1] = 4;
1838
- s->power[2] = 0x0000c;
1839
- s->power[3] = 0x14;
1840
- s->rstctrl[0] = 1;
1841
- s->rst[3] = 1;
1842
- omap_prcm_apll_update(s);
1843
- omap_prcm_dpll_update(s);
1844
-}
1845
-
1846
-static void omap_prcm_coldreset(struct omap_prcm_s *s)
1847
-{
1848
- s->setuptime[0] = 0;
1849
- s->setuptime[1] = 0;
1850
- memset(&s->scratch, 0, sizeof(s->scratch));
1851
- s->rst[0] = 0x01;
1852
- s->rst[1] = 0x00;
1853
- s->rst[2] = 0x01;
1854
- s->clken[0] = 0;
1855
- s->clken[2] = 0;
1856
- s->clkidle[1] = 0;
1857
- s->clksel[5] = 0;
1858
- s->clksel[6] = 2;
1859
- s->clksrc[0] = 0x43;
1860
- s->clkout[0] = 0x0303;
1861
- s->clkemul[0] = 0;
1862
- s->clkpol[0] = 0x100;
1863
- s->rsttime_wkup = 0x1002;
1864
-
1865
- omap_prcm_reset(s);
1866
-}
1867
-
1868
-static struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
1869
- qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
1870
- struct omap_mpu_state_s *mpu)
1871
-{
1872
- struct omap_prcm_s *s = g_new0(struct omap_prcm_s, 1);
1873
-
1874
- s->irq[0] = mpu_int;
1875
- s->irq[1] = dsp_int;
1876
- s->irq[2] = iva_int;
1877
- s->mpu = mpu;
1878
- omap_prcm_coldreset(s);
1879
-
1880
- memory_region_init_io(&s->iomem0, NULL, &omap_prcm_ops, s, "omap.pcrm0",
1881
- omap_l4_region_size(ta, 0));
1882
- memory_region_init_io(&s->iomem1, NULL, &omap_prcm_ops, s, "omap.pcrm1",
1883
- omap_l4_region_size(ta, 1));
1884
- omap_l4_attach(ta, 0, &s->iomem0);
1885
- omap_l4_attach(ta, 1, &s->iomem1);
1886
-
1887
- return s;
1888
-}
1889
-
1890
-/* System and Pinout control */
1891
-struct omap_sysctl_s {
1892
- struct omap_mpu_state_s *mpu;
1893
- MemoryRegion iomem;
1894
-
1895
- uint32_t sysconfig;
1896
- uint32_t devconfig;
1897
- uint32_t psaconfig;
1898
- uint32_t padconf[0x45];
1899
- uint8_t obs;
1900
- uint32_t msuspendmux[5];
1901
-};
1902
-
1903
-static uint32_t omap_sysctl_read8(void *opaque, hwaddr addr)
1904
-{
1905
-
1906
- struct omap_sysctl_s *s = opaque;
1907
- int pad_offset, byte_offset;
1908
- int value;
1909
-
1910
- switch (addr) {
1911
- case 0x030 ... 0x140:    /* CONTROL_PADCONF - only used in the POP */
1912
- pad_offset = (addr - 0x30) >> 2;
1913
- byte_offset = (addr - 0x30) & (4 - 1);
1914
-
1915
- value = s->padconf[pad_offset];
1916
- value = (value >> (byte_offset * 8)) & 0xff;
1917
-
1918
- return value;
1919
-
1920
- default:
1921
- break;
1922
- }
1923
-
1924
- OMAP_BAD_REG(addr);
1925
- return 0;
1926
-}
1927
-
1928
-static uint32_t omap_sysctl_read(void *opaque, hwaddr addr)
1929
-{
1930
- struct omap_sysctl_s *s = opaque;
1931
-
1932
- switch (addr) {
1933
- case 0x000:    /* CONTROL_REVISION */
1934
- return 0x20;
1935
-
1936
- case 0x010:    /* CONTROL_SYSCONFIG */
1937
- return s->sysconfig;
1938
-
1939
- case 0x030 ... 0x140:    /* CONTROL_PADCONF - only used in the POP */
1940
- return s->padconf[(addr - 0x30) >> 2];
1941
-
1942
- case 0x270:    /* CONTROL_DEBOBS */
1943
- return s->obs;
1944
-
1945
- case 0x274:    /* CONTROL_DEVCONF */
1946
- return s->devconfig;
1947
-
1948
- case 0x28c:    /* CONTROL_EMU_SUPPORT */
1949
- return 0;
1950
-
1951
- case 0x290:    /* CONTROL_MSUSPENDMUX_0 */
1952
- return s->msuspendmux[0];
1953
- case 0x294:    /* CONTROL_MSUSPENDMUX_1 */
1954
- return s->msuspendmux[1];
1955
- case 0x298:    /* CONTROL_MSUSPENDMUX_2 */
1956
- return s->msuspendmux[2];
1957
- case 0x29c:    /* CONTROL_MSUSPENDMUX_3 */
1958
- return s->msuspendmux[3];
1959
- case 0x2a0:    /* CONTROL_MSUSPENDMUX_4 */
1960
- return s->msuspendmux[4];
1961
- case 0x2a4:    /* CONTROL_MSUSPENDMUX_5 */
1962
- return 0;
1963
-
1964
- case 0x2b8:    /* CONTROL_PSA_CTRL */
1965
- return s->psaconfig;
1966
- case 0x2bc:    /* CONTROL_PSA_CMD */
1967
- case 0x2c0:    /* CONTROL_PSA_VALUE */
1968
- return 0;
1969
-
1970
- case 0x2b0:    /* CONTROL_SEC_CTRL */
1971
- return 0x800000f1;
1972
- case 0x2d0:    /* CONTROL_SEC_EMU */
1973
- return 0x80000015;
1974
- case 0x2d4:    /* CONTROL_SEC_TAP */
1975
- return 0x8000007f;
1976
- case 0x2b4:    /* CONTROL_SEC_TEST */
1977
- case 0x2f0:    /* CONTROL_SEC_STATUS */
1978
- case 0x2f4:    /* CONTROL_SEC_ERR_STATUS */
1979
- /* Secure mode is not present on general-pusrpose device. Outside
1980
- * secure mode these values cannot be read or written. */
1981
- return 0;
1982
-
1983
- case 0x2d8:    /* CONTROL_OCM_RAM_PERM */
1984
- return 0xff;
1985
- case 0x2dc:    /* CONTROL_OCM_PUB_RAM_ADD */
1986
- case 0x2e0:    /* CONTROL_EXT_SEC_RAM_START_ADD */
1987
- case 0x2e4:    /* CONTROL_EXT_SEC_RAM_STOP_ADD */
1988
- /* No secure mode so no Extended Secure RAM present. */
1989
- return 0;
1990
-
1991
- case 0x2f8:    /* CONTROL_STATUS */
1992
- /* Device Type => General-purpose */
1993
- return 0x0300;
1994
- case 0x2fc:    /* CONTROL_GENERAL_PURPOSE_STATUS */
1995
-
1996
- case 0x300:    /* CONTROL_RPUB_KEY_H_0 */
1997
- case 0x304:    /* CONTROL_RPUB_KEY_H_1 */
1998
- case 0x308:    /* CONTROL_RPUB_KEY_H_2 */
1999
- case 0x30c:    /* CONTROL_RPUB_KEY_H_3 */
2000
- return 0xdecafbad;
2001
-
2002
- case 0x310:    /* CONTROL_RAND_KEY_0 */
2003
- case 0x314:    /* CONTROL_RAND_KEY_1 */
2004
- case 0x318:    /* CONTROL_RAND_KEY_2 */
2005
- case 0x31c:    /* CONTROL_RAND_KEY_3 */
2006
- case 0x320:    /* CONTROL_CUST_KEY_0 */
2007
- case 0x324:    /* CONTROL_CUST_KEY_1 */
2008
- case 0x330:    /* CONTROL_TEST_KEY_0 */
2009
- case 0x334:    /* CONTROL_TEST_KEY_1 */
2010
- case 0x338:    /* CONTROL_TEST_KEY_2 */
2011
- case 0x33c:    /* CONTROL_TEST_KEY_3 */
2012
- case 0x340:    /* CONTROL_TEST_KEY_4 */
2013
- case 0x344:    /* CONTROL_TEST_KEY_5 */
2014
- case 0x348:    /* CONTROL_TEST_KEY_6 */
2015
- case 0x34c:    /* CONTROL_TEST_KEY_7 */
2016
- case 0x350:    /* CONTROL_TEST_KEY_8 */
2017
- case 0x354:    /* CONTROL_TEST_KEY_9 */
2018
- /* Can only be accessed in secure mode and when C_FieldAccEnable
2019
- * bit is set in CONTROL_SEC_CTRL.
2020
- * TODO: otherwise an interconnect access error is generated. */
2021
- return 0;
2022
- }
2023
-
2024
- OMAP_BAD_REG(addr);
2025
- return 0;
2026
-}
2027
-
2028
-static void omap_sysctl_write8(void *opaque, hwaddr addr, uint32_t value)
2029
-{
2030
- struct omap_sysctl_s *s = opaque;
2031
- int pad_offset, byte_offset;
2032
- int prev_value;
2033
-
2034
- switch (addr) {
2035
- case 0x030 ... 0x140:    /* CONTROL_PADCONF - only used in the POP */
2036
- pad_offset = (addr - 0x30) >> 2;
2037
- byte_offset = (addr - 0x30) & (4 - 1);
2038
-
2039
- prev_value = s->padconf[pad_offset];
2040
- prev_value &= ~(0xff << (byte_offset * 8));
2041
- prev_value |= ((value & 0x1f1f1f1f) << (byte_offset * 8)) & 0x1f1f1f1f;
2042
- s->padconf[pad_offset] = prev_value;
2043
- break;
2044
-
2045
- default:
2046
- OMAP_BAD_REG(addr);
2047
- break;
2048
- }
2049
-}
2050
-
2051
-static void omap_sysctl_write(void *opaque, hwaddr addr, uint32_t value)
2052
-{
2053
- struct omap_sysctl_s *s = opaque;
2054
-
2055
- switch (addr) {
2056
- case 0x000:    /* CONTROL_REVISION */
2057
- case 0x2a4:    /* CONTROL_MSUSPENDMUX_5 */
2058
- case 0x2c0:    /* CONTROL_PSA_VALUE */
2059
- case 0x2f8:    /* CONTROL_STATUS */
2060
- case 0x2fc:    /* CONTROL_GENERAL_PURPOSE_STATUS */
2061
- case 0x300:    /* CONTROL_RPUB_KEY_H_0 */
2062
- case 0x304:    /* CONTROL_RPUB_KEY_H_1 */
2063
- case 0x308:    /* CONTROL_RPUB_KEY_H_2 */
2064
- case 0x30c:    /* CONTROL_RPUB_KEY_H_3 */
2065
- case 0x310:    /* CONTROL_RAND_KEY_0 */
2066
- case 0x314:    /* CONTROL_RAND_KEY_1 */
2067
- case 0x318:    /* CONTROL_RAND_KEY_2 */
2068
- case 0x31c:    /* CONTROL_RAND_KEY_3 */
2069
- case 0x320:    /* CONTROL_CUST_KEY_0 */
2070
- case 0x324:    /* CONTROL_CUST_KEY_1 */
2071
- case 0x330:    /* CONTROL_TEST_KEY_0 */
2072
- case 0x334:    /* CONTROL_TEST_KEY_1 */
2073
- case 0x338:    /* CONTROL_TEST_KEY_2 */
2074
- case 0x33c:    /* CONTROL_TEST_KEY_3 */
2075
- case 0x340:    /* CONTROL_TEST_KEY_4 */
2076
- case 0x344:    /* CONTROL_TEST_KEY_5 */
2077
- case 0x348:    /* CONTROL_TEST_KEY_6 */
2078
- case 0x34c:    /* CONTROL_TEST_KEY_7 */
2079
- case 0x350:    /* CONTROL_TEST_KEY_8 */
2080
- case 0x354:    /* CONTROL_TEST_KEY_9 */
2081
- OMAP_RO_REG(addr);
2082
- return;
2083
-
2084
- case 0x010:    /* CONTROL_SYSCONFIG */
2085
- s->sysconfig = value & 0x1e;
2086
- break;
2087
-
2088
- case 0x030 ... 0x140:    /* CONTROL_PADCONF - only used in the POP */
2089
- /* XXX: should check constant bits */
2090
- s->padconf[(addr - 0x30) >> 2] = value & 0x1f1f1f1f;
2091
- break;
2092
-
2093
- case 0x270:    /* CONTROL_DEBOBS */
2094
- s->obs = value & 0xff;
2095
- break;
2096
-
2097
- case 0x274:    /* CONTROL_DEVCONF */
2098
- s->devconfig = value & 0xffffc7ff;
2099
- break;
2100
-
2101
- case 0x28c:    /* CONTROL_EMU_SUPPORT */
2102
- break;
2103
-
2104
- case 0x290:    /* CONTROL_MSUSPENDMUX_0 */
2105
- s->msuspendmux[0] = value & 0x3fffffff;
2106
- break;
2107
- case 0x294:    /* CONTROL_MSUSPENDMUX_1 */
2108
- s->msuspendmux[1] = value & 0x3fffffff;
2109
- break;
2110
- case 0x298:    /* CONTROL_MSUSPENDMUX_2 */
2111
- s->msuspendmux[2] = value & 0x3fffffff;
2112
- break;
2113
- case 0x29c:    /* CONTROL_MSUSPENDMUX_3 */
2114
- s->msuspendmux[3] = value & 0x3fffffff;
2115
- break;
2116
- case 0x2a0:    /* CONTROL_MSUSPENDMUX_4 */
2117
- s->msuspendmux[4] = value & 0x3fffffff;
2118
- break;
2119
-
2120
- case 0x2b8:    /* CONTROL_PSA_CTRL */
2121
- s->psaconfig = value & 0x1c;
2122
- s->psaconfig |= (value & 0x20) ? 2 : 1;
2123
- break;
2124
- case 0x2bc:    /* CONTROL_PSA_CMD */
2125
- break;
2126
-
2127
- case 0x2b0:    /* CONTROL_SEC_CTRL */
2128
- case 0x2b4:    /* CONTROL_SEC_TEST */
2129
- case 0x2d0:    /* CONTROL_SEC_EMU */
2130
- case 0x2d4:    /* CONTROL_SEC_TAP */
2131
- case 0x2d8:    /* CONTROL_OCM_RAM_PERM */
2132
- case 0x2dc:    /* CONTROL_OCM_PUB_RAM_ADD */
2133
- case 0x2e0:    /* CONTROL_EXT_SEC_RAM_START_ADD */
2134
- case 0x2e4:    /* CONTROL_EXT_SEC_RAM_STOP_ADD */
2135
- case 0x2f0:    /* CONTROL_SEC_STATUS */
2136
- case 0x2f4:    /* CONTROL_SEC_ERR_STATUS */
2137
- break;
2138
-
2139
- default:
2140
- OMAP_BAD_REG(addr);
2141
- return;
2142
- }
2143
-}
2144
-
2145
-static uint64_t omap_sysctl_readfn(void *opaque, hwaddr addr,
2146
- unsigned size)
2147
-{
2148
- switch (size) {
2149
- case 1:
2150
- return omap_sysctl_read8(opaque, addr);
2151
- case 2:
2152
- return omap_badwidth_read32(opaque, addr); /* TODO */
2153
- case 4:
2154
- return omap_sysctl_read(opaque, addr);
2155
- default:
2156
- g_assert_not_reached();
2157
- }
2158
-}
2159
-
2160
-static void omap_sysctl_writefn(void *opaque, hwaddr addr,
2161
- uint64_t value, unsigned size)
2162
-{
2163
- switch (size) {
2164
- case 1:
2165
- omap_sysctl_write8(opaque, addr, value);
2166
- break;
2167
- case 2:
2168
- omap_badwidth_write32(opaque, addr, value); /* TODO */
2169
- break;
2170
- case 4:
2171
- omap_sysctl_write(opaque, addr, value);
2172
- break;
67
- break;
2173
- default:
68
- default:
2174
- g_assert_not_reached();
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);
2175
- }
75
- }
2176
-}
76
- return a;
2177
-
77
+ return ret;
2178
-static const MemoryRegionOps omap_sysctl_ops = {
78
2179
- .read = omap_sysctl_readfn,
79
default_nan:
2180
- .write = omap_sysctl_writefn,
80
parts_default_nan(a, s);
2181
- .valid.min_access_size = 1,
2182
- .valid.max_access_size = 4,
2183
- .endianness = DEVICE_NATIVE_ENDIAN,
2184
-};
2185
-
2186
-static void omap_sysctl_reset(struct omap_sysctl_s *s)
2187
-{
2188
- /* (power-on reset) */
2189
- s->sysconfig = 0;
2190
- s->obs = 0;
2191
- s->devconfig = 0x0c000000;
2192
- s->msuspendmux[0] = 0x00000000;
2193
- s->msuspendmux[1] = 0x00000000;
2194
- s->msuspendmux[2] = 0x00000000;
2195
- s->msuspendmux[3] = 0x00000000;
2196
- s->msuspendmux[4] = 0x00000000;
2197
- s->psaconfig = 1;
2198
-
2199
- s->padconf[0x00] = 0x000f0f0f;
2200
- s->padconf[0x01] = 0x00000000;
2201
- s->padconf[0x02] = 0x00000000;
2202
- s->padconf[0x03] = 0x00000000;
2203
- s->padconf[0x04] = 0x00000000;
2204
- s->padconf[0x05] = 0x00000000;
2205
- s->padconf[0x06] = 0x00000000;
2206
- s->padconf[0x07] = 0x00000000;
2207
- s->padconf[0x08] = 0x08080800;
2208
- s->padconf[0x09] = 0x08080808;
2209
- s->padconf[0x0a] = 0x08080808;
2210
- s->padconf[0x0b] = 0x08080808;
2211
- s->padconf[0x0c] = 0x08080808;
2212
- s->padconf[0x0d] = 0x08080800;
2213
- s->padconf[0x0e] = 0x08080808;
2214
- s->padconf[0x0f] = 0x08080808;
2215
- s->padconf[0x10] = 0x18181808;    /* | 0x07070700 if SBoot3 */
2216
- s->padconf[0x11] = 0x18181818;    /* | 0x07070707 if SBoot3 */
2217
- s->padconf[0x12] = 0x18181818;    /* | 0x07070707 if SBoot3 */
2218
- s->padconf[0x13] = 0x18181818;    /* | 0x07070707 if SBoot3 */
2219
- s->padconf[0x14] = 0x18181818;    /* | 0x00070707 if SBoot3 */
2220
- s->padconf[0x15] = 0x18181818;
2221
- s->padconf[0x16] = 0x18181818;    /* | 0x07000000 if SBoot3 */
2222
- s->padconf[0x17] = 0x1f001f00;
2223
- s->padconf[0x18] = 0x1f1f1f1f;
2224
- s->padconf[0x19] = 0x00000000;
2225
- s->padconf[0x1a] = 0x1f180000;
2226
- s->padconf[0x1b] = 0x00001f1f;
2227
- s->padconf[0x1c] = 0x1f001f00;
2228
- s->padconf[0x1d] = 0x00000000;
2229
- s->padconf[0x1e] = 0x00000000;
2230
- s->padconf[0x1f] = 0x08000000;
2231
- s->padconf[0x20] = 0x08080808;
2232
- s->padconf[0x21] = 0x08080808;
2233
- s->padconf[0x22] = 0x0f080808;
2234
- s->padconf[0x23] = 0x0f0f0f0f;
2235
- s->padconf[0x24] = 0x000f0f0f;
2236
- s->padconf[0x25] = 0x1f1f1f0f;
2237
- s->padconf[0x26] = 0x080f0f1f;
2238
- s->padconf[0x27] = 0x070f1808;
2239
- s->padconf[0x28] = 0x0f070707;
2240
- s->padconf[0x29] = 0x000f0f1f;
2241
- s->padconf[0x2a] = 0x0f0f0f1f;
2242
- s->padconf[0x2b] = 0x08000000;
2243
- s->padconf[0x2c] = 0x0000001f;
2244
- s->padconf[0x2d] = 0x0f0f1f00;
2245
- s->padconf[0x2e] = 0x1f1f0f0f;
2246
- s->padconf[0x2f] = 0x0f1f1f1f;
2247
- s->padconf[0x30] = 0x0f0f0f0f;
2248
- s->padconf[0x31] = 0x0f1f0f1f;
2249
- s->padconf[0x32] = 0x0f0f0f0f;
2250
- s->padconf[0x33] = 0x0f1f0f1f;
2251
- s->padconf[0x34] = 0x1f1f0f0f;
2252
- s->padconf[0x35] = 0x0f0f1f1f;
2253
- s->padconf[0x36] = 0x0f0f1f0f;
2254
- s->padconf[0x37] = 0x0f0f0f0f;
2255
- s->padconf[0x38] = 0x1f18180f;
2256
- s->padconf[0x39] = 0x1f1f1f1f;
2257
- s->padconf[0x3a] = 0x00001f1f;
2258
- s->padconf[0x3b] = 0x00000000;
2259
- s->padconf[0x3c] = 0x00000000;
2260
- s->padconf[0x3d] = 0x0f0f0f0f;
2261
- s->padconf[0x3e] = 0x18000f0f;
2262
- s->padconf[0x3f] = 0x00070000;
2263
- s->padconf[0x40] = 0x00000707;
2264
- s->padconf[0x41] = 0x0f1f0700;
2265
- s->padconf[0x42] = 0x1f1f070f;
2266
- s->padconf[0x43] = 0x0008081f;
2267
- s->padconf[0x44] = 0x00000800;
2268
-}
2269
-
2270
-static struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
2271
- omap_clk iclk, struct omap_mpu_state_s *mpu)
2272
-{
2273
- struct omap_sysctl_s *s = g_new0(struct omap_sysctl_s, 1);
2274
-
2275
- s->mpu = mpu;
2276
- omap_sysctl_reset(s);
2277
-
2278
- memory_region_init_io(&s->iomem, NULL, &omap_sysctl_ops, s, "omap.sysctl",
2279
- omap_l4_region_size(ta, 0));
2280
- omap_l4_attach(ta, 0, &s->iomem);
2281
-
2282
- return s;
2283
-}
2284
-
2285
-/* General chip reset */
2286
-static void omap2_mpu_reset(void *opaque)
2287
-{
2288
- struct omap_mpu_state_s *mpu = opaque;
2289
-
2290
- omap_dma_reset(mpu->dma);
2291
- omap_prcm_reset(mpu->prcm);
2292
- omap_sysctl_reset(mpu->sysc);
2293
- omap_gp_timer_reset(mpu->gptimer[0]);
2294
- omap_gp_timer_reset(mpu->gptimer[1]);
2295
- omap_gp_timer_reset(mpu->gptimer[2]);
2296
- omap_gp_timer_reset(mpu->gptimer[3]);
2297
- omap_gp_timer_reset(mpu->gptimer[4]);
2298
- omap_gp_timer_reset(mpu->gptimer[5]);
2299
- omap_gp_timer_reset(mpu->gptimer[6]);
2300
- omap_gp_timer_reset(mpu->gptimer[7]);
2301
- omap_gp_timer_reset(mpu->gptimer[8]);
2302
- omap_gp_timer_reset(mpu->gptimer[9]);
2303
- omap_gp_timer_reset(mpu->gptimer[10]);
2304
- omap_gp_timer_reset(mpu->gptimer[11]);
2305
- omap_synctimer_reset(mpu->synctimer);
2306
- omap_sdrc_reset(mpu->sdrc);
2307
- omap_gpmc_reset(mpu->gpmc);
2308
- omap_dss_reset(mpu->dss);
2309
- omap_uart_reset(mpu->uart[0]);
2310
- omap_uart_reset(mpu->uart[1]);
2311
- omap_uart_reset(mpu->uart[2]);
2312
- omap_mmc_reset(mpu->mmc);
2313
- omap_mcspi_reset(mpu->mcspi[0]);
2314
- omap_mcspi_reset(mpu->mcspi[1]);
2315
- cpu_reset(CPU(mpu->cpu));
2316
-}
2317
-
2318
-static int omap2_validate_addr(struct omap_mpu_state_s *s,
2319
- hwaddr addr)
2320
-{
2321
- return 1;
2322
-}
2323
-
2324
-static const struct dma_irq_map omap2_dma_irq_map[] = {
2325
- { 0, OMAP_INT_24XX_SDMA_IRQ0 },
2326
- { 0, OMAP_INT_24XX_SDMA_IRQ1 },
2327
- { 0, OMAP_INT_24XX_SDMA_IRQ2 },
2328
- { 0, OMAP_INT_24XX_SDMA_IRQ3 },
2329
-};
2330
-
2331
-struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sdram,
2332
- const char *cpu_type)
2333
-{
2334
- struct omap_mpu_state_s *s = g_new0(struct omap_mpu_state_s, 1);
2335
- qemu_irq dma_irqs[4];
2336
- DriveInfo *dinfo;
2337
- int i;
2338
- SysBusDevice *busdev;
2339
- struct omap_target_agent_s *ta;
2340
- MemoryRegion *sysmem = get_system_memory();
2341
-
2342
- /* Core */
2343
- s->mpu_model = omap2420;
2344
- s->cpu = ARM_CPU(cpu_create(cpu_type));
2345
- s->sram_size = OMAP242X_SRAM_SIZE;
2346
-
2347
- s->wakeup = qemu_allocate_irq(omap_mpu_wakeup, s, 0);
2348
-
2349
- /* Clocks */
2350
- omap_clk_init(s);
2351
-
2352
- /* Memory-mapped stuff */
2353
- memory_region_init_ram(&s->sram, NULL, "omap2.sram", s->sram_size,
2354
- &error_fatal);
2355
- memory_region_add_subregion(sysmem, OMAP2_SRAM_BASE, &s->sram);
2356
-
2357
- s->l4 = omap_l4_init(sysmem, OMAP2_L4_BASE, 54);
2358
-
2359
- /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
2360
- s->ih[0] = qdev_new("omap2-intc");
2361
- qdev_prop_set_uint8(s->ih[0], "revision", 0x21);
2362
- omap_intc_set_fclk(OMAP_INTC(s->ih[0]), omap_findclk(s, "mpu_intc_fclk"));
2363
- omap_intc_set_iclk(OMAP_INTC(s->ih[0]), omap_findclk(s, "mpu_intc_iclk"));
2364
- busdev = SYS_BUS_DEVICE(s->ih[0]);
2365
- sysbus_realize_and_unref(busdev, &error_fatal);
2366
- sysbus_connect_irq(busdev, 0,
2367
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
2368
- sysbus_connect_irq(busdev, 1,
2369
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
2370
- sysbus_mmio_map(busdev, 0, 0x480fe000);
2371
- s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
2372
- qdev_get_gpio_in(s->ih[0],
2373
- OMAP_INT_24XX_PRCM_MPU_IRQ),
2374
- NULL, NULL, s);
2375
-
2376
- s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1),
2377
- omap_findclk(s, "omapctrl_iclk"), s);
2378
-
2379
- for (i = 0; i < 4; i++) {
2380
- dma_irqs[i] = qdev_get_gpio_in(s->ih[omap2_dma_irq_map[i].ih],
2381
- omap2_dma_irq_map[i].intr);
2382
- }
2383
- s->dma = omap_dma4_init(0x48056000, dma_irqs, sysmem, s, 256, 32,
2384
- omap_findclk(s, "sdma_iclk"),
2385
- omap_findclk(s, "sdma_fclk"));
2386
- s->port->addr_valid = omap2_validate_addr;
2387
-
2388
- /* Register SDRAM and SRAM ports for fast DMA transfers. */
2389
- soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(sdram),
2390
- OMAP2_Q2_BASE, memory_region_size(sdram));
2391
- soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->sram),
2392
- OMAP2_SRAM_BASE, s->sram_size);
2393
-
2394
- s->uart[0] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 19),
2395
- qdev_get_gpio_in(s->ih[0],
2396
- OMAP_INT_24XX_UART1_IRQ),
2397
- omap_findclk(s, "uart1_fclk"),
2398
- omap_findclk(s, "uart1_iclk"),
2399
- s->drq[OMAP24XX_DMA_UART1_TX],
2400
- s->drq[OMAP24XX_DMA_UART1_RX],
2401
- "uart1",
2402
- serial_hd(0));
2403
- s->uart[1] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 20),
2404
- qdev_get_gpio_in(s->ih[0],
2405
- OMAP_INT_24XX_UART2_IRQ),
2406
- omap_findclk(s, "uart2_fclk"),
2407
- omap_findclk(s, "uart2_iclk"),
2408
- s->drq[OMAP24XX_DMA_UART2_TX],
2409
- s->drq[OMAP24XX_DMA_UART2_RX],
2410
- "uart2",
2411
- serial_hd(0) ? serial_hd(1) : NULL);
2412
- s->uart[2] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 21),
2413
- qdev_get_gpio_in(s->ih[0],
2414
- OMAP_INT_24XX_UART3_IRQ),
2415
- omap_findclk(s, "uart3_fclk"),
2416
- omap_findclk(s, "uart3_iclk"),
2417
- s->drq[OMAP24XX_DMA_UART3_TX],
2418
- s->drq[OMAP24XX_DMA_UART3_RX],
2419
- "uart3",
2420
- serial_hd(0) && serial_hd(1) ? serial_hd(2) : NULL);
2421
-
2422
- s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
2423
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER1),
2424
- omap_findclk(s, "wu_gpt1_clk"),
2425
- omap_findclk(s, "wu_l4_iclk"));
2426
- s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8),
2427
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER2),
2428
- omap_findclk(s, "core_gpt2_clk"),
2429
- omap_findclk(s, "core_l4_iclk"));
2430
- s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22),
2431
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER3),
2432
- omap_findclk(s, "core_gpt3_clk"),
2433
- omap_findclk(s, "core_l4_iclk"));
2434
- s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23),
2435
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER4),
2436
- omap_findclk(s, "core_gpt4_clk"),
2437
- omap_findclk(s, "core_l4_iclk"));
2438
- s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24),
2439
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER5),
2440
- omap_findclk(s, "core_gpt5_clk"),
2441
- omap_findclk(s, "core_l4_iclk"));
2442
- s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25),
2443
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER6),
2444
- omap_findclk(s, "core_gpt6_clk"),
2445
- omap_findclk(s, "core_l4_iclk"));
2446
- s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26),
2447
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER7),
2448
- omap_findclk(s, "core_gpt7_clk"),
2449
- omap_findclk(s, "core_l4_iclk"));
2450
- s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27),
2451
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER8),
2452
- omap_findclk(s, "core_gpt8_clk"),
2453
- omap_findclk(s, "core_l4_iclk"));
2454
- s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28),
2455
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER9),
2456
- omap_findclk(s, "core_gpt9_clk"),
2457
- omap_findclk(s, "core_l4_iclk"));
2458
- s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29),
2459
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER10),
2460
- omap_findclk(s, "core_gpt10_clk"),
2461
- omap_findclk(s, "core_l4_iclk"));
2462
- s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30),
2463
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER11),
2464
- omap_findclk(s, "core_gpt11_clk"),
2465
- omap_findclk(s, "core_l4_iclk"));
2466
- s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31),
2467
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER12),
2468
- omap_findclk(s, "core_gpt12_clk"),
2469
- omap_findclk(s, "core_l4_iclk"));
2470
-
2471
- omap_tap_init(omap_l4ta(s->l4, 2), s);
2472
-
2473
- s->synctimer = omap_synctimer_init(omap_l4tao(s->l4, 2), s,
2474
- omap_findclk(s, "clk32-kHz"),
2475
- omap_findclk(s, "core_l4_iclk"));
2476
-
2477
- s->i2c[0] = qdev_new("omap_i2c");
2478
- qdev_prop_set_uint8(s->i2c[0], "revision", 0x34);
2479
- omap_i2c_set_iclk(OMAP_I2C(s->i2c[0]), omap_findclk(s, "i2c1.iclk"));
2480
- omap_i2c_set_fclk(OMAP_I2C(s->i2c[0]), omap_findclk(s, "i2c1.fclk"));
2481
- busdev = SYS_BUS_DEVICE(s->i2c[0]);
2482
- sysbus_realize_and_unref(busdev, &error_fatal);
2483
- sysbus_connect_irq(busdev, 0,
2484
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C1_IRQ));
2485
- sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_I2C1_TX]);
2486
- sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_I2C1_RX]);
2487
- sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4tao(s->l4, 5), 0));
2488
-
2489
- s->i2c[1] = qdev_new("omap_i2c");
2490
- qdev_prop_set_uint8(s->i2c[1], "revision", 0x34);
2491
- omap_i2c_set_iclk(OMAP_I2C(s->i2c[1]), omap_findclk(s, "i2c2.iclk"));
2492
- omap_i2c_set_fclk(OMAP_I2C(s->i2c[1]), omap_findclk(s, "i2c2.fclk"));
2493
- busdev = SYS_BUS_DEVICE(s->i2c[1]);
2494
- sysbus_realize_and_unref(busdev, &error_fatal);
2495
- sysbus_connect_irq(busdev, 0,
2496
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C2_IRQ));
2497
- sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_I2C2_TX]);
2498
- sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_I2C2_RX]);
2499
- sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4tao(s->l4, 6), 0));
2500
-
2501
- s->gpio = qdev_new("omap2-gpio");
2502
- qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
2503
- omap2_gpio_set_iclk(OMAP2_GPIO(s->gpio), omap_findclk(s, "gpio_iclk"));
2504
- omap2_gpio_set_fclk(OMAP2_GPIO(s->gpio), 0, omap_findclk(s, "gpio1_dbclk"));
2505
- omap2_gpio_set_fclk(OMAP2_GPIO(s->gpio), 1, omap_findclk(s, "gpio2_dbclk"));
2506
- omap2_gpio_set_fclk(OMAP2_GPIO(s->gpio), 2, omap_findclk(s, "gpio3_dbclk"));
2507
- omap2_gpio_set_fclk(OMAP2_GPIO(s->gpio), 3, omap_findclk(s, "gpio4_dbclk"));
2508
- if (s->mpu_model == omap2430) {
2509
- omap2_gpio_set_fclk(OMAP2_GPIO(s->gpio), 4,
2510
- omap_findclk(s, "gpio5_dbclk"));
2511
- }
2512
- busdev = SYS_BUS_DEVICE(s->gpio);
2513
- sysbus_realize_and_unref(busdev, &error_fatal);
2514
- sysbus_connect_irq(busdev, 0,
2515
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK1));
2516
- sysbus_connect_irq(busdev, 3,
2517
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK2));
2518
- sysbus_connect_irq(busdev, 6,
2519
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK3));
2520
- sysbus_connect_irq(busdev, 9,
2521
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK4));
2522
- if (s->mpu_model == omap2430) {
2523
- sysbus_connect_irq(busdev, 12,
2524
- qdev_get_gpio_in(s->ih[0],
2525
- OMAP_INT_243X_GPIO_BANK5));
2526
- }
2527
- ta = omap_l4ta(s->l4, 3);
2528
- sysbus_mmio_map(busdev, 0, omap_l4_region_base(ta, 1));
2529
- sysbus_mmio_map(busdev, 1, omap_l4_region_base(ta, 0));
2530
- sysbus_mmio_map(busdev, 2, omap_l4_region_base(ta, 2));
2531
- sysbus_mmio_map(busdev, 3, omap_l4_region_base(ta, 4));
2532
- sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5));
2533
-
2534
- s->sdrc = omap_sdrc_init(sysmem, 0x68009000);
2535
- s->gpmc = omap_gpmc_init(s, 0x6800a000,
2536
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPMC_IRQ),
2537
- s->drq[OMAP24XX_DMA_GPMC]);
2538
-
2539
- dinfo = drive_get(IF_SD, 0, 0);
2540
- if (!dinfo && !qtest_enabled()) {
2541
- warn_report("missing SecureDigital device");
2542
- }
2543
- s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9),
2544
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
2545
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
2546
- &s->drq[OMAP24XX_DMA_MMC1_TX],
2547
- omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
2548
-
2549
- s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4,
2550
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI1_IRQ),
2551
- &s->drq[OMAP24XX_DMA_SPI1_TX0],
2552
- omap_findclk(s, "spi1_fclk"),
2553
- omap_findclk(s, "spi1_iclk"));
2554
- s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2,
2555
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI2_IRQ),
2556
- &s->drq[OMAP24XX_DMA_SPI2_TX0],
2557
- omap_findclk(s, "spi2_fclk"),
2558
- omap_findclk(s, "spi2_iclk"));
2559
-
2560
- s->dss = omap_dss_init(omap_l4ta(s->l4, 10), sysmem, 0x68000800,
2561
- /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */
2562
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_DSS_IRQ),
2563
- s->drq[OMAP24XX_DMA_DSS],
2564
- omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"),
2565
- omap_findclk(s, "dss_54m_clk"),
2566
- omap_findclk(s, "dss_l3_iclk"),
2567
- omap_findclk(s, "dss_l4_iclk"));
2568
-
2569
- omap_sti_init(omap_l4ta(s->l4, 18), sysmem, 0x54000000,
2570
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_STI),
2571
- omap_findclk(s, "emul_ck"),
2572
- serial_hd(0) && serial_hd(1) && serial_hd(2) ?
2573
- serial_hd(3) : NULL);
2574
-
2575
- s->eac = omap_eac_init(omap_l4ta(s->l4, 32),
2576
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_EAC_IRQ),
2577
- /* Ten consecutive lines */
2578
- &s->drq[OMAP24XX_DMA_EAC_AC_RD],
2579
- omap_findclk(s, "func_96m_clk"),
2580
- omap_findclk(s, "core_l4_iclk"));
2581
-
2582
- /* All register mappings (including those not currently implemented):
2583
- * SystemControlMod    48000000 - 48000fff
2584
- * SystemControlL4    48001000 - 48001fff
2585
- * 32kHz Timer Mod    48004000 - 48004fff
2586
- * 32kHz Timer L4    48005000 - 48005fff
2587
- * PRCM ModA    48008000 - 480087ff
2588
- * PRCM ModB    48008800 - 48008fff
2589
- * PRCM L4        48009000 - 48009fff
2590
- * TEST-BCM Mod    48012000 - 48012fff
2591
- * TEST-BCM L4    48013000 - 48013fff
2592
- * TEST-TAP Mod    48014000 - 48014fff
2593
- * TEST-TAP L4    48015000 - 48015fff
2594
- * GPIO1 Mod    48018000 - 48018fff
2595
- * GPIO Top        48019000 - 48019fff
2596
- * GPIO2 Mod    4801a000 - 4801afff
2597
- * GPIO L4        4801b000 - 4801bfff
2598
- * GPIO3 Mod    4801c000 - 4801cfff
2599
- * GPIO4 Mod    4801e000 - 4801efff
2600
- * WDTIMER1 Mod    48020000 - 48010fff
2601
- * WDTIMER Top    48021000 - 48011fff
2602
- * WDTIMER2 Mod    48022000 - 48012fff
2603
- * WDTIMER L4    48023000 - 48013fff
2604
- * WDTIMER3 Mod    48024000 - 48014fff
2605
- * WDTIMER3 L4    48025000 - 48015fff
2606
- * WDTIMER4 Mod    48026000 - 48016fff
2607
- * WDTIMER4 L4    48027000 - 48017fff
2608
- * GPTIMER1 Mod    48028000 - 48018fff
2609
- * GPTIMER1 L4    48029000 - 48019fff
2610
- * GPTIMER2 Mod    4802a000 - 4801afff
2611
- * GPTIMER2 L4    4802b000 - 4801bfff
2612
- * L4-Config AP    48040000 - 480407ff
2613
- * L4-Config IP    48040800 - 48040fff
2614
- * L4-Config LA    48041000 - 48041fff
2615
- * ARM11ETB Mod    48048000 - 48049fff
2616
- * ARM11ETB L4    4804a000 - 4804afff
2617
- * DISPLAY Top    48050000 - 480503ff
2618
- * DISPLAY DISPC    48050400 - 480507ff
2619
- * DISPLAY RFBI    48050800 - 48050bff
2620
- * DISPLAY VENC    48050c00 - 48050fff
2621
- * DISPLAY L4    48051000 - 48051fff
2622
- * CAMERA Top    48052000 - 480523ff
2623
- * CAMERA core    48052400 - 480527ff
2624
- * CAMERA DMA    48052800 - 48052bff
2625
- * CAMERA MMU    48052c00 - 48052fff
2626
- * CAMERA L4    48053000 - 48053fff
2627
- * SDMA Mod        48056000 - 48056fff
2628
- * SDMA L4        48057000 - 48057fff
2629
- * SSI Top        48058000 - 48058fff
2630
- * SSI GDD        48059000 - 48059fff
2631
- * SSI Port1    4805a000 - 4805afff
2632
- * SSI Port2    4805b000 - 4805bfff
2633
- * SSI L4        4805c000 - 4805cfff
2634
- * USB Mod        4805e000 - 480fefff
2635
- * USB L4        4805f000 - 480fffff
2636
- * WIN_TRACER1 Mod    48060000 - 48060fff
2637
- * WIN_TRACER1 L4    48061000 - 48061fff
2638
- * WIN_TRACER2 Mod    48062000 - 48062fff
2639
- * WIN_TRACER2 L4    48063000 - 48063fff
2640
- * WIN_TRACER3 Mod    48064000 - 48064fff
2641
- * WIN_TRACER3 L4    48065000 - 48065fff
2642
- * WIN_TRACER4 Top    48066000 - 480660ff
2643
- * WIN_TRACER4 ETT    48066100 - 480661ff
2644
- * WIN_TRACER4 WT    48066200 - 480662ff
2645
- * WIN_TRACER4 L4    48067000 - 48067fff
2646
- * XTI Mod        48068000 - 48068fff
2647
- * XTI L4        48069000 - 48069fff
2648
- * UART1 Mod    4806a000 - 4806afff
2649
- * UART1 L4        4806b000 - 4806bfff
2650
- * UART2 Mod    4806c000 - 4806cfff
2651
- * UART2 L4        4806d000 - 4806dfff
2652
- * UART3 Mod    4806e000 - 4806efff
2653
- * UART3 L4        4806f000 - 4806ffff
2654
- * I2C1 Mod        48070000 - 48070fff
2655
- * I2C1 L4        48071000 - 48071fff
2656
- * I2C2 Mod        48072000 - 48072fff
2657
- * I2C2 L4        48073000 - 48073fff
2658
- * McBSP1 Mod    48074000 - 48074fff
2659
- * McBSP1 L4    48075000 - 48075fff
2660
- * McBSP2 Mod    48076000 - 48076fff
2661
- * McBSP2 L4    48077000 - 48077fff
2662
- * GPTIMER3 Mod    48078000 - 48078fff
2663
- * GPTIMER3 L4    48079000 - 48079fff
2664
- * GPTIMER4 Mod    4807a000 - 4807afff
2665
- * GPTIMER4 L4    4807b000 - 4807bfff
2666
- * GPTIMER5 Mod    4807c000 - 4807cfff
2667
- * GPTIMER5 L4    4807d000 - 4807dfff
2668
- * GPTIMER6 Mod    4807e000 - 4807efff
2669
- * GPTIMER6 L4    4807f000 - 4807ffff
2670
- * GPTIMER7 Mod    48080000 - 48080fff
2671
- * GPTIMER7 L4    48081000 - 48081fff
2672
- * GPTIMER8 Mod    48082000 - 48082fff
2673
- * GPTIMER8 L4    48083000 - 48083fff
2674
- * GPTIMER9 Mod    48084000 - 48084fff
2675
- * GPTIMER9 L4    48085000 - 48085fff
2676
- * GPTIMER10 Mod    48086000 - 48086fff
2677
- * GPTIMER10 L4    48087000 - 48087fff
2678
- * GPTIMER11 Mod    48088000 - 48088fff
2679
- * GPTIMER11 L4    48089000 - 48089fff
2680
- * GPTIMER12 Mod    4808a000 - 4808afff
2681
- * GPTIMER12 L4    4808b000 - 4808bfff
2682
- * EAC Mod        48090000 - 48090fff
2683
- * EAC L4        48091000 - 48091fff
2684
- * FAC Mod        48092000 - 48092fff
2685
- * FAC L4        48093000 - 48093fff
2686
- * MAILBOX Mod    48094000 - 48094fff
2687
- * MAILBOX L4    48095000 - 48095fff
2688
- * SPI1 Mod        48098000 - 48098fff
2689
- * SPI1 L4        48099000 - 48099fff
2690
- * SPI2 Mod        4809a000 - 4809afff
2691
- * SPI2 L4        4809b000 - 4809bfff
2692
- * MMC/SDIO Mod    4809c000 - 4809cfff
2693
- * MMC/SDIO L4    4809d000 - 4809dfff
2694
- * MS_PRO Mod    4809e000 - 4809efff
2695
- * MS_PRO L4    4809f000 - 4809ffff
2696
- * RNG Mod        480a0000 - 480a0fff
2697
- * RNG L4        480a1000 - 480a1fff
2698
- * DES3DES Mod    480a2000 - 480a2fff
2699
- * DES3DES L4    480a3000 - 480a3fff
2700
- * SHA1MD5 Mod    480a4000 - 480a4fff
2701
- * SHA1MD5 L4    480a5000 - 480a5fff
2702
- * AES Mod        480a6000 - 480a6fff
2703
- * AES L4        480a7000 - 480a7fff
2704
- * PKA Mod        480a8000 - 480a9fff
2705
- * PKA L4        480aa000 - 480aafff
2706
- * MG Mod        480b0000 - 480b0fff
2707
- * MG L4        480b1000 - 480b1fff
2708
- * HDQ/1-wire Mod    480b2000 - 480b2fff
2709
- * HDQ/1-wire L4    480b3000 - 480b3fff
2710
- * MPU interrupt    480fe000 - 480fefff
2711
- * STI channel base    54000000 - 5400ffff
2712
- * IVA RAM        5c000000 - 5c01ffff
2713
- * IVA ROM        5c020000 - 5c027fff
2714
- * IMG_BUF_A    5c040000 - 5c040fff
2715
- * IMG_BUF_B    5c042000 - 5c042fff
2716
- * VLCDS        5c048000 - 5c0487ff
2717
- * IMX_COEF        5c049000 - 5c04afff
2718
- * IMX_CMD        5c051000 - 5c051fff
2719
- * VLCDQ        5c053000 - 5c0533ff
2720
- * VLCDH        5c054000 - 5c054fff
2721
- * SEQ_CMD        5c055000 - 5c055fff
2722
- * IMX_REG        5c056000 - 5c0560ff
2723
- * VLCD_REG        5c056100 - 5c0561ff
2724
- * SEQ_REG        5c056200 - 5c0562ff
2725
- * IMG_BUF_REG    5c056300 - 5c0563ff
2726
- * SEQIRQ_REG    5c056400 - 5c0564ff
2727
- * OCP_REG        5c060000 - 5c060fff
2728
- * SYSC_REG        5c070000 - 5c070fff
2729
- * MMU_REG        5d000000 - 5d000fff
2730
- * sDMA R        68000400 - 680005ff
2731
- * sDMA W        68000600 - 680007ff
2732
- * Display Control    68000800 - 680009ff
2733
- * DSP subsystem    68000a00 - 68000bff
2734
- * MPU subsystem    68000c00 - 68000dff
2735
- * IVA subsystem    68001000 - 680011ff
2736
- * USB        68001200 - 680013ff
2737
- * Camera        68001400 - 680015ff
2738
- * VLYNQ (firewall)    68001800 - 68001bff
2739
- * VLYNQ        68001e00 - 68001fff
2740
- * SSI        68002000 - 680021ff
2741
- * L4        68002400 - 680025ff
2742
- * DSP (firewall)    68002800 - 68002bff
2743
- * DSP subsystem    68002e00 - 68002fff
2744
- * IVA (firewall)    68003000 - 680033ff
2745
- * IVA        68003600 - 680037ff
2746
- * GFX        68003a00 - 68003bff
2747
- * CMDWR emulation    68003c00 - 68003dff
2748
- * SMS        68004000 - 680041ff
2749
- * OCM        68004200 - 680043ff
2750
- * GPMC        68004400 - 680045ff
2751
- * RAM (firewall)    68005000 - 680053ff
2752
- * RAM (err login)    68005400 - 680057ff
2753
- * ROM (firewall)    68005800 - 68005bff
2754
- * ROM (err login)    68005c00 - 68005fff
2755
- * GPMC (firewall)    68006000 - 680063ff
2756
- * GPMC (err login)    68006400 - 680067ff
2757
- * SMS (err login)    68006c00 - 68006fff
2758
- * SMS registers    68008000 - 68008fff
2759
- * SDRC registers    68009000 - 68009fff
2760
- * GPMC registers    6800a000 6800afff
2761
- */
2762
-
2763
- qemu_register_reset(omap2_mpu_reset, s);
2764
-
2765
- return s;
2766
-}
2767
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
2768
index XXXXXXX..XXXXXXX 100644
2769
--- a/hw/arm/meson.build
2770
+++ b/hw/arm/meson.build
2771
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c'))
2772
system_ss.add(when: 'CONFIG_COLLIE', if_true: files('collie.c'))
2773
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4_boards.c'))
2774
system_ss.add(when: 'CONFIG_NETDUINO2', if_true: files('netduino2.c'))
2775
-system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap2.c'))
2776
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_peripherals.c'))
2777
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2838_peripherals.c'))
2778
system_ss.add(when: 'CONFIG_STRONGARM', if_true: files('strongarm.c'))
2779
--
81
--
2780
2.34.1
82
2.34.1
2781
83
2782
84
diff view generated by jsdifflib
1
The connex and verdex machines have been deprecated since
1
From: Richard Henderson <richard.henderson@linaro.org>
2
9.0 and so can be removed for the 9.2 release.
3
2
3
While all indices into val[] should be in [0-2], the mask
4
applied is two bits. To help static analysis see there is
5
no possibility of read beyond the end of the array, pad the
6
array to 4 entries, with the final being (implicitly) NULL.
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20241203203949.483774-6-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240903160751.4100218-10-peter.maydell@linaro.org
8
---
12
---
9
MAINTAINERS | 8 --
13
fpu/softfloat-parts.c.inc | 2 +-
10
docs/system/arm/gumstix.rst | 21 ----
14
1 file changed, 1 insertion(+), 1 deletion(-)
11
docs/system/target-arm.rst | 1 -
12
configs/devices/arm-softmmu/default.mak | 1 -
13
hw/arm/gumstix.c | 141 ------------------------
14
hw/arm/Kconfig | 8 --
15
hw/arm/meson.build | 1 -
16
7 files changed, 181 deletions(-)
17
delete mode 100644 docs/system/arm/gumstix.rst
18
delete mode 100644 hw/arm/gumstix.c
19
15
20
diff --git a/MAINTAINERS b/MAINTAINERS
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/MAINTAINERS
18
--- a/fpu/softfloat-parts.c.inc
23
+++ b/MAINTAINERS
19
+++ b/fpu/softfloat-parts.c.inc
24
@@ -XXX,XX +XXX,XX @@ S: Maintained
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
25
F: hw/rtc/goldfish_rtc.c
21
}
26
F: include/hw/rtc/goldfish_rtc.h
22
ret = c;
27
23
} else {
28
-Gumstix
24
- FloatPartsN *val[3] = { a, b, c };
29
-M: Peter Maydell <peter.maydell@linaro.org>
25
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
30
-R: Philippe Mathieu-Daudé <philmd@linaro.org>
26
Float3NaNPropRule rule = s->float_3nan_prop_rule;
31
-L: qemu-arm@nongnu.org
27
32
-S: Odd Fixes
28
assert(rule != float_3nan_prop_none);
33
-F: hw/arm/gumstix.c
34
-F: docs/system/arm/gumstix.rst
35
-
36
i.MX25 PDK
37
M: Peter Maydell <peter.maydell@linaro.org>
38
R: Jean-Christophe Dubois <jcd@tribudubois.net>
39
diff --git a/docs/system/arm/gumstix.rst b/docs/system/arm/gumstix.rst
40
deleted file mode 100644
41
index XXXXXXX..XXXXXXX
42
--- a/docs/system/arm/gumstix.rst
43
+++ /dev/null
44
@@ -XXX,XX +XXX,XX @@
45
-Gumstix Connex and Verdex (``connex``, ``verdex``)
46
-==================================================
47
-
48
-These machines model the Gumstix Connex and Verdex boards.
49
-The Connex has a PXA255 CPU and the Verdex has a PXA270.
50
-
51
-Implemented devices:
52
-
53
- * NOR flash
54
- * SMC91C111 ethernet
55
- * Interrupt controller
56
- * DMA
57
- * Timer
58
- * GPIO
59
- * MMC/SD card
60
- * Fast infra-red communications port (FIR)
61
- * LCD controller
62
- * Synchronous serial ports (SPI)
63
- * PCMCIA interface
64
- * I2C
65
- * I2S
66
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
67
index XXXXXXX..XXXXXXX 100644
68
--- a/docs/system/target-arm.rst
69
+++ b/docs/system/target-arm.rst
70
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
71
arm/cubieboard
72
arm/emcraft-sf2
73
arm/musicpal
74
- arm/gumstix
75
arm/mainstone
76
arm/kzm
77
arm/nseries
78
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
79
index XXXXXXX..XXXXXXX 100644
80
--- a/configs/devices/arm-softmmu/default.mak
81
+++ b/configs/devices/arm-softmmu/default.mak
82
@@ -XXX,XX +XXX,XX @@
83
# CONFIG_VEXPRESS=n
84
# CONFIG_ZYNQ=n
85
# CONFIG_MAINSTONE=n
86
-# CONFIG_GUMSTIX=n
87
# CONFIG_Z2=n
88
# CONFIG_NPCM7XX=n
89
# CONFIG_COLLIE=n
90
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
91
deleted file mode 100644
92
index XXXXXXX..XXXXXXX
93
--- a/hw/arm/gumstix.c
94
+++ /dev/null
95
@@ -XXX,XX +XXX,XX @@
96
-/*
97
- * Gumstix Platforms
98
- *
99
- * Copyright (c) 2007 by Thorsten Zitterell <info@bitmux.org>
100
- *
101
- * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org>
102
- *
103
- * This code is licensed under the GNU GPL v2.
104
- *
105
- * Contributions after 2012-01-13 are licensed under the terms of the
106
- * GNU GPL, version 2 or (at your option) any later version.
107
- */
108
-
109
-/*
110
- * Example usage:
111
- *
112
- * connex:
113
- * =======
114
- * create image:
115
- * # dd of=flash bs=1k count=16k if=/dev/zero
116
- * # dd of=flash bs=1k conv=notrunc if=u-boot.bin
117
- * # dd of=flash bs=1k conv=notrunc seek=256 if=rootfs.arm_nofpu.jffs2
118
- * start it:
119
- * # qemu-system-arm -M connex -pflash flash -monitor null -nographic
120
- *
121
- * verdex:
122
- * =======
123
- * create image:
124
- * # dd of=flash bs=1k count=32k if=/dev/zero
125
- * # dd of=flash bs=1k conv=notrunc if=u-boot.bin
126
- * # dd of=flash bs=1k conv=notrunc seek=256 if=rootfs.arm_nofpu.jffs2
127
- * # dd of=flash bs=1k conv=notrunc seek=31744 if=uImage
128
- * start it:
129
- * # qemu-system-arm -M verdex -pflash flash -monitor null -nographic -m 289
130
- */
131
-
132
-#include "qemu/osdep.h"
133
-#include "qemu/units.h"
134
-#include "qemu/error-report.h"
135
-#include "hw/arm/pxa.h"
136
-#include "net/net.h"
137
-#include "hw/block/flash.h"
138
-#include "hw/net/smc91c111.h"
139
-#include "hw/boards.h"
140
-#include "exec/address-spaces.h"
141
-#include "sysemu/qtest.h"
142
-
143
-#define CONNEX_FLASH_SIZE (16 * MiB)
144
-#define CONNEX_RAM_SIZE (64 * MiB)
145
-
146
-#define VERDEX_FLASH_SIZE (32 * MiB)
147
-#define VERDEX_RAM_SIZE (256 * MiB)
148
-
149
-#define FLASH_SECTOR_SIZE (128 * KiB)
150
-
151
-static void connex_init(MachineState *machine)
152
-{
153
- PXA2xxState *cpu;
154
- DriveInfo *dinfo;
155
-
156
- cpu = pxa255_init(CONNEX_RAM_SIZE);
157
-
158
- dinfo = drive_get(IF_PFLASH, 0, 0);
159
- if (!dinfo && !qtest_enabled()) {
160
- error_report("A flash image must be given with the "
161
- "'pflash' parameter");
162
- exit(1);
163
- }
164
-
165
- /* Numonyx RC28F128J3F75 */
166
- pflash_cfi01_register(0x00000000, "connext.rom", CONNEX_FLASH_SIZE,
167
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
168
- FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0);
169
-
170
- /* Interrupt line of NIC is connected to GPIO line 36 */
171
- smc91c111_init(0x04000300, qdev_get_gpio_in(cpu->gpio, 36));
172
-}
173
-
174
-static void verdex_init(MachineState *machine)
175
-{
176
- PXA2xxState *cpu;
177
- DriveInfo *dinfo;
178
-
179
- cpu = pxa270_init(VERDEX_RAM_SIZE, machine->cpu_type);
180
-
181
- dinfo = drive_get(IF_PFLASH, 0, 0);
182
- if (!dinfo && !qtest_enabled()) {
183
- error_report("A flash image must be given with the "
184
- "'pflash' parameter");
185
- exit(1);
186
- }
187
-
188
- /* Micron RC28F256P30TFA */
189
- pflash_cfi01_register(0x00000000, "verdex.rom", VERDEX_FLASH_SIZE,
190
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
191
- FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0);
192
-
193
- /* Interrupt line of NIC is connected to GPIO line 99 */
194
- smc91c111_init(0x04000300, qdev_get_gpio_in(cpu->gpio, 99));
195
-}
196
-
197
-static void connex_class_init(ObjectClass *oc, void *data)
198
-{
199
- MachineClass *mc = MACHINE_CLASS(oc);
200
-
201
- mc->desc = "Gumstix Connex (PXA255)";
202
- mc->init = connex_init;
203
- mc->ignore_memory_transaction_failures = true;
204
- mc->deprecation_reason = "machine is old and unmaintained";
205
-}
206
-
207
-static const TypeInfo connex_type = {
208
- .name = MACHINE_TYPE_NAME("connex"),
209
- .parent = TYPE_MACHINE,
210
- .class_init = connex_class_init,
211
-};
212
-
213
-static void verdex_class_init(ObjectClass *oc, void *data)
214
-{
215
- MachineClass *mc = MACHINE_CLASS(oc);
216
-
217
- mc->desc = "Gumstix Verdex Pro XL6P COMs (PXA270)";
218
- mc->init = verdex_init;
219
- mc->ignore_memory_transaction_failures = true;
220
- mc->deprecation_reason = "machine is old and unmaintained";
221
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
222
-}
223
-
224
-static const TypeInfo verdex_type = {
225
- .name = MACHINE_TYPE_NAME("verdex"),
226
- .parent = TYPE_MACHINE,
227
- .class_init = verdex_class_init,
228
-};
229
-
230
-static void gumstix_machine_init(void)
231
-{
232
- type_register_static(&connex_type);
233
- type_register_static(&verdex_type);
234
-}
235
-
236
-type_init(gumstix_machine_init)
237
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
238
index XXXXXXX..XXXXXXX 100644
239
--- a/hw/arm/Kconfig
240
+++ b/hw/arm/Kconfig
241
@@ -XXX,XX +XXX,XX @@ config PXA2XX
242
select USB_OHCI_SYSBUS
243
select PCMCIA
244
245
-config GUMSTIX
246
- bool
247
- default y
248
- depends on TCG && ARM
249
- select PFLASH_CFI01
250
- select SMC91C111
251
- select PXA2XX
252
-
253
config Z2
254
bool
255
default y
256
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
257
index XXXXXXX..XXXXXXX 100644
258
--- a/hw/arm/meson.build
259
+++ b/hw/arm/meson.build
260
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_XEN', if_true: files(
261
system_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c'))
262
system_ss.add(when: 'CONFIG_COLLIE', if_true: files('collie.c'))
263
system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4_boards.c'))
264
-system_ss.add(when: 'CONFIG_GUMSTIX', if_true: files('gumstix.c'))
265
system_ss.add(when: 'CONFIG_NETDUINO2', if_true: files('netduino2.c'))
266
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap2.c'))
267
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_peripherals.c'))
268
--
29
--
269
2.34.1
30
2.34.1
270
31
271
32
diff view generated by jsdifflib
1
Remove the pxa2xx-specific pxa2xx_mmci device.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This function is part of the public interface and
4
is not "specialized" to any target in any way.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20240903160751.4100218-17-peter.maydell@linaro.org
7
---
10
---
8
include/hw/arm/pxa.h | 10 -
11
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
9
hw/sd/pxa2xx_mmci.c | 594 -------------------------------------------
12
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
10
hw/sd/meson.build | 1 -
13
2 files changed, 52 insertions(+), 52 deletions(-)
11
hw/sd/trace-events | 4 -
12
4 files changed, 609 deletions(-)
13
delete mode 100644 hw/sd/pxa2xx_mmci.c
14
14
15
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/pxa.h
17
--- a/fpu/softfloat.c
18
+++ b/include/hw/arm/pxa.h
18
+++ b/fpu/softfloat.c
19
@@ -XXX,XX +XXX,XX @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
20
hwaddr base, qemu_irq irq);
20
*zExpPtr = 1 - shiftCount;
21
void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler);
21
}
22
22
23
-/* pxa2xx_mmci.c */
23
+/*----------------------------------------------------------------------------
24
-#define TYPE_PXA2XX_MMCI "pxa2xx-mmci"
24
+| Takes two extended double-precision floating-point values `a' and `b', one
25
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxMMCIState, PXA2XX_MMCI)
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
+*----------------------------------------------------------------------------*/
28
+
29
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
30
+{
31
+ bool aIsLargerSignificand;
32
+ FloatClass a_cls, b_cls;
33
+
34
+ /* This is not complete, but is good enough for pickNaN. */
35
+ a_cls = (!floatx80_is_any_nan(a)
36
+ ? float_class_normal
37
+ : floatx80_is_signaling_nan(a, status)
38
+ ? float_class_snan
39
+ : float_class_qnan);
40
+ b_cls = (!floatx80_is_any_nan(b)
41
+ ? float_class_normal
42
+ : floatx80_is_signaling_nan(b, status)
43
+ ? float_class_snan
44
+ : float_class_qnan);
45
+
46
+ if (is_snan(a_cls) || is_snan(b_cls)) {
47
+ float_raise(float_flag_invalid, status);
48
+ }
49
+
50
+ if (status->default_nan_mode) {
51
+ return floatx80_default_nan(status);
52
+ }
53
+
54
+ if (a.low < b.low) {
55
+ aIsLargerSignificand = 0;
56
+ } else if (b.low < a.low) {
57
+ aIsLargerSignificand = 1;
58
+ } else {
59
+ aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
60
+ }
61
+
62
+ if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
63
+ if (is_snan(b_cls)) {
64
+ return floatx80_silence_nan(b, status);
65
+ }
66
+ return b;
67
+ } else {
68
+ if (is_snan(a_cls)) {
69
+ return floatx80_silence_nan(a, status);
70
+ }
71
+ return a;
72
+ }
73
+}
74
+
75
/*----------------------------------------------------------------------------
76
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
77
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
78
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
79
index XXXXXXX..XXXXXXX 100644
80
--- a/fpu/softfloat-specialize.c.inc
81
+++ b/fpu/softfloat-specialize.c.inc
82
@@ -XXX,XX +XXX,XX @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
83
return a;
84
}
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
-*----------------------------------------------------------------------------*/
26
-
91
-
27
-PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
92
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
28
- hwaddr base,
93
-{
29
- qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma);
94
- bool aIsLargerSignificand;
30
-void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
95
- FloatClass a_cls, b_cls;
31
- qemu_irq coverswitch);
32
-
96
-
33
/* pxa2xx_pcmcia.c */
97
- /* This is not complete, but is good enough for pickNaN. */
34
#define TYPE_PXA2XX_PCMCIA "pxa2xx-pcmcia"
98
- a_cls = (!floatx80_is_any_nan(a)
35
OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxPCMCIAState, PXA2XX_PCMCIA)
99
- ? float_class_normal
36
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
100
- : floatx80_is_signaling_nan(a, status)
37
deleted file mode 100644
101
- ? float_class_snan
38
index XXXXXXX..XXXXXXX
102
- : float_class_qnan);
39
--- a/hw/sd/pxa2xx_mmci.c
103
- b_cls = (!floatx80_is_any_nan(b)
40
+++ /dev/null
104
- ? float_class_normal
41
@@ -XXX,XX +XXX,XX @@
105
- : floatx80_is_signaling_nan(b, status)
42
-/*
106
- ? float_class_snan
43
- * Intel XScale PXA255/270 MultiMediaCard/SD/SDIO Controller emulation.
107
- : float_class_qnan);
44
- *
45
- * Copyright (c) 2006 Openedhand Ltd.
46
- * Written by Andrzej Zaborowski <balrog@zabor.org>
47
- *
48
- * This code is licensed under the GPLv2.
49
- *
50
- * Contributions after 2012-01-13 are licensed under the terms of the
51
- * GNU GPL, version 2 or (at your option) any later version.
52
- */
53
-
108
-
54
-#include "qemu/osdep.h"
109
- if (is_snan(a_cls) || is_snan(b_cls)) {
55
-#include "qapi/error.h"
110
- float_raise(float_flag_invalid, status);
56
-#include "hw/irq.h"
57
-#include "hw/sysbus.h"
58
-#include "migration/vmstate.h"
59
-#include "hw/arm/pxa.h"
60
-#include "hw/sd/sd.h"
61
-#include "hw/qdev-properties.h"
62
-#include "qemu/log.h"
63
-#include "qemu/module.h"
64
-#include "trace.h"
65
-#include "qom/object.h"
66
-
67
-#define TYPE_PXA2XX_MMCI_BUS "pxa2xx-mmci-bus"
68
-/* This is reusing the SDBus typedef from SD_BUS */
69
-DECLARE_INSTANCE_CHECKER(SDBus, PXA2XX_MMCI_BUS,
70
- TYPE_PXA2XX_MMCI_BUS)
71
-
72
-struct PXA2xxMMCIState {
73
- SysBusDevice parent_obj;
74
-
75
- MemoryRegion iomem;
76
- qemu_irq irq;
77
- qemu_irq rx_dma;
78
- qemu_irq tx_dma;
79
- qemu_irq inserted;
80
- qemu_irq readonly;
81
-
82
- BlockBackend *blk;
83
- SDBus sdbus;
84
-
85
- uint32_t status;
86
- uint32_t clkrt;
87
- uint32_t spi;
88
- uint32_t cmdat;
89
- uint32_t resp_tout;
90
- uint32_t read_tout;
91
- int32_t blklen;
92
- int32_t numblk;
93
- uint32_t intmask;
94
- uint32_t intreq;
95
- int32_t cmd;
96
- uint32_t arg;
97
-
98
- int32_t active;
99
- int32_t bytesleft;
100
- uint8_t tx_fifo[64];
101
- uint32_t tx_start;
102
- uint32_t tx_len;
103
- uint8_t rx_fifo[32];
104
- uint32_t rx_start;
105
- uint32_t rx_len;
106
- uint16_t resp_fifo[9];
107
- uint32_t resp_len;
108
-
109
- int32_t cmdreq;
110
-};
111
-
112
-static bool pxa2xx_mmci_vmstate_validate(void *opaque, int version_id)
113
-{
114
- PXA2xxMMCIState *s = opaque;
115
-
116
- return s->tx_start < ARRAY_SIZE(s->tx_fifo)
117
- && s->rx_start < ARRAY_SIZE(s->rx_fifo)
118
- && s->tx_len <= ARRAY_SIZE(s->tx_fifo)
119
- && s->rx_len <= ARRAY_SIZE(s->rx_fifo)
120
- && s->resp_len <= ARRAY_SIZE(s->resp_fifo);
121
-}
122
-
123
-
124
-static const VMStateDescription vmstate_pxa2xx_mmci = {
125
- .name = "pxa2xx-mmci",
126
- .version_id = 2,
127
- .minimum_version_id = 2,
128
- .fields = (const VMStateField[]) {
129
- VMSTATE_UINT32(status, PXA2xxMMCIState),
130
- VMSTATE_UINT32(clkrt, PXA2xxMMCIState),
131
- VMSTATE_UINT32(spi, PXA2xxMMCIState),
132
- VMSTATE_UINT32(cmdat, PXA2xxMMCIState),
133
- VMSTATE_UINT32(resp_tout, PXA2xxMMCIState),
134
- VMSTATE_UINT32(read_tout, PXA2xxMMCIState),
135
- VMSTATE_INT32(blklen, PXA2xxMMCIState),
136
- VMSTATE_INT32(numblk, PXA2xxMMCIState),
137
- VMSTATE_UINT32(intmask, PXA2xxMMCIState),
138
- VMSTATE_UINT32(intreq, PXA2xxMMCIState),
139
- VMSTATE_INT32(cmd, PXA2xxMMCIState),
140
- VMSTATE_UINT32(arg, PXA2xxMMCIState),
141
- VMSTATE_INT32(cmdreq, PXA2xxMMCIState),
142
- VMSTATE_INT32(active, PXA2xxMMCIState),
143
- VMSTATE_INT32(bytesleft, PXA2xxMMCIState),
144
- VMSTATE_UINT32(tx_start, PXA2xxMMCIState),
145
- VMSTATE_UINT32(tx_len, PXA2xxMMCIState),
146
- VMSTATE_UINT32(rx_start, PXA2xxMMCIState),
147
- VMSTATE_UINT32(rx_len, PXA2xxMMCIState),
148
- VMSTATE_UINT32(resp_len, PXA2xxMMCIState),
149
- VMSTATE_VALIDATE("fifo size incorrect", pxa2xx_mmci_vmstate_validate),
150
- VMSTATE_UINT8_ARRAY(tx_fifo, PXA2xxMMCIState, 64),
151
- VMSTATE_UINT8_ARRAY(rx_fifo, PXA2xxMMCIState, 32),
152
- VMSTATE_UINT16_ARRAY(resp_fifo, PXA2xxMMCIState, 9),
153
- VMSTATE_END_OF_LIST()
154
- }
155
-};
156
-
157
-#define MMC_STRPCL    0x00    /* MMC Clock Start/Stop register */
158
-#define MMC_STAT    0x04    /* MMC Status register */
159
-#define MMC_CLKRT    0x08    /* MMC Clock Rate register */
160
-#define MMC_SPI        0x0c    /* MMC SPI Mode register */
161
-#define MMC_CMDAT    0x10    /* MMC Command/Data register */
162
-#define MMC_RESTO    0x14    /* MMC Response Time-Out register */
163
-#define MMC_RDTO    0x18    /* MMC Read Time-Out register */
164
-#define MMC_BLKLEN    0x1c    /* MMC Block Length register */
165
-#define MMC_NUMBLK    0x20    /* MMC Number of Blocks register */
166
-#define MMC_PRTBUF    0x24    /* MMC Buffer Partly Full register */
167
-#define MMC_I_MASK    0x28    /* MMC Interrupt Mask register */
168
-#define MMC_I_REG    0x2c    /* MMC Interrupt Request register */
169
-#define MMC_CMD        0x30    /* MMC Command register */
170
-#define MMC_ARGH    0x34    /* MMC Argument High register */
171
-#define MMC_ARGL    0x38    /* MMC Argument Low register */
172
-#define MMC_RES        0x3c    /* MMC Response FIFO */
173
-#define MMC_RXFIFO    0x40    /* MMC Receive FIFO */
174
-#define MMC_TXFIFO    0x44    /* MMC Transmit FIFO */
175
-#define MMC_RDWAIT    0x48    /* MMC RD_WAIT register */
176
-#define MMC_BLKS_REM    0x4c    /* MMC Blocks Remaining register */
177
-
178
-/* Bitfield masks */
179
-#define STRPCL_STOP_CLK    (1 << 0)
180
-#define STRPCL_STRT_CLK    (1 << 1)
181
-#define STAT_TOUT_RES    (1 << 1)
182
-#define STAT_CLK_EN    (1 << 8)
183
-#define STAT_DATA_DONE    (1 << 11)
184
-#define STAT_PRG_DONE    (1 << 12)
185
-#define STAT_END_CMDRES    (1 << 13)
186
-#define SPI_SPI_MODE    (1 << 0)
187
-#define CMDAT_RES_TYPE    (3 << 0)
188
-#define CMDAT_DATA_EN    (1 << 2)
189
-#define CMDAT_WR_RD    (1 << 3)
190
-#define CMDAT_DMA_EN    (1 << 7)
191
-#define CMDAT_STOP_TRAN    (1 << 10)
192
-#define INT_DATA_DONE    (1 << 0)
193
-#define INT_PRG_DONE    (1 << 1)
194
-#define INT_END_CMD    (1 << 2)
195
-#define INT_STOP_CMD    (1 << 3)
196
-#define INT_CLK_OFF    (1 << 4)
197
-#define INT_RXFIFO_REQ    (1 << 5)
198
-#define INT_TXFIFO_REQ    (1 << 6)
199
-#define INT_TINT    (1 << 7)
200
-#define INT_DAT_ERR    (1 << 8)
201
-#define INT_RES_ERR    (1 << 9)
202
-#define INT_RD_STALLED    (1 << 10)
203
-#define INT_SDIO_INT    (1 << 11)
204
-#define INT_SDIO_SACK    (1 << 12)
205
-#define PRTBUF_PRT_BUF    (1 << 0)
206
-
207
-/* Route internal interrupt lines to the global IC and DMA */
208
-static void pxa2xx_mmci_int_update(PXA2xxMMCIState *s)
209
-{
210
- uint32_t mask = s->intmask;
211
- if (s->cmdat & CMDAT_DMA_EN) {
212
- mask |= INT_RXFIFO_REQ | INT_TXFIFO_REQ;
213
-
214
- qemu_set_irq(s->rx_dma, !!(s->intreq & INT_RXFIFO_REQ));
215
- qemu_set_irq(s->tx_dma, !!(s->intreq & INT_TXFIFO_REQ));
216
- }
111
- }
217
-
112
-
218
- qemu_set_irq(s->irq, !!(s->intreq & ~mask));
113
- if (status->default_nan_mode) {
219
-}
114
- return floatx80_default_nan(status);
220
-
221
-static void pxa2xx_mmci_fifo_update(PXA2xxMMCIState *s)
222
-{
223
- if (!s->active)
224
- return;
225
-
226
- if (s->cmdat & CMDAT_WR_RD) {
227
- while (s->bytesleft && s->tx_len) {
228
- sdbus_write_byte(&s->sdbus, s->tx_fifo[s->tx_start++]);
229
- s->tx_start &= 0x1f;
230
- s->tx_len --;
231
- s->bytesleft --;
232
- }
233
- if (s->bytesleft)
234
- s->intreq |= INT_TXFIFO_REQ;
235
- } else
236
- while (s->bytesleft && s->rx_len < 32) {
237
- s->rx_fifo[(s->rx_start + (s->rx_len ++)) & 0x1f] =
238
- sdbus_read_byte(&s->sdbus);
239
- s->bytesleft --;
240
- s->intreq |= INT_RXFIFO_REQ;
241
- }
242
-
243
- if (!s->bytesleft) {
244
- s->active = 0;
245
- s->intreq |= INT_DATA_DONE;
246
- s->status |= STAT_DATA_DONE;
247
-
248
- if (s->cmdat & CMDAT_WR_RD) {
249
- s->intreq |= INT_PRG_DONE;
250
- s->status |= STAT_PRG_DONE;
251
- }
252
- }
115
- }
253
-
116
-
254
- pxa2xx_mmci_int_update(s);
117
- if (a.low < b.low) {
255
-}
118
- aIsLargerSignificand = 0;
256
-
119
- } else if (b.low < a.low) {
257
-static void pxa2xx_mmci_wakequeues(PXA2xxMMCIState *s)
120
- aIsLargerSignificand = 1;
258
-{
121
- } else {
259
- int rsplen, i;
122
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
260
- SDRequest request;
261
- uint8_t response[16];
262
-
263
- s->active = 1;
264
- s->rx_len = 0;
265
- s->tx_len = 0;
266
- s->cmdreq = 0;
267
-
268
- request.cmd = s->cmd;
269
- request.arg = s->arg;
270
- request.crc = 0;    /* FIXME */
271
-
272
- rsplen = sdbus_do_command(&s->sdbus, &request, response);
273
- s->intreq |= INT_END_CMD;
274
-
275
- memset(s->resp_fifo, 0, sizeof(s->resp_fifo));
276
- switch (s->cmdat & CMDAT_RES_TYPE) {
277
-#define PXAMMCI_RESP(wd, value0, value1)    \
278
- s->resp_fifo[(wd) + 0] |= (value0);    \
279
- s->resp_fifo[(wd) + 1] |= (value1) << 8;
280
- case 0:    /* No response */
281
- goto complete;
282
-
283
- case 1:    /* R1, R4, R5 or R6 */
284
- if (rsplen < 4)
285
- goto timeout;
286
- goto complete;
287
-
288
- case 2:    /* R2 */
289
- if (rsplen < 16)
290
- goto timeout;
291
- goto complete;
292
-
293
- case 3:    /* R3 */
294
- if (rsplen < 4)
295
- goto timeout;
296
- goto complete;
297
-
298
- complete:
299
- for (i = 0; rsplen > 0; i ++, rsplen -= 2) {
300
- PXAMMCI_RESP(i, response[i * 2], response[i * 2 + 1]);
301
- }
302
- s->status |= STAT_END_CMDRES;
303
-
304
- if (!(s->cmdat & CMDAT_DATA_EN))
305
- s->active = 0;
306
- else
307
- s->bytesleft = s->numblk * s->blklen;
308
-
309
- s->resp_len = 0;
310
- break;
311
-
312
- timeout:
313
- s->active = 0;
314
- s->status |= STAT_TOUT_RES;
315
- break;
316
- }
123
- }
317
-
124
-
318
- pxa2xx_mmci_fifo_update(s);
125
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
319
-}
126
- if (is_snan(b_cls)) {
320
-
127
- return floatx80_silence_nan(b, status);
321
-static uint64_t pxa2xx_mmci_read(void *opaque, hwaddr offset, unsigned size)
322
-{
323
- PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
324
- uint32_t ret = 0;
325
-
326
- switch (offset) {
327
- case MMC_STRPCL:
328
- break;
329
- case MMC_STAT:
330
- ret = s->status;
331
- break;
332
- case MMC_CLKRT:
333
- ret = s->clkrt;
334
- break;
335
- case MMC_SPI:
336
- ret = s->spi;
337
- break;
338
- case MMC_CMDAT:
339
- ret = s->cmdat;
340
- break;
341
- case MMC_RESTO:
342
- ret = s->resp_tout;
343
- break;
344
- case MMC_RDTO:
345
- ret = s->read_tout;
346
- break;
347
- case MMC_BLKLEN:
348
- ret = s->blklen;
349
- break;
350
- case MMC_NUMBLK:
351
- ret = s->numblk;
352
- break;
353
- case MMC_PRTBUF:
354
- break;
355
- case MMC_I_MASK:
356
- ret = s->intmask;
357
- break;
358
- case MMC_I_REG:
359
- ret = s->intreq;
360
- break;
361
- case MMC_CMD:
362
- ret = s->cmd | 0x40;
363
- break;
364
- case MMC_ARGH:
365
- ret = s->arg >> 16;
366
- break;
367
- case MMC_ARGL:
368
- ret = s->arg & 0xffff;
369
- break;
370
- case MMC_RES:
371
- ret = (s->resp_len < 9) ? s->resp_fifo[s->resp_len++] : 0;
372
- break;
373
- case MMC_RXFIFO:
374
- while (size-- && s->rx_len) {
375
- ret |= s->rx_fifo[s->rx_start++] << (size << 3);
376
- s->rx_start &= 0x1f;
377
- s->rx_len --;
378
- }
128
- }
379
- s->intreq &= ~INT_RXFIFO_REQ;
129
- return b;
380
- pxa2xx_mmci_fifo_update(s);
130
- } else {
381
- break;
131
- if (is_snan(a_cls)) {
382
- case MMC_RDWAIT:
132
- return floatx80_silence_nan(a, status);
383
- break;
384
- case MMC_BLKS_REM:
385
- ret = s->numblk;
386
- break;
387
- default:
388
- qemu_log_mask(LOG_GUEST_ERROR,
389
- "%s: incorrect register 0x%02" HWADDR_PRIx "\n",
390
- __func__, offset);
391
- }
392
- trace_pxa2xx_mmci_read(size, offset, ret);
393
-
394
- return ret;
395
-}
396
-
397
-static void pxa2xx_mmci_write(void *opaque,
398
- hwaddr offset, uint64_t value, unsigned size)
399
-{
400
- PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
401
-
402
- trace_pxa2xx_mmci_write(size, offset, value);
403
- switch (offset) {
404
- case MMC_STRPCL:
405
- if (value & STRPCL_STRT_CLK) {
406
- s->status |= STAT_CLK_EN;
407
- s->intreq &= ~INT_CLK_OFF;
408
-
409
- if (s->cmdreq && !(s->cmdat & CMDAT_STOP_TRAN)) {
410
- s->status &= STAT_CLK_EN;
411
- pxa2xx_mmci_wakequeues(s);
412
- }
413
- }
133
- }
414
-
134
- return a;
415
- if (value & STRPCL_STOP_CLK) {
416
- s->status &= ~STAT_CLK_EN;
417
- s->intreq |= INT_CLK_OFF;
418
- s->active = 0;
419
- }
420
-
421
- pxa2xx_mmci_int_update(s);
422
- break;
423
-
424
- case MMC_CLKRT:
425
- s->clkrt = value & 7;
426
- break;
427
-
428
- case MMC_SPI:
429
- s->spi = value & 0xf;
430
- if (value & SPI_SPI_MODE) {
431
- qemu_log_mask(LOG_GUEST_ERROR,
432
- "%s: attempted to use card in SPI mode\n", __func__);
433
- }
434
- break;
435
-
436
- case MMC_CMDAT:
437
- s->cmdat = value & 0x3dff;
438
- s->active = 0;
439
- s->cmdreq = 1;
440
- if (!(value & CMDAT_STOP_TRAN)) {
441
- s->status &= STAT_CLK_EN;
442
-
443
- if (s->status & STAT_CLK_EN)
444
- pxa2xx_mmci_wakequeues(s);
445
- }
446
-
447
- pxa2xx_mmci_int_update(s);
448
- break;
449
-
450
- case MMC_RESTO:
451
- s->resp_tout = value & 0x7f;
452
- break;
453
-
454
- case MMC_RDTO:
455
- s->read_tout = value & 0xffff;
456
- break;
457
-
458
- case MMC_BLKLEN:
459
- s->blklen = value & 0xfff;
460
- break;
461
-
462
- case MMC_NUMBLK:
463
- s->numblk = value & 0xffff;
464
- break;
465
-
466
- case MMC_PRTBUF:
467
- if (value & PRTBUF_PRT_BUF) {
468
- s->tx_start ^= 32;
469
- s->tx_len = 0;
470
- }
471
- pxa2xx_mmci_fifo_update(s);
472
- break;
473
-
474
- case MMC_I_MASK:
475
- s->intmask = value & 0x1fff;
476
- pxa2xx_mmci_int_update(s);
477
- break;
478
-
479
- case MMC_CMD:
480
- s->cmd = value & 0x3f;
481
- break;
482
-
483
- case MMC_ARGH:
484
- s->arg &= 0x0000ffff;
485
- s->arg |= value << 16;
486
- break;
487
-
488
- case MMC_ARGL:
489
- s->arg &= 0xffff0000;
490
- s->arg |= value & 0x0000ffff;
491
- break;
492
-
493
- case MMC_TXFIFO:
494
- while (size-- && s->tx_len < 0x20)
495
- s->tx_fifo[(s->tx_start + (s->tx_len ++)) & 0x1f] =
496
- (value >> (size << 3)) & 0xff;
497
- s->intreq &= ~INT_TXFIFO_REQ;
498
- pxa2xx_mmci_fifo_update(s);
499
- break;
500
-
501
- case MMC_RDWAIT:
502
- case MMC_BLKS_REM:
503
- break;
504
-
505
- default:
506
- qemu_log_mask(LOG_GUEST_ERROR,
507
- "%s: incorrect reg 0x%02" HWADDR_PRIx " "
508
- "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
509
- }
135
- }
510
-}
136
-}
511
-
137
-
512
-static const MemoryRegionOps pxa2xx_mmci_ops = {
138
/*----------------------------------------------------------------------------
513
- .read = pxa2xx_mmci_read,
139
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
514
- .write = pxa2xx_mmci_write,
140
| NaN; otherwise returns 0.
515
- .endianness = DEVICE_NATIVE_ENDIAN,
516
-};
517
-
518
-PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
519
- hwaddr base,
520
- qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma)
521
-{
522
- DeviceState *dev;
523
-
524
- dev = sysbus_create_simple(TYPE_PXA2XX_MMCI, base, irq);
525
- qdev_connect_gpio_out_named(dev, "rx-dma", 0, rx_dma);
526
- qdev_connect_gpio_out_named(dev, "tx-dma", 0, tx_dma);
527
-
528
- return PXA2XX_MMCI(dev);
529
-}
530
-
531
-static void pxa2xx_mmci_set_inserted(DeviceState *dev, bool inserted)
532
-{
533
- PXA2xxMMCIState *s = PXA2XX_MMCI(dev);
534
-
535
- qemu_set_irq(s->inserted, inserted);
536
-}
537
-
538
-static void pxa2xx_mmci_set_readonly(DeviceState *dev, bool readonly)
539
-{
540
- PXA2xxMMCIState *s = PXA2XX_MMCI(dev);
541
-
542
- qemu_set_irq(s->readonly, readonly);
543
-}
544
-
545
-void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
546
- qemu_irq coverswitch)
547
-{
548
- DeviceState *dev = DEVICE(s);
549
-
550
- s->readonly = readonly;
551
- s->inserted = coverswitch;
552
-
553
- pxa2xx_mmci_set_inserted(dev, sdbus_get_inserted(&s->sdbus));
554
- pxa2xx_mmci_set_readonly(dev, sdbus_get_readonly(&s->sdbus));
555
-}
556
-
557
-static void pxa2xx_mmci_reset(DeviceState *d)
558
-{
559
- PXA2xxMMCIState *s = PXA2XX_MMCI(d);
560
-
561
- s->status = 0;
562
- s->clkrt = 0;
563
- s->spi = 0;
564
- s->cmdat = 0;
565
- s->resp_tout = 0;
566
- s->read_tout = 0;
567
- s->blklen = 0;
568
- s->numblk = 0;
569
- s->intmask = 0;
570
- s->intreq = 0;
571
- s->cmd = 0;
572
- s->arg = 0;
573
- s->active = 0;
574
- s->bytesleft = 0;
575
- s->tx_start = 0;
576
- s->tx_len = 0;
577
- s->rx_start = 0;
578
- s->rx_len = 0;
579
- s->resp_len = 0;
580
- s->cmdreq = 0;
581
- memset(s->tx_fifo, 0, sizeof(s->tx_fifo));
582
- memset(s->rx_fifo, 0, sizeof(s->rx_fifo));
583
- memset(s->resp_fifo, 0, sizeof(s->resp_fifo));
584
-}
585
-
586
-static void pxa2xx_mmci_instance_init(Object *obj)
587
-{
588
- PXA2xxMMCIState *s = PXA2XX_MMCI(obj);
589
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
590
- DeviceState *dev = DEVICE(obj);
591
-
592
- memory_region_init_io(&s->iomem, obj, &pxa2xx_mmci_ops, s,
593
- "pxa2xx-mmci", 0x00100000);
594
- sysbus_init_mmio(sbd, &s->iomem);
595
- sysbus_init_irq(sbd, &s->irq);
596
- qdev_init_gpio_out_named(dev, &s->rx_dma, "rx-dma", 1);
597
- qdev_init_gpio_out_named(dev, &s->tx_dma, "tx-dma", 1);
598
-
599
- qbus_init(&s->sdbus, sizeof(s->sdbus),
600
- TYPE_PXA2XX_MMCI_BUS, DEVICE(obj), "sd-bus");
601
-}
602
-
603
-static void pxa2xx_mmci_class_init(ObjectClass *klass, void *data)
604
-{
605
- DeviceClass *dc = DEVICE_CLASS(klass);
606
-
607
- dc->vmsd = &vmstate_pxa2xx_mmci;
608
- device_class_set_legacy_reset(dc, pxa2xx_mmci_reset);
609
-}
610
-
611
-static void pxa2xx_mmci_bus_class_init(ObjectClass *klass, void *data)
612
-{
613
- SDBusClass *sbc = SD_BUS_CLASS(klass);
614
-
615
- sbc->set_inserted = pxa2xx_mmci_set_inserted;
616
- sbc->set_readonly = pxa2xx_mmci_set_readonly;
617
-}
618
-
619
-static const TypeInfo pxa2xx_mmci_types[] = {
620
- {
621
- .name = TYPE_PXA2XX_MMCI,
622
- .parent = TYPE_SYS_BUS_DEVICE,
623
- .instance_size = sizeof(PXA2xxMMCIState),
624
- .instance_init = pxa2xx_mmci_instance_init,
625
- .class_init = pxa2xx_mmci_class_init,
626
- },
627
- {
628
- .name = TYPE_PXA2XX_MMCI_BUS,
629
- .parent = TYPE_SD_BUS,
630
- .instance_size = sizeof(SDBus),
631
- .class_init = pxa2xx_mmci_bus_class_init,
632
- },
633
-};
634
-
635
-DEFINE_TYPES(pxa2xx_mmci_types)
636
diff --git a/hw/sd/meson.build b/hw/sd/meson.build
637
index XXXXXXX..XXXXXXX 100644
638
--- a/hw/sd/meson.build
639
+++ b/hw/sd/meson.build
640
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_SDHCI_PCI', if_true: files('sdhci-pci.c'))
641
system_ss.add(when: 'CONFIG_SSI_SD', if_true: files('ssi-sd.c'))
642
643
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_mmc.c'))
644
-system_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_mmci.c'))
645
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_sdhost.c'))
646
system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_sdhci.c'))
647
system_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-sdhost.c'))
648
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
649
index XXXXXXX..XXXXXXX 100644
650
--- a/hw/sd/trace-events
651
+++ b/hw/sd/trace-events
652
@@ -XXX,XX +XXX,XX @@ sdcard_set_voltage(uint16_t millivolts) "%u mV"
653
sdcard_ext_csd_update(unsigned index, uint8_t oval, uint8_t nval) "index %u: 0x%02x -> 0x%02x"
654
sdcard_switch(unsigned access, unsigned index, unsigned value, unsigned set) "SWITCH acc:%u idx:%u val:%u set:%u"
655
656
-# pxa2xx_mmci.c
657
-pxa2xx_mmci_read(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"
658
-pxa2xx_mmci_write(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"
659
-
660
# pl181.c
661
pl181_command_send(uint8_t cmd, uint32_t arg) "sending CMD%02d arg 0x%08" PRIx32
662
pl181_command_sent(void) "command sent"
663
--
141
--
664
2.34.1
142
2.34.1
665
666
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
It has been a learning experience to contribute to QEMU for our
3
Unpacking and repacking the parts may be slightly more work
4
end-of-studies project. For a few months now, Arnaud and I aren't
4
than we did before, but we get to reuse more code. For a
5
actively involved anymore as we lack time and access to the hardware.
5
code path handling exceptional values, this is an improvement.
6
Therefore it's high time to update the maintainers file: from now on,
7
Samuel Tardieu who is behind the project will be taking up the role of
8
maintainer.
9
6
10
This commit updates maintainers and the list of files, and places the
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
two devices in alphabetical order.
8
Message-id: 20241203203949.483774-8-richard.henderson@linaro.org
12
13
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
14
Signed-off-by: Samuel Tardieu <sam@rfc1149.net>
15
Message-id: 20240921104751.43671-1-ines.varhol@telecom-paris.fr
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
---
11
---
19
MAINTAINERS | 41 +++++++++++++++++++++--------------------
12
fpu/softfloat.c | 43 +++++--------------------------------------
20
1 file changed, 21 insertions(+), 20 deletions(-)
13
1 file changed, 5 insertions(+), 38 deletions(-)
21
14
22
diff --git a/MAINTAINERS b/MAINTAINERS
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
23
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
24
--- a/MAINTAINERS
17
--- a/fpu/softfloat.c
25
+++ b/MAINTAINERS
18
+++ b/fpu/softfloat.c
26
@@ -XXX,XX +XXX,XX @@ F: include/hw/timer/armv7m_systick.h
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
27
F: include/hw/misc/armv7m_ras.h
20
28
F: tests/qtest/test-arm-mptimer.c
21
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
29
22
{
30
+B-L475E-IOT01A IoT Node
23
- bool aIsLargerSignificand;
31
+M: Samuel Tardieu <sam@rfc1149.net>
24
- FloatClass a_cls, b_cls;
32
+L: qemu-arm@nongnu.org
25
+ FloatParts128 pa, pb, *pr;
33
+S: Maintained
26
34
+F: hw/arm/b-l475e-iot01a.c
27
- /* This is not complete, but is good enough for pickNaN. */
35
+F: hw/display/dm163.c
28
- a_cls = (!floatx80_is_any_nan(a)
36
+F: tests/qtest/dm163-test.c
29
- ? float_class_normal
37
+
30
- : floatx80_is_signaling_nan(a, status)
38
Exynos
31
- ? float_class_snan
39
M: Igor Mitsyanko <i.mitsyanko@gmail.com>
32
- : float_class_qnan);
40
M: Peter Maydell <peter.maydell@linaro.org>
33
- b_cls = (!floatx80_is_any_nan(b)
41
@@ -XXX,XX +XXX,XX @@ F: include/hw/input/gamepad.h
34
- ? float_class_normal
42
F: include/hw/timer/stellaris-gptm.h
35
- : floatx80_is_signaling_nan(b, status)
43
F: docs/system/arm/stellaris.rst
36
- ? float_class_snan
44
37
- : float_class_qnan);
45
+STM32L4x5 SoC Family
46
+M: Samuel Tardieu <sam@rfc1149.net>
47
+L: qemu-arm@nongnu.org
48
+S: Maintained
49
+F: hw/arm/stm32l4x5_soc.c
50
+F: hw/char/stm32l4x5_usart.c
51
+F: hw/misc/stm32l4x5_exti.c
52
+F: hw/misc/stm32l4x5_syscfg.c
53
+F: hw/misc/stm32l4x5_rcc.c
54
+F: hw/gpio/stm32l4x5_gpio.c
55
+F: include/hw/*/stm32l4x5_*.h
56
+F: tests/qtest/stm32l4x5*
57
+
58
STM32VLDISCOVERY
59
M: Alexandre Iooss <erdnaxe@crans.org>
60
L: qemu-arm@nongnu.org
61
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
62
S: Maintained
63
F: hw/arm/olimex-stm32-h405.c
64
65
-STM32L4x5 SoC Family
66
-M: Arnaud Minier <arnaud.minier@telecom-paris.fr>
67
-M: Inès Varhol <ines.varhol@telecom-paris.fr>
68
-L: qemu-arm@nongnu.org
69
-S: Maintained
70
-F: hw/arm/stm32l4x5_soc.c
71
-F: hw/char/stm32l4x5_usart.c
72
-F: hw/misc/stm32l4x5_exti.c
73
-F: hw/misc/stm32l4x5_syscfg.c
74
-F: hw/misc/stm32l4x5_rcc.c
75
-F: hw/gpio/stm32l4x5_gpio.c
76
-F: include/hw/*/stm32l4x5_*.h
77
-
38
-
78
-B-L475E-IOT01A IoT Node
39
- if (is_snan(a_cls) || is_snan(b_cls)) {
79
-M: Arnaud Minier <arnaud.minier@telecom-paris.fr>
40
- float_raise(float_flag_invalid, status);
80
-M: Inès Varhol <ines.varhol@telecom-paris.fr>
41
- }
81
-L: qemu-arm@nongnu.org
82
-S: Maintained
83
-F: hw/arm/b-l475e-iot01a.c
84
-
42
-
85
SmartFusion2
43
- if (status->default_nan_mode) {
86
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
44
+ if (!floatx80_unpack_canonical(&pa, a, status) ||
87
M: Peter Maydell <peter.maydell@linaro.org>
45
+ !floatx80_unpack_canonical(&pb, b, status)) {
46
return floatx80_default_nan(status);
47
}
48
49
- if (a.low < b.low) {
50
- aIsLargerSignificand = 0;
51
- } else if (b.low < a.low) {
52
- aIsLargerSignificand = 1;
53
- } else {
54
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
55
- }
56
-
57
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
58
- if (is_snan(b_cls)) {
59
- return floatx80_silence_nan(b, status);
60
- }
61
- return b;
62
- } else {
63
- if (is_snan(a_cls)) {
64
- return floatx80_silence_nan(a, status);
65
- }
66
- return a;
67
- }
68
+ pr = parts_pick_nan(&pa, &pb, status);
69
+ return floatx80_round_pack_canonical(pr, status);
70
}
71
72
/*----------------------------------------------------------------------------
88
--
73
--
89
2.34.1
74
2.34.1
90
91
diff view generated by jsdifflib
1
The omap_gptimer device is only in the OMAP2 SoC, which we
1
From: Richard Henderson <richard.henderson@linaro.org>
2
are removing.
2
3
3
Inline pickNaN into its only caller. This makes one assert
4
redundant with the immediately preceding IF.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-9-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240903160751.4100218-45-peter.maydell@linaro.org
8
---
10
---
9
include/hw/arm/omap.h | 8 -
11
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
10
hw/timer/omap_gptimer.c | 512 ----------------------------------------
12
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
11
hw/timer/meson.build | 1 -
13
2 files changed, 73 insertions(+), 105 deletions(-)
12
3 files changed, 521 deletions(-)
14
13
delete mode 100644 hw/timer/omap_gptimer.c
15
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
14
15
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/omap.h
17
--- a/fpu/softfloat-parts.c.inc
18
+++ b/include/hw/arm/omap.h
18
+++ b/fpu/softfloat-parts.c.inc
19
@@ -XXX,XX +XXX,XX @@ struct omap_dma_lcd_channel_s {
19
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
20
# define OMAP24XX_DMA_MS        63    /* Not in OMAP2420 */
20
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
21
# define OMAP24XX_DMA_EXT_DMAREQ5    64
21
float_status *s)
22
22
{
23
-/* omap[123].c */
23
+ int cmp, which;
24
-/* OMAP2 gp timer */
24
+
25
-struct omap_gp_timer_s;
25
if (is_snan(a->cls) || is_snan(b->cls)) {
26
-struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta,
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
27
- qemu_irq irq, omap_clk fclk, omap_clk iclk);
27
}
28
-void omap_gp_timer_reset(struct omap_gp_timer_s *s);
28
29
if (s->default_nan_mode) {
30
parts_default_nan(a, s);
31
- } else {
32
- int cmp = frac_cmp(a, b);
33
- if (cmp == 0) {
34
- cmp = a->sign < b->sign;
35
- }
36
+ return a;
37
+ }
38
39
- if (pickNaN(a->cls, b->cls, cmp > 0, s)) {
40
- a = b;
41
- }
42
+ cmp = frac_cmp(a, b);
43
+ if (cmp == 0) {
44
+ cmp = a->sign < b->sign;
45
+ }
46
+
47
+ switch (s->float_2nan_prop_rule) {
48
+ case float_2nan_prop_s_ab:
49
if (is_snan(a->cls)) {
50
- parts_silence_nan(a, s);
51
+ which = 0;
52
+ } else if (is_snan(b->cls)) {
53
+ which = 1;
54
+ } else if (is_qnan(a->cls)) {
55
+ which = 0;
56
+ } else {
57
+ which = 1;
58
}
59
+ break;
60
+ case float_2nan_prop_s_ba:
61
+ if (is_snan(b->cls)) {
62
+ which = 1;
63
+ } else if (is_snan(a->cls)) {
64
+ which = 0;
65
+ } else if (is_qnan(b->cls)) {
66
+ which = 1;
67
+ } else {
68
+ which = 0;
69
+ }
70
+ break;
71
+ case float_2nan_prop_ab:
72
+ which = is_nan(a->cls) ? 0 : 1;
73
+ break;
74
+ case float_2nan_prop_ba:
75
+ which = is_nan(b->cls) ? 1 : 0;
76
+ break;
77
+ case float_2nan_prop_x87:
78
+ /*
79
+ * This implements x87 NaN propagation rules:
80
+ * SNaN + QNaN => return the QNaN
81
+ * two SNaNs => return the one with the larger significand, silenced
82
+ * two QNaNs => return the one with the larger significand
83
+ * SNaN and a non-NaN => return the SNaN, silenced
84
+ * QNaN and a non-NaN => return the QNaN
85
+ *
86
+ * If we get down to comparing significands and they are the same,
87
+ * return the NaN with the positive sign bit (if any).
88
+ */
89
+ if (is_snan(a->cls)) {
90
+ if (is_snan(b->cls)) {
91
+ which = cmp > 0 ? 0 : 1;
92
+ } else {
93
+ which = is_qnan(b->cls) ? 1 : 0;
94
+ }
95
+ } else if (is_qnan(a->cls)) {
96
+ if (is_snan(b->cls) || !is_qnan(b->cls)) {
97
+ which = 0;
98
+ } else {
99
+ which = cmp > 0 ? 0 : 1;
100
+ }
101
+ } else {
102
+ which = 1;
103
+ }
104
+ break;
105
+ default:
106
+ g_assert_not_reached();
107
+ }
108
+
109
+ if (which) {
110
+ a = b;
111
+ }
112
+ if (is_snan(a->cls)) {
113
+ parts_silence_nan(a, s);
114
}
115
return a;
116
}
117
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
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
-*----------------------------------------------------------------------------*/
29
-
141
-
30
/* OMAP2 sysctimer */
142
-static int pickNaN(FloatClass a_cls, FloatClass b_cls,
31
struct omap_synctimer_s;
143
- bool aIsLargerSignificand, float_status *status)
32
struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta,
144
-{
33
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s {
145
- /*
34
/* OMAP2-only peripherals */
146
- * We guarantee not to require the target to tell us how to
35
struct omap_l4_s *l4;
147
- * pick a NaN if we're always returning the default NaN.
36
148
- * But if we're not in default-NaN mode then the target must
37
- struct omap_gp_timer_s *gptimer[12];
149
- * specify via set_float_2nan_prop_rule().
38
struct omap_synctimer_s *synctimer;
150
- */
39
151
- assert(!status->default_nan_mode);
40
struct omap_mcspi_s *mcspi[2];
41
diff --git a/hw/timer/omap_gptimer.c b/hw/timer/omap_gptimer.c
42
deleted file mode 100644
43
index XXXXXXX..XXXXXXX
44
--- a/hw/timer/omap_gptimer.c
45
+++ /dev/null
46
@@ -XXX,XX +XXX,XX @@
47
-/*
48
- * TI OMAP2 general purpose timers emulation.
49
- *
50
- * Copyright (C) 2007-2008 Nokia Corporation
51
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
52
- *
53
- * This program is free software; you can redistribute it and/or
54
- * modify it under the terms of the GNU General Public License as
55
- * published by the Free Software Foundation; either version 2 or
56
- * (at your option) any later version of the License.
57
- *
58
- * This program is distributed in the hope that it will be useful,
59
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
60
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
61
- * GNU General Public License for more details.
62
- *
63
- * You should have received a copy of the GNU General Public License along
64
- * with this program; if not, see <http://www.gnu.org/licenses/>.
65
- */
66
-
152
-
67
-#include "qemu/osdep.h"
153
- switch (status->float_2nan_prop_rule) {
68
-#include "hw/irq.h"
154
- case float_2nan_prop_s_ab:
69
-#include "qemu/timer.h"
155
- if (is_snan(a_cls)) {
70
-#include "hw/arm/omap.h"
156
- return 0;
71
-
157
- } else if (is_snan(b_cls)) {
72
-/* GP timers */
158
- return 1;
73
-struct omap_gp_timer_s {
159
- } else if (is_qnan(a_cls)) {
74
- MemoryRegion iomem;
160
- return 0;
75
- qemu_irq irq;
161
- } else {
76
- qemu_irq wkup;
162
- return 1;
77
- qemu_irq in;
163
- }
78
- qemu_irq out;
164
- break;
79
- omap_clk clk;
165
- case float_2nan_prop_s_ba:
80
- QEMUTimer *timer;
166
- if (is_snan(b_cls)) {
81
- QEMUTimer *match;
167
- return 1;
82
- struct omap_target_agent_s *ta;
168
- } else if (is_snan(a_cls)) {
83
-
169
- return 0;
84
- int in_val;
170
- } else if (is_qnan(b_cls)) {
85
- int out_val;
171
- return 1;
86
- int64_t time;
172
- } else {
87
- int64_t rate;
173
- return 0;
88
- int64_t ticks_per_sec;
174
- }
89
-
175
- break;
90
- int16_t config;
176
- case float_2nan_prop_ab:
91
- int status;
177
- if (is_nan(a_cls)) {
92
- int it_ena;
178
- return 0;
93
- int wu_ena;
179
- } else {
94
- int enable;
180
- return 1;
95
- int inout;
181
- }
96
- int capt2;
182
- break;
97
- int pt;
183
- case float_2nan_prop_ba:
98
- enum {
184
- if (is_nan(b_cls)) {
99
- gpt_trigger_none, gpt_trigger_overflow, gpt_trigger_both
185
- return 1;
100
- } trigger;
186
- } else {
101
- enum {
187
- return 0;
102
- gpt_capture_none, gpt_capture_rising,
188
- }
103
- gpt_capture_falling, gpt_capture_both
189
- break;
104
- } capture;
190
- case float_2nan_prop_x87:
105
- int scpwm;
191
- /*
106
- int ce;
192
- * This implements x87 NaN propagation rules:
107
- int pre;
193
- * SNaN + QNaN => return the QNaN
108
- int ptv;
194
- * two SNaNs => return the one with the larger significand, silenced
109
- int ar;
195
- * two QNaNs => return the one with the larger significand
110
- int st;
196
- * SNaN and a non-NaN => return the SNaN, silenced
111
- int posted;
197
- * QNaN and a non-NaN => return the QNaN
112
- uint32_t val;
198
- *
113
- uint32_t load_val;
199
- * If we get down to comparing significands and they are the same,
114
- uint32_t capture_val[2];
200
- * return the NaN with the positive sign bit (if any).
115
- uint32_t match_val;
201
- */
116
- int capt_num;
202
- if (is_snan(a_cls)) {
117
-
203
- if (is_snan(b_cls)) {
118
- uint16_t writeh;    /* LSB */
204
- return aIsLargerSignificand ? 0 : 1;
119
- uint16_t readh;    /* MSB */
205
- }
120
-};
206
- return is_qnan(b_cls) ? 1 : 0;
121
-
207
- } else if (is_qnan(a_cls)) {
122
-#define GPT_TCAR_IT    (1 << 2)
208
- if (is_snan(b_cls) || !is_qnan(b_cls)) {
123
-#define GPT_OVF_IT    (1 << 1)
209
- return 0;
124
-#define GPT_MAT_IT    (1 << 0)
210
- } else {
125
-
211
- return aIsLargerSignificand ? 0 : 1;
126
-static inline void omap_gp_timer_intr(struct omap_gp_timer_s *timer, int it)
212
- }
127
-{
213
- } else {
128
- if (timer->it_ena & it) {
214
- return 1;
129
- if (!timer->status)
215
- }
130
- qemu_irq_raise(timer->irq);
131
-
132
- timer->status |= it;
133
- /* Or are the status bits set even when masked?
134
- * i.e. is masking applied before or after the status register? */
135
- }
136
-
137
- if (timer->wu_ena & it)
138
- qemu_irq_pulse(timer->wkup);
139
-}
140
-
141
-static inline void omap_gp_timer_out(struct omap_gp_timer_s *timer, int level)
142
-{
143
- if (!timer->inout && timer->out_val != level) {
144
- timer->out_val = level;
145
- qemu_set_irq(timer->out, level);
146
- }
147
-}
148
-
149
-static inline uint32_t omap_gp_timer_read(struct omap_gp_timer_s *timer)
150
-{
151
- uint64_t distance;
152
-
153
- if (timer->st && timer->rate) {
154
- distance = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->time;
155
- distance = muldiv64(distance, timer->rate, timer->ticks_per_sec);
156
-
157
- if (distance >= 0xffffffff - timer->val)
158
- return 0xffffffff;
159
- else
160
- return timer->val + distance;
161
- } else
162
- return timer->val;
163
-}
164
-
165
-static inline void omap_gp_timer_sync(struct omap_gp_timer_s *timer)
166
-{
167
- if (timer->st) {
168
- timer->val = omap_gp_timer_read(timer);
169
- timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
170
- }
171
-}
172
-
173
-static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer)
174
-{
175
- int64_t expires, matches;
176
-
177
- if (timer->st && timer->rate) {
178
- expires = muldiv64(0x100000000ll - timer->val,
179
- timer->ticks_per_sec, timer->rate);
180
- timer_mod(timer->timer, timer->time + expires);
181
-
182
- if (timer->ce && timer->match_val >= timer->val) {
183
- matches = muldiv64(timer->ticks_per_sec,
184
- timer->match_val - timer->val, timer->rate);
185
- timer_mod(timer->match, timer->time + matches);
186
- } else
187
- timer_del(timer->match);
188
- } else {
189
- timer_del(timer->timer);
190
- timer_del(timer->match);
191
- omap_gp_timer_out(timer, timer->scpwm);
192
- }
193
-}
194
-
195
-static inline void omap_gp_timer_trigger(struct omap_gp_timer_s *timer)
196
-{
197
- if (timer->pt)
198
- /* TODO in overflow-and-match mode if the first event to
199
- * occur is the match, don't toggle. */
200
- omap_gp_timer_out(timer, !timer->out_val);
201
- else
202
- /* TODO inverted pulse on timer->out_val == 1? */
203
- qemu_irq_pulse(timer->out);
204
-}
205
-
206
-static void omap_gp_timer_tick(void *opaque)
207
-{
208
- struct omap_gp_timer_s *timer = opaque;
209
-
210
- if (!timer->ar) {
211
- timer->st = 0;
212
- timer->val = 0;
213
- } else {
214
- timer->val = timer->load_val;
215
- timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
216
- }
217
-
218
- if (timer->trigger == gpt_trigger_overflow ||
219
- timer->trigger == gpt_trigger_both)
220
- omap_gp_timer_trigger(timer);
221
-
222
- omap_gp_timer_intr(timer, GPT_OVF_IT);
223
- omap_gp_timer_update(timer);
224
-}
225
-
226
-static void omap_gp_timer_match(void *opaque)
227
-{
228
- struct omap_gp_timer_s *timer = opaque;
229
-
230
- if (timer->trigger == gpt_trigger_both)
231
- omap_gp_timer_trigger(timer);
232
-
233
- omap_gp_timer_intr(timer, GPT_MAT_IT);
234
-}
235
-
236
-static void omap_gp_timer_input(void *opaque, int line, int on)
237
-{
238
- struct omap_gp_timer_s *s = opaque;
239
- int trigger;
240
-
241
- switch (s->capture) {
242
- default:
243
- case gpt_capture_none:
244
- trigger = 0;
245
- break;
246
- case gpt_capture_rising:
247
- trigger = !s->in_val && on;
248
- break;
249
- case gpt_capture_falling:
250
- trigger = s->in_val && !on;
251
- break;
252
- case gpt_capture_both:
253
- trigger = (s->in_val == !on);
254
- break;
255
- }
256
- s->in_val = on;
257
-
258
- if (s->inout && trigger && s->capt_num < 2) {
259
- s->capture_val[s->capt_num] = omap_gp_timer_read(s);
260
-
261
- if (s->capt2 == s->capt_num ++)
262
- omap_gp_timer_intr(s, GPT_TCAR_IT);
263
- }
264
-}
265
-
266
-static void omap_gp_timer_clk_update(void *opaque, int line, int on)
267
-{
268
- struct omap_gp_timer_s *timer = opaque;
269
-
270
- omap_gp_timer_sync(timer);
271
- timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
272
- omap_gp_timer_update(timer);
273
-}
274
-
275
-static void omap_gp_timer_clk_setup(struct omap_gp_timer_s *timer)
276
-{
277
- omap_clk_adduser(timer->clk,
278
- qemu_allocate_irq(omap_gp_timer_clk_update, timer, 0));
279
- timer->rate = omap_clk_getrate(timer->clk);
280
-}
281
-
282
-void omap_gp_timer_reset(struct omap_gp_timer_s *s)
283
-{
284
- s->config = 0x000;
285
- s->status = 0;
286
- s->it_ena = 0;
287
- s->wu_ena = 0;
288
- s->inout = 0;
289
- s->capt2 = 0;
290
- s->capt_num = 0;
291
- s->pt = 0;
292
- s->trigger = gpt_trigger_none;
293
- s->capture = gpt_capture_none;
294
- s->scpwm = 0;
295
- s->ce = 0;
296
- s->pre = 0;
297
- s->ptv = 0;
298
- s->ar = 0;
299
- s->st = 0;
300
- s->posted = 1;
301
- s->val = 0x00000000;
302
- s->load_val = 0x00000000;
303
- s->capture_val[0] = 0x00000000;
304
- s->capture_val[1] = 0x00000000;
305
- s->match_val = 0x00000000;
306
- omap_gp_timer_update(s);
307
-}
308
-
309
-static uint32_t omap_gp_timer_readw(void *opaque, hwaddr addr)
310
-{
311
- struct omap_gp_timer_s *s = opaque;
312
-
313
- switch (addr) {
314
- case 0x00:    /* TIDR */
315
- return 0x21;
316
-
317
- case 0x10:    /* TIOCP_CFG */
318
- return s->config;
319
-
320
- case 0x14:    /* TISTAT */
321
- /* ??? When's this bit reset? */
322
- return 1;                        /* RESETDONE */
323
-
324
- case 0x18:    /* TISR */
325
- return s->status;
326
-
327
- case 0x1c:    /* TIER */
328
- return s->it_ena;
329
-
330
- case 0x20:    /* TWER */
331
- return s->wu_ena;
332
-
333
- case 0x24:    /* TCLR */
334
- return (s->inout << 14) |
335
- (s->capt2 << 13) |
336
- (s->pt << 12) |
337
- (s->trigger << 10) |
338
- (s->capture << 8) |
339
- (s->scpwm << 7) |
340
- (s->ce << 6) |
341
- (s->pre << 5) |
342
- (s->ptv << 2) |
343
- (s->ar << 1) |
344
- (s->st << 0);
345
-
346
- case 0x28:    /* TCRR */
347
- return omap_gp_timer_read(s);
348
-
349
- case 0x2c:    /* TLDR */
350
- return s->load_val;
351
-
352
- case 0x30:    /* TTGR */
353
- return 0xffffffff;
354
-
355
- case 0x34:    /* TWPS */
356
- return 0x00000000;    /* No posted writes pending. */
357
-
358
- case 0x38:    /* TMAR */
359
- return s->match_val;
360
-
361
- case 0x3c:    /* TCAR1 */
362
- return s->capture_val[0];
363
-
364
- case 0x40:    /* TSICR */
365
- return s->posted << 2;
366
-
367
- case 0x44:    /* TCAR2 */
368
- return s->capture_val[1];
369
- }
370
-
371
- OMAP_BAD_REG(addr);
372
- return 0;
373
-}
374
-
375
-static uint32_t omap_gp_timer_readh(void *opaque, hwaddr addr)
376
-{
377
- struct omap_gp_timer_s *s = opaque;
378
- uint32_t ret;
379
-
380
- if (addr & 2)
381
- return s->readh;
382
- else {
383
- ret = omap_gp_timer_readw(opaque, addr);
384
- s->readh = ret >> 16;
385
- return ret & 0xffff;
386
- }
387
-}
388
-
389
-static void omap_gp_timer_write(void *opaque, hwaddr addr, uint32_t value)
390
-{
391
- struct omap_gp_timer_s *s = opaque;
392
-
393
- switch (addr) {
394
- case 0x00:    /* TIDR */
395
- case 0x14:    /* TISTAT */
396
- case 0x34:    /* TWPS */
397
- case 0x3c:    /* TCAR1 */
398
- case 0x44:    /* TCAR2 */
399
- OMAP_RO_REG(addr);
400
- break;
401
-
402
- case 0x10:    /* TIOCP_CFG */
403
- s->config = value & 0x33d;
404
- if (((value >> 3) & 3) == 3)                /* IDLEMODE */
405
- fprintf(stderr, "%s: illegal IDLEMODE value in TIOCP_CFG\n",
406
- __func__);
407
- if (value & 2)                        /* SOFTRESET */
408
- omap_gp_timer_reset(s);
409
- break;
410
-
411
- case 0x18:    /* TISR */
412
- if (value & GPT_TCAR_IT)
413
- s->capt_num = 0;
414
- if (s->status && !(s->status &= ~value))
415
- qemu_irq_lower(s->irq);
416
- break;
417
-
418
- case 0x1c:    /* TIER */
419
- s->it_ena = value & 7;
420
- break;
421
-
422
- case 0x20:    /* TWER */
423
- s->wu_ena = value & 7;
424
- break;
425
-
426
- case 0x24:    /* TCLR */
427
- omap_gp_timer_sync(s);
428
- s->inout = (value >> 14) & 1;
429
- s->capt2 = (value >> 13) & 1;
430
- s->pt = (value >> 12) & 1;
431
- s->trigger = (value >> 10) & 3;
432
- if (s->capture == gpt_capture_none &&
433
- ((value >> 8) & 3) != gpt_capture_none)
434
- s->capt_num = 0;
435
- s->capture = (value >> 8) & 3;
436
- s->scpwm = (value >> 7) & 1;
437
- s->ce = (value >> 6) & 1;
438
- s->pre = (value >> 5) & 1;
439
- s->ptv = (value >> 2) & 7;
440
- s->ar = (value >> 1) & 1;
441
- s->st = (value >> 0) & 1;
442
- if (s->inout && s->trigger != gpt_trigger_none)
443
- fprintf(stderr, "%s: GP timer pin must be an output "
444
- "for this trigger mode\n", __func__);
445
- if (!s->inout && s->capture != gpt_capture_none)
446
- fprintf(stderr, "%s: GP timer pin must be an input "
447
- "for this capture mode\n", __func__);
448
- if (s->trigger == gpt_trigger_none)
449
- omap_gp_timer_out(s, s->scpwm);
450
- /* TODO: make sure this doesn't overflow 32-bits */
451
- s->ticks_per_sec = NANOSECONDS_PER_SECOND << (s->pre ? s->ptv + 1 : 0);
452
- omap_gp_timer_update(s);
453
- break;
454
-
455
- case 0x28:    /* TCRR */
456
- s->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
457
- s->val = value;
458
- omap_gp_timer_update(s);
459
- break;
460
-
461
- case 0x2c:    /* TLDR */
462
- s->load_val = value;
463
- break;
464
-
465
- case 0x30:    /* TTGR */
466
- s->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
467
- s->val = s->load_val;
468
- omap_gp_timer_update(s);
469
- break;
470
-
471
- case 0x38:    /* TMAR */
472
- omap_gp_timer_sync(s);
473
- s->match_val = value;
474
- omap_gp_timer_update(s);
475
- break;
476
-
477
- case 0x40:    /* TSICR */
478
- s->posted = (value >> 2) & 1;
479
- if (value & 2)    /* How much exactly are we supposed to reset? */
480
- omap_gp_timer_reset(s);
481
- break;
482
-
483
- default:
484
- OMAP_BAD_REG(addr);
485
- }
486
-}
487
-
488
-static void omap_gp_timer_writeh(void *opaque, hwaddr addr, uint32_t value)
489
-{
490
- struct omap_gp_timer_s *s = opaque;
491
-
492
- if (addr & 2)
493
- omap_gp_timer_write(opaque, addr, (value << 16) | s->writeh);
494
- else
495
- s->writeh = (uint16_t) value;
496
-}
497
-
498
-static uint64_t omap_gp_timer_readfn(void *opaque, hwaddr addr,
499
- unsigned size)
500
-{
501
- switch (size) {
502
- case 1:
503
- return omap_badwidth_read32(opaque, addr);
504
- case 2:
505
- return omap_gp_timer_readh(opaque, addr);
506
- case 4:
507
- return omap_gp_timer_readw(opaque, addr);
508
- default:
216
- default:
509
- g_assert_not_reached();
217
- g_assert_not_reached();
510
- }
218
- }
511
-}
219
-}
512
-
220
-
513
-static void omap_gp_timer_writefn(void *opaque, hwaddr addr,
221
/*----------------------------------------------------------------------------
514
- uint64_t value, unsigned size)
222
| Returns 1 if the double-precision floating-point value `a' is a quiet
515
-{
223
| NaN; otherwise returns 0.
516
- switch (size) {
517
- case 1:
518
- omap_badwidth_write32(opaque, addr, value);
519
- break;
520
- case 2:
521
- omap_gp_timer_writeh(opaque, addr, value);
522
- break;
523
- case 4:
524
- omap_gp_timer_write(opaque, addr, value);
525
- break;
526
- default:
527
- g_assert_not_reached();
528
- }
529
-}
530
-
531
-static const MemoryRegionOps omap_gp_timer_ops = {
532
- .read = omap_gp_timer_readfn,
533
- .write = omap_gp_timer_writefn,
534
- .valid.min_access_size = 1,
535
- .valid.max_access_size = 4,
536
- .endianness = DEVICE_NATIVE_ENDIAN,
537
-};
538
-
539
-struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta,
540
- qemu_irq irq, omap_clk fclk, omap_clk iclk)
541
-{
542
- struct omap_gp_timer_s *s = g_new0(struct omap_gp_timer_s, 1);
543
-
544
- s->ta = ta;
545
- s->irq = irq;
546
- s->clk = fclk;
547
- s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_gp_timer_tick, s);
548
- s->match = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_gp_timer_match, s);
549
- s->in = qemu_allocate_irq(omap_gp_timer_input, s, 0);
550
- omap_gp_timer_reset(s);
551
- omap_gp_timer_clk_setup(s);
552
-
553
- memory_region_init_io(&s->iomem, NULL, &omap_gp_timer_ops, s, "omap.gptimer",
554
- omap_l4_region_size(ta, 0));
555
- omap_l4_attach(ta, 0, &s->iomem);
556
-
557
- return s;
558
-}
559
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
560
index XXXXXXX..XXXXXXX 100644
561
--- a/hw/timer/meson.build
562
+++ b/hw/timer/meson.build
563
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gictimer.c'))
564
system_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-timer.c'))
565
system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_timer.c'))
566
system_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_timer.c'))
567
-system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_gptimer.c'))
568
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_synctimer.c'))
569
system_ss.add(when: 'CONFIG_PXA2XX_TIMER', if_true: files('pxa2xx_timer.c'))
570
system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_systmr.c'))
571
--
224
--
572
2.34.1
225
2.34.1
573
226
574
227
diff view generated by jsdifflib
1
From: Shiva sagar Myana <Shivasagar.Myana@amd.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add the SFDP table for the Micron Xccela mt35xu01g flash.
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: Shiva sagar Myana <Shivasagar.Myana@amd.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20240829120117.616861-1-Shivasagar.Myana@amd.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
hw/block/m25p80_sfdp.h | 1 +
14
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
11
hw/block/m25p80.c | 3 ++-
15
1 file changed, 12 insertions(+), 20 deletions(-)
12
hw/block/m25p80_sfdp.c | 37 +++++++++++++++++++++++++++++++++++++
13
3 files changed, 40 insertions(+), 1 deletion(-)
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 void partsN(return_nan)(FloatPartsN *a, float_status *s)
20
#define M25P80_SFDP_MAX_SIZE (1 << 24)
22
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
21
23
float_status *s)
22
uint8_t m25p80_sfdp_n25q256a(uint32_t addr);
24
{
23
+uint8_t m25p80_sfdp_mt35xu01g(uint32_t addr);
25
+ bool have_snan = false;
24
uint8_t m25p80_sfdp_mt35xu02g(uint32_t addr);
26
int cmp, which;
25
27
26
uint8_t m25p80_sfdp_mx25l25635e(uint32_t addr);
28
if (is_snan(a->cls) || is_snan(b->cls)) {
27
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
29
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
28
index XXXXXXX..XXXXXXX 100644
30
+ have_snan = true;
29
--- a/hw/block/m25p80.c
31
}
30
+++ b/hw/block/m25p80.c
32
31
@@ -XXX,XX +XXX,XX @@ static const FlashPartInfo known_devices[] = {
33
if (s->default_nan_mode) {
32
{ INFO("n25q512ax3", 0x20ba20, 0x1000, 64 << 10, 1024, ER_4K) },
34
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
33
{ INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
35
34
{ INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
36
switch (s->float_2nan_prop_rule) {
35
- ER_4K | ER_32K, 2) },
37
case float_2nan_prop_s_ab:
36
+ ER_4K | ER_32K, 2),
38
- if (is_snan(a->cls)) {
37
+ .sfdp_read = m25p80_sfdp_mt35xu01g },
39
- which = 0;
38
{ INFO_STACKED("mt35xu02gbba", 0x2c5b1c, 0x104100, 128 << 10, 2048,
40
- } else if (is_snan(b->cls)) {
39
ER_4K | ER_32K, 4),
41
- which = 1;
40
.sfdp_read = m25p80_sfdp_mt35xu02g },
42
- } else if (is_qnan(a->cls)) {
41
diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c
43
- which = 0;
42
index XXXXXXX..XXXXXXX 100644
44
- } else {
43
--- a/hw/block/m25p80_sfdp.c
45
- which = 1;
44
+++ b/hw/block/m25p80_sfdp.c
46
+ if (have_snan) {
45
@@ -XXX,XX +XXX,XX @@ static const uint8_t sfdp_n25q256a[] = {
47
+ which = is_snan(a->cls) ? 0 : 1;
46
};
48
+ break;
47
define_sfdp_read(n25q256a);
49
}
48
50
- break;
49
+static const uint8_t sfdp_mt35xu01g[] = {
51
- case float_2nan_prop_s_ba:
50
+ 0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x01, 0xff,
52
- if (is_snan(b->cls)) {
51
+ 0x00, 0x06, 0x01, 0x10, 0x30, 0x00, 0x00, 0xff,
53
- which = 1;
52
+ 0x84, 0x00, 0x01, 0x02, 0x80, 0x00, 0x00, 0xff,
54
- } else if (is_snan(a->cls)) {
53
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
55
- which = 0;
54
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
56
- } else if (is_qnan(b->cls)) {
55
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
57
- which = 1;
56
+ 0xe5, 0x20, 0x8a, 0xff, 0xff, 0xff, 0xff, 0x3f,
58
- } else {
57
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59
- which = 0;
58
+ 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
60
- }
59
+ 0xff, 0xff, 0x00, 0x00, 0x0c, 0x20, 0x11, 0xd8,
61
- break;
60
+ 0x0f, 0x52, 0x00, 0x00, 0x24, 0x5a, 0x99, 0x00,
62
+ /* fall through */
61
+ 0x8b, 0x8e, 0x03, 0xe1, 0xac, 0x01, 0x27, 0x38,
63
case float_2nan_prop_ab:
62
+ 0x7a, 0x75, 0x7a, 0x75, 0xfb, 0xbd, 0xd5, 0x5c,
64
which = is_nan(a->cls) ? 0 : 1;
63
+ 0x00, 0x00, 0x70, 0xff, 0x81, 0xb0, 0x38, 0x36,
65
break;
64
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
66
+ case float_2nan_prop_s_ba:
65
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
67
+ if (have_snan) {
66
+ 0x43, 0x0e, 0xff, 0xff, 0x21, 0xdc, 0x5c, 0xff,
68
+ which = is_snan(b->cls) ? 1 : 0;
67
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
69
+ break;
68
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
70
+ }
69
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
71
+ /* fall through */
70
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
72
case float_2nan_prop_ba:
71
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
73
which = is_nan(b->cls) ? 1 : 0;
72
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
74
break;
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(mt35xu01g);
85
+
86
static const uint8_t sfdp_mt35xu02g[] = {
87
0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x01, 0xff,
88
0x00, 0x06, 0x01, 0x10, 0x30, 0x00, 0x00, 0xff,
89
--
75
--
90
2.34.1
76
2.34.1
diff view generated by jsdifflib
1
From: Jan Luebbe <jlu@pengutronix.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The enable bits in the EXT_CSD_PART_CONFIG ext_csd register do *not*
3
Move the fractional comparison to the end of the
4
specify whether the boot partitions exist, but whether they are enabled
4
float_2nan_prop_x87 case. This is not required for
5
for booting. Existence of the boot partitions is specified by a
5
any other 2nan propagation rule. Reorganize the
6
EXT_CSD_BOOT_MULT != 0.
6
x87 case itself to break out of the switch when the
7
fractional comparison is not required.
7
8
8
Currently, in the case of boot-partition-size=1M and boot-config=0,
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Linux detects boot partitions of 1M. But as sd_bootpart_offset always
10
returns 0, all reads/writes are mapped to the same offset in the backing
11
file.
12
13
Fix this bug by calculating the offset independent of which partition is
14
enabled for booting.
15
16
This bug is unlikely to affect many users with QEMU's current set of
17
boards, because only aspeed sets boot-partition-size, and it also
18
sets boot-config to 8. So to run into this a user would have to
19
manually mark the boot partition non-booting from within the guest.
20
21
Cc: qemu-stable@nongnu.org
22
Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
23
Message-id: 20240906164834.130257-1-jlu@pengutronix.de
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
[PMM: added note to commit message about effects of bug]
11
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
13
---
28
hw/sd/sd.c | 7 -------
14
fpu/softfloat-parts.c.inc | 19 +++++++++----------
29
1 file changed, 7 deletions(-)
15
1 file changed, 9 insertions(+), 10 deletions(-)
30
16
31
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
32
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/sd/sd.c
19
--- a/fpu/softfloat-parts.c.inc
34
+++ b/hw/sd/sd.c
20
+++ b/fpu/softfloat-parts.c.inc
35
@@ -XXX,XX +XXX,XX @@ static uint32_t sd_blk_len(SDState *sd)
21
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
36
*/
22
return a;
37
static uint32_t sd_bootpart_offset(SDState *sd)
38
{
39
- bool partitions_enabled;
40
unsigned partition_access;
41
42
if (!sd->boot_part_size || !sd_is_emmc(sd)) {
43
return 0;
44
}
23
}
45
24
46
- partitions_enabled = sd->ext_csd[EXT_CSD_PART_CONFIG]
25
- cmp = frac_cmp(a, b);
47
- & EXT_CSD_PART_CONFIG_EN_MASK;
26
- if (cmp == 0) {
48
- if (!partitions_enabled) {
27
- cmp = a->sign < b->sign;
49
- return 0;
50
- }
28
- }
51
-
29
-
52
partition_access = sd->ext_csd[EXT_CSD_PART_CONFIG]
30
switch (s->float_2nan_prop_rule) {
53
& EXT_CSD_PART_CONFIG_ACC_MASK;
31
case float_2nan_prop_s_ab:
54
switch (partition_access) {
32
if (have_snan) {
33
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
34
* return the NaN with the positive sign bit (if any).
35
*/
36
if (is_snan(a->cls)) {
37
- if (is_snan(b->cls)) {
38
- which = cmp > 0 ? 0 : 1;
39
- } else {
40
+ if (!is_snan(b->cls)) {
41
which = is_qnan(b->cls) ? 1 : 0;
42
+ break;
43
}
44
} else if (is_qnan(a->cls)) {
45
if (is_snan(b->cls) || !is_qnan(b->cls)) {
46
which = 0;
47
- } else {
48
- which = cmp > 0 ? 0 : 1;
49
+ break;
50
}
51
} else {
52
which = 1;
53
+ break;
54
}
55
+ cmp = frac_cmp(a, b);
56
+ if (cmp == 0) {
57
+ cmp = a->sign < b->sign;
58
+ }
59
+ which = cmp > 0 ? 0 : 1;
60
break;
61
default:
62
g_assert_not_reached();
55
--
63
--
56
2.34.1
64
2.34.1
diff view generated by jsdifflib
1
From: Kinsey Moore <kinsey.moore@oarcorp.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The Cadence GEM peripherals as configured for Zynq MPSoC and Versal
3
Replace the "index" selecting between A and B with a result variable
4
platforms have two priority queues with separate interrupt sources for
4
of the proper type. This improves clarity within the function.
5
each. If the interrupt source for the second priority queue is not
6
connected, they work in polling mode only. This change connects the
7
second interrupt source for platforms where it is available. This patch
8
has been tested using the lwIP stack with a Xilinx-supplied driver from
9
their embeddedsw repository.
10
5
11
Signed-off-by: Kinsey Moore <kinsey.moore@oarcorp.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-12-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
include/hw/arm/xlnx-versal.h | 1 +
11
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
17
include/hw/arm/xlnx-zynqmp.h | 1 +
12
1 file changed, 13 insertions(+), 15 deletions(-)
18
hw/arm/xlnx-versal.c | 12 +++++++++++-
19
hw/arm/xlnx-zynqmp.c | 11 ++++++++++-
20
4 files changed, 23 insertions(+), 2 deletions(-)
21
13
22
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/xlnx-versal.h
16
--- a/fpu/softfloat-parts.c.inc
25
+++ b/include/hw/arm/xlnx-versal.h
17
+++ b/fpu/softfloat-parts.c.inc
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
27
struct {
19
float_status *s)
28
PL011State uart[XLNX_VERSAL_NR_UARTS];
20
{
29
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
21
bool have_snan = false;
30
+ OrIRQState gem_irq_orgate[XLNX_VERSAL_NR_GEMS];
22
- int cmp, which;
31
XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
23
+ FloatPartsN *ret;
32
VersalUsb2 usb;
24
+ int cmp;
33
CanBusState *canbus[XLNX_VERSAL_NR_CANFD];
25
34
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
26
if (is_snan(a->cls) || is_snan(b->cls)) {
35
index XXXXXXX..XXXXXXX 100644
27
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
36
--- a/include/hw/arm/xlnx-zynqmp.h
28
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
37
+++ b/include/hw/arm/xlnx-zynqmp.h
29
switch (s->float_2nan_prop_rule) {
38
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
30
case float_2nan_prop_s_ab:
39
MemoryRegion mr_unimp[XLNX_ZYNQMP_NUM_UNIMP_AREAS];
31
if (have_snan) {
40
32
- which = is_snan(a->cls) ? 0 : 1;
41
CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS];
33
+ ret = is_snan(a->cls) ? a : b;
42
+ OrIRQState gem_irq_orgate[XLNX_ZYNQMP_NUM_GEMS];
34
break;
43
CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS];
35
}
44
XlnxZynqMPCANState can[XLNX_ZYNQMP_NUM_CAN];
36
/* fall through */
45
SysbusAHCIState sata;
37
case float_2nan_prop_ab:
46
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
38
- which = is_nan(a->cls) ? 0 : 1;
47
index XXXXXXX..XXXXXXX 100644
39
+ ret = is_nan(a->cls) ? a : b;
48
--- a/hw/arm/xlnx-versal.c
40
break;
49
+++ b/hw/arm/xlnx-versal.c
41
case float_2nan_prop_s_ba:
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
42
if (have_snan) {
51
char *name = g_strdup_printf("gem%d", i);
43
- which = is_snan(b->cls) ? 1 : 0;
52
DeviceState *dev;
44
+ ret = is_snan(b->cls) ? b : a;
53
MemoryRegion *mr;
45
break;
54
+ OrIRQState *or_irq;
46
}
55
47
/* fall through */
56
object_initialize_child(OBJECT(s), name, &s->lpd.iou.gem[i],
48
case float_2nan_prop_ba:
57
TYPE_CADENCE_GEM);
49
- which = is_nan(b->cls) ? 1 : 0;
58
+ or_irq = &s->lpd.iou.gem_irq_orgate[i];
50
+ ret = is_nan(b->cls) ? b : a;
59
+ object_initialize_child(OBJECT(s), "gem-irq-orgate[*]",
51
break;
60
+ or_irq, TYPE_OR_IRQ);
52
case float_2nan_prop_x87:
61
dev = DEVICE(&s->lpd.iou.gem[i]);
53
/*
62
qemu_configure_nic_device(dev, true, NULL);
54
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
63
object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort);
55
*/
64
object_property_set_int(OBJECT(dev), "num-priority-queues", 2,
56
if (is_snan(a->cls)) {
65
&error_abort);
57
if (!is_snan(b->cls)) {
66
+ object_property_set_int(OBJECT(or_irq),
58
- which = is_qnan(b->cls) ? 1 : 0;
67
+ "num-lines", 2, &error_fatal);
59
+ ret = is_qnan(b->cls) ? b : a;
68
+ qdev_realize(DEVICE(or_irq), NULL, &error_fatal);
60
break;
69
+ qdev_connect_gpio_out(DEVICE(or_irq), 0, pic[irqs[i]]);
61
}
70
+
62
} else if (is_qnan(a->cls)) {
71
object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps),
63
if (is_snan(b->cls) || !is_qnan(b->cls)) {
72
&error_abort);
64
- which = 0;
73
sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
65
+ ret = a;
74
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
66
break;
75
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
67
}
76
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
68
} else {
77
69
- which = 1;
78
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
70
+ ret = b;
79
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(DEVICE(or_irq), 0));
71
break;
80
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, qdev_get_gpio_in(DEVICE(or_irq), 1));
72
}
81
g_free(name);
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
}
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;
83
}
94
}
84
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
95
85
index XXXXXXX..XXXXXXX 100644
96
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
86
--- a/hw/arm/xlnx-zynqmp.c
87
+++ b/hw/arm/xlnx-zynqmp.c
88
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(Object *obj)
89
90
for (i = 0; i < XLNX_ZYNQMP_NUM_GEMS; i++) {
91
object_initialize_child(obj, "gem[*]", &s->gem[i], TYPE_CADENCE_GEM);
92
+ object_initialize_child(obj, "gem-irq-orgate[*]",
93
+ &s->gem_irq_orgate[i], TYPE_OR_IRQ);
94
}
95
96
for (i = 0; i < XLNX_ZYNQMP_NUM_UARTS; i++) {
97
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
98
&error_abort);
99
object_property_set_int(OBJECT(&s->gem[i]), "num-priority-queues", 2,
100
&error_abort);
101
+ object_property_set_int(OBJECT(&s->gem_irq_orgate[i]),
102
+ "num-lines", 2, &error_fatal);
103
+ qdev_realize(DEVICE(&s->gem_irq_orgate[i]), NULL, &error_fatal);
104
+ qdev_connect_gpio_out(DEVICE(&s->gem_irq_orgate[i]), 0, gic_spi[gem_intr[i]]);
105
+
106
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gem[i]), errp)) {
107
return;
108
}
109
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem[i]), 0, gem_addr[i]);
110
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem[i]), 0,
111
- gic_spi[gem_intr[i]]);
112
+ qdev_get_gpio_in(DEVICE(&s->gem_irq_orgate[i]), 0));
113
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem[i]), 1,
114
+ qdev_get_gpio_in(DEVICE(&s->gem_irq_orgate[i]), 1));
115
}
116
117
for (i = 0; i < XLNX_ZYNQMP_NUM_UARTS; i++) {
118
--
97
--
119
2.34.1
98
2.34.1
120
99
121
100
diff view generated by jsdifflib
1
The ZAURUS KConfig symbol used to do multiple things:
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
* pull in the tc6393xb display device
3
* pull in the Zaurus SCOOP GPIO device
4
* pull in hw/block/nand.c code
5
* pull in hw/block/ecc.c code
6
and was used by multiple machine types in the Zaurus family.
7
2
8
Now that we've removed all the Zaurus machine types except
3
I'm migrating to Qualcomm's new open source email infrastructure, so
9
"collie" (which is not currently deprecated), we can simplify
4
update my email address, and update the mailmap to match.
10
this. "collie" doesn't need any of the above things except
11
for the SCOOP GPIO device.
12
5
13
Remove the does-lots-of-things ZAURUS KConfig symbol and instead have
6
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
14
collie pull in ZAURUS_SCOOP, a new KConfig symbol which exists only
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
15
to control the presence of the SCOOP GPIO device. Move the
8
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
16
associated source file lines in MAINTAINERS into the Collie
17
subsection, since this is now its only user.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
21
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
22
Message-id: 20240903160751.4100218-8-peter.maydell@linaro.org
11
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
13
---
24
MAINTAINERS | 4 ++--
14
MAINTAINERS | 2 +-
25
hw/arm/Kconfig | 7 +------
15
.mailmap | 5 +++--
26
hw/gpio/Kconfig | 3 +++
16
2 files changed, 4 insertions(+), 3 deletions(-)
27
hw/gpio/meson.build | 2 +-
28
4 files changed, 7 insertions(+), 9 deletions(-)
29
17
30
diff --git a/MAINTAINERS b/MAINTAINERS
18
diff --git a/MAINTAINERS b/MAINTAINERS
31
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
32
--- a/MAINTAINERS
20
--- a/MAINTAINERS
33
+++ b/MAINTAINERS
21
+++ b/MAINTAINERS
34
@@ -XXX,XX +XXX,XX @@ F: hw/arm/mainstone.c
22
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
35
F: hw/arm/z2.c
23
SBSA-REF
36
F: hw/*/pxa2xx*
24
M: Radoslaw Biernacki <rad@semihalf.com>
37
F: hw/gpio/max7310.c
25
M: Peter Maydell <peter.maydell@linaro.org>
38
-F: hw/gpio/zaurus.c
26
-R: Leif Lindholm <quic_llindhol@quicinc.com>
39
F: hw/misc/mst_fpga.c
27
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
40
F: hw/adc/max111x.c
28
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
41
F: include/hw/adc/max111x.h
29
L: qemu-arm@nongnu.org
42
F: include/hw/arm/pxa.h
30
S: Maintained
43
-F: include/hw/arm/sharpsl.h
31
diff --git a/.mailmap b/.mailmap
44
F: docs/system/arm/mainstone.rst
45
46
SABRELITE / i.MX6
47
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
48
S: Odd Fixes
49
F: hw/arm/collie.c
50
F: hw/arm/strongarm*
51
+F: hw/gpio/zaurus.c
52
+F: include/hw/arm/sharpsl.h
53
F: docs/system/arm/collie.rst
54
55
Stellaris
56
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
57
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/arm/Kconfig
33
--- a/.mailmap
59
+++ b/hw/arm/Kconfig
34
+++ b/.mailmap
60
@@ -XXX,XX +XXX,XX @@ config COLLIE
35
@@ -XXX,XX +XXX,XX @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
61
default y
36
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
62
depends on TCG && ARM
37
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
63
select PFLASH_CFI01
38
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
64
- select ZAURUS # scoop
39
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
65
+ select ZAURUS_SCOOP
40
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
66
select STRONGARM
41
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
67
42
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
68
config SX1
43
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
69
@@ -XXX,XX +XXX,XX @@ config MSF2
44
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
70
select SSI
45
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
71
select UNIMP
46
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
72
73
-config ZAURUS
74
- bool
75
- select NAND
76
- select ECC
77
-
78
config ARMSSE
79
bool
80
select ARM_V7M
81
diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/gpio/Kconfig
84
+++ b/hw/gpio/Kconfig
85
@@ -XXX,XX +XXX,XX @@ config STM32L4X5_GPIO
86
config PCF8574
87
bool
88
depends on I2C
89
+
90
+config ZAURUS_SCOOP
91
+ bool
92
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/gpio/meson.build
95
+++ b/hw/gpio/meson.build
96
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_MAX7310', if_true: files('max7310.c'))
97
system_ss.add(when: 'CONFIG_PCA9552', if_true: files('pca9552.c'))
98
system_ss.add(when: 'CONFIG_PCA9554', if_true: files('pca9554.c'))
99
system_ss.add(when: 'CONFIG_PL061', if_true: files('pl061.c'))
100
-system_ss.add(when: 'CONFIG_ZAURUS', if_true: files('zaurus.c'))
101
+system_ss.add(when: 'CONFIG_ZAURUS_SCOOP', if_true: files('zaurus.c'))
102
103
system_ss.add(when: 'CONFIG_IMX', if_true: files('imx_gpio.c'))
104
system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_gpio.c'))
105
--
47
--
106
2.34.1
48
2.34.1
107
49
108
50
diff view generated by jsdifflib
1
The ADS7846 touchscreen controller device was used only by
1
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
2
the XScale-based PDA machine types. Now that they have been
3
removed, this device is not used in the tree and can be
4
deleted.
5
2
3
Previously, maintainer role was paused due to inactive email id. Commit id:
4
c009d715721861984c4987bcc78b7ee183e86d75.
5
6
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Message-id: 20240903160751.4100218-3-peter.maydell@linaro.org
9
---
10
---
10
MAINTAINERS | 1 -
11
MAINTAINERS | 2 ++
11
hw/input/ads7846.c | 186 -------------------------------------------
12
1 file changed, 2 insertions(+)
12
hw/input/Kconfig | 3 -
13
hw/input/meson.build | 1 -
14
4 files changed, 191 deletions(-)
15
delete mode 100644 hw/input/ads7846.c
16
13
17
diff --git a/MAINTAINERS b/MAINTAINERS
14
diff --git a/MAINTAINERS b/MAINTAINERS
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/MAINTAINERS
16
--- a/MAINTAINERS
20
+++ b/MAINTAINERS
17
+++ b/MAINTAINERS
21
@@ -XXX,XX +XXX,XX @@ F: hw/*/pxa2xx*
18
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-sb16-test.c
22
F: hw/display/tc6393xb.c
19
23
F: hw/gpio/max7310.c
20
Xilinx CAN
24
F: hw/gpio/zaurus.c
21
M: Francisco Iglesias <francisco.iglesias@amd.com>
25
-F: hw/input/ads7846.c
22
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
26
F: hw/misc/mst_fpga.c
23
S: Maintained
27
F: hw/adc/max111x.c
24
F: hw/net/can/xlnx-*
28
F: include/hw/adc/max111x.h
25
F: include/hw/net/xlnx-*
29
diff --git a/hw/input/ads7846.c b/hw/input/ads7846.c
26
@@ -XXX,XX +XXX,XX @@ F: include/hw/rx/
30
deleted file mode 100644
27
CAN bus subsystem and hardware
31
index XXXXXXX..XXXXXXX
28
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
32
--- a/hw/input/ads7846.c
29
M: Francisco Iglesias <francisco.iglesias@amd.com>
33
+++ /dev/null
30
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
34
@@ -XXX,XX +XXX,XX @@
31
S: Maintained
35
-/*
32
W: https://canbus.pages.fel.cvut.cz/
36
- * TI ADS7846 / TSC2046 chip emulation.
33
F: net/can/*
37
- *
38
- * Copyright (c) 2006 Openedhand Ltd.
39
- * Written by Andrzej Zaborowski <balrog@zabor.org>
40
- *
41
- * This code is licensed under the GNU GPL v2.
42
- *
43
- * Contributions after 2012-01-13 are licensed under the terms of the
44
- * GNU GPL, version 2 or (at your option) any later version.
45
- */
46
-
47
-#include "qemu/osdep.h"
48
-#include "hw/irq.h"
49
-#include "hw/ssi/ssi.h"
50
-#include "migration/vmstate.h"
51
-#include "qemu/module.h"
52
-#include "ui/console.h"
53
-#include "qom/object.h"
54
-
55
-struct ADS7846State {
56
- SSIPeripheral ssidev;
57
- qemu_irq interrupt;
58
-
59
- int input[8];
60
- int pressure;
61
- int noise;
62
-
63
- int cycle;
64
- int output;
65
-};
66
-
67
-#define TYPE_ADS7846 "ads7846"
68
-OBJECT_DECLARE_SIMPLE_TYPE(ADS7846State, ADS7846)
69
-
70
-/* Control-byte bitfields */
71
-#define CB_PD0 (1 << 0)
72
-#define CB_PD1 (1 << 1)
73
-#define CB_SER (1 << 2)
74
-#define CB_MODE (1 << 3)
75
-#define CB_A0 (1 << 4)
76
-#define CB_A1 (1 << 5)
77
-#define CB_A2 (1 << 6)
78
-#define CB_START (1 << 7)
79
-
80
-#define X_AXIS_DMAX 3470
81
-#define X_AXIS_MIN 290
82
-#define Y_AXIS_DMAX 3450
83
-#define Y_AXIS_MIN 200
84
-
85
-#define ADS_VBAT 2000
86
-#define ADS_VAUX 2000
87
-#define ADS_TEMP0 2000
88
-#define ADS_TEMP1 3000
89
-#define ADS_XPOS(x, y) (X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15))
90
-#define ADS_YPOS(x, y) (Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15))
91
-#define ADS_Z1POS(x, y) 600
92
-#define ADS_Z2POS(x, y) (600 + 6000 / ADS_XPOS(x, y))
93
-
94
-static void ads7846_int_update(ADS7846State *s)
95
-{
96
- if (s->interrupt)
97
- qemu_set_irq(s->interrupt, s->pressure == 0);
98
-}
99
-
100
-static uint32_t ads7846_transfer(SSIPeripheral *dev, uint32_t value)
101
-{
102
- ADS7846State *s = ADS7846(dev);
103
-
104
- switch (s->cycle ++) {
105
- case 0:
106
- if (!(value & CB_START)) {
107
- s->cycle = 0;
108
- break;
109
- }
110
-
111
- s->output = s->input[(value >> 4) & 7];
112
-
113
- /* Imitate the ADC noise, some drivers expect this. */
114
- s->noise = (s->noise + 3) & 7;
115
- switch ((value >> 4) & 7) {
116
- case 1: s->output += s->noise ^ 2; break;
117
- case 3: s->output += s->noise ^ 0; break;
118
- case 4: s->output += s->noise ^ 7; break;
119
- case 5: s->output += s->noise ^ 5; break;
120
- }
121
-
122
- if (value & CB_MODE)
123
- s->output >>= 4; /* 8 bits instead of 12 */
124
-
125
- break;
126
- case 1:
127
- s->cycle = 0;
128
- break;
129
- }
130
- return s->output;
131
-}
132
-
133
-static void ads7846_ts_event(void *opaque,
134
- int x, int y, int z, int buttons_state)
135
-{
136
- ADS7846State *s = opaque;
137
-
138
- if (buttons_state) {
139
- x = 0x7fff - x;
140
- s->input[1] = ADS_XPOS(x, y);
141
- s->input[3] = ADS_Z1POS(x, y);
142
- s->input[4] = ADS_Z2POS(x, y);
143
- s->input[5] = ADS_YPOS(x, y);
144
- }
145
-
146
- if (s->pressure == !buttons_state) {
147
- s->pressure = !!buttons_state;
148
-
149
- ads7846_int_update(s);
150
- }
151
-}
152
-
153
-static int ads7856_post_load(void *opaque, int version_id)
154
-{
155
- ADS7846State *s = opaque;
156
-
157
- s->pressure = 0;
158
- ads7846_int_update(s);
159
- return 0;
160
-}
161
-
162
-static const VMStateDescription vmstate_ads7846 = {
163
- .name = "ads7846",
164
- .version_id = 1,
165
- .minimum_version_id = 1,
166
- .post_load = ads7856_post_load,
167
- .fields = (const VMStateField[]) {
168
- VMSTATE_SSI_PERIPHERAL(ssidev, ADS7846State),
169
- VMSTATE_INT32_ARRAY(input, ADS7846State, 8),
170
- VMSTATE_INT32(noise, ADS7846State),
171
- VMSTATE_INT32(cycle, ADS7846State),
172
- VMSTATE_INT32(output, ADS7846State),
173
- VMSTATE_END_OF_LIST()
174
- }
175
-};
176
-
177
-static void ads7846_realize(SSIPeripheral *d, Error **errp)
178
-{
179
- DeviceState *dev = DEVICE(d);
180
- ADS7846State *s = ADS7846(d);
181
-
182
- qdev_init_gpio_out(dev, &s->interrupt, 1);
183
-
184
- s->input[0] = ADS_TEMP0; /* TEMP0 */
185
- s->input[2] = ADS_VBAT; /* VBAT */
186
- s->input[6] = ADS_VAUX; /* VAUX */
187
- s->input[7] = ADS_TEMP1; /* TEMP1 */
188
-
189
- /* We want absolute coordinates */
190
- qemu_add_mouse_event_handler(ads7846_ts_event, s, 1,
191
- "QEMU ADS7846-driven Touchscreen");
192
-
193
- ads7846_int_update(s);
194
-
195
- vmstate_register_any(NULL, &vmstate_ads7846, s);
196
-}
197
-
198
-static void ads7846_class_init(ObjectClass *klass, void *data)
199
-{
200
- DeviceClass *dc = DEVICE_CLASS(klass);
201
- SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
202
-
203
- k->realize = ads7846_realize;
204
- k->transfer = ads7846_transfer;
205
- set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
206
-}
207
-
208
-static const TypeInfo ads7846_info = {
209
- .name = TYPE_ADS7846,
210
- .parent = TYPE_SSI_PERIPHERAL,
211
- .instance_size = sizeof(ADS7846State),
212
- .class_init = ads7846_class_init,
213
-};
214
-
215
-static void ads7846_register_types(void)
216
-{
217
- type_register_static(&ads7846_info);
218
-}
219
-
220
-type_init(ads7846_register_types)
221
diff --git a/hw/input/Kconfig b/hw/input/Kconfig
222
index XXXXXXX..XXXXXXX 100644
223
--- a/hw/input/Kconfig
224
+++ b/hw/input/Kconfig
225
@@ -XXX,XX +XXX,XX @@
226
config ADB
227
bool
228
229
-config ADS7846
230
- bool
231
-
232
config LM832X
233
bool
234
depends on I2C
235
diff --git a/hw/input/meson.build b/hw/input/meson.build
236
index XXXXXXX..XXXXXXX 100644
237
--- a/hw/input/meson.build
238
+++ b/hw/input/meson.build
239
@@ -XXX,XX +XXX,XX @@
240
system_ss.add(files('hid.c'))
241
system_ss.add(when: 'CONFIG_ADB', if_true: files('adb.c', 'adb-mouse.c', 'adb-kbd.c'))
242
-system_ss.add(when: 'CONFIG_ADS7846', if_true: files('ads7846.c'))
243
system_ss.add(when: 'CONFIG_LM832X', if_true: files('lm832x.c'))
244
system_ss.add(when: 'CONFIG_PCKBD', if_true: files('pckbd.c'))
245
system_ss.add(when: 'CONFIG_PL050', if_true: files('pl050.c'))
246
--
34
--
247
2.34.1
35
2.34.1
diff view generated by jsdifflib