@@ -433,6 +433,107 @@ static const TypeInfo vt82c686b_superio_info = {
};
+#define TYPE_VT8231_SUPERIO "vt8231-superio"
+
+static void vt8231_superio_cfg_write(void *opaque, hwaddr addr,
+ uint64_t data, unsigned size)
+{
+ ViaSuperIOState *sc = opaque;
+ uint8_t idx = sc->regs[0];
+
+ if (addr == 0) { /* config index register */
+ sc->regs[0] = data;
+ return;
+ }
+
+ /* config data register */
+ trace_via_superio_write(idx, data);
+ switch (idx) {
+ case 0x00 ... 0xdf:
+ case 0xe7 ... 0xef:
+ case 0xf0 ... 0xf1:
+ case 0xf5:
+ case 0xf8:
+ case 0xfd:
+ /* ignore write to read only registers */
+ return;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "via_superio_cfg: unimplemented register 0x%x\n", idx);
+ break;
+ }
+ sc->regs[idx] = data;
+}
+
+static const MemoryRegionOps vt8231_superio_cfg_ops = {
+ .read = via_superio_cfg_read,
+ .write = vt8231_superio_cfg_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
+};
+
+static void vt8231_superio_reset(DeviceState *dev)
+{
+ ViaSuperIOState *s = VIA_SUPERIO(dev);
+
+ memset(s->regs, 0, sizeof(s->regs));
+ /* Device ID */
+ s->regs[0xf0] = 0x3c;
+ /* Device revision */
+ s->regs[0xf1] = 0x01;
+ /* Function select - all disabled */
+ vt8231_superio_cfg_write(s, 0, 0xf2, 1);
+ vt8231_superio_cfg_write(s, 1, 0x03, 1);
+ /* Serial port base addr */
+ vt8231_superio_cfg_write(s, 0, 0xf4, 1);
+ vt8231_superio_cfg_write(s, 1, 0xfe, 1);
+ /* Parallel port base addr */
+ vt8231_superio_cfg_write(s, 0, 0xf6, 1);
+ vt8231_superio_cfg_write(s, 1, 0xde, 1);
+ /* Floppy ctrl base addr */
+ vt8231_superio_cfg_write(s, 0, 0xf7, 1);
+ vt8231_superio_cfg_write(s, 1, 0xfc, 1);
+
+ vt8231_superio_cfg_write(s, 0, 0, 1);
+}
+
+static void vt8231_superio_init(Object *obj)
+{
+ VIA_SUPERIO(obj)->io_ops = &vt8231_superio_cfg_ops;
+}
+
+static uint16_t vt8231_superio_serial_iobase(ISASuperIODevice *sio,
+ uint8_t index)
+{
+ return 0x2f8; /* FIXME: This should be settable via registers f2-f4 */
+}
+
+static void vt8231_superio_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass);
+
+ dc->reset = vt8231_superio_reset;
+ sc->serial.count = 1;
+ sc->serial.get_iobase = vt8231_superio_serial_iobase;
+ sc->parallel.count = 1;
+ sc->ide.count = 0; /* emulated by via-ide */
+ sc->floppy.count = 1;
+}
+
+static const TypeInfo vt8231_superio_info = {
+ .name = TYPE_VT8231_SUPERIO,
+ .parent = TYPE_VIA_SUPERIO,
+ .instance_size = sizeof(ViaSuperIOState),
+ .instance_init = vt8231_superio_init,
+ .class_size = sizeof(ISASuperIOClass),
+ .class_init = vt8231_superio_class_init,
+};
+
+
OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA)
struct VT82C686BISAState {
@@ -556,6 +657,7 @@ static void vt82c686b_register_types(void)
type_register_static(&vt8231_pm_info);
type_register_static(&via_superio_info);
type_register_static(&vt82c686b_superio_info);
+ type_register_static(&vt8231_superio_info);
type_register_static(&via_info);
}