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 = ®ions[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 |