On Wed, Feb 08, 2012 at 12:00:15PM +0100, Gerd Hoffmann wrote:
> This patch switches pc s3 suspend over to the new infrastructure.
> The cmos_s3 qemu_irq is killed, the new notifier is used instead.
> The xen hack goes away with that too, the hypercall can simply be
> done in a notifier function now.
> 
> This patch also makes the guest actually stay suspended instead
> of leaving suspend instantly, so it is useful for more than just
> testing whenever the suspend/resume cycle actually works.
> 
> Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
> ---
>  hw/acpi.c        |   11 +----------
>  hw/acpi.h        |    2 --
>  hw/acpi_piix4.c  |    3 +--
>  hw/mc146818rtc.c |   12 ++++++++++++
>  hw/mips_malta.c  |    2 +-
>  hw/pc.c          |   11 -----------
>  hw/pc.h          |    3 +--
>  hw/pc_piix.c     |    8 +-------
>  hw/vt82c686.c    |    1 -
>  xen-all.c        |   11 ++++++-----
>  10 files changed, 23 insertions(+), 41 deletions(-)
> 
> diff --git a/hw/acpi.c b/hw/acpi.c
> index 79b179b..67dcd43 100644
> --- a/hw/acpi.c
> +++ b/hw/acpi.c
> @@ -330,11 +330,6 @@ void acpi_pm_tmr_reset(ACPIPMTimer *tmr)
>  }
>  
>  /* ACPI PM1aCNT */
> -void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3)
> -{
> -    pm1_cnt->cmos_s3 = cmos_s3;
> -}
> -
>  void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val)
>  {
>      pm1_cnt->cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
> @@ -351,8 +346,7 @@ void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT 
> *pm1_cnt, uint16_t val)
>                 Pretend that resume was caused by power button */
>              pm1a->sts |=
>                  (ACPI_BITMASK_WAKE_STATUS | 
> ACPI_BITMASK_POWER_BUTTON_STATUS);
Here we should report real reason for a wakeup (if it can be reported in
mp1sts that is).

> -            qemu_system_reset_request();
> -            qemu_irq_raise(pm1_cnt->cmos_s3);
> +            qemu_system_suspend_request();
>          default:
>              break;
>          }
> @@ -373,9 +367,6 @@ void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
>  void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt)
>  {
>      pm1_cnt->cnt = 0;
> -    if (pm1_cnt->cmos_s3) {
> -        qemu_irq_lower(pm1_cnt->cmos_s3);
> -    }
>  }
>  
>  /* ACPI GPE */
> diff --git a/hw/acpi.h b/hw/acpi.h
> index c141e65..e0c7dbe 100644
> --- a/hw/acpi.h
> +++ b/hw/acpi.h
> @@ -115,8 +115,6 @@ void acpi_pm1_evt_reset(ACPIPM1EVT *pm1);
>  /* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
>  struct ACPIPM1CNT {
>      uint16_t cnt;
> -
> -    qemu_irq cmos_s3;
>  };
>  typedef struct ACPIPM1CNT ACPIPM1CNT;
>  
> diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
> index 21484ae..bc77dc5 100644
> --- a/hw/acpi_piix4.c
> +++ b/hw/acpi_piix4.c
> @@ -376,7 +376,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
>  }
>  
>  i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
> -                       qemu_irq sci_irq, qemu_irq cmos_s3, qemu_irq smi_irq,
> +                       qemu_irq sci_irq, qemu_irq smi_irq,
>                         int kvm_enabled)
>  {
>      PCIDevice *dev;
> @@ -387,7 +387,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->pm1_cnt, cmos_s3);
>      s->smi_irq = smi_irq;
>      s->kvm_enabled = kvm_enabled;
>  
> diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
> index 4a43225..314ed52 100644
> --- a/hw/mc146818rtc.c
> +++ b/hw/mc146818rtc.c
> @@ -102,6 +102,7 @@ typedef struct RTCState {
>      QEMUTimer *second_timer2;
>      Notifier clock_reset_notifier;
>      LostTickPolicy lost_tick_policy;
> +    Notifier suspend_notifier;
>  } RTCState;
>  
>  static void rtc_set_time(RTCState *s);
> @@ -596,6 +597,14 @@ static void rtc_notify_clock_reset(Notifier *notifier, 
> void *data)
>  #endif
>  }
>  
> +/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
> +   BIOS will read it and start S3 resume at POST Entry */
> +static void rtc_notify_suspend(Notifier *notifier, void *data)
> +{
> +    RTCState *s = container_of(notifier, RTCState, suspend_notifier);
> +    rtc_set_memory(&s->dev, 0xF, 0xFE);
> +}
> +
>  static void rtc_reset(void *opaque)
>  {
>      RTCState *s = opaque;
> @@ -676,6 +685,9 @@ static int rtc_initfn(ISADevice *dev)
>      s->clock_reset_notifier.notify = rtc_notify_clock_reset;
>      qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier);
>  
> +    s->suspend_notifier.notify = rtc_notify_suspend;
> +    qemu_register_suspend_notifier(&s->suspend_notifier);
> +
>      s->next_second_time =
>          qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100;
>      qemu_mod_timer(s->second_timer2, s->next_second_time);
> diff --git a/hw/mips_malta.c b/hw/mips_malta.c
> index d232630..fe02c93 100644
> --- a/hw/mips_malta.c
> +++ b/hw/mips_malta.c
> @@ -966,7 +966,7 @@ void mips_malta_init (ram_addr_t ram_size,
>      pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
>      usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
>      smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
> -                          isa_get_irq(NULL, 9), NULL, NULL, 0);
> +                          isa_get_irq(NULL, 9), NULL, 0);
>      /* TODO: Populate SPD eeprom data.  */
>      smbus_eeprom_init(smbus, 8, NULL, 0);
>      pit = pit_init(isa_bus, 0x40, 0);
> diff --git a/hw/pc.c b/hw/pc.c
> index 7f3aa65..7b93aee 100644
> --- a/hw/pc.c
> +++ b/hw/pc.c
> @@ -915,17 +915,6 @@ static DeviceState *apic_init(void *env, uint8_t apic_id)
>      return dev;
>  }
>  
> -/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
> -   BIOS will read it and start S3 resume at POST Entry */
> -void pc_cmos_set_s3_resume(void *opaque, int irq, int level)
> -{
> -    ISADevice *s = opaque;
> -
> -    if (level) {
> -        rtc_set_memory(s, 0xF, 0xFE);
> -    }
> -}
> -
>  void pc_acpi_smi_interrupt(void *opaque, int irq, int level)
>  {
>      CPUState *s = opaque;
> diff --git a/hw/pc.h b/hw/pc.h
> index c666ec9..571c915 100644
> --- a/hw/pc.h
> +++ b/hw/pc.h
> @@ -128,7 +128,6 @@ void i8042_setup_a20_line(ISADevice *dev, qemu_irq 
> *a20_out);
>  extern int fd_bootchk;
>  
>  void pc_register_ferr_irq(qemu_irq irq);
> -void pc_cmos_set_s3_resume(void *opaque, int irq, int level);
>  void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
>  
>  void pc_cpus_init(const char *cpu_model);
> @@ -167,7 +166,7 @@ int acpi_table_add(const char *table_desc);
>  /* acpi_piix.c */
>  
>  i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
> -                       qemu_irq sci_irq, qemu_irq cmos_s3, qemu_irq smi_irq,
> +                       qemu_irq sci_irq, qemu_irq smi_irq,
>                         int kvm_enabled);
>  void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
>  
> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
> index c06f1b5..918f5ac 100644
> --- a/hw/pc_piix.c
> +++ b/hw/pc_piix.c
> @@ -139,7 +139,6 @@ static void pc_init1(MemoryRegion *system_memory,
>      qemu_irq *cpu_irq;
>      qemu_irq *gsi;
>      qemu_irq *i8259;
> -    qemu_irq *cmos_s3;
>      qemu_irq *smi_irq;
>      GSIState *gsi_state;
>      DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
> @@ -291,15 +290,10 @@ static void pc_init1(MemoryRegion *system_memory,
>      if (pci_enabled && acpi_enabled) {
>          i2c_bus *smbus;
>  
> -        if (!xen_enabled()) {
> -            cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 
> 1);
> -        } else {
> -            cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 
> 1);
> -        }
>          smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
>          /* TODO: Populate SPD eeprom data.  */
>          smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
> -                              gsi[9], *cmos_s3, *smi_irq,
> +                              gsi[9], *smi_irq,
>                                kvm_enabled());
>          smbus_eeprom_init(smbus, 8, NULL, 0);
>      }
> diff --git a/hw/vt82c686.c b/hw/vt82c686.c
> index aa0954f..8beb6c5 100644
> --- a/hw/vt82c686.c
> +++ b/hw/vt82c686.c
> @@ -446,7 +446,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
>      apm_init(&s->apm, NULL, s);
>  
>      acpi_pm_tmr_init(&s->tmr, pm_tmr_timer);
> -    acpi_pm1_cnt_init(&s->pm1_cnt, NULL);
>  
>      pm_smbus_init(&s->dev.qdev, &s->smb);
>  
> diff --git a/xen-all.c b/xen-all.c
> index fd39168..b0ed1ed 100644
> --- a/xen-all.c
> +++ b/xen-all.c
> @@ -89,6 +89,7 @@ typedef struct XenIOState {
>      const XenPhysmap *log_for_dirtybit;
>  
>      Notifier exit;
> +    Notifier suspend;
>  } XenIOState;
>  
>  /* Xen specific function for piix pci */
> @@ -121,12 +122,9 @@ void xen_piix_pci_write_config_client(uint32_t address, 
> uint32_t val, int len)
>      }
>  }
>  
> -void xen_cmos_set_s3_resume(void *opaque, int irq, int level)
> +static void xen_suspend_notifier(Notifier *notifier, void *data)
>  {
> -    pc_cmos_set_s3_resume(opaque, irq, level);
> -    if (level) {
> -        xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3);
> -    }
> +    xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3);
>  }
>  
>  /* Xen Interrupt Controller */
> @@ -936,6 +934,9 @@ int xen_hvm_init(void)
>      state->exit.notify = xen_exit_notifier;
>      qemu_add_exit_notifier(&state->exit);
>  
> +    state->suspend.notify = xen_suspend_notifier;
> +    qemu_register_suspend_notifier(&state->suspend);
> +
>      xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
>      DPRINTF("shared page at pfn %lx\n", ioreq_pfn);
>      state->shared_page = xc_map_foreign_range(xen_xc, xen_domid, 
> XC_PAGE_SIZE,
> -- 
> 1.7.1
> 
> 

--
                        Gleb.

Reply via email to