* [Qemu-devel] [PATCH v5 00/12] initial suspend support
@ 2012-02-15 10:28 Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 01/12] acpi: move around structs Gerd Hoffmann
` (11 more replies)
0 siblings, 12 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Hi,
Next and hopefully final suspend support patch series. It makes s3
support alot more useful by leaving guests actually suspended and
allowing them to be woken up by certain events, with ps/2 keyboard
input (wakeup-by-tap-enter) and real time clock (see 'man rtcwake')
being the most useful ones.
ACPI integration is there, so the guest can enable/disable wakeup
events like it is done on real hardware. The patch series also
features some acpi cleanups which where needed to get this done.
QMP support is there, which consists of qmp events which are sent
out on suspend and wakeup and a monitor command to wakeup a
suspended guest.
cheers,
Gerd
The following changes since commit 59f971d451fbabee3194bb565f40846398ee6e6f:
qdev: print error message before aborting (2012-02-14 18:57:33 +0000)
are available in the git repository at:
git://git.kraxel.org/qemu suspend.1
Gerd Hoffmann (12):
acpi: move around structs
acpi: add ACPIREGS
acpi: don't pass overflow_time to acpi_pm1_evt_get_sts
acpi: add acpi_pm1_evt_write_en
suspend: add infrastructure
suspend: switch acpi s3 to new infrastructure.
suspend: add system_wakeup monitor command
suspend: make ps/2 devices wakeup the guest
suspend: make serial ports wakeup the guest.
suspend: make rtc alarm wakeup the guest.
suspend: make acpi timer wakeup the guest.
suspend: add qmp events
hmp-commands.hx | 14 +++++
hmp.c | 5 ++
hmp.h | 1 +
hw/acpi.c | 172 +++++++++++++++++++++++++++++++-----------------------
hw/acpi.h | 93 ++++++++++++++++-------------
hw/acpi_piix4.c | 70 ++++++++++------------
hw/mc146818rtc.c | 13 ++++
hw/mips_malta.c | 2 +-
hw/pc.c | 11 ----
hw/pc.h | 3 +-
hw/pc_piix.c | 8 +--
hw/ps2.c | 6 ++
hw/serial.c | 6 ++
hw/vt82c686.c | 42 ++++++-------
monitor.c | 6 ++
monitor.h | 2 +
qapi-schema.json | 11 ++++
qmp-commands.hx | 21 +++++++
qmp.c | 5 ++
sysemu.h | 11 ++++
vl.c | 82 ++++++++++++++++++++++++++
xen-all.c | 11 ++--
22 files changed, 396 insertions(+), 199 deletions(-)
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 01/12] acpi: move around structs
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 02/12] acpi: add ACPIREGS Gerd Hoffmann
` (10 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Group all structs at the top of hw/acpi.h.
Just moving around lines, no code changes.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/acpi.h | 48 +++++++++++++++++++++++-------------------------
1 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/hw/acpi.h b/hw/acpi.h
index c141e65..5c43b7d 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -73,9 +73,11 @@
/* PM2_CNT */
#define ACPI_BITMASK_ARB_DISABLE 0x0001
-/* PM_TMR */
-struct ACPIPMTimer;
+/* structs */
typedef struct ACPIPMTimer ACPIPMTimer;
+typedef struct ACPIPM1EVT ACPIPM1EVT;
+typedef struct ACPIPM1CNT ACPIPM1CNT;
+typedef struct ACPIGPE ACPIGPE;
typedef void (*acpi_update_sci_fn)(ACPIPMTimer *tmr);
@@ -86,6 +88,25 @@ struct ACPIPMTimer {
acpi_update_sci_fn update_sci;
};
+struct ACPIPM1EVT {
+ uint16_t sts;
+ uint16_t en;
+};
+
+struct ACPIPM1CNT {
+ uint16_t cnt;
+ qemu_irq cmos_s3;
+};
+
+struct ACPIGPE {
+ uint32_t blk;
+ uint8_t len;
+
+ uint8_t *sts;
+ uint8_t *en;
+};
+
+/* PM_TMR */
void acpi_pm_tmr_update(ACPIPMTimer *tmr, bool enable);
void acpi_pm_tmr_calc_overflow_time(ACPIPMTimer *tmr);
uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr);
@@ -100,26 +121,12 @@ static inline int64_t acpi_pm_tmr_get_clock(void)
}
/* PM1a_EVT: piix and ich9 don't implement PM1b. */
-struct ACPIPM1EVT
-{
- uint16_t sts;
- uint16_t en;
-};
-typedef struct ACPIPM1EVT ACPIPM1EVT;
-
uint16_t acpi_pm1_evt_get_sts(ACPIPM1EVT *pm1, int64_t overflow_time);
void acpi_pm1_evt_write_sts(ACPIPM1EVT *pm1, ACPIPMTimer *tmr, uint16_t val);
void acpi_pm1_evt_power_down(ACPIPM1EVT *pm1, ACPIPMTimer *tmr);
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;
-
void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3);
void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val);
void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
@@ -127,15 +134,6 @@ void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt);
/* GPE0 */
-struct ACPIGPE {
- uint32_t blk;
- uint8_t len;
-
- uint8_t *sts;
- uint8_t *en;
-};
-typedef struct ACPIGPE ACPIGPE;
-
void acpi_gpe_init(ACPIGPE *gpe, uint8_t len);
void acpi_gpe_blk(ACPIGPE *gpe, uint32_t blk);
void acpi_gpe_reset(ACPIGPE *gpe);
--
1.7.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 02/12] acpi: add ACPIREGS
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 01/12] acpi: move around structs Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 03/12] acpi: don't pass overflow_time to acpi_pm1_evt_get_sts Gerd Hoffmann
` (9 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
All those acpi structs are not independent from each other.
Various acpi functions expecting multiple acpi structs passed
in are a clean indicator for that ;)
So this patch bundles all acpi structs in the new ACPIREGS
struct, then use it everythere pass around acpi state.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/acpi.c | 130 +++++++++++++++++++++++++++----------------------------
hw/acpi.h | 48 ++++++++++++--------
hw/acpi_piix4.c | 68 +++++++++++++---------------
hw/vt82c686.c | 42 ++++++++---------
4 files changed, 145 insertions(+), 143 deletions(-)
diff --git a/hw/acpi.c b/hw/acpi.c
index 79b179b..1922e53 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -249,63 +249,61 @@ int acpi_table_add(const char *t)
}
/* ACPI PM1a EVT */
-uint16_t acpi_pm1_evt_get_sts(ACPIPM1EVT *pm1, int64_t overflow_time)
+uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar, int64_t overflow_time)
{
int64_t d = acpi_pm_tmr_get_clock();
if (d >= overflow_time) {
- pm1->sts |= ACPI_BITMASK_TIMER_STATUS;
+ ar->pm1.evt.sts |= ACPI_BITMASK_TIMER_STATUS;
}
- return pm1->sts;
+ return ar->pm1.evt.sts;
}
-void acpi_pm1_evt_write_sts(ACPIPM1EVT *pm1, ACPIPMTimer *tmr, uint16_t val)
+void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
{
- uint16_t pm1_sts = acpi_pm1_evt_get_sts(pm1, tmr->overflow_time);
+ uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar, ar->tmr.overflow_time);
if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) {
/* if TMRSTS is reset, then compute the new overflow time */
- acpi_pm_tmr_calc_overflow_time(tmr);
+ acpi_pm_tmr_calc_overflow_time(ar);
}
- pm1->sts &= ~val;
+ ar->pm1.evt.sts &= ~val;
}
-void acpi_pm1_evt_power_down(ACPIPM1EVT *pm1, ACPIPMTimer *tmr)
+void acpi_pm1_evt_power_down(ACPIREGS *ar)
{
- if (!pm1) {
- qemu_system_shutdown_request();
- } else if (pm1->en & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
- pm1->sts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
- tmr->update_sci(tmr);
+ if (ar->pm1.evt.en & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
+ ar->pm1.evt.sts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
+ ar->tmr.update_sci(ar);
}
}
-void acpi_pm1_evt_reset(ACPIPM1EVT *pm1)
+void acpi_pm1_evt_reset(ACPIREGS *ar)
{
- pm1->sts = 0;
- pm1->en = 0;
+ ar->pm1.evt.sts = 0;
+ ar->pm1.evt.en = 0;
}
/* ACPI PM_TMR */
-void acpi_pm_tmr_update(ACPIPMTimer *tmr, bool enable)
+void acpi_pm_tmr_update(ACPIREGS *ar, bool enable)
{
int64_t expire_time;
/* schedule a timer interruption if needed */
if (enable) {
- expire_time = muldiv64(tmr->overflow_time, get_ticks_per_sec(),
+ expire_time = muldiv64(ar->tmr.overflow_time, get_ticks_per_sec(),
PM_TIMER_FREQUENCY);
- qemu_mod_timer(tmr->timer, expire_time);
+ qemu_mod_timer(ar->tmr.timer, expire_time);
} else {
- qemu_del_timer(tmr->timer);
+ qemu_del_timer(ar->tmr.timer);
}
}
-void acpi_pm_tmr_calc_overflow_time(ACPIPMTimer *tmr)
+void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar)
{
int64_t d = acpi_pm_tmr_get_clock();
- tmr->overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
+ ar->tmr.overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
}
-uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr)
+uint32_t acpi_pm_tmr_get(ACPIREGS *ar)
{
uint32_t d = acpi_pm_tmr_get_clock();
return d & 0xffffff;
@@ -313,31 +311,31 @@ uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr)
static void acpi_pm_tmr_timer(void *opaque)
{
- ACPIPMTimer *tmr = opaque;
- tmr->update_sci(tmr);
+ ACPIREGS *ar = opaque;
+ ar->tmr.update_sci(ar);
}
-void acpi_pm_tmr_init(ACPIPMTimer *tmr, acpi_update_sci_fn update_sci)
+void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci)
{
- tmr->update_sci = update_sci;
- tmr->timer = qemu_new_timer_ns(vm_clock, acpi_pm_tmr_timer, tmr);
+ ar->tmr.update_sci = update_sci;
+ ar->tmr.timer = qemu_new_timer_ns(vm_clock, acpi_pm_tmr_timer, ar);
}
-void acpi_pm_tmr_reset(ACPIPMTimer *tmr)
+void acpi_pm_tmr_reset(ACPIREGS *ar)
{
- tmr->overflow_time = 0;
- qemu_del_timer(tmr->timer);
+ ar->tmr.overflow_time = 0;
+ qemu_del_timer(ar->tmr.timer);
}
/* ACPI PM1aCNT */
-void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3)
+void acpi_pm1_cnt_init(ACPIREGS *ar, qemu_irq cmos_s3)
{
- pm1_cnt->cmos_s3 = cmos_s3;
+ ar->pm1.cnt.cmos_s3 = cmos_s3;
}
-void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val)
+void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val)
{
- pm1_cnt->cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
+ ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
if (val & ACPI_BITMASK_SLEEP_ENABLE) {
/* change suspend type */
@@ -349,62 +347,62 @@ void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val)
case 1:
/* ACPI_BITMASK_WAKE_STATUS should be set on resume.
Pretend that resume was caused by power button */
- pm1a->sts |=
+ ar->pm1.evt.sts |=
(ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS);
qemu_system_reset_request();
- qemu_irq_raise(pm1_cnt->cmos_s3);
+ qemu_irq_raise(ar->pm1.cnt.cmos_s3);
default:
break;
}
}
}
-void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
+void acpi_pm1_cnt_update(ACPIREGS *ar,
bool sci_enable, bool sci_disable)
{
/* ACPI specs 3.0, 4.7.2.5 */
if (sci_enable) {
- pm1_cnt->cnt |= ACPI_BITMASK_SCI_ENABLE;
+ ar->pm1.cnt.cnt |= ACPI_BITMASK_SCI_ENABLE;
} else if (sci_disable) {
- pm1_cnt->cnt &= ~ACPI_BITMASK_SCI_ENABLE;
+ ar->pm1.cnt.cnt &= ~ACPI_BITMASK_SCI_ENABLE;
}
}
-void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt)
+void acpi_pm1_cnt_reset(ACPIREGS *ar)
{
- pm1_cnt->cnt = 0;
- if (pm1_cnt->cmos_s3) {
- qemu_irq_lower(pm1_cnt->cmos_s3);
+ ar->pm1.cnt.cnt = 0;
+ if (ar->pm1.cnt.cmos_s3) {
+ qemu_irq_lower(ar->pm1.cnt.cmos_s3);
}
}
/* ACPI GPE */
-void acpi_gpe_init(ACPIGPE *gpe, uint8_t len)
+void acpi_gpe_init(ACPIREGS *ar, uint8_t len)
{
- gpe->len = len;
- gpe->sts = g_malloc0(len / 2);
- gpe->en = g_malloc0(len / 2);
+ ar->gpe.len = len;
+ ar->gpe.sts = g_malloc0(len / 2);
+ ar->gpe.en = g_malloc0(len / 2);
}
-void acpi_gpe_blk(ACPIGPE *gpe, uint32_t blk)
+void acpi_gpe_blk(ACPIREGS *ar, uint32_t blk)
{
- gpe->blk = blk;
+ ar->gpe.blk = blk;
}
-void acpi_gpe_reset(ACPIGPE *gpe)
+void acpi_gpe_reset(ACPIREGS *ar)
{
- memset(gpe->sts, 0, gpe->len / 2);
- memset(gpe->en, 0, gpe->len / 2);
+ memset(ar->gpe.sts, 0, ar->gpe.len / 2);
+ memset(ar->gpe.en, 0, ar->gpe.len / 2);
}
-static uint8_t *acpi_gpe_ioport_get_ptr(ACPIGPE *gpe, uint32_t addr)
+static uint8_t *acpi_gpe_ioport_get_ptr(ACPIREGS *ar, uint32_t addr)
{
uint8_t *cur = NULL;
- if (addr < gpe->len / 2) {
- cur = gpe->sts + addr;
- } else if (addr < gpe->len) {
- cur = gpe->en + addr - gpe->len / 2;
+ if (addr < ar->gpe.len / 2) {
+ cur = ar->gpe.sts + addr;
+ } else if (addr < ar->gpe.len) {
+ cur = ar->gpe.en + addr - ar->gpe.len / 2;
} else {
abort();
}
@@ -412,16 +410,16 @@ static uint8_t *acpi_gpe_ioport_get_ptr(ACPIGPE *gpe, uint32_t addr)
return cur;
}
-void acpi_gpe_ioport_writeb(ACPIGPE *gpe, uint32_t addr, uint32_t val)
+void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val)
{
uint8_t *cur;
- addr -= gpe->blk;
- cur = acpi_gpe_ioport_get_ptr(gpe, addr);
- if (addr < gpe->len / 2) {
+ addr -= ar->gpe.blk;
+ cur = acpi_gpe_ioport_get_ptr(ar, addr);
+ if (addr < ar->gpe.len / 2) {
/* GPE_STS */
*cur = (*cur) & ~val;
- } else if (addr < gpe->len) {
+ } else if (addr < ar->gpe.len) {
/* GPE_EN */
*cur = val;
} else {
@@ -429,13 +427,13 @@ void acpi_gpe_ioport_writeb(ACPIGPE *gpe, uint32_t addr, uint32_t val)
}
}
-uint32_t acpi_gpe_ioport_readb(ACPIGPE *gpe, uint32_t addr)
+uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
{
uint8_t *cur;
uint32_t val;
- addr -= gpe->blk;
- cur = acpi_gpe_ioport_get_ptr(gpe, addr);
+ addr -= ar->gpe.blk;
+ cur = acpi_gpe_ioport_get_ptr(ar, addr);
val = 0;
if (cur != NULL) {
val = *cur;
diff --git a/hw/acpi.h b/hw/acpi.h
index 5c43b7d..530c86a 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -78,8 +78,9 @@ typedef struct ACPIPMTimer ACPIPMTimer;
typedef struct ACPIPM1EVT ACPIPM1EVT;
typedef struct ACPIPM1CNT ACPIPM1CNT;
typedef struct ACPIGPE ACPIGPE;
+typedef struct ACPIREGS ACPIREGS;
-typedef void (*acpi_update_sci_fn)(ACPIPMTimer *tmr);
+typedef void (*acpi_update_sci_fn)(ACPIREGS *ar);
struct ACPIPMTimer {
QEMUTimer *timer;
@@ -106,12 +107,21 @@ struct ACPIGPE {
uint8_t *en;
};
+struct ACPIREGS {
+ ACPIPMTimer tmr;
+ ACPIGPE gpe;
+ struct {
+ ACPIPM1EVT evt;
+ ACPIPM1CNT cnt;
+ } pm1;
+};
+
/* PM_TMR */
-void acpi_pm_tmr_update(ACPIPMTimer *tmr, bool enable);
-void acpi_pm_tmr_calc_overflow_time(ACPIPMTimer *tmr);
-uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr);
-void acpi_pm_tmr_init(ACPIPMTimer *tmr, acpi_update_sci_fn update_sci);
-void acpi_pm_tmr_reset(ACPIPMTimer *tmr);
+void acpi_pm_tmr_update(ACPIREGS *ar, bool enable);
+void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar);
+uint32_t acpi_pm_tmr_get(ACPIREGS *ar);
+void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci);
+void acpi_pm_tmr_reset(ACPIREGS *ar);
#include "qemu-timer.h"
static inline int64_t acpi_pm_tmr_get_clock(void)
@@ -121,24 +131,24 @@ static inline int64_t acpi_pm_tmr_get_clock(void)
}
/* PM1a_EVT: piix and ich9 don't implement PM1b. */
-uint16_t acpi_pm1_evt_get_sts(ACPIPM1EVT *pm1, int64_t overflow_time);
-void acpi_pm1_evt_write_sts(ACPIPM1EVT *pm1, ACPIPMTimer *tmr, uint16_t val);
-void acpi_pm1_evt_power_down(ACPIPM1EVT *pm1, ACPIPMTimer *tmr);
-void acpi_pm1_evt_reset(ACPIPM1EVT *pm1);
+uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar, int64_t overflow_time);
+void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val);
+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(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3);
-void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val);
-void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
+void acpi_pm1_cnt_init(ACPIREGS *ar, qemu_irq cmos_s3);
+void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val);
+void acpi_pm1_cnt_update(ACPIREGS *ar,
bool sci_enable, bool sci_disable);
-void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt);
+void acpi_pm1_cnt_reset(ACPIREGS *ar);
/* GPE0 */
-void acpi_gpe_init(ACPIGPE *gpe, uint8_t len);
-void acpi_gpe_blk(ACPIGPE *gpe, uint32_t blk);
-void acpi_gpe_reset(ACPIGPE *gpe);
+void acpi_gpe_init(ACPIREGS *ar, uint8_t len);
+void acpi_gpe_blk(ACPIREGS *ar, uint32_t blk);
+void acpi_gpe_reset(ACPIREGS *ar);
-void acpi_gpe_ioport_writeb(ACPIGPE *gpe, uint32_t addr, uint32_t val);
-uint32_t acpi_gpe_ioport_readb(ACPIGPE *gpe, uint32_t addr);
+void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val);
+uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
#endif /* !QEMU_HW_ACPI_H */
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 21484ae..afb37e2 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -54,13 +54,10 @@ struct pci_status {
typedef struct PIIX4PMState {
PCIDevice dev;
IORange ioport;
- ACPIPM1EVT pm1a;
- ACPIPM1CNT pm1_cnt;
+ ACPIREGS ar;
APMState apm;
- ACPIPMTimer tmr;
-
PMSMBus smb;
uint32_t smb_io_base;
@@ -70,7 +67,6 @@ typedef struct PIIX4PMState {
Notifier machine_ready;
/* for pci hotplug */
- ACPIGPE gpe;
struct pci_status pci0_status;
uint32_t pci0_hotplug_enable;
} PIIX4PMState;
@@ -84,23 +80,24 @@ static void pm_update_sci(PIIX4PMState *s)
{
int sci_level, pmsts;
- pmsts = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
- sci_level = (((pmsts & s->pm1a.en) &
+ pmsts = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
+ sci_level = (((pmsts & s->ar.pm1.evt.en) &
(ACPI_BITMASK_RT_CLOCK_ENABLE |
ACPI_BITMASK_POWER_BUTTON_ENABLE |
ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
- (((s->gpe.sts[0] & s->gpe.en[0]) & PIIX4_PCI_HOTPLUG_STATUS) != 0);
+ (((s->ar.gpe.sts[0] & s->ar.gpe.en[0])
+ & PIIX4_PCI_HOTPLUG_STATUS) != 0);
qemu_set_irq(s->irq, sci_level);
/* schedule a timer interruption if needed */
- acpi_pm_tmr_update(&s->tmr, (s->pm1a.en & ACPI_BITMASK_TIMER_ENABLE) &&
+ acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
!(pmsts & ACPI_BITMASK_TIMER_STATUS));
}
-static void pm_tmr_timer(ACPIPMTimer *tmr)
+static void pm_tmr_timer(ACPIREGS *ar)
{
- PIIX4PMState *s = container_of(tmr, PIIX4PMState, tmr);
+ PIIX4PMState *s = container_of(ar, PIIX4PMState, ar);
pm_update_sci(s);
}
@@ -116,15 +113,15 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
switch(addr) {
case 0x00:
- acpi_pm1_evt_write_sts(&s->pm1a, &s->tmr, val);
+ acpi_pm1_evt_write_sts(&s->ar, val);
pm_update_sci(s);
break;
case 0x02:
- s->pm1a.en = val;
+ s->ar.pm1.evt.en = val;
pm_update_sci(s);
break;
case 0x04:
- acpi_pm1_cnt_write(&s->pm1a, &s->pm1_cnt, val);
+ acpi_pm1_cnt_write(&s->ar, val);
break;
default:
break;
@@ -141,16 +138,16 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
switch(addr) {
case 0x00:
- val = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
+ val = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
break;
case 0x02:
- val = s->pm1a.en;
+ val = s->ar.pm1.evt.en;
break;
case 0x04:
- val = s->pm1_cnt.cnt;
+ val = s->ar.pm1.cnt.cnt;
break;
case 0x08:
- val = acpi_pm_tmr_get(&s->tmr);
+ val = acpi_pm_tmr_get(&s->ar);
break;
default:
val = 0;
@@ -170,7 +167,7 @@ static void apm_ctrl_changed(uint32_t val, void *arg)
PIIX4PMState *s = arg;
/* ACPI specs 3.0, 4.7.2.5 */
- acpi_pm1_cnt_update(&s->pm1_cnt, val == ACPI_ENABLE, val == ACPI_DISABLE);
+ acpi_pm1_cnt_update(&s->ar, val == ACPI_ENABLE, val == ACPI_DISABLE);
if (s->dev.config[0x5b] & (1 << 1)) {
if (s->smi_irq) {
@@ -258,13 +255,13 @@ static const VMStateDescription vmstate_acpi = {
.post_load = vmstate_acpi_post_load,
.fields = (VMStateField []) {
VMSTATE_PCI_DEVICE(dev, PIIX4PMState),
- VMSTATE_UINT16(pm1a.sts, PIIX4PMState),
- VMSTATE_UINT16(pm1a.en, PIIX4PMState),
- VMSTATE_UINT16(pm1_cnt.cnt, PIIX4PMState),
+ VMSTATE_UINT16(ar.pm1.evt.sts, PIIX4PMState),
+ VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),
+ VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState),
VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
- VMSTATE_TIMER(tmr.timer, PIIX4PMState),
- VMSTATE_INT64(tmr.overflow_time, PIIX4PMState),
- VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
+ VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState),
+ VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState),
+ VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status,
struct pci_status),
VMSTATE_END_OF_LIST()
@@ -310,10 +307,9 @@ static void piix4_reset(void *opaque)
static void piix4_powerdown(void *opaque, int irq, int power_failing)
{
PIIX4PMState *s = opaque;
- ACPIPM1EVT *pm1a = s? &s->pm1a: NULL;
- ACPIPMTimer *tmr = s? &s->tmr: NULL;
- acpi_pm1_evt_power_down(pm1a, tmr);
+ assert(s != NULL);
+ acpi_pm1_evt_power_down(&s->ar);
}
static void piix4_pm_machine_ready(Notifier *n, void *opaque)
@@ -361,8 +357,8 @@ 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);
- acpi_pm_tmr_init(&s->tmr, pm_tmr_timer);
- acpi_gpe_init(&s->gpe, GPE_LEN);
+ acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
+ acpi_gpe_init(&s->ar, GPE_LEN);
qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1);
@@ -387,7 +383,7 @@ 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);
+ acpi_pm1_cnt_init(&s->ar, cmos_s3);
s->smi_irq = smi_irq;
s->kvm_enabled = kvm_enabled;
@@ -436,7 +432,7 @@ device_init(piix4_pm_register);
static uint32_t gpe_readb(void *opaque, uint32_t addr)
{
PIIX4PMState *s = opaque;
- uint32_t val = acpi_gpe_ioport_readb(&s->gpe, addr);
+ uint32_t val = acpi_gpe_ioport_readb(&s->ar, addr);
PIIX4_DPRINTF("gpe read %x == %x\n", addr, val);
return val;
@@ -446,7 +442,7 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
{
PIIX4PMState *s = opaque;
- acpi_gpe_ioport_writeb(&s->gpe, addr, val);
+ acpi_gpe_ioport_writeb(&s->ar, addr, val);
pm_update_sci(s);
PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
@@ -531,7 +527,7 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s);
register_ioport_read(GPE_BASE, GPE_LEN, 1, gpe_readb, s);
- acpi_gpe_blk(&s->gpe, GPE_BASE);
+ acpi_gpe_blk(&s->ar, GPE_BASE);
register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status);
register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, pci0_status);
@@ -547,13 +543,13 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
static void enable_device(PIIX4PMState *s, int slot)
{
- s->gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
+ s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
s->pci0_status.up |= (1 << slot);
}
static void disable_device(PIIX4PMState *s, int slot)
{
- s->gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
+ s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
s->pci0_status.down |= (1 << slot);
}
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index aa0954f..8370434 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -159,10 +159,8 @@ static void vt82c686b_write_config(PCIDevice * d, uint32_t address,
typedef struct VT686PMState {
PCIDevice dev;
- ACPIPM1EVT pm1a;
- ACPIPM1CNT pm1_cnt;
+ ACPIREGS ar;
APMState apm;
- ACPIPMTimer tmr;
PMSMBus smb;
uint32_t smb_io_base;
} VT686PMState;
@@ -179,21 +177,21 @@ static void pm_update_sci(VT686PMState *s)
{
int sci_level, pmsts;
- pmsts = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
- sci_level = (((pmsts & s->pm1a.en) &
+ pmsts = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
+ sci_level = (((pmsts & s->ar.pm1.evt.en) &
(ACPI_BITMASK_RT_CLOCK_ENABLE |
ACPI_BITMASK_POWER_BUTTON_ENABLE |
ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
ACPI_BITMASK_TIMER_ENABLE)) != 0);
qemu_set_irq(s->dev.irq[0], sci_level);
/* schedule a timer interruption if needed */
- acpi_pm_tmr_update(&s->tmr, (s->pm1a.en & ACPI_BITMASK_TIMER_ENABLE) &&
+ acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
!(pmsts & ACPI_BITMASK_TIMER_STATUS));
}
-static void pm_tmr_timer(ACPIPMTimer *tmr)
+static void pm_tmr_timer(ACPIREGS *ar)
{
- VT686PMState *s = container_of(tmr, VT686PMState, tmr);
+ VT686PMState *s = container_of(ar, VT686PMState, ar);
pm_update_sci(s);
}
@@ -204,15 +202,15 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
addr &= 0x0f;
switch (addr) {
case 0x00:
- acpi_pm1_evt_write_sts(&s->pm1a, &s->tmr, val);
+ acpi_pm1_evt_write_sts(&s->ar, val);
pm_update_sci(s);
break;
case 0x02:
- s->pm1a.en = val;
+ s->ar.pm1.evt.en = val;
pm_update_sci(s);
break;
case 0x04:
- acpi_pm1_cnt_write(&s->pm1a, &s->pm1_cnt, val);
+ acpi_pm1_cnt_write(&s->ar, val);
break;
default:
break;
@@ -228,13 +226,13 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
addr &= 0x0f;
switch (addr) {
case 0x00:
- val = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
+ val = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
break;
case 0x02:
- val = s->pm1a.en;
+ val = s->ar.pm1.evt.en;
break;
case 0x04:
- val = s->pm1_cnt.cnt;
+ val = s->ar.pm1.cnt.cnt;
break;
default:
val = 0;
@@ -258,7 +256,7 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
addr &= 0x0f;
switch (addr) {
case 0x08:
- val = acpi_pm_tmr_get(&s->tmr);
+ val = acpi_pm_tmr_get(&s->ar);
break;
default:
val = 0;
@@ -309,12 +307,12 @@ static const VMStateDescription vmstate_acpi = {
.post_load = vmstate_acpi_post_load,
.fields = (VMStateField []) {
VMSTATE_PCI_DEVICE(dev, VT686PMState),
- VMSTATE_UINT16(pm1a.sts, VT686PMState),
- VMSTATE_UINT16(pm1a.en, VT686PMState),
- VMSTATE_UINT16(pm1_cnt.cnt, VT686PMState),
+ VMSTATE_UINT16(ar.pm1.evt.sts, VT686PMState),
+ VMSTATE_UINT16(ar.pm1.evt.en, VT686PMState),
+ VMSTATE_UINT16(ar.pm1.cnt.cnt, VT686PMState),
VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState),
- VMSTATE_TIMER(tmr.timer, VT686PMState),
- VMSTATE_INT64(tmr.overflow_time, VT686PMState),
+ VMSTATE_TIMER(ar.tmr.timer, VT686PMState),
+ VMSTATE_INT64(ar.tmr.overflow_time, VT686PMState),
VMSTATE_END_OF_LIST()
}
};
@@ -445,8 +443,8 @@ 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);
+ acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
+ acpi_pm1_cnt_init(&s->ar, NULL);
pm_smbus_init(&s->dev.qdev, &s->smb);
--
1.7.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 03/12] acpi: don't pass overflow_time to acpi_pm1_evt_get_sts
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 01/12] acpi: move around structs Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 02/12] acpi: add ACPIREGS Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 04/12] acpi: add acpi_pm1_evt_write_en Gerd Hoffmann
` (8 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Pretty pointless, can easily be reached via ACPIREGS now.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/acpi.c | 6 +++---
hw/acpi.h | 2 +-
hw/acpi_piix4.c | 4 ++--
hw/vt82c686.c | 4 ++--
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/hw/acpi.c b/hw/acpi.c
index 1922e53..1129335 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -249,10 +249,10 @@ int acpi_table_add(const char *t)
}
/* ACPI PM1a EVT */
-uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar, int64_t overflow_time)
+uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar)
{
int64_t d = acpi_pm_tmr_get_clock();
- if (d >= overflow_time) {
+ if (d >= ar->tmr.overflow_time) {
ar->pm1.evt.sts |= ACPI_BITMASK_TIMER_STATUS;
}
return ar->pm1.evt.sts;
@@ -260,7 +260,7 @@ uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar, int64_t overflow_time)
void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
{
- uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar, ar->tmr.overflow_time);
+ uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar);
if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) {
/* if TMRSTS is reset, then compute the new overflow time */
acpi_pm_tmr_calc_overflow_time(ar);
diff --git a/hw/acpi.h b/hw/acpi.h
index 530c86a..e1d5e3b 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -131,7 +131,7 @@ static inline int64_t acpi_pm_tmr_get_clock(void)
}
/* PM1a_EVT: piix and ich9 don't implement PM1b. */
-uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar, int64_t overflow_time);
+uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar);
void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val);
void acpi_pm1_evt_power_down(ACPIREGS *ar);
void acpi_pm1_evt_reset(ACPIREGS *ar);
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index afb37e2..b6899f4 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -80,7 +80,7 @@ static void pm_update_sci(PIIX4PMState *s)
{
int sci_level, pmsts;
- pmsts = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
+ pmsts = acpi_pm1_evt_get_sts(&s->ar);
sci_level = (((pmsts & s->ar.pm1.evt.en) &
(ACPI_BITMASK_RT_CLOCK_ENABLE |
ACPI_BITMASK_POWER_BUTTON_ENABLE |
@@ -138,7 +138,7 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
switch(addr) {
case 0x00:
- val = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
+ val = acpi_pm1_evt_get_sts(&s->ar);
break;
case 0x02:
val = s->ar.pm1.evt.en;
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 8370434..10e066b 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -177,7 +177,7 @@ static void pm_update_sci(VT686PMState *s)
{
int sci_level, pmsts;
- pmsts = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
+ pmsts = acpi_pm1_evt_get_sts(&s->ar);
sci_level = (((pmsts & s->ar.pm1.evt.en) &
(ACPI_BITMASK_RT_CLOCK_ENABLE |
ACPI_BITMASK_POWER_BUTTON_ENABLE |
@@ -226,7 +226,7 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
addr &= 0x0f;
switch (addr) {
case 0x00:
- val = acpi_pm1_evt_get_sts(&s->ar, s->ar.tmr.overflow_time);
+ val = acpi_pm1_evt_get_sts(&s->ar);
break;
case 0x02:
val = s->ar.pm1.evt.en;
--
1.7.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 04/12] acpi: add acpi_pm1_evt_write_en
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
` (2 preceding siblings ...)
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 03/12] acpi: don't pass overflow_time to acpi_pm1_evt_get_sts Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 05/12] suspend: add infrastructure Gerd Hoffmann
` (7 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Do APCIREGS->pm1.evt.en updates using the new acpi_pm1_evt_write_en
function, so the acpi code will see those updates.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/acpi.c | 5 +++++
hw/acpi.h | 1 +
hw/acpi_piix4.c | 2 +-
hw/vt82c686.c | 2 +-
4 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/hw/acpi.c b/hw/acpi.c
index 1129335..407949b 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -268,6 +268,11 @@ void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
ar->pm1.evt.sts &= ~val;
}
+void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val)
+{
+ ar->pm1.evt.en = val;
+}
+
void acpi_pm1_evt_power_down(ACPIREGS *ar)
{
if (ar->pm1.evt.en & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
diff --git a/hw/acpi.h b/hw/acpi.h
index e1d5e3b..88f8051 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -133,6 +133,7 @@ static inline int64_t acpi_pm_tmr_get_clock(void)
/* PM1a_EVT: piix and ich9 don't implement PM1b. */
uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar);
void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val);
+void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val);
void acpi_pm1_evt_power_down(ACPIREGS *ar);
void acpi_pm1_evt_reset(ACPIREGS *ar);
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index b6899f4..9c72e62 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -117,7 +117,7 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
pm_update_sci(s);
break;
case 0x02:
- s->ar.pm1.evt.en = val;
+ acpi_pm1_evt_write_en(&s->ar, val);
pm_update_sci(s);
break;
case 0x04:
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 10e066b..d8f4e26 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -206,7 +206,7 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
pm_update_sci(s);
break;
case 0x02:
- s->ar.pm1.evt.en = val;
+ acpi_pm1_evt_write_en(&s->ar, val);
pm_update_sci(s);
break;
case 0x04:
--
1.7.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 05/12] suspend: add infrastructure
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
` (3 preceding siblings ...)
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 04/12] acpi: add acpi_pm1_evt_write_en Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 06/12] suspend: switch acpi s3 to new infrastructure Gerd Hoffmann
` (6 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
This patch adds some infrastructure to handle suspend and resume to
qemu. First there are two functions to switch state and second there
is a suspend notifier:
* qemu_system_suspend_request is supposed to be called when the
guest asks for being be suspended, for example via ACPI.
* qemu_system_wakeup_request is supposed to be called on events
which should wake up the guest.
* qemu_register_suspend_notifier can be used to register a notifier
which will be called when the guest is suspended. Machine types
and device models can hook in there to modify state if needed.
* qemu_register_wakeup_notifier can be used to register a notifier
which will be called when the guest is woken up. Machine types
and device models can hook in there to modify state if needed.
* qemu_system_wakeup_enable can be used to enable/disable wakeup
events.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
sysemu.h | 9 ++++++++
vl.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 76 insertions(+), 0 deletions(-)
diff --git a/sysemu.h b/sysemu.h
index 9d5ce33..af73813 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -38,7 +38,16 @@ void vm_start(void);
void vm_stop(RunState state);
void vm_stop_force_state(RunState state);
+typedef enum WakeupReason {
+ QEMU_WAKEUP_REASON_OTHER = 0,
+} WakeupReason;
+
void qemu_system_reset_request(void);
+void qemu_system_suspend_request(void);
+void qemu_register_suspend_notifier(Notifier *notifier);
+void qemu_system_wakeup_request(WakeupReason reason);
+void qemu_system_wakeup_enable(WakeupReason reason, bool enabled);
+void qemu_register_wakeup_notifier(Notifier *notifier);
void qemu_system_shutdown_request(void);
void qemu_system_powerdown_request(void);
void qemu_system_debug_request(void);
diff --git a/vl.c b/vl.c
index 63dd725..bfdcb7c 100644
--- a/vl.c
+++ b/vl.c
@@ -1283,6 +1283,13 @@ static int shutdown_requested, shutdown_signal = -1;
static pid_t shutdown_pid;
static int powerdown_requested;
static int debug_requested;
+static int suspend_requested;
+static bool is_suspended;
+static NotifierList suspend_notifiers =
+ NOTIFIER_LIST_INITIALIZER(suspend_notifiers);
+static NotifierList wakeup_notifiers =
+ NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
+static uint32_t wakeup_reason_mask = ~0;
static RunState vmstop_requested = RUN_STATE_MAX;
int qemu_shutdown_requested_get(void)
@@ -1325,6 +1332,13 @@ int qemu_reset_requested(void)
return r;
}
+static int qemu_suspend_requested(void)
+{
+ int r = suspend_requested;
+ suspend_requested = 0;
+ return r;
+}
+
int qemu_powerdown_requested(void)
{
int r = powerdown_requested;
@@ -1398,6 +1412,56 @@ void qemu_system_reset_request(void)
qemu_notify_event();
}
+static void qemu_system_suspend(void)
+{
+ pause_all_vcpus();
+ notifier_list_notify(&suspend_notifiers, NULL);
+ is_suspended = true;
+}
+
+void qemu_system_suspend_request(void)
+{
+ if (is_suspended) {
+ return;
+ }
+ suspend_requested = 1;
+ cpu_stop_current();
+ qemu_notify_event();
+}
+
+void qemu_register_suspend_notifier(Notifier *notifier)
+{
+ notifier_list_add(&suspend_notifiers, notifier);
+}
+
+void qemu_system_wakeup_request(WakeupReason reason)
+{
+ if (!is_suspended) {
+ return;
+ }
+ if (!(wakeup_reason_mask & (1 << reason))) {
+ return;
+ }
+ notifier_list_notify(&wakeup_notifiers, &reason);
+ reset_requested = 1;
+ qemu_notify_event();
+ is_suspended = false;
+}
+
+void qemu_system_wakeup_enable(WakeupReason reason, bool enabled)
+{
+ if (enabled) {
+ wakeup_reason_mask |= (1 << reason);
+ } else {
+ wakeup_reason_mask &= ~(1 << reason);
+ }
+}
+
+void qemu_register_wakeup_notifier(Notifier *notifier)
+{
+ notifier_list_add(&wakeup_notifiers, notifier);
+}
+
void qemu_system_killed(int signal, pid_t pid)
{
shutdown_signal = signal;
@@ -1438,6 +1502,9 @@ static bool main_loop_should_exit(void)
if (qemu_debug_requested()) {
vm_stop(RUN_STATE_DEBUG);
}
+ if (qemu_suspend_requested()) {
+ qemu_system_suspend();
+ }
if (qemu_shutdown_requested()) {
qemu_kill_report();
monitor_protocol_event(QEVENT_SHUTDOWN, NULL);
--
1.7.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 06/12] suspend: switch acpi s3 to new infrastructure.
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
` (4 preceding siblings ...)
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 05/12] suspend: add infrastructure Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 07/12] suspend: add system_wakeup monitor command Gerd Hoffmann
` (5 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
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 <kraxel@redhat.com>
---
hw/acpi.c | 32 +++++++++++++++++++++-----------
hw/acpi.h | 4 ++--
hw/acpi_piix4.c | 4 ++--
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 | 2 +-
xen-all.c | 11 ++++++-----
10 files changed, 47 insertions(+), 42 deletions(-)
diff --git a/hw/acpi.c b/hw/acpi.c
index 407949b..7b16716 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -248,6 +248,22 @@ int acpi_table_add(const char *t)
}
+static void acpi_notify_wakeup(Notifier *notifier, void *data)
+{
+ ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup);
+ WakeupReason *reason = data;
+
+ switch (*reason) {
+ case QEMU_WAKEUP_REASON_OTHER:
+ default:
+ /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
+ Pretend that resume was caused by power button */
+ ar->pm1.evt.sts |=
+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS);
+ break;
+ }
+}
+
/* ACPI PM1a EVT */
uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar)
{
@@ -333,9 +349,10 @@ void acpi_pm_tmr_reset(ACPIREGS *ar)
}
/* ACPI PM1aCNT */
-void acpi_pm1_cnt_init(ACPIREGS *ar, qemu_irq cmos_s3)
+void acpi_pm1_cnt_init(ACPIREGS *ar)
{
- ar->pm1.cnt.cmos_s3 = cmos_s3;
+ ar->wakeup.notify = acpi_notify_wakeup;
+ qemu_register_wakeup_notifier(&ar->wakeup);
}
void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val)
@@ -350,12 +367,8 @@ void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val)
qemu_system_shutdown_request();
break;
case 1:
- /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
- Pretend that resume was caused by power button */
- ar->pm1.evt.sts |=
- (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS);
- qemu_system_reset_request();
- qemu_irq_raise(ar->pm1.cnt.cmos_s3);
+ qemu_system_suspend_request();
+ break;
default:
break;
}
@@ -376,9 +389,6 @@ void acpi_pm1_cnt_update(ACPIREGS *ar,
void acpi_pm1_cnt_reset(ACPIREGS *ar)
{
ar->pm1.cnt.cnt = 0;
- if (ar->pm1.cnt.cmos_s3) {
- qemu_irq_lower(ar->pm1.cnt.cmos_s3);
- }
}
/* ACPI GPE */
diff --git a/hw/acpi.h b/hw/acpi.h
index 88f8051..fe8cdb4 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -96,7 +96,6 @@ struct ACPIPM1EVT {
struct ACPIPM1CNT {
uint16_t cnt;
- qemu_irq cmos_s3;
};
struct ACPIGPE {
@@ -114,6 +113,7 @@ struct ACPIREGS {
ACPIPM1EVT evt;
ACPIPM1CNT cnt;
} pm1;
+ Notifier wakeup;
};
/* PM_TMR */
@@ -138,7 +138,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, qemu_irq cmos_s3);
+void acpi_pm1_cnt_init(ACPIREGS *ar);
void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val);
void acpi_pm1_cnt_update(ACPIREGS *ar,
bool sci_enable, bool sci_disable);
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 9c72e62..f7f0a47 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -372,7 +372,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;
@@ -383,7 +383,7 @@ 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, cmos_s3);
+ acpi_pm1_cnt_init(&s->ar);
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 d8f4e26..75e29f8 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -444,7 +444,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
apm_init(&s->apm, NULL, s);
acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
- acpi_pm1_cnt_init(&s->ar, NULL);
+ acpi_pm1_cnt_init(&s->ar);
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
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 07/12] suspend: add system_wakeup monitor command
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
` (5 preceding siblings ...)
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 06/12] suspend: switch acpi s3 to new infrastructure Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-17 17:32 ` Luiz Capitulino
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 08/12] suspend: make ps/2 devices wakeup the guest Gerd Hoffmann
` (4 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
This patch adds the system_wakeup monitor command which will simply
wake up suspended guests.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hmp-commands.hx | 14 ++++++++++++++
hmp.c | 5 +++++
hmp.h | 1 +
qapi-schema.json | 11 +++++++++++
qmp-commands.hx | 21 +++++++++++++++++++++
qmp.c | 5 +++++
6 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 573b823..64b3656 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -352,6 +352,20 @@ Resume emulation.
ETEXI
{
+ .name = "system_wakeup",
+ .args_type = "",
+ .params = "",
+ .help = "wakeup guest from suspend",
+ .mhandler.cmd = hmp_system_wakeup,
+ },
+
+STEXI
+@item system_wakeup
+@findex system_wakeup
+Wakeup guest from suspend.
+ETEXI
+
+ {
.name = "gdbserver",
.args_type = "device:s?",
.params = "[device]",
diff --git a/hmp.c b/hmp.c
index 8ff8c94..3a54455 100644
--- a/hmp.c
+++ b/hmp.c
@@ -632,6 +632,11 @@ void hmp_cont(Monitor *mon, const QDict *qdict)
}
}
+void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
+{
+ qmp_system_wakeup(NULL);
+}
+
void hmp_inject_nmi(Monitor *mon, const QDict *qdict)
{
Error *errp = NULL;
diff --git a/hmp.h b/hmp.h
index 18eecbd..5409464 100644
--- a/hmp.h
+++ b/hmp.h
@@ -41,6 +41,7 @@ void hmp_cpu(Monitor *mon, const QDict *qdict);
void hmp_memsave(Monitor *mon, const QDict *qdict);
void hmp_pmemsave(Monitor *mon, const QDict *qdict);
void hmp_cont(Monitor *mon, const QDict *qdict);
+void hmp_system_wakeup(Monitor *mon, const QDict *qdict);
void hmp_inject_nmi(Monitor *mon, const QDict *qdict);
void hmp_set_link(Monitor *mon, const QDict *qdict);
void hmp_block_passwd(Monitor *mon, const QDict *qdict);
diff --git a/qapi-schema.json b/qapi-schema.json
index d02ee86..226c1da 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -999,6 +999,17 @@
{ 'command': 'cont' }
##
+# @system_wakeup:
+#
+# Wakeup guest from suspend
+#
+# Since: 1.1
+#
+# Returns: nothing.
+##
+{ 'command': 'system_wakeup' }
+
+##
# @inject-nmi:
#
# Injects an Non-Maskable Interrupt into all guest's VCPUs.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index b5e2ab8..f5081e2 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -212,6 +212,27 @@ Example:
EQMP
{
+ .name = "system_wakeup",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_system_wakeup,
+ },
+
+SQMP
+system_wakeup
+-------------
+
+Wakeup guest from suspend.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "system_wakeup" }
+<- { "return": {} }
+
+EQMP
+
+ {
.name = "system_reset",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_input_system_reset,
diff --git a/qmp.c b/qmp.c
index 1f64844..a182b51 100644
--- a/qmp.c
+++ b/qmp.c
@@ -163,6 +163,11 @@ void qmp_cont(Error **errp)
vm_start();
}
+void qmp_system_wakeup(Error **errp)
+{
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
+}
+
ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
{
Object *obj;
--
1.7.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 08/12] suspend: make ps/2 devices wakeup the guest
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
` (6 preceding siblings ...)
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 07/12] suspend: add system_wakeup monitor command Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 09/12] suspend: make serial ports " Gerd Hoffmann
` (3 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
This patch adds wakeup support to ps/2 emulation. Any key press on the
ps/2 keyboard will wakeup the guest. Likewise any mouse button press
will wakeup the guest. Mouse moves are ignored, so the guest will not
wakeup in case your mouse crosses the vnc window of a suspended guest by
accident.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/ps2.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/hw/ps2.c b/hw/ps2.c
index 1d9057b..b1a67bc 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -24,6 +24,7 @@
#include "hw.h"
#include "ps2.h"
#include "console.h"
+#include "sysemu.h"
/* debug PC keyboard */
//#define DEBUG_KBD
@@ -154,6 +155,7 @@ static void ps2_put_keycode(void *opaque, int keycode)
{
PS2KbdState *s = opaque;
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
/* XXX: add support for scancode set 1 */
if (!s->translate && keycode < 0xe0 && s->scancode_set > 1) {
if (keycode & 0x80) {
@@ -368,6 +370,10 @@ static void ps2_mouse_event(void *opaque,
return;
s->mouse_buttons = buttons_state;
+ if (buttons_state) {
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
+ }
+
if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
(s->common.queue.count < (PS2_QUEUE_SIZE - 16))) {
for(;;) {
--
1.7.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 09/12] suspend: make serial ports wakeup the guest.
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
` (7 preceding siblings ...)
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 08/12] suspend: make ps/2 devices wakeup the guest Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 10/12] suspend: make rtc alarm " Gerd Hoffmann
` (2 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add a 'wakeup' property to the serial port. It is off by default. When
enabled any incoming character on the serial line will wake up the
guest. Useful for guests which have a serial console configured.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/serial.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/hw/serial.c b/hw/serial.c
index 82917e2..8224607 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -139,6 +139,7 @@ struct SerialState {
int it_shift;
int baudbase;
int tsr_retry;
+ uint32_t wakeup;
uint64_t last_xmit_ts; /* Time when the last byte was successfully sent out of the tsr */
SerialFIFO recv_fifo;
@@ -635,6 +636,10 @@ static int serial_can_receive1(void *opaque)
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
{
SerialState *s = opaque;
+
+ if (s->wakeup) {
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
+ }
if(s->fcr & UART_FCR_FE) {
int i;
for (i = 0; i < size; i++) {
@@ -884,6 +889,7 @@ static Property serial_isa_properties[] = {
DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, -1),
DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1),
DEFINE_PROP_CHR("chardev", ISASerialState, state.chr),
+ DEFINE_PROP_UINT32("wakeup", ISASerialState, state.wakeup, 0),
DEFINE_PROP_END_OF_LIST(),
};
--
1.7.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 10/12] suspend: make rtc alarm wakeup the guest.
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
` (8 preceding siblings ...)
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 09/12] suspend: make serial ports " Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 11/12] suspend: make acpi timer " Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events Gerd Hoffmann
11 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Make the rtc wake up the guest when the alarm fires.
Add acpi windup to property support RTC_EN, so guests
can enable and disable this.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/acpi.c | 7 +++++++
hw/mc146818rtc.c | 1 +
sysemu.h | 1 +
3 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/hw/acpi.c b/hw/acpi.c
index 7b16716..c05dde6 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -254,6 +254,10 @@ static void acpi_notify_wakeup(Notifier *notifier, void *data)
WakeupReason *reason = data;
switch (*reason) {
+ case QEMU_WAKEUP_REASON_RTC:
+ ar->pm1.evt.sts |=
+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS);
+ break;
case QEMU_WAKEUP_REASON_OTHER:
default:
/* ACPI_BITMASK_WAKE_STATUS should be set on resume.
@@ -287,6 +291,8 @@ void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val)
{
ar->pm1.evt.en = val;
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC,
+ val & ACPI_BITMASK_RT_CLOCK_ENABLE);
}
void acpi_pm1_evt_power_down(ACPIREGS *ar)
@@ -301,6 +307,7 @@ void acpi_pm1_evt_reset(ACPIREGS *ar)
{
ar->pm1.evt.sts = 0;
ar->pm1.evt.en = 0;
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, 0);
}
/* ACPI PM_TMR */
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 314ed52..37adddb 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -437,6 +437,7 @@ static void rtc_update_second2(void *opaque)
s->cmos_data[RTC_REG_C] |= REG_C_AF;
if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC);
qemu_irq_raise(s->irq);
s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
}
diff --git a/sysemu.h b/sysemu.h
index af73813..781bdaf 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -40,6 +40,7 @@ void vm_stop_force_state(RunState state);
typedef enum WakeupReason {
QEMU_WAKEUP_REASON_OTHER = 0,
+ QEMU_WAKEUP_REASON_RTC,
} WakeupReason;
void qemu_system_reset_request(void);
--
1.7.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 11/12] suspend: make acpi timer wakeup the guest.
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
` (9 preceding siblings ...)
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 10/12] suspend: make rtc alarm " Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events Gerd Hoffmann
11 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Make the acpi timer wake up the guest.
Guests can enable/disable this via acpi too.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/acpi.c | 8 ++++++++
sysemu.h | 1 +
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/hw/acpi.c b/hw/acpi.c
index c05dde6..5d521e5 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -258,6 +258,10 @@ static void acpi_notify_wakeup(Notifier *notifier, void *data)
ar->pm1.evt.sts |=
(ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS);
break;
+ case QEMU_WAKEUP_REASON_PMTIMER:
+ ar->pm1.evt.sts |=
+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS);
+ break;
case QEMU_WAKEUP_REASON_OTHER:
default:
/* ACPI_BITMASK_WAKE_STATUS should be set on resume.
@@ -293,6 +297,8 @@ void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val)
ar->pm1.evt.en = val;
qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC,
val & ACPI_BITMASK_RT_CLOCK_ENABLE);
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER,
+ val & ACPI_BITMASK_TIMER_ENABLE);
}
void acpi_pm1_evt_power_down(ACPIREGS *ar)
@@ -308,6 +314,7 @@ void acpi_pm1_evt_reset(ACPIREGS *ar)
ar->pm1.evt.sts = 0;
ar->pm1.evt.en = 0;
qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, 0);
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, 0);
}
/* ACPI PM_TMR */
@@ -340,6 +347,7 @@ uint32_t acpi_pm_tmr_get(ACPIREGS *ar)
static void acpi_pm_tmr_timer(void *opaque)
{
ACPIREGS *ar = opaque;
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_PMTIMER);
ar->tmr.update_sci(ar);
}
diff --git a/sysemu.h b/sysemu.h
index 781bdaf..98118cc 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -41,6 +41,7 @@ void vm_stop_force_state(RunState state);
typedef enum WakeupReason {
QEMU_WAKEUP_REASON_OTHER = 0,
QEMU_WAKEUP_REASON_RTC,
+ QEMU_WAKEUP_REASON_PMTIMER,
} WakeupReason;
void qemu_system_reset_request(void);
--
1.7.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
` (10 preceding siblings ...)
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 11/12] suspend: make acpi timer " Gerd Hoffmann
@ 2012-02-15 10:28 ` Gerd Hoffmann
2012-02-17 14:23 ` Anthony Liguori
2012-02-17 17:33 ` Luiz Capitulino
11 siblings, 2 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-15 10:28 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Send qmp events on suspend and wakeup so libvirt
has a chance to track the vm state.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
monitor.c | 6 ++++++
monitor.h | 2 ++
vl.c | 15 +++++++++++++++
3 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/monitor.c b/monitor.c
index aadbdcb..e6f5fad 100644
--- a/monitor.c
+++ b/monitor.c
@@ -485,6 +485,12 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
case QEVENT_BLOCK_JOB_CANCELLED:
event_name = "BLOCK_JOB_CANCELLED";
break;
+ case QEVENT_SUSPEND:
+ event_name = "SUSPEND";
+ break;
+ case QEVENT_WAKEUP:
+ event_name = "WAKEUP";
+ break;
default:
abort();
break;
diff --git a/monitor.h b/monitor.h
index b72ea07..9df3bab 100644
--- a/monitor.h
+++ b/monitor.h
@@ -38,6 +38,8 @@ typedef enum MonitorEvent {
QEVENT_SPICE_DISCONNECTED,
QEVENT_BLOCK_JOB_COMPLETED,
QEVENT_BLOCK_JOB_CANCELLED,
+ QEVENT_SUSPEND,
+ QEVENT_WAKEUP,
QEVENT_MAX,
} MonitorEvent;
diff --git a/vl.c b/vl.c
index bfdcb7c..570ea05 100644
--- a/vl.c
+++ b/vl.c
@@ -1416,6 +1416,7 @@ static void qemu_system_suspend(void)
{
pause_all_vcpus();
notifier_list_notify(&suspend_notifiers, NULL);
+ monitor_protocol_event(QEVENT_SUSPEND, NULL);
is_suspended = true;
}
@@ -1436,12 +1437,26 @@ void qemu_register_suspend_notifier(Notifier *notifier)
void qemu_system_wakeup_request(WakeupReason reason)
{
+ static const char *names[] = {
+ [QEMU_WAKEUP_REASON_OTHER] = "other",
+ [QEMU_WAKEUP_REASON_RTC] = "rtc",
+ [QEMU_WAKEUP_REASON_PMTIMER] = "pmtimer",
+ };
+ const char *name;
+ QObject *data;
+
if (!is_suspended) {
return;
}
if (!(wakeup_reason_mask & (1 << reason))) {
return;
}
+
+ name = (reason < ARRAY_SIZE(names)) ? names[reason] : "unknown";
+ data = qobject_from_jsonf("{ 'reason': %s }", name);
+ monitor_protocol_event(QEVENT_WAKEUP, data);
+ qobject_decref(data);
+
notifier_list_notify(&wakeup_notifiers, &reason);
reset_requested = 1;
qemu_notify_event();
--
1.7.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events Gerd Hoffmann
@ 2012-02-17 14:23 ` Anthony Liguori
2012-02-17 17:33 ` Luiz Capitulino
1 sibling, 0 replies; 21+ messages in thread
From: Anthony Liguori @ 2012-02-17 14:23 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel, Luiz Capitulino
On 02/15/2012 04:28 AM, Gerd Hoffmann wrote:
> Send qmp events on suspend and wakeup so libvirt
> has a chance to track the vm state.
>
> Signed-off-by: Gerd Hoffmann<kraxel@redhat.com>
Luiz, please Ack.
Regards,
Anthony Liguori
> ---
> monitor.c | 6 ++++++
> monitor.h | 2 ++
> vl.c | 15 +++++++++++++++
> 3 files changed, 23 insertions(+), 0 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index aadbdcb..e6f5fad 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -485,6 +485,12 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
> case QEVENT_BLOCK_JOB_CANCELLED:
> event_name = "BLOCK_JOB_CANCELLED";
> break;
> + case QEVENT_SUSPEND:
> + event_name = "SUSPEND";
> + break;
> + case QEVENT_WAKEUP:
> + event_name = "WAKEUP";
> + break;
> default:
> abort();
> break;
> diff --git a/monitor.h b/monitor.h
> index b72ea07..9df3bab 100644
> --- a/monitor.h
> +++ b/monitor.h
> @@ -38,6 +38,8 @@ typedef enum MonitorEvent {
> QEVENT_SPICE_DISCONNECTED,
> QEVENT_BLOCK_JOB_COMPLETED,
> QEVENT_BLOCK_JOB_CANCELLED,
> + QEVENT_SUSPEND,
> + QEVENT_WAKEUP,
> QEVENT_MAX,
> } MonitorEvent;
>
> diff --git a/vl.c b/vl.c
> index bfdcb7c..570ea05 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1416,6 +1416,7 @@ static void qemu_system_suspend(void)
> {
> pause_all_vcpus();
> notifier_list_notify(&suspend_notifiers, NULL);
> + monitor_protocol_event(QEVENT_SUSPEND, NULL);
> is_suspended = true;
> }
>
> @@ -1436,12 +1437,26 @@ void qemu_register_suspend_notifier(Notifier *notifier)
>
> void qemu_system_wakeup_request(WakeupReason reason)
> {
> + static const char *names[] = {
> + [QEMU_WAKEUP_REASON_OTHER] = "other",
> + [QEMU_WAKEUP_REASON_RTC] = "rtc",
> + [QEMU_WAKEUP_REASON_PMTIMER] = "pmtimer",
> + };
> + const char *name;
> + QObject *data;
> +
> if (!is_suspended) {
> return;
> }
> if (!(wakeup_reason_mask& (1<< reason))) {
> return;
> }
> +
> + name = (reason< ARRAY_SIZE(names)) ? names[reason] : "unknown";
> + data = qobject_from_jsonf("{ 'reason': %s }", name);
> + monitor_protocol_event(QEVENT_WAKEUP, data);
> + qobject_decref(data);
> +
> notifier_list_notify(&wakeup_notifiers,&reason);
> reset_requested = 1;
> qemu_notify_event();
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v5 07/12] suspend: add system_wakeup monitor command
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 07/12] suspend: add system_wakeup monitor command Gerd Hoffmann
@ 2012-02-17 17:32 ` Luiz Capitulino
2012-02-21 9:56 ` Gerd Hoffmann
0 siblings, 1 reply; 21+ messages in thread
From: Luiz Capitulino @ 2012-02-17 17:32 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Wed, 15 Feb 2012 11:28:16 +0100
Gerd Hoffmann <kraxel@redhat.com> wrote:
> This patch adds the system_wakeup monitor command which will simply
> wake up suspended guests.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> hmp-commands.hx | 14 ++++++++++++++
> hmp.c | 5 +++++
> hmp.h | 1 +
> qapi-schema.json | 11 +++++++++++
> qmp-commands.hx | 21 +++++++++++++++++++++
> qmp.c | 5 +++++
> 6 files changed, 57 insertions(+), 0 deletions(-)
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 573b823..64b3656 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -352,6 +352,20 @@ Resume emulation.
> ETEXI
>
> {
> + .name = "system_wakeup",
> + .args_type = "",
> + .params = "",
> + .help = "wakeup guest from suspend",
> + .mhandler.cmd = hmp_system_wakeup,
> + },
> +
> +STEXI
> +@item system_wakeup
> +@findex system_wakeup
> +Wakeup guest from suspend.
> +ETEXI
> +
> + {
> .name = "gdbserver",
> .args_type = "device:s?",
> .params = "[device]",
> diff --git a/hmp.c b/hmp.c
> index 8ff8c94..3a54455 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -632,6 +632,11 @@ void hmp_cont(Monitor *mon, const QDict *qdict)
> }
> }
>
> +void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
> +{
> + qmp_system_wakeup(NULL);
> +}
> +
> void hmp_inject_nmi(Monitor *mon, const QDict *qdict)
> {
> Error *errp = NULL;
> diff --git a/hmp.h b/hmp.h
> index 18eecbd..5409464 100644
> --- a/hmp.h
> +++ b/hmp.h
> @@ -41,6 +41,7 @@ void hmp_cpu(Monitor *mon, const QDict *qdict);
> void hmp_memsave(Monitor *mon, const QDict *qdict);
> void hmp_pmemsave(Monitor *mon, const QDict *qdict);
> void hmp_cont(Monitor *mon, const QDict *qdict);
> +void hmp_system_wakeup(Monitor *mon, const QDict *qdict);
> void hmp_inject_nmi(Monitor *mon, const QDict *qdict);
> void hmp_set_link(Monitor *mon, const QDict *qdict);
> void hmp_block_passwd(Monitor *mon, const QDict *qdict);
> diff --git a/qapi-schema.json b/qapi-schema.json
> index d02ee86..226c1da 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -999,6 +999,17 @@
> { 'command': 'cont' }
>
> ##
> +# @system_wakeup:
> +#
> +# Wakeup guest from suspend
> +#
> +# Since: 1.1
> +#
> +# Returns: nothing.
Would be nice to note that this command does nothing if the guest is already
suspended (btw, does is_suspend account for guest initiated suspends too?).
> +##
> +{ 'command': 'system_wakeup' }
> +
> +##
> # @inject-nmi:
> #
> # Injects an Non-Maskable Interrupt into all guest's VCPUs.
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index b5e2ab8..f5081e2 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -212,6 +212,27 @@ Example:
> EQMP
>
> {
> + .name = "system_wakeup",
> + .args_type = "",
> + .mhandler.cmd_new = qmp_marshal_input_system_wakeup,
> + },
> +
> +SQMP
> +system_wakeup
> +-------------
> +
> +Wakeup guest from suspend.
> +
> +Arguments: None.
> +
> +Example:
> +
> +-> { "execute": "system_wakeup" }
> +<- { "return": {} }
> +
> +EQMP
> +
> + {
> .name = "system_reset",
> .args_type = "",
> .mhandler.cmd_new = qmp_marshal_input_system_reset,
> diff --git a/qmp.c b/qmp.c
> index 1f64844..a182b51 100644
> --- a/qmp.c
> +++ b/qmp.c
> @@ -163,6 +163,11 @@ void qmp_cont(Error **errp)
> vm_start();
> }
>
> +void qmp_system_wakeup(Error **errp)
> +{
> + qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
qemu_system_wakeup_request() does:
if (!(wakeup_reason_mask & (1 << reason))) {
return;
}
But I think you never disable REASON_OTHER, meaning that this will
never be true when the wakeup request comes from the command, right?
If that's right, this patch is fine with me. Otherwise we need to
return an error.
> +}
> +
> ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
> {
> Object *obj;
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events Gerd Hoffmann
2012-02-17 14:23 ` Anthony Liguori
@ 2012-02-17 17:33 ` Luiz Capitulino
2012-02-21 10:00 ` Gerd Hoffmann
1 sibling, 1 reply; 21+ messages in thread
From: Luiz Capitulino @ 2012-02-17 17:33 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Wed, 15 Feb 2012 11:28:21 +0100
Gerd Hoffmann <kraxel@redhat.com> wrote:
> Send qmp events on suspend and wakeup so libvirt
> has a chance to track the vm state.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> monitor.c | 6 ++++++
> monitor.h | 2 ++
> vl.c | 15 +++++++++++++++
> 3 files changed, 23 insertions(+), 0 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index aadbdcb..e6f5fad 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -485,6 +485,12 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
> case QEVENT_BLOCK_JOB_CANCELLED:
> event_name = "BLOCK_JOB_CANCELLED";
> break;
> + case QEVENT_SUSPEND:
> + event_name = "SUSPEND";
> + break;
> + case QEVENT_WAKEUP:
> + event_name = "WAKEUP";
> + break;
> default:
> abort();
> break;
> diff --git a/monitor.h b/monitor.h
> index b72ea07..9df3bab 100644
> --- a/monitor.h
> +++ b/monitor.h
> @@ -38,6 +38,8 @@ typedef enum MonitorEvent {
> QEVENT_SPICE_DISCONNECTED,
> QEVENT_BLOCK_JOB_COMPLETED,
> QEVENT_BLOCK_JOB_CANCELLED,
> + QEVENT_SUSPEND,
> + QEVENT_WAKEUP,
> QEVENT_MAX,
> } MonitorEvent;
>
> diff --git a/vl.c b/vl.c
> index bfdcb7c..570ea05 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1416,6 +1416,7 @@ static void qemu_system_suspend(void)
> {
> pause_all_vcpus();
> notifier_list_notify(&suspend_notifiers, NULL);
> + monitor_protocol_event(QEVENT_SUSPEND, NULL);
> is_suspended = true;
> }
>
> @@ -1436,12 +1437,26 @@ void qemu_register_suspend_notifier(Notifier *notifier)
>
> void qemu_system_wakeup_request(WakeupReason reason)
> {
> + static const char *names[] = {
> + [QEMU_WAKEUP_REASON_OTHER] = "other",
> + [QEMU_WAKEUP_REASON_RTC] = "rtc",
> + [QEMU_WAKEUP_REASON_PMTIMER] = "pmtimer",
Is the reason really important for mngt? Can we just leave it out?
> + };
> + const char *name;
> + QObject *data;
> +
> if (!is_suspended) {
> return;
> }
> if (!(wakeup_reason_mask & (1 << reason))) {
> return;
> }
> +
> + name = (reason < ARRAY_SIZE(names)) ? names[reason] : "unknown";
> + data = qobject_from_jsonf("{ 'reason': %s }", name);
> + monitor_protocol_event(QEVENT_WAKEUP, data);
> + qobject_decref(data);
> +
> notifier_list_notify(&wakeup_notifiers, &reason);
> reset_requested = 1;
> qemu_notify_event();
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v5 07/12] suspend: add system_wakeup monitor command
2012-02-17 17:32 ` Luiz Capitulino
@ 2012-02-21 9:56 ` Gerd Hoffmann
0 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-21 9:56 UTC (permalink / raw)
To: Luiz Capitulino; +Cc: qemu-devel
Hi,
>> +# @system_wakeup:
>> +#
>> +# Wakeup guest from suspend
>> +#
>> +# Since: 1.1
>> +#
>> +# Returns: nothing.
>
> Would be nice to note that this command does nothing if the guest is already
> suspended (btw, does is_suspend account for guest initiated suspends too?).
s/suspended/running/, but yes.
There are only guest initiated suspends (well, libvirt-via-agent is
somewhat grey ...).
cheers,
Gerd
>> diff --git a/qmp.c b/qmp.c
>> index 1f64844..a182b51 100644
>> --- a/qmp.c
>> +++ b/qmp.c
>> @@ -163,6 +163,11 @@ void qmp_cont(Error **errp)
>> vm_start();
>> }
>>
>> +void qmp_system_wakeup(Error **errp)
>> +{
>> + qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
>
> qemu_system_wakeup_request() does:
>
> if (!(wakeup_reason_mask & (1 << reason))) {
> return;
> }
>
> But I think you never disable REASON_OTHER, meaning that this will
> never be true when the wakeup request comes from the command, right?
Correct. The mask is for wakeup events the guest is able to
enable/disable (i.e. rtc wakeups can be enabled/disabled via acpi).
REASON_OTHER can't be maked.
cheers,
Gerd
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events
2012-02-17 17:33 ` Luiz Capitulino
@ 2012-02-21 10:00 ` Gerd Hoffmann
2012-02-21 16:30 ` Eric Blake
0 siblings, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-21 10:00 UTC (permalink / raw)
To: Luiz Capitulino; +Cc: qemu-devel, libvirt-list
On 02/17/12 18:33, Luiz Capitulino wrote:
> On Wed, 15 Feb 2012 11:28:21 +0100
> Gerd Hoffmann <kraxel@redhat.com> wrote:
>
>> Send qmp events on suspend and wakeup so libvirt
>> has a chance to track the vm state.
[ added libvirt to Cc:, leaving full context.
this is about qmp events when the guest enters/leaves s3 ].
>> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>> ---
>> monitor.c | 6 ++++++
>> monitor.h | 2 ++
>> vl.c | 15 +++++++++++++++
>> 3 files changed, 23 insertions(+), 0 deletions(-)
>>
>> diff --git a/monitor.c b/monitor.c
>> index aadbdcb..e6f5fad 100644
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -485,6 +485,12 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
>> case QEVENT_BLOCK_JOB_CANCELLED:
>> event_name = "BLOCK_JOB_CANCELLED";
>> break;
>> + case QEVENT_SUSPEND:
>> + event_name = "SUSPEND";
>> + break;
>> + case QEVENT_WAKEUP:
>> + event_name = "WAKEUP";
>> + break;
>> default:
>> abort();
>> break;
>> diff --git a/monitor.h b/monitor.h
>> index b72ea07..9df3bab 100644
>> --- a/monitor.h
>> +++ b/monitor.h
>> @@ -38,6 +38,8 @@ typedef enum MonitorEvent {
>> QEVENT_SPICE_DISCONNECTED,
>> QEVENT_BLOCK_JOB_COMPLETED,
>> QEVENT_BLOCK_JOB_CANCELLED,
>> + QEVENT_SUSPEND,
>> + QEVENT_WAKEUP,
>> QEVENT_MAX,
>> } MonitorEvent;
>>
>> diff --git a/vl.c b/vl.c
>> index bfdcb7c..570ea05 100644
>> --- a/vl.c
>> +++ b/vl.c
>> @@ -1416,6 +1416,7 @@ static void qemu_system_suspend(void)
>> {
>> pause_all_vcpus();
>> notifier_list_notify(&suspend_notifiers, NULL);
>> + monitor_protocol_event(QEVENT_SUSPEND, NULL);
>> is_suspended = true;
>> }
>>
>> @@ -1436,12 +1437,26 @@ void qemu_register_suspend_notifier(Notifier *notifier)
>>
>> void qemu_system_wakeup_request(WakeupReason reason)
>> {
>> + static const char *names[] = {
>> + [QEMU_WAKEUP_REASON_OTHER] = "other",
>> + [QEMU_WAKEUP_REASON_RTC] = "rtc",
>> + [QEMU_WAKEUP_REASON_PMTIMER] = "pmtimer",
>
> Is the reason really important for mngt? Can we just leave it out?
I assumed the wakeup reason could be useful, but dunno.
Zapping the code is no problem of course.
Lets ask mgmt aka libvirt folks ;)
cheers,
Gerd
>> + };
>> + const char *name;
>> + QObject *data;
>> +
>> if (!is_suspended) {
>> return;
>> }
>> if (!(wakeup_reason_mask & (1 << reason))) {
>> return;
>> }
>> +
>> + name = (reason < ARRAY_SIZE(names)) ? names[reason] : "unknown";
>> + data = qobject_from_jsonf("{ 'reason': %s }", name);
>> + monitor_protocol_event(QEVENT_WAKEUP, data);
>> + qobject_decref(data);
>> +
>> notifier_list_notify(&wakeup_notifiers, &reason);
>> reset_requested = 1;
>> qemu_notify_event();
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events
2012-02-21 10:00 ` Gerd Hoffmann
@ 2012-02-21 16:30 ` Eric Blake
2012-02-22 12:08 ` Gerd Hoffmann
0 siblings, 1 reply; 21+ messages in thread
From: Eric Blake @ 2012-02-21 16:30 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: libvirt-list, qemu-devel, Luiz Capitulino
[-- Attachment #1: Type: text/plain, Size: 1306 bytes --]
On 02/21/2012 03:00 AM, Gerd Hoffmann wrote:
> [ added libvirt to Cc:, leaving full context.
> this is about qmp events when the guest enters/leaves s3 ].
>
>>> @@ -1436,12 +1437,26 @@ void qemu_register_suspend_notifier(Notifier *notifier)
>>>
>>> void qemu_system_wakeup_request(WakeupReason reason)
>>> {
>>> + static const char *names[] = {
>>> + [QEMU_WAKEUP_REASON_OTHER] = "other",
>>> + [QEMU_WAKEUP_REASON_RTC] = "rtc",
>>> + [QEMU_WAKEUP_REASON_PMTIMER] = "pmtimer",
>>
>> Is the reason really important for mngt? Can we just leave it out?
>
> I assumed the wakeup reason could be useful, but dunno.
> Zapping the code is no problem of course.
>
> Lets ask mgmt aka libvirt folks ;)
If you present the reason, libvirt will pass it on to the management
app. But I don't see any reason why libvirt itself would care about the
reason, so it won't hurt libvirt if you drop a reason field. I don't
know whether higher-level management apps, like oVirt, would care or not.
Isn't this something where it is easier to omit first and add later once
we have a use case, than to add up front only to find that no one cares?
--
Eric Blake eblake@redhat.com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 620 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events
2012-02-21 16:30 ` Eric Blake
@ 2012-02-22 12:08 ` Gerd Hoffmann
2012-02-22 13:22 ` Luiz Capitulino
0 siblings, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2012-02-22 12:08 UTC (permalink / raw)
To: Eric Blake; +Cc: Luiz Capitulino, libvirt-list, qemu-devel
Hi,
> Isn't this something where it is easier to omit first and add later
> once we have a use case, than to add up front only to find that no
> one cares?
Yes. I'll drop it.
cheers,
Gerd
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events
2012-02-22 12:08 ` Gerd Hoffmann
@ 2012-02-22 13:22 ` Luiz Capitulino
0 siblings, 0 replies; 21+ messages in thread
From: Luiz Capitulino @ 2012-02-22 13:22 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Eric Blake, libvirt-list, qemu-devel
On Wed, 22 Feb 2012 13:08:16 +0100
Gerd Hoffmann <kraxel@redhat.com> wrote:
> Hi,
>
> > Isn't this something where it is easier to omit first and add later
> > once we have a use case, than to add up front only to find that no
> > one cares?
>
> Yes. I'll drop it.
Yes, I think it's better to drop it for now and add it back if really needed,
when we'll know better how mngt apps are going to use this.
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2012-02-22 13:22 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-15 10:28 [Qemu-devel] [PATCH v5 00/12] initial suspend support Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 01/12] acpi: move around structs Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 02/12] acpi: add ACPIREGS Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 03/12] acpi: don't pass overflow_time to acpi_pm1_evt_get_sts Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 04/12] acpi: add acpi_pm1_evt_write_en Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 05/12] suspend: add infrastructure Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 06/12] suspend: switch acpi s3 to new infrastructure Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 07/12] suspend: add system_wakeup monitor command Gerd Hoffmann
2012-02-17 17:32 ` Luiz Capitulino
2012-02-21 9:56 ` Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 08/12] suspend: make ps/2 devices wakeup the guest Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 09/12] suspend: make serial ports " Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 10/12] suspend: make rtc alarm " Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 11/12] suspend: make acpi timer " Gerd Hoffmann
2012-02-15 10:28 ` [Qemu-devel] [PATCH v5 12/12] suspend: add qmp events Gerd Hoffmann
2012-02-17 14:23 ` Anthony Liguori
2012-02-17 17:33 ` Luiz Capitulino
2012-02-21 10:00 ` Gerd Hoffmann
2012-02-21 16:30 ` Eric Blake
2012-02-22 12:08 ` Gerd Hoffmann
2012-02-22 13:22 ` Luiz Capitulino
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).