xref: /openbmc/qemu/hw/isa/vt82c686.c (revision 8c8a7ed5)
1 /*
2  * VT82C686B south bridge support
3  *
4  * Copyright (c) 2008 yajin (yajin@vm-kernel.org)
5  * Copyright (c) 2009 chenming (chenming@rdc.faw.com.cn)
6  * Copyright (c) 2010 Huacai Chen (zltjiangshi@gmail.com)
7  * This code is licensed under the GNU GPL v2.
8  *
9  * Contributions after 2012-01-13 are licensed under the terms of the
10  * GNU GPL, version 2 or (at your option) any later version.
11  *
12  * VT8231 south bridge support and general clean up to allow it
13  * Copyright (c) 2018-2020 BALATON Zoltan
14  */
15 
16 #include "qemu/osdep.h"
17 #include "hw/isa/vt82c686.h"
18 #include "hw/pci/pci.h"
19 #include "hw/qdev-properties.h"
20 #include "hw/isa/isa.h"
21 #include "hw/isa/superio.h"
22 #include "hw/intc/i8259.h"
23 #include "hw/irq.h"
24 #include "hw/dma/i8257.h"
25 #include "hw/timer/i8254.h"
26 #include "hw/rtc/mc146818rtc.h"
27 #include "migration/vmstate.h"
28 #include "hw/isa/apm.h"
29 #include "hw/acpi/acpi.h"
30 #include "hw/i2c/pm_smbus.h"
31 #include "qapi/error.h"
32 #include "qemu/log.h"
33 #include "qemu/module.h"
34 #include "qemu/range.h"
35 #include "qemu/timer.h"
36 #include "exec/address-spaces.h"
37 #include "trace.h"
38 
39 #define TYPE_VIA_PM "via-pm"
40 OBJECT_DECLARE_SIMPLE_TYPE(ViaPMState, VIA_PM)
41 
42 struct ViaPMState {
43     PCIDevice dev;
44     MemoryRegion io;
45     ACPIREGS ar;
46     APMState apm;
47     PMSMBus smb;
48 };
49 
50 static void pm_io_space_update(ViaPMState *s)
51 {
52     uint32_t pmbase = pci_get_long(s->dev.config + 0x48) & 0xff80UL;
53 
54     memory_region_transaction_begin();
55     memory_region_set_address(&s->io, pmbase);
56     memory_region_set_enabled(&s->io, s->dev.config[0x41] & BIT(7));
57     memory_region_transaction_commit();
58 }
59 
60 static void smb_io_space_update(ViaPMState *s)
61 {
62     uint32_t smbase = pci_get_long(s->dev.config + 0x90) & 0xfff0UL;
63 
64     memory_region_transaction_begin();
65     memory_region_set_address(&s->smb.io, smbase);
66     memory_region_set_enabled(&s->smb.io, s->dev.config[0xd2] & BIT(0));
67     memory_region_transaction_commit();
68 }
69 
70 static int vmstate_acpi_post_load(void *opaque, int version_id)
71 {
72     ViaPMState *s = opaque;
73 
74     pm_io_space_update(s);
75     smb_io_space_update(s);
76     return 0;
77 }
78 
79 static const VMStateDescription vmstate_acpi = {
80     .name = "vt82c686b_pm",
81     .version_id = 1,
82     .minimum_version_id = 1,
83     .post_load = vmstate_acpi_post_load,
84     .fields = (VMStateField[]) {
85         VMSTATE_PCI_DEVICE(dev, ViaPMState),
86         VMSTATE_UINT16(ar.pm1.evt.sts, ViaPMState),
87         VMSTATE_UINT16(ar.pm1.evt.en, ViaPMState),
88         VMSTATE_UINT16(ar.pm1.cnt.cnt, ViaPMState),
89         VMSTATE_STRUCT(apm, ViaPMState, 0, vmstate_apm, APMState),
90         VMSTATE_TIMER_PTR(ar.tmr.timer, ViaPMState),
91         VMSTATE_INT64(ar.tmr.overflow_time, ViaPMState),
92         VMSTATE_END_OF_LIST()
93     }
94 };
95 
96 static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len)
97 {
98     ViaPMState *s = VIA_PM(d);
99 
100     trace_via_pm_write(addr, val, len);
101     pci_default_write_config(d, addr, val, len);
102     if (ranges_overlap(addr, len, 0x48, 4)) {
103         uint32_t v = pci_get_long(s->dev.config + 0x48);
104         pci_set_long(s->dev.config + 0x48, (v & 0xff80UL) | 1);
105     }
106     if (range_covers_byte(addr, len, 0x41)) {
107         pm_io_space_update(s);
108     }
109     if (ranges_overlap(addr, len, 0x90, 4)) {
110         uint32_t v = pci_get_long(s->dev.config + 0x90);
111         pci_set_long(s->dev.config + 0x90, (v & 0xfff0UL) | 1);
112     }
113     if (range_covers_byte(addr, len, 0xd2)) {
114         s->dev.config[0xd2] &= 0xf;
115         smb_io_space_update(s);
116     }
117 }
118 
119 static void pm_io_write(void *op, hwaddr addr, uint64_t data, unsigned size)
120 {
121     trace_via_pm_io_write(addr, data, size);
122 }
123 
124 static uint64_t pm_io_read(void *op, hwaddr addr, unsigned size)
125 {
126     trace_via_pm_io_read(addr, 0, size);
127     return 0;
128 }
129 
130 static const MemoryRegionOps pm_io_ops = {
131     .read = pm_io_read,
132     .write = pm_io_write,
133     .endianness = DEVICE_NATIVE_ENDIAN,
134     .impl = {
135         .min_access_size = 1,
136         .max_access_size = 1,
137     },
138 };
139 
140 static void pm_update_sci(ViaPMState *s)
141 {
142     int sci_level, pmsts;
143 
144     pmsts = acpi_pm1_evt_get_sts(&s->ar);
145     sci_level = (((pmsts & s->ar.pm1.evt.en) &
146                   (ACPI_BITMASK_RT_CLOCK_ENABLE |
147                    ACPI_BITMASK_POWER_BUTTON_ENABLE |
148                    ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
149                    ACPI_BITMASK_TIMER_ENABLE)) != 0);
150     if (pci_get_byte(s->dev.config + PCI_INTERRUPT_PIN)) {
151         /*
152          * FIXME:
153          * Fix device model that realizes this PM device and remove
154          * this work around.
155          * The device model should wire SCI and setup
156          * PCI_INTERRUPT_PIN properly.
157          * If PIN# = 0(interrupt pin isn't used), don't raise SCI as
158          * work around.
159          */
160         pci_set_irq(&s->dev, sci_level);
161     }
162     /* schedule a timer interruption if needed */
163     acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
164                        !(pmsts & ACPI_BITMASK_TIMER_STATUS));
165 }
166 
167 static void pm_tmr_timer(ACPIREGS *ar)
168 {
169     ViaPMState *s = container_of(ar, ViaPMState, ar);
170     pm_update_sci(s);
171 }
172 
173 static void via_pm_reset(DeviceState *d)
174 {
175     ViaPMState *s = VIA_PM(d);
176 
177     memset(s->dev.config + PCI_CONFIG_HEADER_SIZE, 0,
178            PCI_CONFIG_SPACE_SIZE - PCI_CONFIG_HEADER_SIZE);
179     /* Power Management IO base */
180     pci_set_long(s->dev.config + 0x48, 1);
181     /* SMBus IO base */
182     pci_set_long(s->dev.config + 0x90, 1);
183 
184     acpi_pm1_evt_reset(&s->ar);
185     acpi_pm1_cnt_reset(&s->ar);
186     acpi_pm_tmr_reset(&s->ar);
187     pm_update_sci(s);
188 
189     pm_io_space_update(s);
190     smb_io_space_update(s);
191 }
192 
193 static void via_pm_realize(PCIDevice *dev, Error **errp)
194 {
195     ViaPMState *s = VIA_PM(dev);
196 
197     pci_set_word(dev->config + PCI_STATUS, PCI_STATUS_FAST_BACK |
198                  PCI_STATUS_DEVSEL_MEDIUM);
199 
200     pm_smbus_init(DEVICE(s), &s->smb, false);
201     memory_region_add_subregion(pci_address_space_io(dev), 0, &s->smb.io);
202     memory_region_set_enabled(&s->smb.io, false);
203 
204     apm_init(dev, &s->apm, NULL, s);
205 
206     memory_region_init_io(&s->io, OBJECT(dev), &pm_io_ops, s, "via-pm", 128);
207     memory_region_add_subregion(pci_address_space_io(dev), 0, &s->io);
208     memory_region_set_enabled(&s->io, false);
209 
210     acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
211     acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
212     acpi_pm1_cnt_init(&s->ar, &s->io, false, false, 2, false);
213 }
214 
215 typedef struct via_pm_init_info {
216     uint16_t device_id;
217 } ViaPMInitInfo;
218 
219 static void via_pm_class_init(ObjectClass *klass, void *data)
220 {
221     DeviceClass *dc = DEVICE_CLASS(klass);
222     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
223     ViaPMInitInfo *info = data;
224 
225     k->realize = via_pm_realize;
226     k->config_write = pm_write_config;
227     k->vendor_id = PCI_VENDOR_ID_VIA;
228     k->device_id = info->device_id;
229     k->class_id = PCI_CLASS_BRIDGE_OTHER;
230     k->revision = 0x40;
231     dc->reset = via_pm_reset;
232     /* Reason: part of VIA south bridge, does not exist stand alone */
233     dc->user_creatable = false;
234     dc->vmsd = &vmstate_acpi;
235 }
236 
237 static const TypeInfo via_pm_info = {
238     .name          = TYPE_VIA_PM,
239     .parent        = TYPE_PCI_DEVICE,
240     .instance_size = sizeof(ViaPMState),
241     .abstract      = true,
242     .interfaces = (InterfaceInfo[]) {
243         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
244         { },
245     },
246 };
247 
248 static const ViaPMInitInfo vt82c686b_pm_init_info = {
249     .device_id = PCI_DEVICE_ID_VIA_82C686B_PM,
250 };
251 
252 static const TypeInfo vt82c686b_pm_info = {
253     .name          = TYPE_VT82C686B_PM,
254     .parent        = TYPE_VIA_PM,
255     .class_init    = via_pm_class_init,
256     .class_data    = (void *)&vt82c686b_pm_init_info,
257 };
258 
259 static const ViaPMInitInfo vt8231_pm_init_info = {
260     .device_id = PCI_DEVICE_ID_VIA_8231_PM,
261 };
262 
263 static const TypeInfo vt8231_pm_info = {
264     .name          = TYPE_VT8231_PM,
265     .parent        = TYPE_VIA_PM,
266     .class_init    = via_pm_class_init,
267     .class_data    = (void *)&vt8231_pm_init_info,
268 };
269 
270 
271 #define TYPE_VIA_SUPERIO "via-superio"
272 OBJECT_DECLARE_SIMPLE_TYPE(ViaSuperIOState, VIA_SUPERIO)
273 
274 struct ViaSuperIOState {
275     ISASuperIODevice superio;
276     uint8_t regs[0x100];
277     const MemoryRegionOps *io_ops;
278     MemoryRegion io;
279 };
280 
281 static inline void via_superio_io_enable(ViaSuperIOState *s, bool enable)
282 {
283     memory_region_set_enabled(&s->io, enable);
284 }
285 
286 static void via_superio_realize(DeviceState *d, Error **errp)
287 {
288     ViaSuperIOState *s = VIA_SUPERIO(d);
289     ISASuperIOClass *ic = ISA_SUPERIO_GET_CLASS(s);
290     Error *local_err = NULL;
291 
292     assert(s->io_ops);
293     ic->parent_realize(d, &local_err);
294     if (local_err) {
295         error_propagate(errp, local_err);
296         return;
297     }
298     memory_region_init_io(&s->io, OBJECT(d), s->io_ops, s, "via-superio", 2);
299     memory_region_set_enabled(&s->io, false);
300     /* The floppy also uses 0x3f0 and 0x3f1 but this seems to work anyway */
301     memory_region_add_subregion(isa_address_space_io(ISA_DEVICE(s)), 0x3f0,
302                                 &s->io);
303 }
304 
305 static uint64_t via_superio_cfg_read(void *opaque, hwaddr addr, unsigned size)
306 {
307     ViaSuperIOState *sc = opaque;
308     uint8_t idx = sc->regs[0];
309     uint8_t val = sc->regs[idx];
310 
311     if (addr == 0) {
312         return idx;
313     }
314     if (addr == 1 && idx == 0) {
315         val = 0; /* reading reg 0 where we store index value */
316     }
317     trace_via_superio_read(idx, val);
318     return val;
319 }
320 
321 static void via_superio_class_init(ObjectClass *klass, void *data)
322 {
323     DeviceClass *dc = DEVICE_CLASS(klass);
324     ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass);
325 
326     sc->parent_realize = dc->realize;
327     dc->realize = via_superio_realize;
328 }
329 
330 static const TypeInfo via_superio_info = {
331     .name          = TYPE_VIA_SUPERIO,
332     .parent        = TYPE_ISA_SUPERIO,
333     .instance_size = sizeof(ViaSuperIOState),
334     .class_size    = sizeof(ISASuperIOClass),
335     .class_init    = via_superio_class_init,
336     .abstract      = true,
337 };
338 
339 #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio"
340 
341 static void vt82c686b_superio_cfg_write(void *opaque, hwaddr addr,
342                                         uint64_t data, unsigned size)
343 {
344     ViaSuperIOState *sc = opaque;
345     uint8_t idx = sc->regs[0];
346 
347     if (addr == 0) { /* config index register */
348         sc->regs[0] = data;
349         return;
350     }
351 
352     /* config data register */
353     trace_via_superio_write(idx, data);
354     switch (idx) {
355     case 0x00 ... 0xdf:
356     case 0xe4:
357     case 0xe5:
358     case 0xe9 ... 0xed:
359     case 0xf3:
360     case 0xf5:
361     case 0xf7:
362     case 0xf9 ... 0xfb:
363     case 0xfd ... 0xff:
364         /* ignore write to read only registers */
365         return;
366     /* case 0xe6 ... 0xe8: Should set base port of parallel and serial */
367     default:
368         qemu_log_mask(LOG_UNIMP,
369                       "via_superio_cfg: unimplemented register 0x%x\n", idx);
370         break;
371     }
372     sc->regs[idx] = data;
373 }
374 
375 static const MemoryRegionOps vt82c686b_superio_cfg_ops = {
376     .read = via_superio_cfg_read,
377     .write = vt82c686b_superio_cfg_write,
378     .endianness = DEVICE_NATIVE_ENDIAN,
379     .impl = {
380         .min_access_size = 1,
381         .max_access_size = 1,
382     },
383 };
384 
385 static void vt82c686b_superio_reset(DeviceState *dev)
386 {
387     ViaSuperIOState *s = VIA_SUPERIO(dev);
388 
389     memset(s->regs, 0, sizeof(s->regs));
390     /* Device ID */
391     vt82c686b_superio_cfg_write(s, 0, 0xe0, 1);
392     vt82c686b_superio_cfg_write(s, 1, 0x3c, 1);
393     /* Function select - all disabled */
394     vt82c686b_superio_cfg_write(s, 0, 0xe2, 1);
395     vt82c686b_superio_cfg_write(s, 1, 0x03, 1);
396     /* Floppy ctrl base addr 0x3f0-7 */
397     vt82c686b_superio_cfg_write(s, 0, 0xe3, 1);
398     vt82c686b_superio_cfg_write(s, 1, 0xfc, 1);
399     /* Parallel port base addr 0x378-f */
400     vt82c686b_superio_cfg_write(s, 0, 0xe6, 1);
401     vt82c686b_superio_cfg_write(s, 1, 0xde, 1);
402     /* Serial port 1 base addr 0x3f8-f */
403     vt82c686b_superio_cfg_write(s, 0, 0xe7, 1);
404     vt82c686b_superio_cfg_write(s, 1, 0xfe, 1);
405     /* Serial port 2 base addr 0x2f8-f */
406     vt82c686b_superio_cfg_write(s, 0, 0xe8, 1);
407     vt82c686b_superio_cfg_write(s, 1, 0xbe, 1);
408 
409     vt82c686b_superio_cfg_write(s, 0, 0, 1);
410 }
411 
412 static void vt82c686b_superio_init(Object *obj)
413 {
414     VIA_SUPERIO(obj)->io_ops = &vt82c686b_superio_cfg_ops;
415 }
416 
417 static void vt82c686b_superio_class_init(ObjectClass *klass, void *data)
418 {
419     DeviceClass *dc = DEVICE_CLASS(klass);
420     ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass);
421 
422     dc->reset = vt82c686b_superio_reset;
423     sc->serial.count = 2;
424     sc->parallel.count = 1;
425     sc->ide.count = 0; /* emulated by via-ide */
426     sc->floppy.count = 1;
427 }
428 
429 static const TypeInfo vt82c686b_superio_info = {
430     .name          = TYPE_VT82C686B_SUPERIO,
431     .parent        = TYPE_VIA_SUPERIO,
432     .instance_size = sizeof(ViaSuperIOState),
433     .instance_init = vt82c686b_superio_init,
434     .class_size    = sizeof(ISASuperIOClass),
435     .class_init    = vt82c686b_superio_class_init,
436 };
437 
438 
439 #define TYPE_VT8231_SUPERIO "vt8231-superio"
440 
441 static void vt8231_superio_cfg_write(void *opaque, hwaddr addr,
442                                      uint64_t data, unsigned size)
443 {
444     ViaSuperIOState *sc = opaque;
445     uint8_t idx = sc->regs[0];
446 
447     if (addr == 0) { /* config index register */
448         sc->regs[0] = data;
449         return;
450     }
451 
452     /* config data register */
453     trace_via_superio_write(idx, data);
454     switch (idx) {
455     case 0x00 ... 0xdf:
456     case 0xe7 ... 0xef:
457     case 0xf0 ... 0xf1:
458     case 0xf5:
459     case 0xf8:
460     case 0xfd:
461         /* ignore write to read only registers */
462         return;
463     default:
464         qemu_log_mask(LOG_UNIMP,
465                       "via_superio_cfg: unimplemented register 0x%x\n", idx);
466         break;
467     }
468     sc->regs[idx] = data;
469 }
470 
471 static const MemoryRegionOps vt8231_superio_cfg_ops = {
472     .read = via_superio_cfg_read,
473     .write = vt8231_superio_cfg_write,
474     .endianness = DEVICE_NATIVE_ENDIAN,
475     .impl = {
476         .min_access_size = 1,
477         .max_access_size = 1,
478     },
479 };
480 
481 static void vt8231_superio_reset(DeviceState *dev)
482 {
483     ViaSuperIOState *s = VIA_SUPERIO(dev);
484 
485     memset(s->regs, 0, sizeof(s->regs));
486     /* Device ID */
487     s->regs[0xf0] = 0x3c;
488     /* Device revision */
489     s->regs[0xf1] = 0x01;
490     /* Function select - all disabled */
491     vt8231_superio_cfg_write(s, 0, 0xf2, 1);
492     vt8231_superio_cfg_write(s, 1, 0x03, 1);
493     /* Serial port base addr */
494     vt8231_superio_cfg_write(s, 0, 0xf4, 1);
495     vt8231_superio_cfg_write(s, 1, 0xfe, 1);
496     /* Parallel port base addr */
497     vt8231_superio_cfg_write(s, 0, 0xf6, 1);
498     vt8231_superio_cfg_write(s, 1, 0xde, 1);
499     /* Floppy ctrl base addr */
500     vt8231_superio_cfg_write(s, 0, 0xf7, 1);
501     vt8231_superio_cfg_write(s, 1, 0xfc, 1);
502 
503     vt8231_superio_cfg_write(s, 0, 0, 1);
504 }
505 
506 static void vt8231_superio_init(Object *obj)
507 {
508     VIA_SUPERIO(obj)->io_ops = &vt8231_superio_cfg_ops;
509 }
510 
511 static uint16_t vt8231_superio_serial_iobase(ISASuperIODevice *sio,
512                                              uint8_t index)
513 {
514         return 0x2f8; /* FIXME: This should be settable via registers f2-f4 */
515 }
516 
517 static void vt8231_superio_class_init(ObjectClass *klass, void *data)
518 {
519     DeviceClass *dc = DEVICE_CLASS(klass);
520     ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass);
521 
522     dc->reset = vt8231_superio_reset;
523     sc->serial.count = 1;
524     sc->serial.get_iobase = vt8231_superio_serial_iobase;
525     sc->parallel.count = 1;
526     sc->ide.count = 0; /* emulated by via-ide */
527     sc->floppy.count = 1;
528 }
529 
530 static const TypeInfo vt8231_superio_info = {
531     .name          = TYPE_VT8231_SUPERIO,
532     .parent        = TYPE_VIA_SUPERIO,
533     .instance_size = sizeof(ViaSuperIOState),
534     .instance_init = vt8231_superio_init,
535     .class_size    = sizeof(ISASuperIOClass),
536     .class_init    = vt8231_superio_class_init,
537 };
538 
539 
540 #define TYPE_VIA_ISA "via-isa"
541 OBJECT_DECLARE_SIMPLE_TYPE(ViaISAState, VIA_ISA)
542 
543 struct ViaISAState {
544     PCIDevice dev;
545     qemu_irq cpu_intr;
546     ViaSuperIOState *via_sio;
547 };
548 
549 static const VMStateDescription vmstate_via = {
550     .name = "via-isa",
551     .version_id = 1,
552     .minimum_version_id = 1,
553     .fields = (VMStateField[]) {
554         VMSTATE_PCI_DEVICE(dev, ViaISAState),
555         VMSTATE_END_OF_LIST()
556     }
557 };
558 
559 static const TypeInfo via_isa_info = {
560     .name          = TYPE_VIA_ISA,
561     .parent        = TYPE_PCI_DEVICE,
562     .instance_size = sizeof(ViaISAState),
563     .abstract      = true,
564     .interfaces    = (InterfaceInfo[]) {
565         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
566         { },
567     },
568 };
569 
570 static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
571 {
572     ViaISAState *s = opaque;
573     qemu_set_irq(s->cpu_intr, level);
574 }
575 
576 /* TYPE_VT82C686B_ISA */
577 
578 static void vt82c686b_write_config(PCIDevice *d, uint32_t addr,
579                                    uint32_t val, int len)
580 {
581     ViaISAState *s = VIA_ISA(d);
582 
583     trace_via_isa_write(addr, val, len);
584     pci_default_write_config(d, addr, val, len);
585     if (addr == 0x85) {
586         /* BIT(1): enable or disable superio config io ports */
587         via_superio_io_enable(s->via_sio, val & BIT(1));
588     }
589 }
590 
591 static void vt82c686b_isa_reset(DeviceState *dev)
592 {
593     ViaISAState *s = VIA_ISA(dev);
594     uint8_t *pci_conf = s->dev.config;
595 
596     pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
597     pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
598                  PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
599     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
600 
601     pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */
602     pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
603     pci_conf[0x4f] = 0x03; /* DMA/Master Mem Access Control 3 */
604     pci_conf[0x50] = 0x2d; /* PnP DMA Request Control */
605     pci_conf[0x59] = 0x04;
606     pci_conf[0x5a] = 0x04; /* KBC/RTC Control*/
607     pci_conf[0x5f] = 0x04;
608     pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */
609 }
610 
611 static void vt82c686b_realize(PCIDevice *d, Error **errp)
612 {
613     ViaISAState *s = VIA_ISA(d);
614     DeviceState *dev = DEVICE(d);
615     ISABus *isa_bus;
616     qemu_irq *isa_irq;
617     int i;
618 
619     qdev_init_gpio_out(dev, &s->cpu_intr, 1);
620     isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
621     isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d),
622                           &error_fatal);
623     isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq));
624     i8254_pit_init(isa_bus, 0x40, 0, NULL);
625     i8257_dma_init(isa_bus, 0);
626     s->via_sio = VIA_SUPERIO(isa_create_simple(isa_bus,
627                                                TYPE_VT82C686B_SUPERIO));
628     mc146818_rtc_init(isa_bus, 2000, NULL);
629 
630     for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) {
631         if (i < PCI_COMMAND || i >= PCI_REVISION_ID) {
632             d->wmask[i] = 0;
633         }
634     }
635 }
636 
637 static void vt82c686b_class_init(ObjectClass *klass, void *data)
638 {
639     DeviceClass *dc = DEVICE_CLASS(klass);
640     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
641 
642     k->realize = vt82c686b_realize;
643     k->config_write = vt82c686b_write_config;
644     k->vendor_id = PCI_VENDOR_ID_VIA;
645     k->device_id = PCI_DEVICE_ID_VIA_82C686B_ISA;
646     k->class_id = PCI_CLASS_BRIDGE_ISA;
647     k->revision = 0x40;
648     dc->reset = vt82c686b_isa_reset;
649     dc->desc = "ISA bridge";
650     dc->vmsd = &vmstate_via;
651     /* Reason: part of VIA VT82C686 southbridge, needs to be wired up */
652     dc->user_creatable = false;
653 }
654 
655 static const TypeInfo vt82c686b_isa_info = {
656     .name          = TYPE_VT82C686B_ISA,
657     .parent        = TYPE_VIA_ISA,
658     .instance_size = sizeof(ViaISAState),
659     .class_init    = vt82c686b_class_init,
660 };
661 
662 /* TYPE_VT8231_ISA */
663 
664 static void vt8231_write_config(PCIDevice *d, uint32_t addr,
665                                 uint32_t val, int len)
666 {
667     ViaISAState *s = VIA_ISA(d);
668 
669     trace_via_isa_write(addr, val, len);
670     pci_default_write_config(d, addr, val, len);
671     if (addr == 0x50) {
672         /* BIT(2): enable or disable superio config io ports */
673         via_superio_io_enable(s->via_sio, val & BIT(2));
674     }
675 }
676 
677 static void vt8231_isa_reset(DeviceState *dev)
678 {
679     ViaISAState *s = VIA_ISA(dev);
680     uint8_t *pci_conf = s->dev.config;
681 
682     pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
683     pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
684                  PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
685     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
686 
687     pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */
688     pci_conf[0x67] = 0x08; /* Fast IR Config */
689     pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */
690 }
691 
692 static void vt8231_realize(PCIDevice *d, Error **errp)
693 {
694     ViaISAState *s = VIA_ISA(d);
695     DeviceState *dev = DEVICE(d);
696     ISABus *isa_bus;
697     qemu_irq *isa_irq;
698     int i;
699 
700     qdev_init_gpio_out(dev, &s->cpu_intr, 1);
701     isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
702     isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d),
703                           &error_fatal);
704     isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq));
705     i8254_pit_init(isa_bus, 0x40, 0, NULL);
706     i8257_dma_init(isa_bus, 0);
707     s->via_sio = VIA_SUPERIO(isa_create_simple(isa_bus, TYPE_VT8231_SUPERIO));
708     mc146818_rtc_init(isa_bus, 2000, NULL);
709 
710     for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) {
711         if (i < PCI_COMMAND || i >= PCI_REVISION_ID) {
712             d->wmask[i] = 0;
713         }
714     }
715 }
716 
717 static void vt8231_class_init(ObjectClass *klass, void *data)
718 {
719     DeviceClass *dc = DEVICE_CLASS(klass);
720     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
721 
722     k->realize = vt8231_realize;
723     k->config_write = vt8231_write_config;
724     k->vendor_id = PCI_VENDOR_ID_VIA;
725     k->device_id = PCI_DEVICE_ID_VIA_8231_ISA;
726     k->class_id = PCI_CLASS_BRIDGE_ISA;
727     k->revision = 0x10;
728     dc->reset = vt8231_isa_reset;
729     dc->desc = "ISA bridge";
730     dc->vmsd = &vmstate_via;
731     /* Reason: part of VIA VT8231 southbridge, needs to be wired up */
732     dc->user_creatable = false;
733 }
734 
735 static const TypeInfo vt8231_isa_info = {
736     .name          = TYPE_VT8231_ISA,
737     .parent        = TYPE_VIA_ISA,
738     .instance_size = sizeof(ViaISAState),
739     .class_init    = vt8231_class_init,
740 };
741 
742 
743 static void vt82c686b_register_types(void)
744 {
745     type_register_static(&via_pm_info);
746     type_register_static(&vt82c686b_pm_info);
747     type_register_static(&vt8231_pm_info);
748     type_register_static(&via_superio_info);
749     type_register_static(&vt82c686b_superio_info);
750     type_register_static(&vt8231_superio_info);
751     type_register_static(&via_isa_info);
752     type_register_static(&vt82c686b_isa_info);
753     type_register_static(&vt8231_isa_info);
754 }
755 
756 type_init(vt82c686b_register_types)
757