diff options
-rw-r--r-- | hw/acpi_piix4.c | 5 | ||||
-rw-r--r-- | hw/pm_smbus.c | 17 | ||||
-rw-r--r-- | hw/pm_smbus.h | 3 | ||||
-rw-r--r-- | hw/smbus_ich9.c | 52 | ||||
-rw-r--r-- | hw/vt82c686.c | 6 |
5 files changed, 33 insertions, 50 deletions
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index cf8aa3d7d7..9e6c97ebd3 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -391,8 +391,8 @@ static int piix4_pm_initfn(PCIDevice *dev) pci_conf[0x90] = s->smb_io_base | 1; pci_conf[0x91] = s->smb_io_base >> 8; pci_conf[0xd2] = 0x09; - register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb); - register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb); + pm_smbus_init(&s->dev.qdev, &s->smb); + memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io); memory_region_init(&s->io, "piix4-pm", 64); memory_region_set_enabled(&s->io, false); @@ -406,7 +406,6 @@ static int piix4_pm_initfn(PCIDevice *dev) s->powerdown_notifier.notify = piix4_pm_powerdown_req; qemu_register_powerdown_notifier(&s->powerdown_notifier); - pm_smbus_init(&s->dev.qdev, &s->smb); s->machine_ready.notify = piix4_pm_machine_ready; qemu_add_machine_init_done_notifier(&s->machine_ready); qemu_register_reset(piix4_reset, s); diff --git a/hw/pm_smbus.c b/hw/pm_smbus.c index 5d6046de5a..ea1380ca68 100644 --- a/hw/pm_smbus.c +++ b/hw/pm_smbus.c @@ -94,10 +94,11 @@ static void smb_transaction(PMSMBus *s) s->smb_stat |= 0x04; } -void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) +static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val, + unsigned width) { PMSMBus *s = opaque; - addr &= 0x3f; + SMBUS_DPRINTF("SMB writeb port=0x%04x val=0x%02x\n", addr, val); switch(addr) { case SMBHSTSTS: @@ -131,12 +132,11 @@ void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) } } -uint32_t smb_ioport_readb(void *opaque, uint32_t addr) +static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width) { PMSMBus *s = opaque; uint32_t val; - addr &= 0x3f; switch(addr) { case SMBHSTSTS: val = s->smb_stat; @@ -170,7 +170,16 @@ uint32_t smb_ioport_readb(void *opaque, uint32_t addr) return val; } +static const MemoryRegionOps pm_smbus_ops = { + .read = smb_ioport_readb, + .write = smb_ioport_writeb, + .valid.min_access_size = 1, + .valid.max_access_size = 1, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + void pm_smbus_init(DeviceState *parent, PMSMBus *smb) { smb->smbus = i2c_init_bus(parent, "i2c"); + memory_region_init_io(&smb->io, &pm_smbus_ops, smb, "pm-smbus", 64); } diff --git a/hw/pm_smbus.h b/hw/pm_smbus.h index 4750a409f9..e3069bf7d4 100644 --- a/hw/pm_smbus.h +++ b/hw/pm_smbus.h @@ -3,6 +3,7 @@ typedef struct PMSMBus { i2c_bus *smbus; + MemoryRegion io; uint8_t smb_stat; uint8_t smb_ctl; @@ -15,7 +16,5 @@ typedef struct PMSMBus { } PMSMBus; void pm_smbus_init(DeviceState *parent, PMSMBus *smb); -void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val); -uint32_t smb_ioport_readb(void *opaque, uint32_t addr); #endif /* !PM_SMBUS_H */ diff --git a/hw/smbus_ich9.c b/hw/smbus_ich9.c index 6940583bb6..54e7e1252d 100644 --- a/hw/smbus_ich9.c +++ b/hw/smbus_ich9.c @@ -40,7 +40,6 @@ typedef struct ICH9SMBState { PCIDevice dev; PMSMBus smb; - MemoryRegion mem_bar; } ICH9SMBState; static const VMStateDescription vmstate_ich9_smbus = { @@ -54,42 +53,23 @@ static const VMStateDescription vmstate_ich9_smbus = { } }; -static void ich9_smb_ioport_writeb(void *opaque, hwaddr addr, - uint64_t val, unsigned size) +static void ich9_smbus_write_config(PCIDevice *d, uint32_t address, + uint32_t val, int len) { - ICH9SMBState *s = opaque; - uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC]; + ICH9SMBState *s = ICH9_SMB_DEVICE(d); - if ((hostc & ICH9_SMB_HOSTC_HST_EN) && !(hostc & ICH9_SMB_HOSTC_I2C_EN)) { - uint64_t offset = addr - s->dev.io_regions[ICH9_SMB_SMB_BASE_BAR].addr; - smb_ioport_writeb(&s->smb, offset, val); + pci_default_write_config(d, address, val, len); + if (range_covers_byte(address, len, ICH9_SMB_HOSTC)) { + uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC]; + if ((hostc & ICH9_SMB_HOSTC_HST_EN) && + !(hostc & ICH9_SMB_HOSTC_I2C_EN)) { + memory_region_set_enabled(&s->smb.io, true); + } else { + memory_region_set_enabled(&s->smb.io, false); + } } } -static uint64_t ich9_smb_ioport_readb(void *opaque, hwaddr addr, - unsigned size) -{ - ICH9SMBState *s = opaque; - uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC]; - - if ((hostc & ICH9_SMB_HOSTC_HST_EN) && !(hostc & ICH9_SMB_HOSTC_I2C_EN)) { - uint64_t offset = addr - s->dev.io_regions[ICH9_SMB_SMB_BASE_BAR].addr; - return smb_ioport_readb(&s->smb, offset); - } - - return 0xff; -} - -static const MemoryRegionOps lpc_smb_mmio_ops = { - .read = ich9_smb_ioport_readb, - .write = ich9_smb_ioport_writeb, - .endianness = DEVICE_LITTLE_ENDIAN, - .impl = { - .min_access_size = 1, - .max_access_size = 1, - }, -}; - static int ich9_smbus_initfn(PCIDevice *d) { ICH9SMBState *s = ICH9_SMB_DEVICE(d); @@ -109,15 +89,12 @@ static int ich9_smbus_initfn(PCIDevice *d) * Is there any OS that depends on them? */ - /* TODO smb_io_base */ pci_set_byte(d->config + ICH9_SMB_HOSTC, 0); /* TODO bar0, bar1: 64bit BAR support*/ - memory_region_init_io(&s->mem_bar, &lpc_smb_mmio_ops, s, "ich9-smbus-bar", - ICH9_SMB_SMB_BASE_SIZE); - pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO, - &s->mem_bar); pm_smbus_init(&d->qdev, &s->smb); + pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO, + &s->smb.io); return 0; } @@ -134,6 +111,7 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_ich9_smbus; dc->desc = "ICH9 SMBUS Bridge"; k->init = ich9_smbus_initfn; + k->config_write = ich9_smbus_write_config; } i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base) diff --git a/hw/vt82c686.c b/hw/vt82c686.c index 99e6b2f9a9..5016e954d3 100644 --- a/hw/vt82c686.c +++ b/hw/vt82c686.c @@ -351,8 +351,8 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) pci_conf[0x90] = s->smb_io_base | 1; pci_conf[0x91] = s->smb_io_base >> 8; pci_conf[0xd2] = 0x90; - register_ioport_write(s->smb_io_base, 0xf, 1, smb_ioport_writeb, &s->smb); - register_ioport_read(s->smb_io_base, 0xf, 1, smb_ioport_readb, &s->smb); + pm_smbus_init(&s->dev.qdev, &s->smb); + memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io); apm_init(&s->apm, NULL, s); @@ -364,8 +364,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io); acpi_pm1_cnt_init(&s->ar, &s->io); - pm_smbus_init(&s->dev.qdev, &s->smb); - return 0; } |