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
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
34
* This also includes the PMC CPU idle controller.
37
typedef struct MiscState {
49
typedef struct APCState {
55
#define SYSCTRL_SIZE 4
59
#define AUX2_PWROFF 0x01
60
#define AUX2_PWRINTCLR 0x02
61
#define AUX2_PWRFAIL 0x20
63
#define CFG_PWRINTEN 0x08
65
#define SYS_RESET 0x01
66
#define SYS_RESETSTAT 0x02
68
static void slavio_misc_update_irq(void *opaque)
70
MiscState *s = opaque;
72
if ((s->aux2 & AUX2_PWRFAIL) && (s->config & CFG_PWRINTEN)) {
73
trace_slavio_misc_update_irq_raise();
74
qemu_irq_raise(s->irq);
76
trace_slavio_misc_update_irq_lower();
77
qemu_irq_lower(s->irq);
81
static void slavio_misc_reset(DeviceState *d)
83
MiscState *s = container_of(d, MiscState, busdev.qdev);
85
// Diagnostic and system control registers not cleared in reset
86
s->config = s->aux1 = s->aux2 = s->mctrl = 0;
89
static void slavio_set_power_fail(void *opaque, int irq, int power_failing)
91
MiscState *s = opaque;
93
trace_slavio_set_power_fail(power_failing, s->config);
94
if (power_failing && (s->config & CFG_PWRINTEN)) {
95
s->aux2 |= AUX2_PWRFAIL;
97
s->aux2 &= ~AUX2_PWRFAIL;
99
slavio_misc_update_irq(s);
102
static void slavio_cfg_mem_writeb(void *opaque, target_phys_addr_t addr,
105
MiscState *s = opaque;
107
trace_slavio_cfg_mem_writeb(val & 0xff);
108
s->config = val & 0xff;
109
slavio_misc_update_irq(s);
112
static uint32_t slavio_cfg_mem_readb(void *opaque, target_phys_addr_t addr)
114
MiscState *s = opaque;
118
trace_slavio_cfg_mem_readb(ret);
122
static CPUReadMemoryFunc * const slavio_cfg_mem_read[3] = {
123
slavio_cfg_mem_readb,
128
static CPUWriteMemoryFunc * const slavio_cfg_mem_write[3] = {
129
slavio_cfg_mem_writeb,
134
static void slavio_diag_mem_writeb(void *opaque, target_phys_addr_t addr,
137
MiscState *s = opaque;
139
trace_slavio_diag_mem_writeb(val & 0xff);
140
s->diag = val & 0xff;
143
static uint32_t slavio_diag_mem_readb(void *opaque, target_phys_addr_t addr)
145
MiscState *s = opaque;
149
trace_slavio_diag_mem_readb(ret);
153
static CPUReadMemoryFunc * const slavio_diag_mem_read[3] = {
154
slavio_diag_mem_readb,
159
static CPUWriteMemoryFunc * const slavio_diag_mem_write[3] = {
160
slavio_diag_mem_writeb,
165
static void slavio_mdm_mem_writeb(void *opaque, target_phys_addr_t addr,
168
MiscState *s = opaque;
170
trace_slavio_mdm_mem_writeb(val & 0xff);
171
s->mctrl = val & 0xff;
174
static uint32_t slavio_mdm_mem_readb(void *opaque, target_phys_addr_t addr)
176
MiscState *s = opaque;
180
trace_slavio_mdm_mem_readb(ret);
184
static CPUReadMemoryFunc * const slavio_mdm_mem_read[3] = {
185
slavio_mdm_mem_readb,
190
static CPUWriteMemoryFunc * const slavio_mdm_mem_write[3] = {
191
slavio_mdm_mem_writeb,
196
static void slavio_aux1_mem_writeb(void *opaque, target_phys_addr_t addr,
199
MiscState *s = opaque;
201
trace_slavio_aux1_mem_writeb(val & 0xff);
203
// Send a pulse to floppy terminal count line
205
qemu_irq_raise(s->fdc_tc);
206
qemu_irq_lower(s->fdc_tc);
210
s->aux1 = val & 0xff;
213
static uint32_t slavio_aux1_mem_readb(void *opaque, target_phys_addr_t addr)
215
MiscState *s = opaque;
219
trace_slavio_aux1_mem_readb(ret);
223
static CPUReadMemoryFunc * const slavio_aux1_mem_read[3] = {
224
slavio_aux1_mem_readb,
229
static CPUWriteMemoryFunc * const slavio_aux1_mem_write[3] = {
230
slavio_aux1_mem_writeb,
235
static void slavio_aux2_mem_writeb(void *opaque, target_phys_addr_t addr,
238
MiscState *s = opaque;
240
val &= AUX2_PWRINTCLR | AUX2_PWROFF;
241
trace_slavio_aux2_mem_writeb(val & 0xff);
242
val |= s->aux2 & AUX2_PWRFAIL;
243
if (val & AUX2_PWRINTCLR) // Clear Power Fail int
246
if (val & AUX2_PWROFF)
247
qemu_system_shutdown_request();
248
slavio_misc_update_irq(s);
251
static uint32_t slavio_aux2_mem_readb(void *opaque, target_phys_addr_t addr)
253
MiscState *s = opaque;
257
trace_slavio_aux2_mem_readb(ret);
261
static CPUReadMemoryFunc * const slavio_aux2_mem_read[3] = {
262
slavio_aux2_mem_readb,
267
static CPUWriteMemoryFunc * const slavio_aux2_mem_write[3] = {
268
slavio_aux2_mem_writeb,
273
static void apc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
275
APCState *s = opaque;
277
trace_apc_mem_writeb(val & 0xff);
278
qemu_irq_raise(s->cpu_halt);
281
static uint32_t apc_mem_readb(void *opaque, target_phys_addr_t addr)
285
trace_apc_mem_readb(ret);
289
static CPUReadMemoryFunc * const apc_mem_read[3] = {
295
static CPUWriteMemoryFunc * const apc_mem_write[3] = {
301
static uint32_t slavio_sysctrl_mem_readl(void *opaque, target_phys_addr_t addr)
303
MiscState *s = opaque;
313
trace_slavio_sysctrl_mem_readl(ret);
317
static void slavio_sysctrl_mem_writel(void *opaque, target_phys_addr_t addr,
320
MiscState *s = opaque;
322
trace_slavio_sysctrl_mem_writel(val);
325
if (val & SYS_RESET) {
326
s->sysctrl = SYS_RESETSTAT;
327
qemu_system_reset_request();
335
static CPUReadMemoryFunc * const slavio_sysctrl_mem_read[3] = {
338
slavio_sysctrl_mem_readl,
341
static CPUWriteMemoryFunc * const slavio_sysctrl_mem_write[3] = {
344
slavio_sysctrl_mem_writel,
347
static uint32_t slavio_led_mem_readw(void *opaque, target_phys_addr_t addr)
349
MiscState *s = opaque;
359
trace_slavio_led_mem_readw(ret);
363
static void slavio_led_mem_writew(void *opaque, target_phys_addr_t addr,
366
MiscState *s = opaque;
368
trace_slavio_led_mem_readw(val & 0xffff);
378
static CPUReadMemoryFunc * const slavio_led_mem_read[3] = {
380
slavio_led_mem_readw,
384
static CPUWriteMemoryFunc * const slavio_led_mem_write[3] = {
386
slavio_led_mem_writew,
390
static const VMStateDescription vmstate_misc = {
391
.name ="slavio_misc",
393
.minimum_version_id = 1,
394
.minimum_version_id_old = 1,
395
.fields = (VMStateField []) {
396
VMSTATE_UINT32(dummy, MiscState),
397
VMSTATE_UINT8(config, MiscState),
398
VMSTATE_UINT8(aux1, MiscState),
399
VMSTATE_UINT8(aux2, MiscState),
400
VMSTATE_UINT8(diag, MiscState),
401
VMSTATE_UINT8(mctrl, MiscState),
402
VMSTATE_UINT8(sysctrl, MiscState),
403
VMSTATE_END_OF_LIST()
407
static int apc_init1(SysBusDevice *dev)
409
APCState *s = FROM_SYSBUS(APCState, dev);
412
sysbus_init_irq(dev, &s->cpu_halt);
414
/* Power management (APC) XXX: not a Slavio device */
415
io = cpu_register_io_memory(apc_mem_read, apc_mem_write, s,
416
DEVICE_NATIVE_ENDIAN);
417
sysbus_init_mmio(dev, MISC_SIZE, io);
421
static int slavio_misc_init1(SysBusDevice *dev)
423
MiscState *s = FROM_SYSBUS(MiscState, dev);
426
sysbus_init_irq(dev, &s->irq);
427
sysbus_init_irq(dev, &s->fdc_tc);
429
/* 8 bit registers */
431
io = cpu_register_io_memory(slavio_cfg_mem_read,
432
slavio_cfg_mem_write, s,
433
DEVICE_NATIVE_ENDIAN);
434
sysbus_init_mmio(dev, MISC_SIZE, io);
437
io = cpu_register_io_memory(slavio_diag_mem_read,
438
slavio_diag_mem_write, s,
439
DEVICE_NATIVE_ENDIAN);
440
sysbus_init_mmio(dev, MISC_SIZE, io);
443
io = cpu_register_io_memory(slavio_mdm_mem_read,
444
slavio_mdm_mem_write, s,
445
DEVICE_NATIVE_ENDIAN);
446
sysbus_init_mmio(dev, MISC_SIZE, io);
448
/* 16 bit registers */
449
/* ss600mp diag LEDs */
450
io = cpu_register_io_memory(slavio_led_mem_read,
451
slavio_led_mem_write, s,
452
DEVICE_NATIVE_ENDIAN);
453
sysbus_init_mmio(dev, MISC_SIZE, io);
455
/* 32 bit registers */
457
io = cpu_register_io_memory(slavio_sysctrl_mem_read,
458
slavio_sysctrl_mem_write, s,
459
DEVICE_NATIVE_ENDIAN);
460
sysbus_init_mmio(dev, SYSCTRL_SIZE, io);
462
/* AUX 1 (Misc System Functions) */
463
io = cpu_register_io_memory(slavio_aux1_mem_read,
464
slavio_aux1_mem_write, s,
465
DEVICE_NATIVE_ENDIAN);
466
sysbus_init_mmio(dev, MISC_SIZE, io);
468
/* AUX 2 (Software Powerdown Control) */
469
io = cpu_register_io_memory(slavio_aux2_mem_read,
470
slavio_aux2_mem_write, s,
471
DEVICE_NATIVE_ENDIAN);
472
sysbus_init_mmio(dev, MISC_SIZE, io);
474
qdev_init_gpio_in(&dev->qdev, slavio_set_power_fail, 1);
479
static SysBusDeviceInfo slavio_misc_info = {
480
.init = slavio_misc_init1,
481
.qdev.name = "slavio_misc",
482
.qdev.size = sizeof(MiscState),
483
.qdev.vmsd = &vmstate_misc,
484
.qdev.reset = slavio_misc_reset,
487
static SysBusDeviceInfo apc_info = {
490
.qdev.size = sizeof(MiscState),
493
static void slavio_misc_register_devices(void)
495
sysbus_register_withprop(&slavio_misc_info);
496
sysbus_register_withprop(&apc_info);
499
device_init(slavio_misc_register_devices)