acpi: switch smbus to memory api

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Gerd Hoffmann 2012-11-23 14:57:01 +01:00
parent 4a522de090
commit 798512e552
5 changed files with 33 additions and 50 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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 */

View File

@ -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)

View File

@ -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;
}