提交 798512e5 编写于 作者: G Gerd Hoffmann

acpi: switch smbus to memory api

Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
上级 4a522de0
...@@ -391,8 +391,8 @@ static int piix4_pm_initfn(PCIDevice *dev) ...@@ -391,8 +391,8 @@ static int piix4_pm_initfn(PCIDevice *dev)
pci_conf[0x90] = s->smb_io_base | 1; pci_conf[0x90] = s->smb_io_base | 1;
pci_conf[0x91] = s->smb_io_base >> 8; pci_conf[0x91] = s->smb_io_base >> 8;
pci_conf[0xd2] = 0x09; pci_conf[0xd2] = 0x09;
register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb); pm_smbus_init(&s->dev.qdev, &s->smb);
register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &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_init(&s->io, "piix4-pm", 64);
memory_region_set_enabled(&s->io, false); memory_region_set_enabled(&s->io, false);
...@@ -406,7 +406,6 @@ static int piix4_pm_initfn(PCIDevice *dev) ...@@ -406,7 +406,6 @@ static int piix4_pm_initfn(PCIDevice *dev)
s->powerdown_notifier.notify = piix4_pm_powerdown_req; s->powerdown_notifier.notify = piix4_pm_powerdown_req;
qemu_register_powerdown_notifier(&s->powerdown_notifier); qemu_register_powerdown_notifier(&s->powerdown_notifier);
pm_smbus_init(&s->dev.qdev, &s->smb);
s->machine_ready.notify = piix4_pm_machine_ready; s->machine_ready.notify = piix4_pm_machine_ready;
qemu_add_machine_init_done_notifier(&s->machine_ready); qemu_add_machine_init_done_notifier(&s->machine_ready);
qemu_register_reset(piix4_reset, s); qemu_register_reset(piix4_reset, s);
......
...@@ -94,10 +94,11 @@ static void smb_transaction(PMSMBus *s) ...@@ -94,10 +94,11 @@ static void smb_transaction(PMSMBus *s)
s->smb_stat |= 0x04; 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; PMSMBus *s = opaque;
addr &= 0x3f;
SMBUS_DPRINTF("SMB writeb port=0x%04x val=0x%02x\n", addr, val); SMBUS_DPRINTF("SMB writeb port=0x%04x val=0x%02x\n", addr, val);
switch(addr) { switch(addr) {
case SMBHSTSTS: case SMBHSTSTS:
...@@ -131,12 +132,11 @@ void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) ...@@ -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; PMSMBus *s = opaque;
uint32_t val; uint32_t val;
addr &= 0x3f;
switch(addr) { switch(addr) {
case SMBHSTSTS: case SMBHSTSTS:
val = s->smb_stat; val = s->smb_stat;
...@@ -170,7 +170,16 @@ uint32_t smb_ioport_readb(void *opaque, uint32_t addr) ...@@ -170,7 +170,16 @@ uint32_t smb_ioport_readb(void *opaque, uint32_t addr)
return val; 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) void pm_smbus_init(DeviceState *parent, PMSMBus *smb)
{ {
smb->smbus = i2c_init_bus(parent, "i2c"); smb->smbus = i2c_init_bus(parent, "i2c");
memory_region_init_io(&smb->io, &pm_smbus_ops, smb, "pm-smbus", 64);
} }
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
typedef struct PMSMBus { typedef struct PMSMBus {
i2c_bus *smbus; i2c_bus *smbus;
MemoryRegion io;
uint8_t smb_stat; uint8_t smb_stat;
uint8_t smb_ctl; uint8_t smb_ctl;
...@@ -15,7 +16,5 @@ typedef struct PMSMBus { ...@@ -15,7 +16,5 @@ typedef struct PMSMBus {
} PMSMBus; } PMSMBus;
void pm_smbus_init(DeviceState *parent, PMSMBus *smb); 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 */ #endif /* !PM_SMBUS_H */
...@@ -40,7 +40,6 @@ typedef struct ICH9SMBState { ...@@ -40,7 +40,6 @@ typedef struct ICH9SMBState {
PCIDevice dev; PCIDevice dev;
PMSMBus smb; PMSMBus smb;
MemoryRegion mem_bar;
} ICH9SMBState; } ICH9SMBState;
static const VMStateDescription vmstate_ich9_smbus = { static const VMStateDescription vmstate_ich9_smbus = {
...@@ -54,42 +53,23 @@ 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, static void ich9_smbus_write_config(PCIDevice *d, uint32_t address,
uint64_t val, unsigned size) uint32_t val, int len)
{ {
ICH9SMBState *s = opaque; ICH9SMBState *s = ICH9_SMB_DEVICE(d);
uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC];
if ((hostc & ICH9_SMB_HOSTC_HST_EN) && !(hostc & ICH9_SMB_HOSTC_I2C_EN)) { pci_default_write_config(d, address, val, len);
uint64_t offset = addr - s->dev.io_regions[ICH9_SMB_SMB_BASE_BAR].addr; if (range_covers_byte(address, len, ICH9_SMB_HOSTC)) {
smb_ioport_writeb(&s->smb, offset, val); 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) static int ich9_smbus_initfn(PCIDevice *d)
{ {
ICH9SMBState *s = ICH9_SMB_DEVICE(d); ICH9SMBState *s = ICH9_SMB_DEVICE(d);
...@@ -109,15 +89,12 @@ static int ich9_smbus_initfn(PCIDevice *d) ...@@ -109,15 +89,12 @@ static int ich9_smbus_initfn(PCIDevice *d)
* Is there any OS that depends on them? * Is there any OS that depends on them?
*/ */
/* TODO smb_io_base */
pci_set_byte(d->config + ICH9_SMB_HOSTC, 0); pci_set_byte(d->config + ICH9_SMB_HOSTC, 0);
/* TODO bar0, bar1: 64bit BAR support*/ /* 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); 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; return 0;
} }
...@@ -134,6 +111,7 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data) ...@@ -134,6 +111,7 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_ich9_smbus; dc->vmsd = &vmstate_ich9_smbus;
dc->desc = "ICH9 SMBUS Bridge"; dc->desc = "ICH9 SMBUS Bridge";
k->init = ich9_smbus_initfn; 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) i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
......
...@@ -351,8 +351,8 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) ...@@ -351,8 +351,8 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
pci_conf[0x90] = s->smb_io_base | 1; pci_conf[0x90] = s->smb_io_base | 1;
pci_conf[0x91] = s->smb_io_base >> 8; pci_conf[0x91] = s->smb_io_base >> 8;
pci_conf[0xd2] = 0x90; pci_conf[0xd2] = 0x90;
register_ioport_write(s->smb_io_base, 0xf, 1, smb_ioport_writeb, &s->smb); pm_smbus_init(&s->dev.qdev, &s->smb);
register_ioport_read(s->smb_io_base, 0xf, 1, smb_ioport_readb, &s->smb); memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io);
apm_init(&s->apm, NULL, s); apm_init(&s->apm, NULL, s);
...@@ -364,8 +364,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) ...@@ -364,8 +364,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
acpi_pm1_evt_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); acpi_pm1_cnt_init(&s->ar, &s->io);
pm_smbus_init(&s->dev.qdev, &s->smb);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册