2 * QEMU Sparc SLAVIO aux io port emulation
4 * Copyright (c) 2005 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
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
37 * This also includes the PMC CPU idle controller.
41 #define MISC_DPRINTF(fmt, ...) \
42 do { printf("MISC: " fmt , ## __VA_ARGS__); } while (0)
44 #define MISC_DPRINTF(fmt, ...)
47 typedef struct MiscState
{
58 typedef struct APCState
{
64 #define SYSCTRL_SIZE 4
66 #define MISC_LEDS 0x01600000
67 #define MISC_CFG 0x01800000
68 #define MISC_DIAG 0x01a00000
69 #define MISC_MDM 0x01b00000
70 #define MISC_SYS 0x01f00000
74 #define AUX2_PWROFF 0x01
75 #define AUX2_PWRINTCLR 0x02
76 #define AUX2_PWRFAIL 0x20
78 #define CFG_PWRINTEN 0x08
80 #define SYS_RESET 0x01
81 #define SYS_RESETSTAT 0x02
83 static void slavio_misc_update_irq(void *opaque
)
85 MiscState
*s
= opaque
;
87 if ((s
->aux2
& AUX2_PWRFAIL
) && (s
->config
& CFG_PWRINTEN
)) {
88 MISC_DPRINTF("Raise IRQ\n");
89 qemu_irq_raise(s
->irq
);
91 MISC_DPRINTF("Lower IRQ\n");
92 qemu_irq_lower(s
->irq
);
96 static void slavio_misc_reset(void *opaque
)
98 MiscState
*s
= opaque
;
100 // Diagnostic and system control registers not cleared in reset
101 s
->config
= s
->aux1
= s
->aux2
= s
->mctrl
= 0;
104 void slavio_set_power_fail(void *opaque
, int power_failing
)
106 MiscState
*s
= opaque
;
108 MISC_DPRINTF("Power fail: %d, config: %d\n", power_failing
, s
->config
);
109 if (power_failing
&& (s
->config
& CFG_PWRINTEN
)) {
110 s
->aux2
|= AUX2_PWRFAIL
;
112 s
->aux2
&= ~AUX2_PWRFAIL
;
114 slavio_misc_update_irq(s
);
117 static void slavio_cfg_mem_writeb(void *opaque
, target_phys_addr_t addr
,
120 MiscState
*s
= opaque
;
122 MISC_DPRINTF("Write config %2.2x\n", val
& 0xff);
123 s
->config
= val
& 0xff;
124 slavio_misc_update_irq(s
);
127 static uint32_t slavio_cfg_mem_readb(void *opaque
, target_phys_addr_t addr
)
129 MiscState
*s
= opaque
;
133 MISC_DPRINTF("Read config %2.2x\n", ret
);
137 static CPUReadMemoryFunc
*slavio_cfg_mem_read
[3] = {
138 slavio_cfg_mem_readb
,
143 static CPUWriteMemoryFunc
*slavio_cfg_mem_write
[3] = {
144 slavio_cfg_mem_writeb
,
149 static void slavio_diag_mem_writeb(void *opaque
, target_phys_addr_t addr
,
152 MiscState
*s
= opaque
;
154 MISC_DPRINTF("Write diag %2.2x\n", val
& 0xff);
155 s
->diag
= val
& 0xff;
158 static uint32_t slavio_diag_mem_readb(void *opaque
, target_phys_addr_t addr
)
160 MiscState
*s
= opaque
;
164 MISC_DPRINTF("Read diag %2.2x\n", ret
);
168 static CPUReadMemoryFunc
*slavio_diag_mem_read
[3] = {
169 slavio_diag_mem_readb
,
174 static CPUWriteMemoryFunc
*slavio_diag_mem_write
[3] = {
175 slavio_diag_mem_writeb
,
180 static void slavio_mdm_mem_writeb(void *opaque
, target_phys_addr_t addr
,
183 MiscState
*s
= opaque
;
185 MISC_DPRINTF("Write modem control %2.2x\n", val
& 0xff);
186 s
->mctrl
= val
& 0xff;
189 static uint32_t slavio_mdm_mem_readb(void *opaque
, target_phys_addr_t addr
)
191 MiscState
*s
= opaque
;
195 MISC_DPRINTF("Read modem control %2.2x\n", ret
);
199 static CPUReadMemoryFunc
*slavio_mdm_mem_read
[3] = {
200 slavio_mdm_mem_readb
,
205 static CPUWriteMemoryFunc
*slavio_mdm_mem_write
[3] = {
206 slavio_mdm_mem_writeb
,
211 static void slavio_aux1_mem_writeb(void *opaque
, target_phys_addr_t addr
,
214 MiscState
*s
= opaque
;
216 MISC_DPRINTF("Write aux1 %2.2x\n", val
& 0xff);
218 // Send a pulse to floppy terminal count line
220 qemu_irq_raise(s
->fdc_tc
);
221 qemu_irq_lower(s
->fdc_tc
);
225 s
->aux1
= val
& 0xff;
228 static uint32_t slavio_aux1_mem_readb(void *opaque
, target_phys_addr_t addr
)
230 MiscState
*s
= opaque
;
234 MISC_DPRINTF("Read aux1 %2.2x\n", ret
);
239 static CPUReadMemoryFunc
*slavio_aux1_mem_read
[3] = {
240 slavio_aux1_mem_readb
,
245 static CPUWriteMemoryFunc
*slavio_aux1_mem_write
[3] = {
246 slavio_aux1_mem_writeb
,
251 static void slavio_aux2_mem_writeb(void *opaque
, target_phys_addr_t addr
,
254 MiscState
*s
= opaque
;
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
262 if (val
& AUX2_PWROFF
)
263 qemu_system_shutdown_request();
264 slavio_misc_update_irq(s
);
267 static uint32_t slavio_aux2_mem_readb(void *opaque
, target_phys_addr_t addr
)
269 MiscState
*s
= opaque
;
273 MISC_DPRINTF("Read aux2 %2.2x\n", ret
);
278 static CPUReadMemoryFunc
*slavio_aux2_mem_read
[3] = {
279 slavio_aux2_mem_readb
,
284 static CPUWriteMemoryFunc
*slavio_aux2_mem_write
[3] = {
285 slavio_aux2_mem_writeb
,
290 static void apc_mem_writeb(void *opaque
, target_phys_addr_t addr
, uint32_t val
)
292 APCState
*s
= opaque
;
294 MISC_DPRINTF("Write power management %2.2x\n", val
& 0xff);
295 qemu_irq_raise(s
->cpu_halt
);
298 static uint32_t apc_mem_readb(void *opaque
, target_phys_addr_t addr
)
302 MISC_DPRINTF("Read power management %2.2x\n", ret
);
306 static CPUReadMemoryFunc
*apc_mem_read
[3] = {
312 static CPUWriteMemoryFunc
*apc_mem_write
[3] = {
318 static uint32_t slavio_sysctrl_mem_readl(void *opaque
, target_phys_addr_t addr
)
320 MiscState
*s
= opaque
;
330 MISC_DPRINTF("Read system control %08x\n", ret
);
334 static void slavio_sysctrl_mem_writel(void *opaque
, target_phys_addr_t addr
,
337 MiscState
*s
= opaque
;
339 MISC_DPRINTF("Write system control %08x\n", val
);
342 if (val
& SYS_RESET
) {
343 s
->sysctrl
= SYS_RESETSTAT
;
344 qemu_system_reset_request();
352 static CPUReadMemoryFunc
*slavio_sysctrl_mem_read
[3] = {
355 slavio_sysctrl_mem_readl
,
358 static CPUWriteMemoryFunc
*slavio_sysctrl_mem_write
[3] = {
361 slavio_sysctrl_mem_writel
,
364 static uint32_t slavio_led_mem_readw(void *opaque
, target_phys_addr_t addr
)
366 MiscState
*s
= opaque
;
376 MISC_DPRINTF("Read diagnostic LED %04x\n", ret
);
380 static void slavio_led_mem_writew(void *opaque
, target_phys_addr_t addr
,
383 MiscState
*s
= opaque
;
385 MISC_DPRINTF("Write diagnostic LED %04x\n", val
& 0xffff);
395 static CPUReadMemoryFunc
*slavio_led_mem_read
[3] = {
397 slavio_led_mem_readw
,
401 static CPUWriteMemoryFunc
*slavio_led_mem_write
[3] = {
403 slavio_led_mem_writew
,
407 static void slavio_misc_save(QEMUFile
*f
, void *opaque
)
409 MiscState
*s
= opaque
;
413 qemu_put_be32s(f
, &tmp
); /* ignored, was IRQ. */
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
);
419 tmp8
= s
->sysctrl
& 0xff;
420 qemu_put_8s(f
, &tmp8
);
423 static int slavio_misc_load(QEMUFile
*f
, void *opaque
, int version_id
)
425 MiscState
*s
= opaque
;
432 qemu_get_be32s(f
, &tmp
);
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
);
438 qemu_get_8s(f
, &tmp8
);
439 s
->sysctrl
= (uint32_t)tmp8
;
443 void *slavio_misc_init(target_phys_addr_t base
,
444 target_phys_addr_t aux1_base
,
445 target_phys_addr_t aux2_base
, qemu_irq irq
,
452 dev
= qdev_create(NULL
, "slavio_misc");
454 s
= sysbus_from_qdev(dev
);
456 /* 8 bit registers */
458 sysbus_mmio_map(s
, 0, base
+ MISC_CFG
);
460 sysbus_mmio_map(s
, 1, base
+ MISC_DIAG
);
462 sysbus_mmio_map(s
, 2, base
+ MISC_MDM
);
463 /* 16 bit registers */
464 /* ss600mp diag LEDs */
465 sysbus_mmio_map(s
, 3, base
+ MISC_LEDS
);
466 /* 32 bit registers */
468 sysbus_mmio_map(s
, 4, base
+ MISC_SYS
);
471 /* AUX 1 (Misc System Functions) */
472 sysbus_mmio_map(s
, 5, aux1_base
);
475 /* AUX 2 (Software Powerdown Control) */
476 sysbus_mmio_map(s
, 6, aux2_base
);
478 sysbus_connect_irq(s
, 0, irq
);
479 sysbus_connect_irq(s
, 1, fdc_tc
);
481 d
= FROM_SYSBUS(MiscState
, s
);
486 static void apc_init1(SysBusDevice
*dev
)
488 APCState
*s
= FROM_SYSBUS(APCState
, dev
);
491 sysbus_init_irq(dev
, &s
->cpu_halt
);
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
);
498 void apc_init(target_phys_addr_t power_base
, qemu_irq cpu_halt
)
503 dev
= qdev_create(NULL
, "apc");
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
);
511 static void slavio_misc_init1(SysBusDevice
*dev
)
513 MiscState
*s
= FROM_SYSBUS(MiscState
, dev
);
516 sysbus_init_irq(dev
, &s
->irq
);
517 sysbus_init_irq(dev
, &s
->fdc_tc
);
519 /* 8 bit registers */
521 io
= cpu_register_io_memory(slavio_cfg_mem_read
,
522 slavio_cfg_mem_write
, s
);
523 sysbus_init_mmio(dev
, MISC_SIZE
, io
);
526 io
= cpu_register_io_memory(slavio_diag_mem_read
,
527 slavio_diag_mem_write
, s
);
528 sysbus_init_mmio(dev
, MISC_SIZE
, io
);
531 io
= cpu_register_io_memory(slavio_mdm_mem_read
,
532 slavio_mdm_mem_write
, s
);
533 sysbus_init_mmio(dev
, MISC_SIZE
, io
);
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
);
541 /* 32 bit registers */
543 io
= cpu_register_io_memory(slavio_sysctrl_mem_read
,
544 slavio_sysctrl_mem_write
, s
);
545 sysbus_init_mmio(dev
, SYSCTRL_SIZE
, io
);
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
);
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
);
557 register_savevm("slavio_misc", -1, 1, slavio_misc_save
, slavio_misc_load
,
559 qemu_register_reset(slavio_misc_reset
, s
);
560 slavio_misc_reset(s
);
563 static SysBusDeviceInfo slavio_misc_info
= {
564 .init
= slavio_misc_init1
,
565 .qdev
.name
= "slavio_misc",
566 .qdev
.size
= sizeof(MiscState
),
569 static SysBusDeviceInfo apc_info
= {
572 .qdev
.size
= sizeof(MiscState
),
575 static void slavio_misc_register_devices(void)
577 sysbus_register_withprop(&slavio_misc_info
);
578 sysbus_register_withprop(&apc_info
);
581 device_init(slavio_misc_register_devices
)