]>
Commit | Line | Data |
---|---|---|
3475187d FB |
1 | /* |
2 | * QEMU Sparc SLAVIO aux io port emulation | |
5fafdf24 | 3 | * |
3475187d | 4 | * Copyright (c) 2005 Fabrice Bellard |
5fafdf24 | 5 | * |
3475187d FB |
6 | * 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 | */ | |
2582cfa0 | 24 | |
87ecb68b PB |
25 | #include "sun4m.h" |
26 | #include "sysemu.h" | |
2582cfa0 | 27 | #include "sysbus.h" |
87ecb68b | 28 | |
3475187d FB |
29 | /* debug misc */ |
30 | //#define DEBUG_MISC | |
31 | ||
32 | /* | |
33 | * This is the auxio port, chip control and system control part of | |
34 | * chip STP2001 (Slave I/O), also produced as NCR89C105. See | |
35 | * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt | |
36 | * | |
37 | * This also includes the PMC CPU idle controller. | |
38 | */ | |
39 | ||
40 | #ifdef DEBUG_MISC | |
001faf32 BS |
41 | #define MISC_DPRINTF(fmt, ...) \ |
42 | do { printf("MISC: " fmt , ## __VA_ARGS__); } while (0) | |
3475187d | 43 | #else |
001faf32 | 44 | #define MISC_DPRINTF(fmt, ...) |
3475187d FB |
45 | #endif |
46 | ||
47 | typedef struct MiscState { | |
2582cfa0 | 48 | SysBusDevice busdev; |
d537cf6c | 49 | qemu_irq irq; |
3475187d FB |
50 | uint8_t config; |
51 | uint8_t aux1, aux2; | |
bfa30a38 BS |
52 | uint8_t diag, mctrl; |
53 | uint32_t sysctrl; | |
6a3b9cc9 | 54 | uint16_t leds; |
2be17ebd | 55 | qemu_irq fdc_tc; |
3475187d FB |
56 | } MiscState; |
57 | ||
2582cfa0 BS |
58 | typedef struct APCState { |
59 | SysBusDevice busdev; | |
60 | qemu_irq cpu_halt; | |
61 | } APCState; | |
62 | ||
5aca8c3b | 63 | #define MISC_SIZE 1 |
a8f48dcc | 64 | #define SYSCTRL_SIZE 4 |
3475187d | 65 | |
7debeb82 BS |
66 | #define MISC_LEDS 0x01600000 |
67 | #define MISC_CFG 0x01800000 | |
7debeb82 BS |
68 | #define MISC_DIAG 0x01a00000 |
69 | #define MISC_MDM 0x01b00000 | |
70 | #define MISC_SYS 0x01f00000 | |
7debeb82 | 71 | |
2be17ebd BS |
72 | #define AUX1_TC 0x02 |
73 | ||
7debeb82 BS |
74 | #define AUX2_PWROFF 0x01 |
75 | #define AUX2_PWRINTCLR 0x02 | |
76 | #define AUX2_PWRFAIL 0x20 | |
77 | ||
78 | #define CFG_PWRINTEN 0x08 | |
79 | ||
80 | #define SYS_RESET 0x01 | |
81 | #define SYS_RESETSTAT 0x02 | |
82 | ||
3475187d FB |
83 | static void slavio_misc_update_irq(void *opaque) |
84 | { | |
85 | MiscState *s = opaque; | |
86 | ||
7debeb82 | 87 | if ((s->aux2 & AUX2_PWRFAIL) && (s->config & CFG_PWRINTEN)) { |
d537cf6c PB |
88 | MISC_DPRINTF("Raise IRQ\n"); |
89 | qemu_irq_raise(s->irq); | |
3475187d | 90 | } else { |
d537cf6c PB |
91 | MISC_DPRINTF("Lower IRQ\n"); |
92 | qemu_irq_lower(s->irq); | |
3475187d FB |
93 | } |
94 | } | |
95 | ||
96 | static void slavio_misc_reset(void *opaque) | |
97 | { | |
98 | MiscState *s = opaque; | |
99 | ||
4e3b1ea1 | 100 | // Diagnostic and system control registers not cleared in reset |
3475187d FB |
101 | s->config = s->aux1 = s->aux2 = s->mctrl = 0; |
102 | } | |
103 | ||
104 | void slavio_set_power_fail(void *opaque, int power_failing) | |
105 | { | |
106 | MiscState *s = opaque; | |
107 | ||
108 | MISC_DPRINTF("Power fail: %d, config: %d\n", power_failing, s->config); | |
7debeb82 BS |
109 | if (power_failing && (s->config & CFG_PWRINTEN)) { |
110 | s->aux2 |= AUX2_PWRFAIL; | |
3475187d | 111 | } else { |
7debeb82 | 112 | s->aux2 &= ~AUX2_PWRFAIL; |
3475187d FB |
113 | } |
114 | slavio_misc_update_irq(s); | |
115 | } | |
116 | ||
a8f48dcc BS |
117 | static void slavio_cfg_mem_writeb(void *opaque, target_phys_addr_t addr, |
118 | uint32_t val) | |
119 | { | |
120 | MiscState *s = opaque; | |
121 | ||
122 | MISC_DPRINTF("Write config %2.2x\n", val & 0xff); | |
123 | s->config = val & 0xff; | |
124 | slavio_misc_update_irq(s); | |
125 | } | |
126 | ||
127 | static uint32_t slavio_cfg_mem_readb(void *opaque, target_phys_addr_t addr) | |
128 | { | |
129 | MiscState *s = opaque; | |
130 | uint32_t ret = 0; | |
131 | ||
132 | ret = s->config; | |
133 | MISC_DPRINTF("Read config %2.2x\n", ret); | |
134 | return ret; | |
135 | } | |
136 | ||
137 | static CPUReadMemoryFunc *slavio_cfg_mem_read[3] = { | |
138 | slavio_cfg_mem_readb, | |
139 | NULL, | |
140 | NULL, | |
141 | }; | |
142 | ||
143 | static CPUWriteMemoryFunc *slavio_cfg_mem_write[3] = { | |
144 | slavio_cfg_mem_writeb, | |
145 | NULL, | |
146 | NULL, | |
147 | }; | |
148 | ||
149 | static void slavio_diag_mem_writeb(void *opaque, target_phys_addr_t addr, | |
bfa30a38 | 150 | uint32_t val) |
3475187d FB |
151 | { |
152 | MiscState *s = opaque; | |
153 | ||
a8f48dcc BS |
154 | MISC_DPRINTF("Write diag %2.2x\n", val & 0xff); |
155 | s->diag = val & 0xff; | |
3475187d FB |
156 | } |
157 | ||
a8f48dcc | 158 | static uint32_t slavio_diag_mem_readb(void *opaque, target_phys_addr_t addr) |
3475187d FB |
159 | { |
160 | MiscState *s = opaque; | |
161 | uint32_t ret = 0; | |
162 | ||
a8f48dcc BS |
163 | ret = s->diag; |
164 | MISC_DPRINTF("Read diag %2.2x\n", ret); | |
165 | return ret; | |
166 | } | |
167 | ||
168 | static CPUReadMemoryFunc *slavio_diag_mem_read[3] = { | |
169 | slavio_diag_mem_readb, | |
170 | NULL, | |
171 | NULL, | |
172 | }; | |
173 | ||
174 | static CPUWriteMemoryFunc *slavio_diag_mem_write[3] = { | |
175 | slavio_diag_mem_writeb, | |
176 | NULL, | |
177 | NULL, | |
178 | }; | |
179 | ||
180 | static void slavio_mdm_mem_writeb(void *opaque, target_phys_addr_t addr, | |
181 | uint32_t val) | |
182 | { | |
183 | MiscState *s = opaque; | |
184 | ||
185 | MISC_DPRINTF("Write modem control %2.2x\n", val & 0xff); | |
186 | s->mctrl = val & 0xff; | |
187 | } | |
188 | ||
189 | static uint32_t slavio_mdm_mem_readb(void *opaque, target_phys_addr_t addr) | |
190 | { | |
191 | MiscState *s = opaque; | |
192 | uint32_t ret = 0; | |
193 | ||
194 | ret = s->mctrl; | |
195 | MISC_DPRINTF("Read modem control %2.2x\n", ret); | |
3475187d FB |
196 | return ret; |
197 | } | |
198 | ||
a8f48dcc BS |
199 | static CPUReadMemoryFunc *slavio_mdm_mem_read[3] = { |
200 | slavio_mdm_mem_readb, | |
7c560456 BS |
201 | NULL, |
202 | NULL, | |
3475187d FB |
203 | }; |
204 | ||
a8f48dcc BS |
205 | static CPUWriteMemoryFunc *slavio_mdm_mem_write[3] = { |
206 | slavio_mdm_mem_writeb, | |
7c560456 BS |
207 | NULL, |
208 | NULL, | |
3475187d FB |
209 | }; |
210 | ||
0019ad53 BS |
211 | static void slavio_aux1_mem_writeb(void *opaque, target_phys_addr_t addr, |
212 | uint32_t val) | |
213 | { | |
214 | MiscState *s = opaque; | |
215 | ||
216 | MISC_DPRINTF("Write aux1 %2.2x\n", val & 0xff); | |
2be17ebd BS |
217 | if (val & AUX1_TC) { |
218 | // Send a pulse to floppy terminal count line | |
219 | if (s->fdc_tc) { | |
220 | qemu_irq_raise(s->fdc_tc); | |
221 | qemu_irq_lower(s->fdc_tc); | |
222 | } | |
223 | val &= ~AUX1_TC; | |
224 | } | |
0019ad53 BS |
225 | s->aux1 = val & 0xff; |
226 | } | |
227 | ||
228 | static uint32_t slavio_aux1_mem_readb(void *opaque, target_phys_addr_t addr) | |
229 | { | |
230 | MiscState *s = opaque; | |
231 | uint32_t ret = 0; | |
232 | ||
233 | ret = s->aux1; | |
234 | MISC_DPRINTF("Read aux1 %2.2x\n", ret); | |
235 | ||
236 | return ret; | |
237 | } | |
238 | ||
239 | static CPUReadMemoryFunc *slavio_aux1_mem_read[3] = { | |
240 | slavio_aux1_mem_readb, | |
241 | NULL, | |
242 | NULL, | |
243 | }; | |
244 | ||
245 | static CPUWriteMemoryFunc *slavio_aux1_mem_write[3] = { | |
246 | slavio_aux1_mem_writeb, | |
247 | NULL, | |
248 | NULL, | |
249 | }; | |
250 | ||
251 | static void slavio_aux2_mem_writeb(void *opaque, target_phys_addr_t addr, | |
252 | uint32_t val) | |
253 | { | |
254 | MiscState *s = opaque; | |
255 | ||
256 | val &= AUX2_PWRINTCLR | AUX2_PWROFF; | |
257 | MISC_DPRINTF("Write aux2 %2.2x\n", val); | |
258 | val |= s->aux2 & AUX2_PWRFAIL; | |
259 | if (val & AUX2_PWRINTCLR) // Clear Power Fail int | |
260 | val &= AUX2_PWROFF; | |
261 | s->aux2 = val; | |
262 | if (val & AUX2_PWROFF) | |
263 | qemu_system_shutdown_request(); | |
264 | slavio_misc_update_irq(s); | |
265 | } | |
266 | ||
267 | static uint32_t slavio_aux2_mem_readb(void *opaque, target_phys_addr_t addr) | |
268 | { | |
269 | MiscState *s = opaque; | |
270 | uint32_t ret = 0; | |
271 | ||
272 | ret = s->aux2; | |
273 | MISC_DPRINTF("Read aux2 %2.2x\n", ret); | |
274 | ||
275 | return ret; | |
276 | } | |
277 | ||
278 | static CPUReadMemoryFunc *slavio_aux2_mem_read[3] = { | |
279 | slavio_aux2_mem_readb, | |
280 | NULL, | |
281 | NULL, | |
282 | }; | |
283 | ||
284 | static CPUWriteMemoryFunc *slavio_aux2_mem_write[3] = { | |
285 | slavio_aux2_mem_writeb, | |
286 | NULL, | |
287 | NULL, | |
288 | }; | |
289 | ||
290 | static void apc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) | |
291 | { | |
2582cfa0 | 292 | APCState *s = opaque; |
0019ad53 BS |
293 | |
294 | MISC_DPRINTF("Write power management %2.2x\n", val & 0xff); | |
6d0c293d | 295 | qemu_irq_raise(s->cpu_halt); |
0019ad53 BS |
296 | } |
297 | ||
298 | static uint32_t apc_mem_readb(void *opaque, target_phys_addr_t addr) | |
299 | { | |
300 | uint32_t ret = 0; | |
301 | ||
302 | MISC_DPRINTF("Read power management %2.2x\n", ret); | |
303 | return ret; | |
304 | } | |
305 | ||
306 | static CPUReadMemoryFunc *apc_mem_read[3] = { | |
307 | apc_mem_readb, | |
308 | NULL, | |
309 | NULL, | |
310 | }; | |
311 | ||
312 | static CPUWriteMemoryFunc *apc_mem_write[3] = { | |
313 | apc_mem_writeb, | |
314 | NULL, | |
315 | NULL, | |
316 | }; | |
317 | ||
bfa30a38 BS |
318 | static uint32_t slavio_sysctrl_mem_readl(void *opaque, target_phys_addr_t addr) |
319 | { | |
320 | MiscState *s = opaque; | |
a8f48dcc | 321 | uint32_t ret = 0; |
bfa30a38 | 322 | |
a8f48dcc | 323 | switch (addr) { |
bfa30a38 BS |
324 | case 0: |
325 | ret = s->sysctrl; | |
326 | break; | |
327 | default: | |
328 | break; | |
329 | } | |
5626b017 | 330 | MISC_DPRINTF("Read system control %08x\n", ret); |
bfa30a38 BS |
331 | return ret; |
332 | } | |
333 | ||
334 | static void slavio_sysctrl_mem_writel(void *opaque, target_phys_addr_t addr, | |
335 | uint32_t val) | |
336 | { | |
337 | MiscState *s = opaque; | |
bfa30a38 | 338 | |
5626b017 | 339 | MISC_DPRINTF("Write system control %08x\n", val); |
a8f48dcc | 340 | switch (addr) { |
bfa30a38 | 341 | case 0: |
7debeb82 BS |
342 | if (val & SYS_RESET) { |
343 | s->sysctrl = SYS_RESETSTAT; | |
bfa30a38 BS |
344 | qemu_system_reset_request(); |
345 | } | |
346 | break; | |
347 | default: | |
348 | break; | |
349 | } | |
350 | } | |
351 | ||
352 | static CPUReadMemoryFunc *slavio_sysctrl_mem_read[3] = { | |
7c560456 BS |
353 | NULL, |
354 | NULL, | |
bfa30a38 BS |
355 | slavio_sysctrl_mem_readl, |
356 | }; | |
357 | ||
358 | static CPUWriteMemoryFunc *slavio_sysctrl_mem_write[3] = { | |
7c560456 BS |
359 | NULL, |
360 | NULL, | |
bfa30a38 BS |
361 | slavio_sysctrl_mem_writel, |
362 | }; | |
363 | ||
7c560456 | 364 | static uint32_t slavio_led_mem_readw(void *opaque, target_phys_addr_t addr) |
6a3b9cc9 BS |
365 | { |
366 | MiscState *s = opaque; | |
a8f48dcc | 367 | uint32_t ret = 0; |
6a3b9cc9 | 368 | |
a8f48dcc | 369 | switch (addr) { |
6a3b9cc9 BS |
370 | case 0: |
371 | ret = s->leds; | |
372 | break; | |
373 | default: | |
374 | break; | |
375 | } | |
5626b017 | 376 | MISC_DPRINTF("Read diagnostic LED %04x\n", ret); |
6a3b9cc9 BS |
377 | return ret; |
378 | } | |
379 | ||
7c560456 | 380 | static void slavio_led_mem_writew(void *opaque, target_phys_addr_t addr, |
6a3b9cc9 BS |
381 | uint32_t val) |
382 | { | |
383 | MiscState *s = opaque; | |
6a3b9cc9 | 384 | |
5626b017 | 385 | MISC_DPRINTF("Write diagnostic LED %04x\n", val & 0xffff); |
a8f48dcc | 386 | switch (addr) { |
6a3b9cc9 | 387 | case 0: |
d5296cb5 | 388 | s->leds = val; |
6a3b9cc9 BS |
389 | break; |
390 | default: | |
391 | break; | |
392 | } | |
393 | } | |
394 | ||
395 | static CPUReadMemoryFunc *slavio_led_mem_read[3] = { | |
7c560456 BS |
396 | NULL, |
397 | slavio_led_mem_readw, | |
398 | NULL, | |
6a3b9cc9 BS |
399 | }; |
400 | ||
401 | static CPUWriteMemoryFunc *slavio_led_mem_write[3] = { | |
7c560456 BS |
402 | NULL, |
403 | slavio_led_mem_writew, | |
404 | NULL, | |
6a3b9cc9 BS |
405 | }; |
406 | ||
3475187d FB |
407 | static void slavio_misc_save(QEMUFile *f, void *opaque) |
408 | { | |
409 | MiscState *s = opaque; | |
22548760 | 410 | uint32_t tmp = 0; |
bfa30a38 | 411 | uint8_t tmp8; |
3475187d | 412 | |
d537cf6c | 413 | qemu_put_be32s(f, &tmp); /* ignored, was IRQ. */ |
3475187d FB |
414 | qemu_put_8s(f, &s->config); |
415 | qemu_put_8s(f, &s->aux1); | |
416 | qemu_put_8s(f, &s->aux2); | |
417 | qemu_put_8s(f, &s->diag); | |
418 | qemu_put_8s(f, &s->mctrl); | |
bfa30a38 BS |
419 | tmp8 = s->sysctrl & 0xff; |
420 | qemu_put_8s(f, &tmp8); | |
3475187d FB |
421 | } |
422 | ||
423 | static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id) | |
424 | { | |
425 | MiscState *s = opaque; | |
22548760 | 426 | uint32_t tmp; |
bfa30a38 | 427 | uint8_t tmp8; |
3475187d FB |
428 | |
429 | if (version_id != 1) | |
430 | return -EINVAL; | |
431 | ||
d537cf6c | 432 | qemu_get_be32s(f, &tmp); |
3475187d FB |
433 | qemu_get_8s(f, &s->config); |
434 | qemu_get_8s(f, &s->aux1); | |
435 | qemu_get_8s(f, &s->aux2); | |
436 | qemu_get_8s(f, &s->diag); | |
437 | qemu_get_8s(f, &s->mctrl); | |
bfa30a38 BS |
438 | qemu_get_8s(f, &tmp8); |
439 | s->sysctrl = (uint32_t)tmp8; | |
3475187d FB |
440 | return 0; |
441 | } | |
442 | ||
2582cfa0 | 443 | void *slavio_misc_init(target_phys_addr_t base, |
0019ad53 BS |
444 | target_phys_addr_t aux1_base, |
445 | target_phys_addr_t aux2_base, qemu_irq irq, | |
2582cfa0 | 446 | qemu_irq fdc_tc) |
3475187d | 447 | { |
2582cfa0 BS |
448 | DeviceState *dev; |
449 | SysBusDevice *s; | |
450 | MiscState *d; | |
3475187d | 451 | |
2582cfa0 BS |
452 | dev = qdev_create(NULL, "slavio_misc"); |
453 | qdev_init(dev); | |
454 | s = sysbus_from_qdev(dev); | |
0019ad53 BS |
455 | if (base) { |
456 | /* 8 bit registers */ | |
2582cfa0 BS |
457 | /* Slavio control */ |
458 | sysbus_mmio_map(s, 0, base + MISC_CFG); | |
459 | /* Diagnostics */ | |
460 | sysbus_mmio_map(s, 1, base + MISC_DIAG); | |
461 | /* Modem control */ | |
462 | sysbus_mmio_map(s, 2, base + MISC_MDM); | |
0019ad53 | 463 | /* 16 bit registers */ |
0019ad53 | 464 | /* ss600mp diag LEDs */ |
2582cfa0 | 465 | sysbus_mmio_map(s, 3, base + MISC_LEDS); |
0019ad53 | 466 | /* 32 bit registers */ |
2582cfa0 BS |
467 | /* System control */ |
468 | sysbus_mmio_map(s, 4, base + MISC_SYS); | |
0019ad53 | 469 | } |
0019ad53 | 470 | if (aux1_base) { |
2582cfa0 BS |
471 | /* AUX 1 (Misc System Functions) */ |
472 | sysbus_mmio_map(s, 5, aux1_base); | |
0019ad53 | 473 | } |
0019ad53 | 474 | if (aux2_base) { |
2582cfa0 BS |
475 | /* AUX 2 (Software Powerdown Control) */ |
476 | sysbus_mmio_map(s, 6, aux2_base); | |
0019ad53 | 477 | } |
2582cfa0 BS |
478 | sysbus_connect_irq(s, 0, irq); |
479 | sysbus_connect_irq(s, 1, fdc_tc); | |
0019ad53 | 480 | |
2582cfa0 | 481 | d = FROM_SYSBUS(MiscState, s); |
bfa30a38 | 482 | |
2582cfa0 BS |
483 | return d; |
484 | } | |
485 | ||
486 | static void apc_init1(SysBusDevice *dev) | |
487 | { | |
488 | APCState *s = FROM_SYSBUS(APCState, dev); | |
489 | int io; | |
3475187d | 490 | |
2582cfa0 BS |
491 | sysbus_init_irq(dev, &s->cpu_halt); |
492 | ||
493 | /* Power management (APC) XXX: not a Slavio device */ | |
494 | io = cpu_register_io_memory(apc_mem_read, apc_mem_write, s); | |
495 | sysbus_init_mmio(dev, MISC_SIZE, io); | |
496 | } | |
497 | ||
498 | void apc_init(target_phys_addr_t power_base, qemu_irq cpu_halt) | |
499 | { | |
500 | DeviceState *dev; | |
501 | SysBusDevice *s; | |
502 | ||
503 | dev = qdev_create(NULL, "apc"); | |
504 | qdev_init(dev); | |
505 | s = sysbus_from_qdev(dev); | |
506 | /* Power management (APC) XXX: not a Slavio device */ | |
507 | sysbus_mmio_map(s, 0, power_base); | |
508 | sysbus_connect_irq(s, 0, cpu_halt); | |
509 | } | |
510 | ||
511 | static void slavio_misc_init1(SysBusDevice *dev) | |
512 | { | |
513 | MiscState *s = FROM_SYSBUS(MiscState, dev); | |
514 | int io; | |
515 | ||
516 | sysbus_init_irq(dev, &s->irq); | |
517 | sysbus_init_irq(dev, &s->fdc_tc); | |
518 | ||
519 | /* 8 bit registers */ | |
520 | /* Slavio control */ | |
521 | io = cpu_register_io_memory(slavio_cfg_mem_read, | |
522 | slavio_cfg_mem_write, s); | |
523 | sysbus_init_mmio(dev, MISC_SIZE, io); | |
524 | ||
525 | /* Diagnostics */ | |
526 | io = cpu_register_io_memory(slavio_diag_mem_read, | |
527 | slavio_diag_mem_write, s); | |
528 | sysbus_init_mmio(dev, MISC_SIZE, io); | |
529 | ||
530 | /* Modem control */ | |
531 | io = cpu_register_io_memory(slavio_mdm_mem_read, | |
532 | slavio_mdm_mem_write, s); | |
533 | sysbus_init_mmio(dev, MISC_SIZE, io); | |
534 | ||
535 | /* 16 bit registers */ | |
536 | /* ss600mp diag LEDs */ | |
537 | io = cpu_register_io_memory(slavio_led_mem_read, | |
538 | slavio_led_mem_write, s); | |
539 | sysbus_init_mmio(dev, MISC_SIZE, io); | |
540 | ||
541 | /* 32 bit registers */ | |
542 | /* System control */ | |
543 | io = cpu_register_io_memory(slavio_sysctrl_mem_read, | |
544 | slavio_sysctrl_mem_write, s); | |
545 | sysbus_init_mmio(dev, SYSCTRL_SIZE, io); | |
546 | ||
547 | /* AUX 1 (Misc System Functions) */ | |
548 | io = cpu_register_io_memory(slavio_aux1_mem_read, | |
549 | slavio_aux1_mem_write, s); | |
550 | sysbus_init_mmio(dev, MISC_SIZE, io); | |
551 | ||
552 | /* AUX 2 (Software Powerdown Control) */ | |
553 | io = cpu_register_io_memory(slavio_aux2_mem_read, | |
554 | slavio_aux2_mem_write, s); | |
555 | sysbus_init_mmio(dev, MISC_SIZE, io); | |
556 | ||
557 | register_savevm("slavio_misc", -1, 1, slavio_misc_save, slavio_misc_load, | |
bfa30a38 | 558 | s); |
a08d4367 | 559 | qemu_register_reset(slavio_misc_reset, s); |
3475187d | 560 | slavio_misc_reset(s); |
2582cfa0 | 561 | } |
0019ad53 | 562 | |
2582cfa0 BS |
563 | static SysBusDeviceInfo slavio_misc_info = { |
564 | .init = slavio_misc_init1, | |
565 | .qdev.name = "slavio_misc", | |
566 | .qdev.size = sizeof(MiscState), | |
567 | .qdev.props = (DevicePropList[]) { | |
568 | {.name = NULL} | |
569 | } | |
570 | }; | |
571 | ||
572 | static SysBusDeviceInfo apc_info = { | |
573 | .init = apc_init1, | |
574 | .qdev.name = "apc", | |
575 | .qdev.size = sizeof(MiscState), | |
576 | .qdev.props = (DevicePropList[]) { | |
577 | {.name = NULL} | |
578 | } | |
579 | }; | |
580 | ||
581 | static void slavio_misc_register_devices(void) | |
582 | { | |
583 | sysbus_register_withprop(&slavio_misc_info); | |
584 | sysbus_register_withprop(&apc_info); | |
3475187d | 585 | } |
2582cfa0 BS |
586 | |
587 | device_init(slavio_misc_register_devices) |