blob: 767544eca10ce7dc640cec7d0924f94dbe136de2 [file] [log] [blame]
bellard34751872005-07-02 14:31:34 +00001/*
2 * QEMU Sparc SLAVIO aux io port emulation
ths5fafdf22007-09-16 21:08:06 +00003 *
bellard34751872005-07-02 14:31:34 +00004 * Copyright (c) 2005 Fabrice Bellard
ths5fafdf22007-09-16 21:08:06 +00005 *
bellard34751872005-07-02 14:31:34 +00006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
Blue Swirl2582cfa2009-07-13 16:51:27 +000024
Paolo Bonzini9c17d612012-12-17 18:20:04 +010025#include "sysemu/sysemu.h"
Paolo Bonzini83c9f4c2013-02-04 15:40:22 +010026#include "hw/sysbus.h"
Blue Swirl97bf4852010-10-31 09:24:14 +000027#include "trace.h"
bellard34751872005-07-02 14:31:34 +000028
29/*
30 * This is the auxio port, chip control and system control part of
31 * chip STP2001 (Slave I/O), also produced as NCR89C105. See
32 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
33 *
34 * This also includes the PMC CPU idle controller.
35 */
36
Andreas Färber95eb2082013-07-26 23:19:11 +020037#define TYPE_SLAVIO_MISC "slavio_misc"
38#define SLAVIO_MISC(obj) OBJECT_CHECK(MiscState, (obj), TYPE_SLAVIO_MISC)
39
bellard34751872005-07-02 14:31:34 +000040typedef struct MiscState {
Andreas Färber95eb2082013-07-26 23:19:11 +020041 SysBusDevice parent_obj;
42
Benoît Canetdd703aa2011-11-15 12:13:52 +010043 MemoryRegion cfg_iomem;
Benoît Canet96891e52011-11-15 12:13:53 +010044 MemoryRegion diag_iomem;
Benoît Canet2e66ac32011-11-15 12:13:54 +010045 MemoryRegion mdm_iomem;
Benoît Canetaca23c72011-11-15 12:13:55 +010046 MemoryRegion led_iomem;
Benoît Canetcd64a522011-11-15 12:13:56 +010047 MemoryRegion sysctrl_iomem;
Benoît Canetcccd43c2011-11-15 12:13:57 +010048 MemoryRegion aux1_iomem;
Benoît Canet40ce02f2011-11-15 12:13:58 +010049 MemoryRegion aux2_iomem;
pbrookd537cf62007-04-07 18:14:41 +000050 qemu_irq irq;
Blue Swirl97bbb102011-08-07 19:03:18 +000051 qemu_irq fdc_tc;
Blue Swirld37adb02009-08-29 16:37:09 +030052 uint32_t dummy;
bellard34751872005-07-02 14:31:34 +000053 uint8_t config;
54 uint8_t aux1, aux2;
blueswir1bfa30a32007-11-04 17:27:07 +000055 uint8_t diag, mctrl;
Blue Swirld37adb02009-08-29 16:37:09 +030056 uint8_t sysctrl;
blueswir16a3b9cc2007-11-11 17:56:38 +000057 uint16_t leds;
bellard34751872005-07-02 14:31:34 +000058} MiscState;
59
Andreas Färberf1a0a792013-07-26 23:21:50 +020060#define TYPE_APC "apc"
61#define APC(obj) OBJECT_CHECK(APCState, (obj), TYPE_APC)
62
Blue Swirl2582cfa2009-07-13 16:51:27 +000063typedef struct APCState {
Andreas Färberf1a0a792013-07-26 23:21:50 +020064 SysBusDevice parent_obj;
65
Benoît Canet9c48dee2011-11-15 12:13:51 +010066 MemoryRegion iomem;
Blue Swirl2582cfa2009-07-13 16:51:27 +000067 qemu_irq cpu_halt;
68} APCState;
69
blueswir15aca8c32007-05-26 17:39:43 +000070#define MISC_SIZE 1
blueswir1a8f48dc2008-12-02 17:51:19 +000071#define SYSCTRL_SIZE 4
bellard34751872005-07-02 14:31:34 +000072
blueswir12be17eb2008-03-21 18:05:23 +000073#define AUX1_TC 0x02
74
blueswir17debeb82007-12-01 14:53:22 +000075#define AUX2_PWROFF 0x01
76#define AUX2_PWRINTCLR 0x02
77#define AUX2_PWRFAIL 0x20
78
79#define CFG_PWRINTEN 0x08
80
81#define SYS_RESET 0x01
82#define SYS_RESETSTAT 0x02
83
bellard34751872005-07-02 14:31:34 +000084static void slavio_misc_update_irq(void *opaque)
85{
86 MiscState *s = opaque;
87
blueswir17debeb82007-12-01 14:53:22 +000088 if ((s->aux2 & AUX2_PWRFAIL) && (s->config & CFG_PWRINTEN)) {
Blue Swirl97bf4852010-10-31 09:24:14 +000089 trace_slavio_misc_update_irq_raise();
pbrookd537cf62007-04-07 18:14:41 +000090 qemu_irq_raise(s->irq);
bellard34751872005-07-02 14:31:34 +000091 } else {
Blue Swirl97bf4852010-10-31 09:24:14 +000092 trace_slavio_misc_update_irq_lower();
pbrookd537cf62007-04-07 18:14:41 +000093 qemu_irq_lower(s->irq);
bellard34751872005-07-02 14:31:34 +000094 }
95}
96
Blue Swirl17950572009-10-24 15:27:23 +000097static void slavio_misc_reset(DeviceState *d)
bellard34751872005-07-02 14:31:34 +000098{
Andreas Färber95eb2082013-07-26 23:19:11 +020099 MiscState *s = SLAVIO_MISC(d);
bellard34751872005-07-02 14:31:34 +0000100
bellard4e3b1ea2005-10-30 17:24:19 +0000101 // Diagnostic and system control registers not cleared in reset
bellard34751872005-07-02 14:31:34 +0000102 s->config = s->aux1 = s->aux2 = s->mctrl = 0;
103}
104
Blue Swirlb2b6f6e2009-08-09 07:27:29 +0000105static void slavio_set_power_fail(void *opaque, int irq, int power_failing)
bellard34751872005-07-02 14:31:34 +0000106{
107 MiscState *s = opaque;
108
Blue Swirl97bf4852010-10-31 09:24:14 +0000109 trace_slavio_set_power_fail(power_failing, s->config);
blueswir17debeb82007-12-01 14:53:22 +0000110 if (power_failing && (s->config & CFG_PWRINTEN)) {
111 s->aux2 |= AUX2_PWRFAIL;
bellard34751872005-07-02 14:31:34 +0000112 } else {
blueswir17debeb82007-12-01 14:53:22 +0000113 s->aux2 &= ~AUX2_PWRFAIL;
bellard34751872005-07-02 14:31:34 +0000114 }
115 slavio_misc_update_irq(s);
116}
117
Avi Kivitya8170e52012-10-23 12:30:10 +0200118static void slavio_cfg_mem_writeb(void *opaque, hwaddr addr,
Benoît Canetdd703aa2011-11-15 12:13:52 +0100119 uint64_t val, unsigned size)
bellard34751872005-07-02 14:31:34 +0000120{
121 MiscState *s = opaque;
122
Blue Swirl97bf4852010-10-31 09:24:14 +0000123 trace_slavio_cfg_mem_writeb(val & 0xff);
blueswir1a8f48dc2008-12-02 17:51:19 +0000124 s->config = val & 0xff;
125 slavio_misc_update_irq(s);
bellard34751872005-07-02 14:31:34 +0000126}
127
Avi Kivitya8170e52012-10-23 12:30:10 +0200128static uint64_t slavio_cfg_mem_readb(void *opaque, hwaddr addr,
Benoît Canetdd703aa2011-11-15 12:13:52 +0100129 unsigned size)
bellard34751872005-07-02 14:31:34 +0000130{
131 MiscState *s = opaque;
132 uint32_t ret = 0;
133
blueswir1a8f48dc2008-12-02 17:51:19 +0000134 ret = s->config;
Blue Swirl97bf4852010-10-31 09:24:14 +0000135 trace_slavio_cfg_mem_readb(ret);
bellard34751872005-07-02 14:31:34 +0000136 return ret;
137}
138
Benoît Canetdd703aa2011-11-15 12:13:52 +0100139static const MemoryRegionOps slavio_cfg_mem_ops = {
140 .read = slavio_cfg_mem_readb,
141 .write = slavio_cfg_mem_writeb,
142 .endianness = DEVICE_NATIVE_ENDIAN,
143 .valid = {
144 .min_access_size = 1,
145 .max_access_size = 1,
146 },
blueswir1a8f48dc2008-12-02 17:51:19 +0000147};
148
Avi Kivitya8170e52012-10-23 12:30:10 +0200149static void slavio_diag_mem_writeb(void *opaque, hwaddr addr,
Benoît Canet96891e52011-11-15 12:13:53 +0100150 uint64_t val, unsigned size)
blueswir1a8f48dc2008-12-02 17:51:19 +0000151{
152 MiscState *s = opaque;
153
Blue Swirl97bf4852010-10-31 09:24:14 +0000154 trace_slavio_diag_mem_writeb(val & 0xff);
blueswir1a8f48dc2008-12-02 17:51:19 +0000155 s->diag = val & 0xff;
156}
157
Avi Kivitya8170e52012-10-23 12:30:10 +0200158static uint64_t slavio_diag_mem_readb(void *opaque, hwaddr addr,
Benoît Canet96891e52011-11-15 12:13:53 +0100159 unsigned size)
blueswir1a8f48dc2008-12-02 17:51:19 +0000160{
161 MiscState *s = opaque;
162 uint32_t ret = 0;
163
164 ret = s->diag;
Blue Swirl97bf4852010-10-31 09:24:14 +0000165 trace_slavio_diag_mem_readb(ret);
blueswir1a8f48dc2008-12-02 17:51:19 +0000166 return ret;
167}
168
Benoît Canet96891e52011-11-15 12:13:53 +0100169static const MemoryRegionOps slavio_diag_mem_ops = {
170 .read = slavio_diag_mem_readb,
171 .write = slavio_diag_mem_writeb,
172 .endianness = DEVICE_NATIVE_ENDIAN,
173 .valid = {
174 .min_access_size = 1,
175 .max_access_size = 1,
176 },
blueswir1a8f48dc2008-12-02 17:51:19 +0000177};
178
Avi Kivitya8170e52012-10-23 12:30:10 +0200179static void slavio_mdm_mem_writeb(void *opaque, hwaddr addr,
Benoît Canet2e66ac32011-11-15 12:13:54 +0100180 uint64_t val, unsigned size)
blueswir1a8f48dc2008-12-02 17:51:19 +0000181{
182 MiscState *s = opaque;
183
Blue Swirl97bf4852010-10-31 09:24:14 +0000184 trace_slavio_mdm_mem_writeb(val & 0xff);
blueswir1a8f48dc2008-12-02 17:51:19 +0000185 s->mctrl = val & 0xff;
186}
187
Avi Kivitya8170e52012-10-23 12:30:10 +0200188static uint64_t slavio_mdm_mem_readb(void *opaque, hwaddr addr,
Benoît Canet2e66ac32011-11-15 12:13:54 +0100189 unsigned size)
blueswir1a8f48dc2008-12-02 17:51:19 +0000190{
191 MiscState *s = opaque;
192 uint32_t ret = 0;
193
194 ret = s->mctrl;
Blue Swirl97bf4852010-10-31 09:24:14 +0000195 trace_slavio_mdm_mem_readb(ret);
blueswir1a8f48dc2008-12-02 17:51:19 +0000196 return ret;
197}
198
Benoît Canet2e66ac32011-11-15 12:13:54 +0100199static const MemoryRegionOps slavio_mdm_mem_ops = {
200 .read = slavio_mdm_mem_readb,
201 .write = slavio_mdm_mem_writeb,
202 .endianness = DEVICE_NATIVE_ENDIAN,
203 .valid = {
204 .min_access_size = 1,
205 .max_access_size = 1,
206 },
bellard34751872005-07-02 14:31:34 +0000207};
208
Avi Kivitya8170e52012-10-23 12:30:10 +0200209static void slavio_aux1_mem_writeb(void *opaque, hwaddr addr,
Benoît Canetcccd43c2011-11-15 12:13:57 +0100210 uint64_t val, unsigned size)
blueswir10019ad52008-01-27 09:49:28 +0000211{
212 MiscState *s = opaque;
213
Blue Swirl97bf4852010-10-31 09:24:14 +0000214 trace_slavio_aux1_mem_writeb(val & 0xff);
blueswir12be17eb2008-03-21 18:05:23 +0000215 if (val & AUX1_TC) {
216 // Send a pulse to floppy terminal count line
217 if (s->fdc_tc) {
218 qemu_irq_raise(s->fdc_tc);
219 qemu_irq_lower(s->fdc_tc);
220 }
221 val &= ~AUX1_TC;
222 }
blueswir10019ad52008-01-27 09:49:28 +0000223 s->aux1 = val & 0xff;
224}
225
Avi Kivitya8170e52012-10-23 12:30:10 +0200226static uint64_t slavio_aux1_mem_readb(void *opaque, hwaddr addr,
Benoît Canetcccd43c2011-11-15 12:13:57 +0100227 unsigned size)
blueswir10019ad52008-01-27 09:49:28 +0000228{
229 MiscState *s = opaque;
230 uint32_t ret = 0;
231
232 ret = s->aux1;
Blue Swirl97bf4852010-10-31 09:24:14 +0000233 trace_slavio_aux1_mem_readb(ret);
blueswir10019ad52008-01-27 09:49:28 +0000234 return ret;
235}
236
Benoît Canetcccd43c2011-11-15 12:13:57 +0100237static const MemoryRegionOps slavio_aux1_mem_ops = {
238 .read = slavio_aux1_mem_readb,
239 .write = slavio_aux1_mem_writeb,
240 .endianness = DEVICE_NATIVE_ENDIAN,
241 .valid = {
242 .min_access_size = 1,
243 .max_access_size = 1,
244 },
blueswir10019ad52008-01-27 09:49:28 +0000245};
246
Avi Kivitya8170e52012-10-23 12:30:10 +0200247static void slavio_aux2_mem_writeb(void *opaque, hwaddr addr,
Benoît Canet40ce02f2011-11-15 12:13:58 +0100248 uint64_t val, unsigned size)
blueswir10019ad52008-01-27 09:49:28 +0000249{
250 MiscState *s = opaque;
251
252 val &= AUX2_PWRINTCLR | AUX2_PWROFF;
Blue Swirl97bf4852010-10-31 09:24:14 +0000253 trace_slavio_aux2_mem_writeb(val & 0xff);
blueswir10019ad52008-01-27 09:49:28 +0000254 val |= s->aux2 & AUX2_PWRFAIL;
255 if (val & AUX2_PWRINTCLR) // Clear Power Fail int
256 val &= AUX2_PWROFF;
257 s->aux2 = val;
258 if (val & AUX2_PWROFF)
259 qemu_system_shutdown_request();
260 slavio_misc_update_irq(s);
261}
262
Avi Kivitya8170e52012-10-23 12:30:10 +0200263static uint64_t slavio_aux2_mem_readb(void *opaque, hwaddr addr,
Benoît Canet40ce02f2011-11-15 12:13:58 +0100264 unsigned size)
blueswir10019ad52008-01-27 09:49:28 +0000265{
266 MiscState *s = opaque;
267 uint32_t ret = 0;
268
269 ret = s->aux2;
Blue Swirl97bf4852010-10-31 09:24:14 +0000270 trace_slavio_aux2_mem_readb(ret);
blueswir10019ad52008-01-27 09:49:28 +0000271 return ret;
272}
273
Benoît Canet40ce02f2011-11-15 12:13:58 +0100274static const MemoryRegionOps slavio_aux2_mem_ops = {
275 .read = slavio_aux2_mem_readb,
276 .write = slavio_aux2_mem_writeb,
277 .endianness = DEVICE_NATIVE_ENDIAN,
278 .valid = {
279 .min_access_size = 1,
280 .max_access_size = 1,
281 },
blueswir10019ad52008-01-27 09:49:28 +0000282};
283
Avi Kivitya8170e52012-10-23 12:30:10 +0200284static void apc_mem_writeb(void *opaque, hwaddr addr,
Benoît Canet9c48dee2011-11-15 12:13:51 +0100285 uint64_t val, unsigned size)
blueswir10019ad52008-01-27 09:49:28 +0000286{
Blue Swirl2582cfa2009-07-13 16:51:27 +0000287 APCState *s = opaque;
blueswir10019ad52008-01-27 09:49:28 +0000288
Blue Swirl97bf4852010-10-31 09:24:14 +0000289 trace_apc_mem_writeb(val & 0xff);
blueswir16d0c2932008-11-02 10:51:05 +0000290 qemu_irq_raise(s->cpu_halt);
blueswir10019ad52008-01-27 09:49:28 +0000291}
292
Avi Kivitya8170e52012-10-23 12:30:10 +0200293static uint64_t apc_mem_readb(void *opaque, hwaddr addr,
Benoît Canet9c48dee2011-11-15 12:13:51 +0100294 unsigned size)
blueswir10019ad52008-01-27 09:49:28 +0000295{
296 uint32_t ret = 0;
297
Blue Swirl97bf4852010-10-31 09:24:14 +0000298 trace_apc_mem_readb(ret);
blueswir10019ad52008-01-27 09:49:28 +0000299 return ret;
300}
301
Benoît Canet9c48dee2011-11-15 12:13:51 +0100302static const MemoryRegionOps apc_mem_ops = {
303 .read = apc_mem_readb,
304 .write = apc_mem_writeb,
305 .endianness = DEVICE_NATIVE_ENDIAN,
306 .valid = {
307 .min_access_size = 1,
308 .max_access_size = 1,
309 }
blueswir10019ad52008-01-27 09:49:28 +0000310};
311
Avi Kivitya8170e52012-10-23 12:30:10 +0200312static uint64_t slavio_sysctrl_mem_readl(void *opaque, hwaddr addr,
Benoît Canetcd64a522011-11-15 12:13:56 +0100313 unsigned size)
blueswir1bfa30a32007-11-04 17:27:07 +0000314{
315 MiscState *s = opaque;
blueswir1a8f48dc2008-12-02 17:51:19 +0000316 uint32_t ret = 0;
blueswir1bfa30a32007-11-04 17:27:07 +0000317
blueswir1a8f48dc2008-12-02 17:51:19 +0000318 switch (addr) {
blueswir1bfa30a32007-11-04 17:27:07 +0000319 case 0:
320 ret = s->sysctrl;
321 break;
322 default:
323 break;
324 }
Blue Swirl97bf4852010-10-31 09:24:14 +0000325 trace_slavio_sysctrl_mem_readl(ret);
blueswir1bfa30a32007-11-04 17:27:07 +0000326 return ret;
327}
328
Avi Kivitya8170e52012-10-23 12:30:10 +0200329static void slavio_sysctrl_mem_writel(void *opaque, hwaddr addr,
Benoît Canetcd64a522011-11-15 12:13:56 +0100330 uint64_t val, unsigned size)
blueswir1bfa30a32007-11-04 17:27:07 +0000331{
332 MiscState *s = opaque;
blueswir1bfa30a32007-11-04 17:27:07 +0000333
Blue Swirl97bf4852010-10-31 09:24:14 +0000334 trace_slavio_sysctrl_mem_writel(val);
blueswir1a8f48dc2008-12-02 17:51:19 +0000335 switch (addr) {
blueswir1bfa30a32007-11-04 17:27:07 +0000336 case 0:
blueswir17debeb82007-12-01 14:53:22 +0000337 if (val & SYS_RESET) {
338 s->sysctrl = SYS_RESETSTAT;
blueswir1bfa30a32007-11-04 17:27:07 +0000339 qemu_system_reset_request();
340 }
341 break;
342 default:
343 break;
344 }
345}
346
Benoît Canetcd64a522011-11-15 12:13:56 +0100347static const MemoryRegionOps slavio_sysctrl_mem_ops = {
348 .read = slavio_sysctrl_mem_readl,
349 .write = slavio_sysctrl_mem_writel,
350 .endianness = DEVICE_NATIVE_ENDIAN,
351 .valid = {
352 .min_access_size = 4,
353 .max_access_size = 4,
354 },
blueswir1bfa30a32007-11-04 17:27:07 +0000355};
356
Avi Kivitya8170e52012-10-23 12:30:10 +0200357static uint64_t slavio_led_mem_readw(void *opaque, hwaddr addr,
Benoît Canetaca23c72011-11-15 12:13:55 +0100358 unsigned size)
blueswir16a3b9cc2007-11-11 17:56:38 +0000359{
360 MiscState *s = opaque;
blueswir1a8f48dc2008-12-02 17:51:19 +0000361 uint32_t ret = 0;
blueswir16a3b9cc2007-11-11 17:56:38 +0000362
blueswir1a8f48dc2008-12-02 17:51:19 +0000363 switch (addr) {
blueswir16a3b9cc2007-11-11 17:56:38 +0000364 case 0:
365 ret = s->leds;
366 break;
367 default:
368 break;
369 }
Blue Swirl97bf4852010-10-31 09:24:14 +0000370 trace_slavio_led_mem_readw(ret);
blueswir16a3b9cc2007-11-11 17:56:38 +0000371 return ret;
372}
373
Avi Kivitya8170e52012-10-23 12:30:10 +0200374static void slavio_led_mem_writew(void *opaque, hwaddr addr,
Benoît Canetaca23c72011-11-15 12:13:55 +0100375 uint64_t val, unsigned size)
blueswir16a3b9cc2007-11-11 17:56:38 +0000376{
377 MiscState *s = opaque;
blueswir16a3b9cc2007-11-11 17:56:38 +0000378
Markus Armbrusterf3a64b82013-06-07 12:59:18 +0200379 trace_slavio_led_mem_writew(val & 0xffff);
blueswir1a8f48dc2008-12-02 17:51:19 +0000380 switch (addr) {
blueswir16a3b9cc2007-11-11 17:56:38 +0000381 case 0:
blueswir1d5296cb2007-12-01 15:02:20 +0000382 s->leds = val;
blueswir16a3b9cc2007-11-11 17:56:38 +0000383 break;
384 default:
385 break;
386 }
387}
388
Benoît Canetaca23c72011-11-15 12:13:55 +0100389static const MemoryRegionOps slavio_led_mem_ops = {
390 .read = slavio_led_mem_readw,
391 .write = slavio_led_mem_writew,
392 .endianness = DEVICE_NATIVE_ENDIAN,
393 .valid = {
394 .min_access_size = 2,
395 .max_access_size = 2,
396 },
blueswir16a3b9cc2007-11-11 17:56:38 +0000397};
398
Blue Swirld37adb02009-08-29 16:37:09 +0300399static const VMStateDescription vmstate_misc = {
400 .name ="slavio_misc",
401 .version_id = 1,
402 .minimum_version_id = 1,
403 .minimum_version_id_old = 1,
404 .fields = (VMStateField []) {
405 VMSTATE_UINT32(dummy, MiscState),
406 VMSTATE_UINT8(config, MiscState),
407 VMSTATE_UINT8(aux1, MiscState),
408 VMSTATE_UINT8(aux2, MiscState),
409 VMSTATE_UINT8(diag, MiscState),
410 VMSTATE_UINT8(mctrl, MiscState),
411 VMSTATE_UINT8(sysctrl, MiscState),
412 VMSTATE_END_OF_LIST()
413 }
414};
bellard34751872005-07-02 14:31:34 +0000415
Gerd Hoffmann81a322d2009-08-14 10:36:05 +0200416static int apc_init1(SysBusDevice *dev)
Blue Swirl2582cfa2009-07-13 16:51:27 +0000417{
Andreas Färberf1a0a792013-07-26 23:21:50 +0200418 APCState *s = APC(dev);
Blue Swirl2582cfa2009-07-13 16:51:27 +0000419
420 sysbus_init_irq(dev, &s->cpu_halt);
421
422 /* Power management (APC) XXX: not a Slavio device */
Paolo Bonzini3c161542013-06-06 21:25:08 -0400423 memory_region_init_io(&s->iomem, OBJECT(s), &apc_mem_ops, s,
Benoît Canet9c48dee2011-11-15 12:13:51 +0100424 "apc", MISC_SIZE);
Avi Kivity750ecd42011-11-27 11:38:10 +0200425 sysbus_init_mmio(dev, &s->iomem);
Gerd Hoffmann81a322d2009-08-14 10:36:05 +0200426 return 0;
Blue Swirl2582cfa2009-07-13 16:51:27 +0000427}
428
Andreas Färber95eb2082013-07-26 23:19:11 +0200429static int slavio_misc_init1(SysBusDevice *sbd)
Blue Swirl2582cfa2009-07-13 16:51:27 +0000430{
Andreas Färber95eb2082013-07-26 23:19:11 +0200431 DeviceState *dev = DEVICE(sbd);
432 MiscState *s = SLAVIO_MISC(dev);
Blue Swirl2582cfa2009-07-13 16:51:27 +0000433
Andreas Färber95eb2082013-07-26 23:19:11 +0200434 sysbus_init_irq(sbd, &s->irq);
435 sysbus_init_irq(sbd, &s->fdc_tc);
Blue Swirl2582cfa2009-07-13 16:51:27 +0000436
437 /* 8 bit registers */
438 /* Slavio control */
Paolo Bonzini3c161542013-06-06 21:25:08 -0400439 memory_region_init_io(&s->cfg_iomem, OBJECT(s), &slavio_cfg_mem_ops, s,
Benoît Canetdd703aa2011-11-15 12:13:52 +0100440 "configuration", MISC_SIZE);
Andreas Färber95eb2082013-07-26 23:19:11 +0200441 sysbus_init_mmio(sbd, &s->cfg_iomem);
Blue Swirl2582cfa2009-07-13 16:51:27 +0000442
443 /* Diagnostics */
Paolo Bonzini3c161542013-06-06 21:25:08 -0400444 memory_region_init_io(&s->diag_iomem, OBJECT(s), &slavio_diag_mem_ops, s,
Benoît Canet96891e52011-11-15 12:13:53 +0100445 "diagnostic", MISC_SIZE);
Andreas Färber95eb2082013-07-26 23:19:11 +0200446 sysbus_init_mmio(sbd, &s->diag_iomem);
Blue Swirl2582cfa2009-07-13 16:51:27 +0000447
448 /* Modem control */
Paolo Bonzini3c161542013-06-06 21:25:08 -0400449 memory_region_init_io(&s->mdm_iomem, OBJECT(s), &slavio_mdm_mem_ops, s,
Benoît Canet2e66ac32011-11-15 12:13:54 +0100450 "modem", MISC_SIZE);
Andreas Färber95eb2082013-07-26 23:19:11 +0200451 sysbus_init_mmio(sbd, &s->mdm_iomem);
Blue Swirl2582cfa2009-07-13 16:51:27 +0000452
453 /* 16 bit registers */
454 /* ss600mp diag LEDs */
Paolo Bonzini3c161542013-06-06 21:25:08 -0400455 memory_region_init_io(&s->led_iomem, OBJECT(s), &slavio_led_mem_ops, s,
Benoît Canetaca23c72011-11-15 12:13:55 +0100456 "leds", MISC_SIZE);
Andreas Färber95eb2082013-07-26 23:19:11 +0200457 sysbus_init_mmio(sbd, &s->led_iomem);
Blue Swirl2582cfa2009-07-13 16:51:27 +0000458
459 /* 32 bit registers */
460 /* System control */
Paolo Bonzini3c161542013-06-06 21:25:08 -0400461 memory_region_init_io(&s->sysctrl_iomem, OBJECT(s), &slavio_sysctrl_mem_ops, s,
Benoît Canetcd64a522011-11-15 12:13:56 +0100462 "system-control", MISC_SIZE);
Andreas Färber95eb2082013-07-26 23:19:11 +0200463 sysbus_init_mmio(sbd, &s->sysctrl_iomem);
Blue Swirl2582cfa2009-07-13 16:51:27 +0000464
465 /* AUX 1 (Misc System Functions) */
Paolo Bonzini3c161542013-06-06 21:25:08 -0400466 memory_region_init_io(&s->aux1_iomem, OBJECT(s), &slavio_aux1_mem_ops, s,
Benoît Canetcccd43c2011-11-15 12:13:57 +0100467 "misc-system-functions", MISC_SIZE);
Andreas Färber95eb2082013-07-26 23:19:11 +0200468 sysbus_init_mmio(sbd, &s->aux1_iomem);
Blue Swirl2582cfa2009-07-13 16:51:27 +0000469
470 /* AUX 2 (Software Powerdown Control) */
Paolo Bonzini3c161542013-06-06 21:25:08 -0400471 memory_region_init_io(&s->aux2_iomem, OBJECT(s), &slavio_aux2_mem_ops, s,
Benoît Canet40ce02f2011-11-15 12:13:58 +0100472 "software-powerdown-control", MISC_SIZE);
Andreas Färber95eb2082013-07-26 23:19:11 +0200473 sysbus_init_mmio(sbd, &s->aux2_iomem);
Blue Swirl2582cfa2009-07-13 16:51:27 +0000474
Andreas Färber95eb2082013-07-26 23:19:11 +0200475 qdev_init_gpio_in(dev, slavio_set_power_fail, 1);
Blue Swirlb2b6f6e2009-08-09 07:27:29 +0000476
Gerd Hoffmann81a322d2009-08-14 10:36:05 +0200477 return 0;
bellard34751872005-07-02 14:31:34 +0000478}
Blue Swirl2582cfa2009-07-13 16:51:27 +0000479
Anthony Liguori999e12b2012-01-24 13:12:29 -0600480static void slavio_misc_class_init(ObjectClass *klass, void *data)
481{
Anthony Liguori39bffca2011-12-07 21:34:16 -0600482 DeviceClass *dc = DEVICE_CLASS(klass);
Anthony Liguori999e12b2012-01-24 13:12:29 -0600483 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
484
485 k->init = slavio_misc_init1;
Anthony Liguori39bffca2011-12-07 21:34:16 -0600486 dc->reset = slavio_misc_reset;
487 dc->vmsd = &vmstate_misc;
Anthony Liguori999e12b2012-01-24 13:12:29 -0600488}
489
Andreas Färber8c43a6f2013-01-10 16:19:07 +0100490static const TypeInfo slavio_misc_info = {
Andreas Färber95eb2082013-07-26 23:19:11 +0200491 .name = TYPE_SLAVIO_MISC,
Anthony Liguori39bffca2011-12-07 21:34:16 -0600492 .parent = TYPE_SYS_BUS_DEVICE,
493 .instance_size = sizeof(MiscState),
494 .class_init = slavio_misc_class_init,
Blue Swirl2582cfa2009-07-13 16:51:27 +0000495};
496
Anthony Liguori999e12b2012-01-24 13:12:29 -0600497static void apc_class_init(ObjectClass *klass, void *data)
498{
499 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
500
501 k->init = apc_init1;
502}
503
Andreas Färber8c43a6f2013-01-10 16:19:07 +0100504static const TypeInfo apc_info = {
Andreas Färberf1a0a792013-07-26 23:21:50 +0200505 .name = TYPE_APC,
Anthony Liguori39bffca2011-12-07 21:34:16 -0600506 .parent = TYPE_SYS_BUS_DEVICE,
507 .instance_size = sizeof(MiscState),
508 .class_init = apc_class_init,
Blue Swirl2582cfa2009-07-13 16:51:27 +0000509};
510
Andreas Färber83f7d432012-02-09 15:20:55 +0100511static void slavio_misc_register_types(void)
Blue Swirl2582cfa2009-07-13 16:51:27 +0000512{
Anthony Liguori39bffca2011-12-07 21:34:16 -0600513 type_register_static(&slavio_misc_info);
514 type_register_static(&apc_info);
Blue Swirl2582cfa2009-07-13 16:51:27 +0000515}
516
Andreas Färber83f7d432012-02-09 15:20:55 +0100517type_init(slavio_misc_register_types)