diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 30fe02f4c6..fe8961b057 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -26,112 +26,7 @@ #include "exec/address-spaces.h" #include "trace.h" -typedef struct SuperIOConfig { - uint8_t regs[0x100]; - uint8_t index; - MemoryRegion io; -} SuperIOConfig; - -struct VT82C686BISAState { - PCIDevice dev; - SuperIOConfig superio_cfg; -}; - -OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) - -static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, - unsigned size) -{ - SuperIOConfig *sc = opaque; - - if (addr == 0x3f0) { /* config index register */ - sc->index = data & 0xff; - } else { - bool can_write = true; - /* 0x3f1, config data register */ - trace_via_superio_write(sc->index, data & 0xff); - switch (sc->index) { - case 0x00 ... 0xdf: - case 0xe4: - case 0xe5: - case 0xe9 ... 0xed: - case 0xf3: - case 0xf5: - case 0xf7: - case 0xf9 ... 0xfb: - case 0xfd ... 0xff: - can_write = false; - break; - /* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ - default: - break; - - } - if (can_write) { - sc->regs[sc->index] = data & 0xff; - } - } -} - -static uint64_t superio_cfg_read(void *opaque, hwaddr addr, unsigned size) -{ - SuperIOConfig *sc = opaque; - uint8_t val = sc->regs[sc->index]; - - trace_via_superio_read(sc->index, val); - return val; -} - -static const MemoryRegionOps superio_cfg_ops = { - .read = superio_cfg_read, - .write = superio_cfg_write, - .endianness = DEVICE_NATIVE_ENDIAN, - .impl = { - .min_access_size = 1, - .max_access_size = 1, - }, -}; - -static void vt82c686b_isa_reset(DeviceState *dev) -{ - VT82C686BISAState *s = VT82C686B_ISA(dev); - uint8_t *pci_conf = s->dev.config; - - pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); - pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL); - pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); - - pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */ - pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */ - pci_conf[0x4f] = 0x03; /* DMA/Master Mem Access Control 3 */ - pci_conf[0x50] = 0x2d; /* PnP DMA Request Control */ - pci_conf[0x59] = 0x04; - pci_conf[0x5a] = 0x04; /* KBC/RTC Control*/ - pci_conf[0x5f] = 0x04; - pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ - - s->superio_cfg.regs[0xe0] = 0x3c; /* Device ID */ - s->superio_cfg.regs[0xe2] = 0x03; /* Function select */ - s->superio_cfg.regs[0xe3] = 0xfc; /* Floppy ctrl base addr */ - s->superio_cfg.regs[0xe6] = 0xde; /* Parallel port base addr */ - s->superio_cfg.regs[0xe7] = 0xfe; /* Serial port 1 base addr */ - s->superio_cfg.regs[0xe8] = 0xbe; /* Serial port 2 base addr */ -} - -/* write config pci function0 registers. PCI-ISA bridge */ -static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, - uint32_t val, int len) -{ - VT82C686BISAState *s = VT82C686B_ISA(d); - - trace_via_isa_write(addr, val, len); - pci_default_write_config(d, addr, val, len); - if (addr == 0x85) { - /* BIT(1): enable or disable superio config io ports */ - memory_region_set_enabled(&s->superio_cfg.io, val & BIT(1)); - } -} +OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) struct VT686PMState { PCIDevice dev; @@ -142,30 +37,6 @@ struct VT686PMState { uint32_t smb_io_base; }; -OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) - -static void pm_update_sci(VT686PMState *s) -{ - int sci_level, pmsts; - - pmsts = acpi_pm1_evt_get_sts(&s->ar); - sci_level = (((pmsts & s->ar.pm1.evt.en) & - (ACPI_BITMASK_RT_CLOCK_ENABLE | - ACPI_BITMASK_POWER_BUTTON_ENABLE | - ACPI_BITMASK_GLOBAL_LOCK_ENABLE | - ACPI_BITMASK_TIMER_ENABLE)) != 0); - pci_set_irq(&s->dev, sci_level); - /* schedule a timer interruption if needed */ - acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) && - !(pmsts & ACPI_BITMASK_TIMER_STATUS)); -} - -static void pm_tmr_timer(ACPIREGS *ar) -{ - VT686PMState *s = container_of(ar, VT686PMState, ar); - pm_update_sci(s); -} - static void pm_io_space_update(VT686PMState *s) { uint32_t pm_io_base; @@ -179,12 +50,6 @@ static void pm_io_space_update(VT686PMState *s) memory_region_transaction_commit(); } -static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) -{ - trace_via_pm_write(addr, val, len); - pci_default_write_config(d, addr, val, len); -} - static int vmstate_acpi_post_load(void *opaque, int version_id) { VT686PMState *s = opaque; @@ -210,7 +75,34 @@ static const VMStateDescription vmstate_acpi = { } }; -/* vt82c686 pm init */ +static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) +{ + trace_via_pm_write(addr, val, len); + pci_default_write_config(d, addr, val, len); +} + +static void pm_update_sci(VT686PMState *s) +{ + int sci_level, pmsts; + + pmsts = acpi_pm1_evt_get_sts(&s->ar); + sci_level = (((pmsts & s->ar.pm1.evt.en) & + (ACPI_BITMASK_RT_CLOCK_ENABLE | + ACPI_BITMASK_POWER_BUTTON_ENABLE | + ACPI_BITMASK_GLOBAL_LOCK_ENABLE | + ACPI_BITMASK_TIMER_ENABLE)) != 0); + pci_set_irq(&s->dev, sci_level); + /* schedule a timer interruption if needed */ + acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) && + !(pmsts & ACPI_BITMASK_TIMER_STATUS)); +} + +static void pm_tmr_timer(ACPIREGS *ar) +{ + VT686PMState *s = container_of(ar, VT686PMState, ar); + pm_update_sci(s); +} + static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) { VT686PMState *s = VT82C686B_PM(dev); @@ -276,6 +168,87 @@ static const TypeInfo via_pm_info = { }, }; + +typedef struct SuperIOConfig { + uint8_t regs[0x100]; + uint8_t index; + MemoryRegion io; +} SuperIOConfig; + +static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, + unsigned size) +{ + SuperIOConfig *sc = opaque; + + if (addr == 0x3f0) { /* config index register */ + sc->index = data & 0xff; + } else { + bool can_write = true; + /* 0x3f1, config data register */ + trace_via_superio_write(sc->index, data & 0xff); + switch (sc->index) { + case 0x00 ... 0xdf: + case 0xe4: + case 0xe5: + case 0xe9 ... 0xed: + case 0xf3: + case 0xf5: + case 0xf7: + case 0xf9 ... 0xfb: + case 0xfd ... 0xff: + can_write = false; + break; + /* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ + default: + break; + + } + if (can_write) { + sc->regs[sc->index] = data & 0xff; + } + } +} + +static uint64_t superio_cfg_read(void *opaque, hwaddr addr, unsigned size) +{ + SuperIOConfig *sc = opaque; + uint8_t val = sc->regs[sc->index]; + + trace_via_superio_read(sc->index, val); + return val; +} + +static const MemoryRegionOps superio_cfg_ops = { + .read = superio_cfg_read, + .write = superio_cfg_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + + +OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) + +struct VT82C686BISAState { + PCIDevice dev; + SuperIOConfig superio_cfg; +}; + +static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, + uint32_t val, int len) +{ + VT82C686BISAState *s = VT82C686B_ISA(d); + + trace_via_isa_write(addr, val, len); + pci_default_write_config(d, addr, val, len); + if (addr == 0x85) { + /* BIT(1): enable or disable superio config io ports */ + memory_region_set_enabled(&s->superio_cfg.io, val & BIT(1)); + } +} + static const VMStateDescription vmstate_via = { .name = "vt82c686b", .version_id = 1, @@ -286,7 +259,33 @@ static const VMStateDescription vmstate_via = { } }; -/* init the PCI-to-ISA bridge */ +static void vt82c686b_isa_reset(DeviceState *dev) +{ + VT82C686BISAState *s = VT82C686B_ISA(dev); + uint8_t *pci_conf = s->dev.config; + + pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); + pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL); + pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); + + pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */ + pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */ + pci_conf[0x4f] = 0x03; /* DMA/Master Mem Access Control 3 */ + pci_conf[0x50] = 0x2d; /* PnP DMA Request Control */ + pci_conf[0x59] = 0x04; + pci_conf[0x5a] = 0x04; /* KBC/RTC Control*/ + pci_conf[0x5f] = 0x04; + pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ + + s->superio_cfg.regs[0xe0] = 0x3c; /* Device ID */ + s->superio_cfg.regs[0xe2] = 0x03; /* Function select */ + s->superio_cfg.regs[0xe3] = 0xfc; /* Floppy ctrl base addr */ + s->superio_cfg.regs[0xe6] = 0xde; /* Parallel port base addr */ + s->superio_cfg.regs[0xe7] = 0xfe; /* Serial port 1 base addr */ + s->superio_cfg.regs[0xe8] = 0xbe; /* Serial port 2 base addr */ +} + static void vt82c686b_realize(PCIDevice *d, Error **errp) { VT82C686BISAState *s = VT82C686B_ISA(d); @@ -354,6 +353,7 @@ static const TypeInfo via_info = { }, }; + static void vt82c686b_superio_class_init(ObjectClass *klass, void *data) { ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); @@ -372,11 +372,12 @@ static const TypeInfo via_superio_info = { .class_init = vt82c686b_superio_class_init, }; + static void vt82c686b_register_types(void) { type_register_static(&via_pm_info); - type_register_static(&via_superio_info); type_register_static(&via_info); + type_register_static(&via_superio_info); } type_init(vt82c686b_register_types)