diff options
author | Isaku Yamahata <yamahata@valinux.co.jp> | 2011-03-25 19:54:38 +0900 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2011-04-09 18:39:05 +0200 |
commit | a54d41a8b985cc7ff9d4bc52e6ca20a09216b394 (patch) | |
tree | 5ee739f336ffaff9ba0d008bef2c0b165528de3d /hw/acpi_piix4.c | |
parent | 5145b3d1cc4dc77d82086d99b0690a76e1073071 (diff) |
acpi, acpi_piix, vt82c686: factor out PM_TMR logic
factor out PM_TMR logic. Later This will be used by ich9 acpi.
Also fixes the same bug in vt82c686.c that was fixed by the following
commits.
> commit 055479feab63607b8042bb8ebb2e0523f17cbc4e
> Author: aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
> Date: Wed Jan 21 16:31:20 2009 +0000
>
> Always return latest pmsts instead of the old one (Xiantao Zhang)
>
> It may lead to the issue when booting windows guests with acpi=1
> if return the old pmsts.
>
> Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Cc: Blue Swirl <blauwirbel@gmail.com>
Cc: Huacai Chen <zltjiangshi@gmail.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'hw/acpi_piix4.c')
-rw-r--r-- | hw/acpi_piix4.c | 45 |
1 files changed, 12 insertions, 33 deletions
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 74044ddd9b..e4ba8fc252 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -60,8 +60,7 @@ typedef struct PIIX4PMState { APMState apm; - QEMUTimer *tmr_timer; - int64_t tmr_overflow_time; + ACPIPMTimer tmr; PMSMBus smb; uint32_t smb_io_base; @@ -82,20 +81,10 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s); #define ACPI_ENABLE 0xf1 #define ACPI_DISABLE 0xf0 -static uint32_t get_pmtmr(PIIX4PMState *s) -{ - uint32_t d; - d = muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec()); - return d & 0xffffff; -} - static int get_pmsts(PIIX4PMState *s) { - int64_t d; - - d = muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY, - get_ticks_per_sec()); - if (d >= s->tmr_overflow_time) + int64_t d = acpi_pm_tmr_get_clock(); + if (d >= s->tmr.overflow_time) s->pmsts |= ACPI_BITMASK_TIMER_STATUS; return s->pmsts; } @@ -103,7 +92,6 @@ static int get_pmsts(PIIX4PMState *s) static void pm_update_sci(PIIX4PMState *s) { int sci_level, pmsts; - int64_t expire_time; pmsts = get_pmsts(s); sci_level = (((pmsts & s->pmen) & @@ -115,19 +103,13 @@ static void pm_update_sci(PIIX4PMState *s) qemu_set_irq(s->irq, sci_level); /* schedule a timer interruption if needed */ - if ((s->pmen & ACPI_BITMASK_TIMER_ENABLE) && - !(pmsts & ACPI_BITMASK_TIMER_STATUS)) { - expire_time = muldiv64(s->tmr_overflow_time, get_ticks_per_sec(), - PM_TIMER_FREQUENCY); - qemu_mod_timer(s->tmr_timer, expire_time); - } else { - qemu_del_timer(s->tmr_timer); - } + acpi_pm_tmr_update(&s->tmr, (s->pmen & ACPI_BITMASK_TIMER_ENABLE) && + !(pmsts & ACPI_BITMASK_TIMER_STATUS)); } -static void pm_tmr_timer(void *opaque) +static void pm_tmr_timer(ACPIPMTimer *tmr) { - PIIX4PMState *s = opaque; + PIIX4PMState *s = container_of(tmr, PIIX4PMState, tmr); pm_update_sci(s); } @@ -144,14 +126,11 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width, switch(addr) { case 0x00: { - int64_t d; int pmsts; pmsts = get_pmsts(s); if (pmsts & val & ACPI_BITMASK_TIMER_STATUS) { /* if TMRSTS is reset, then compute the new overflow time */ - d = muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY, - get_ticks_per_sec()); - s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL; + acpi_pm_tmr_calc_overflow_time(&s->tmr); } s->pmsts &= ~val; pm_update_sci(s); @@ -211,7 +190,7 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width, val = s->pmcntrl; break; case 0x08: - val = get_pmtmr(s); + val = acpi_pm_tmr_get(&s->tmr); break; default: val = 0; @@ -316,8 +295,8 @@ static const VMStateDescription vmstate_acpi = { VMSTATE_UINT16(pmen, PIIX4PMState), VMSTATE_UINT16(pmcntrl, PIIX4PMState), VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState), - VMSTATE_TIMER(tmr_timer, PIIX4PMState), - VMSTATE_INT64(tmr_overflow_time, PIIX4PMState), + VMSTATE_TIMER(tmr.timer, PIIX4PMState), + VMSTATE_INT64(tmr.overflow_time, PIIX4PMState), VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, struct gpe_regs), VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status, struct pci_status), @@ -414,7 +393,7 @@ static int piix4_pm_initfn(PCIDevice *dev) 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); - s->tmr_timer = qemu_new_timer_ns(vm_clock, pm_tmr_timer, s); + acpi_pm_tmr_init(&s->tmr, pm_tmr_timer); qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1); |