diff --git a/hw/acpi.c b/hw/acpi.c index ba25c23bed..956db95be4 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -372,13 +372,7 @@ void acpi_pm_tmr_reset(ACPIREGS *ar) } /* ACPI PM1aCNT */ -void acpi_pm1_cnt_init(ACPIREGS *ar) -{ - ar->wakeup.notify = acpi_notify_wakeup; - qemu_register_wakeup_notifier(&ar->wakeup); -} - -void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4) +static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) { ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); @@ -393,7 +387,7 @@ void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4) qemu_system_suspend_request(); break; default: - if (sus_typ == s4) { /* S4 request */ + if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */ monitor_protocol_event(QEVENT_SUSPEND_DISK, NULL); qemu_system_shutdown_request(); } @@ -413,6 +407,34 @@ void acpi_pm1_cnt_update(ACPIREGS *ar, } } +static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width) +{ + ACPIREGS *ar = opaque; + return ar->pm1.cnt.cnt; +} + +static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val, + unsigned width) +{ + acpi_pm1_cnt_write(opaque, val); +} + +static const MemoryRegionOps acpi_pm_cnt_ops = { + .read = acpi_pm_cnt_read, + .write = acpi_pm_cnt_write, + .valid.min_access_size = 2, + .valid.max_access_size = 2, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent) +{ + ar->wakeup.notify = acpi_notify_wakeup; + qemu_register_wakeup_notifier(&ar->wakeup); + memory_region_init_io(&ar->pm1.cnt.io, &acpi_pm_cnt_ops, ar, "acpi-cnt", 2); + memory_region_add_subregion(parent, 4, &ar->pm1.cnt.io); +} + void acpi_pm1_cnt_reset(ACPIREGS *ar) { ar->pm1.cnt.cnt = 0; diff --git a/hw/acpi.h b/hw/acpi.h index 91f42c3db1..97aaab847c 100644 --- a/hw/acpi.h +++ b/hw/acpi.h @@ -96,7 +96,9 @@ struct ACPIPM1EVT { }; struct ACPIPM1CNT { + MemoryRegion io; uint16_t cnt; + uint8_t s4_val; }; struct ACPIGPE { @@ -139,8 +141,7 @@ void acpi_pm1_evt_power_down(ACPIREGS *ar); void acpi_pm1_evt_reset(ACPIREGS *ar); /* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */ -void acpi_pm1_cnt_init(ACPIREGS *ar); -void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4); +void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent); void acpi_pm1_cnt_update(ACPIREGS *ar, bool sci_enable, bool sci_disable); void acpi_pm1_cnt_reset(ACPIREGS *ar); diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c index ec6d5f2b5a..7b6c2ef4dc 100644 --- a/hw/acpi_ich9.c +++ b/hw/acpi_ich9.c @@ -116,9 +116,6 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) pm->acpi_regs.pm1.evt.en = val; pm_update_sci(pm); break; - case ICH9_PMIO_PM1_CNT: - acpi_pm1_cnt_write(&pm->acpi_regs, val, 0); - break; default: pm_ioport_write_fallback(opaque, addr, 2, val); break; @@ -138,9 +135,6 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr) case ICH9_PMIO_PM1_EN: val = pm->acpi_regs.pm1.evt.en; break; - case ICH9_PMIO_PM1_CNT: - val = pm->acpi_regs.pm1.cnt.cnt; - break; default: val = pm_ioport_read_fallback(opaque, addr, 2); break; @@ -318,7 +312,7 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3) memory_region_add_subregion(get_system_io(), 0, &pm->io); acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io); - acpi_pm1_cnt_init(&pm->acpi_regs); + acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io); acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN); acpi_gpe_blk(&pm->acpi_regs, ICH9_PMIO_GPE0_STS); diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 75761a08a7..9d5e346ef3 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -129,9 +129,6 @@ static void pm_ioport_write(void *opaque, hwaddr addr, uint64_t val, acpi_pm1_evt_write_en(&s->ar, val); pm_update_sci(s); break; - case 0x04: - acpi_pm1_cnt_write(&s->ar, val, s->s4_val); - break; default: break; } @@ -151,9 +148,6 @@ static uint64_t pm_ioport_read(void *opaque, hwaddr addr, unsigned width) case 0x02: val = s->ar.pm1.evt.en; break; - case 0x04: - val = s->ar.pm1.cnt.cnt; - break; default: val = 0; break; @@ -461,6 +455,7 @@ static int piix4_pm_initfn(PCIDevice *dev) memory_region_add_subregion(get_system_io(), 0, &s->io); acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io); + acpi_pm1_cnt_init(&s->ar, &s->io); acpi_gpe_init(&s->ar, GPE_LEN); s->powerdown_notifier.notify = piix4_pm_powerdown_req; @@ -487,7 +482,6 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, s = DO_UPCAST(PIIX4PMState, dev, dev); s->irq = sci_irq; - acpi_pm1_cnt_init(&s->ar); s->smi_irq = smi_irq; s->kvm_enabled = kvm_enabled; diff --git a/hw/vt82c686.c b/hw/vt82c686.c index 219cfaec72..15f0b6a91c 100644 --- a/hw/vt82c686.c +++ b/hw/vt82c686.c @@ -211,9 +211,6 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) acpi_pm1_evt_write_en(&s->ar, val); pm_update_sci(s); break; - case 0x04: - acpi_pm1_cnt_write(&s->ar, val, 0); - break; default: break; } @@ -233,9 +230,6 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr) case 0x02: val = s->ar.pm1.evt.en; break; - case 0x04: - val = s->ar.pm1.cnt.cnt; - break; default: val = 0; break; @@ -443,7 +437,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) memory_region_add_subregion(get_system_io(), 0, &s->io); acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io); - acpi_pm1_cnt_init(&s->ar); + acpi_pm1_cnt_init(&s->ar, &s->io); pm_smbus_init(&s->dev.qdev, &s->smb);