* GNU GPL, version 2 or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "hw/hw.h"
-#include "hw/i386/pc.h"
#include "hw/isa/vt82c686.h"
#include "hw/i2c/i2c.h"
-#include "hw/i2c/smbus.h"
#include "hw/pci/pci.h"
#include "hw/isa/isa.h"
+#include "hw/isa/superio.h"
#include "hw/sysbus.h"
#include "hw/mips/mips.h"
#include "hw/isa/apm.h"
#include "hw/acpi/acpi.h"
#include "hw/i2c/pm_smbus.h"
#include "sysemu/sysemu.h"
+#include "qemu/module.h"
#include "qemu/timer.h"
#include "exec/address-spaces.h"
//#define DEBUG_VT82C686B
#ifdef DEBUG_VT82C686B
-#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__)
#else
#define DPRINTF(fmt, ...)
#endif
typedef struct SuperIOConfig
{
- uint8_t config[0xff];
+ uint8_t config[0x100];
uint8_t index;
uint8_t data;
} SuperIOConfig;
SuperIOConfig superio_conf;
} VT82C686BState;
+#define TYPE_VT82C686B_DEVICE "VT82C686B"
+#define VT82C686B_DEVICE(obj) \
+ OBJECT_CHECK(VT82C686BState, (obj), TYPE_VT82C686B_DEVICE)
+
static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data,
unsigned size)
{
- int can_write;
SuperIOConfig *superio_conf = opaque;
DPRINTF("superio_ioport_writeb address 0x%x val 0x%x\n", addr, data);
if (addr == 0x3f0) {
superio_conf->index = data & 0xff;
} else {
+ bool can_write = true;
/* 0x3f1 */
switch (superio_conf->index) {
case 0x00 ... 0xdf:
case 0xf7:
case 0xf9 ... 0xfb:
case 0xfd ... 0xff:
- can_write = 0;
+ can_write = false;
break;
- default:
- can_write = 1;
-
- if (can_write) {
- switch (superio_conf->index) {
- case 0xe7:
- if ((data & 0xff) != 0xfe) {
- DPRINTF("chage uart 1 base. unsupported yet\n");
- }
- break;
- case 0xe8:
- if ((data & 0xff) != 0xbe) {
- DPRINTF("chage uart 2 base. unsupported yet\n");
- }
- break;
-
- default:
- superio_conf->config[superio_conf->index] = data & 0xff;
- }
+ case 0xe7:
+ if ((data & 0xff) != 0xfe) {
+ DPRINTF("change uart 1 base. unsupported yet\n");
+ can_write = false;
+ }
+ break;
+ case 0xe8:
+ if ((data & 0xff) != 0xbe) {
+ DPRINTF("change uart 2 base. unsupported yet\n");
+ can_write = false;
}
+ break;
+ default:
+ break;
+
+ }
+ if (can_write) {
+ superio_conf->config[superio_conf->index] = data & 0xff;
}
- superio_conf->config[superio_conf->index] = data & 0xff;
}
}
{
PCIDevice *d = opaque;
uint8_t *pci_conf = d->config;
- VT82C686BState *vt82c = DO_UPCAST(VT82C686BState, dev, d);
+ VT82C686BState *vt82c = VT82C686B_DEVICE(d);
pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
static void vt82c686b_write_config(PCIDevice * d, uint32_t address,
uint32_t val, int len)
{
- VT82C686BState *vt686 = DO_UPCAST(VT82C686BState, dev, d);
+ VT82C686BState *vt686 = VT82C686B_DEVICE(d);
DPRINTF("vt82c686b_write_config address 0x%x val 0x%x len 0x%x\n",
address, val, len);
PCIDevice dev;
} VT686MC97State;
+#define TYPE_VT82C686B_PM_DEVICE "VT82C686B_PM"
+#define VT82C686B_PM_DEVICE(obj) \
+ OBJECT_CHECK(VT686PMState, (obj), TYPE_VT82C686B_PM_DEVICE)
+
+#define TYPE_VT82C686B_MC97_DEVICE "VT82C686B_MC97"
+#define VT82C686B_MC97_DEVICE(obj) \
+ OBJECT_CHECK(VT686MC97State, (obj), TYPE_VT82C686B_MC97_DEVICE)
+
+#define TYPE_VT82C686B_AC97_DEVICE "VT82C686B_AC97"
+#define VT82C686B_AC97_DEVICE(obj) \
+ OBJECT_CHECK(VT686AC97State, (obj), TYPE_VT82C686B_AC97_DEVICE)
+
static void pm_update_sci(VT686PMState *s)
{
int sci_level, pmsts;
.name = "vt82c686b_pm",
.version_id = 1,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
.post_load = vmstate_acpi_post_load,
- .fields = (VMStateField []) {
+ .fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, VT686PMState),
VMSTATE_UINT16(ar.pm1.evt.sts, VT686PMState),
VMSTATE_UINT16(ar.pm1.evt.en, VT686PMState),
VMSTATE_UINT16(ar.pm1.cnt.cnt, VT686PMState),
VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState),
- VMSTATE_TIMER(ar.tmr.timer, VT686PMState),
+ VMSTATE_TIMER_PTR(ar.tmr.timer, VT686PMState),
VMSTATE_INT64(ar.tmr.overflow_time, VT686PMState),
VMSTATE_END_OF_LIST()
}
* just register a PCI device now, functionalities will be implemented later.
*/
-static int vt82c686b_ac97_initfn(PCIDevice *dev)
+static void vt82c686b_ac97_realize(PCIDevice *dev, Error **errp)
{
- VT686AC97State *s = DO_UPCAST(VT686AC97State, dev, dev);
+ VT686AC97State *s = VT82C686B_AC97_DEVICE(dev);
uint8_t *pci_conf = s->dev.config;
pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE |
pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST |
PCI_STATUS_DEVSEL_MEDIUM);
pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03);
-
- return 0;
}
void vt82c686b_ac97_init(PCIBus *bus, int devfn)
{
PCIDevice *dev;
- dev = pci_create(bus, devfn, "VT82C686B_AC97");
+ dev = pci_create(bus, devfn, TYPE_VT82C686B_AC97_DEVICE);
qdev_init_nofail(&dev->qdev);
}
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = vt82c686b_ac97_initfn;
+ k->realize = vt82c686b_ac97_realize;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_AC97;
k->revision = 0x50;
}
static const TypeInfo via_ac97_info = {
- .name = "VT82C686B_AC97",
+ .name = TYPE_VT82C686B_AC97_DEVICE,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VT686AC97State),
.class_init = via_ac97_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { },
+ },
};
-static int vt82c686b_mc97_initfn(PCIDevice *dev)
+static void vt82c686b_mc97_realize(PCIDevice *dev, Error **errp)
{
- VT686MC97State *s = DO_UPCAST(VT686MC97State, dev, dev);
+ VT686MC97State *s = VT82C686B_MC97_DEVICE(dev);
uint8_t *pci_conf = s->dev.config;
pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE |
PCI_COMMAND_VGA_PALETTE);
pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03);
-
- return 0;
}
void vt82c686b_mc97_init(PCIBus *bus, int devfn)
{
PCIDevice *dev;
- dev = pci_create(bus, devfn, "VT82C686B_MC97");
+ dev = pci_create(bus, devfn, TYPE_VT82C686B_MC97_DEVICE);
qdev_init_nofail(&dev->qdev);
}
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = vt82c686b_mc97_initfn;
+ k->realize = vt82c686b_mc97_realize;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_MC97;
k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
}
static const TypeInfo via_mc97_info = {
- .name = "VT82C686B_MC97",
+ .name = TYPE_VT82C686B_MC97_DEVICE,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VT686MC97State),
.class_init = via_mc97_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { },
+ },
};
/* vt82c686 pm init */
-static int vt82c686b_pm_initfn(PCIDevice *dev)
+static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp)
{
- VT686PMState *s = DO_UPCAST(VT686PMState, dev, dev);
+ VT686PMState *s = VT82C686B_PM_DEVICE(dev);
uint8_t *pci_conf;
pci_conf = s->dev.config;
pci_conf[0x90] = s->smb_io_base | 1;
pci_conf[0x91] = s->smb_io_base >> 8;
pci_conf[0xd2] = 0x90;
- pm_smbus_init(&s->dev.qdev, &s->smb);
+ pm_smbus_init(DEVICE(s), &s->smb, false);
memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io);
apm_init(dev, &s->apm, NULL, s);
acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
- acpi_pm1_cnt_init(&s->ar, &s->io, 2);
-
- return 0;
+ acpi_pm1_cnt_init(&s->ar, &s->io, false, false, 2);
}
I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
PCIDevice *dev;
VT686PMState *s;
- dev = pci_create(bus, devfn, "VT82C686B_PM");
+ dev = pci_create(bus, devfn, TYPE_VT82C686B_PM_DEVICE);
qdev_prop_set_uint32(&dev->qdev, "smb_io_base", smb_io_base);
- s = DO_UPCAST(VT686PMState, dev, dev);
+ s = VT82C686B_PM_DEVICE(dev);
qdev_init_nofail(&dev->qdev);
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = vt82c686b_pm_initfn;
+ k->realize = vt82c686b_pm_realize;
k->config_write = pm_write_config;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_ACPI;
}
static const TypeInfo via_pm_info = {
- .name = "VT82C686B_PM",
+ .name = TYPE_VT82C686B_PM_DEVICE,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VT686PMState),
.class_init = via_pm_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { },
+ },
};
static const VMStateDescription vmstate_via = {
.name = "vt82c686b",
.version_id = 1,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField []) {
+ .fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, VT82C686BState),
VMSTATE_END_OF_LIST()
}
};
/* init the PCI-to-ISA bridge */
-static int vt82c686b_initfn(PCIDevice *d)
+static void vt82c686b_realize(PCIDevice *d, Error **errp)
{
- VT82C686BState *vt82c = DO_UPCAST(VT82C686BState, dev, d);
+ VT82C686BState *vt82c = VT82C686B_DEVICE(d);
uint8_t *pci_conf;
ISABus *isa_bus;
uint8_t *wmask;
int i;
- isa_bus = isa_bus_new(&d->qdev, pci_address_space_io(d));
+ isa_bus = isa_bus_new(DEVICE(d), get_system_memory(),
+ pci_address_space_io(d), errp);
+ if (!isa_bus) {
+ return;
+ }
pci_conf = d->config;
pci_config_set_prog_interface(pci_conf, 0x0);
&vt82c->superio);
qemu_register_reset(vt82c686b_reset, d);
-
- return 0;
}
-ISABus *vt82c686b_init(PCIBus *bus, int devfn)
+ISABus *vt82c686b_isa_init(PCIBus *bus, int devfn)
{
PCIDevice *d;
- d = pci_create_simple_multifunction(bus, devfn, true, "VT82C686B");
+ d = pci_create_simple_multifunction(bus, devfn, true,
+ TYPE_VT82C686B_DEVICE);
return ISA_BUS(qdev_get_child_bus(DEVICE(d), "isa.0"));
}
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = vt82c686b_initfn;
+ k->realize = vt82c686b_realize;
k->config_write = vt82c686b_write_config;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_ISA_BRIDGE;
* Reason: part of VIA VT82C686 southbridge, needs to be wired up,
* e.g. by mips_fulong2e_init()
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo via_info = {
- .name = "VT82C686B",
+ .name = TYPE_VT82C686B_DEVICE,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VT82C686BState),
.class_init = via_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { },
+ },
+};
+
+static void vt82c686b_superio_class_init(ObjectClass *klass, void *data)
+{
+ ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass);
+
+ sc->serial.count = 2;
+ sc->parallel.count = 1;
+ sc->ide.count = 0;
+ sc->floppy.count = 1;
+}
+
+static const TypeInfo via_superio_info = {
+ .name = TYPE_VT82C686B_SUPERIO,
+ .parent = TYPE_ISA_SUPERIO,
+ .instance_size = sizeof(ISASuperIODevice),
+ .class_size = sizeof(ISASuperIOClass),
+ .class_init = vt82c686b_superio_class_init,
};
static void vt82c686b_register_types(void)
type_register_static(&via_ac97_info);
type_register_static(&via_mc97_info);
type_register_static(&via_pm_info);
+ type_register_static(&via_superio_info);
type_register_static(&via_info);
}