* [Qemu-devel] [rfc patch qemu 0/4] s3 improvements
@ 2012-07-17 12:30 Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 1/4] wakeup: add acpi gpe wakeup reasons Gerd Hoffmann
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2012-07-17 12:30 UTC (permalink / raw)
To: qemu-devel, seabios; +Cc: Gerd Hoffmann
Hi,
This patch series (and the seabios patch series following in a minute)
improve s3 support in qemu.
The patches allocates a bunch of acpi gpe bits for s3 wakeup of piix
chipset devices (ps/2 keyboard, ps/2 mouse, serial port, uhci
controller) and does the windup needed so the guest can enable+disable
wakeup per device using apci.
With this patch series applied /proc/acpi/wakeup inside the guest looks
like this ...
Device S-state Status Sysfs node
UHCI S3 *enabled pci:0000:00:01.2
KBD S3 *enabled pnp:00:02
MOU S3 *disabled pnp:00:03
COM1 S3 *disabled pnp:00:05
... and you can use "echo $device > /proc/acpi/wakeup" to toggle
enabled/disabled.
comments?
Gerd
Gerd Hoffmann (4):
wakeup: add acpi gpe wakeup reasons
wakeup: make ps/2 configurable
wakeup: make serial configurable
wakeup: uhci support
hw/acpi.c | 26 ++++++++++++++++++++++++++
hw/ps2.c | 4 ++--
hw/serial.c | 10 +++++++++-
hw/usb/hcd-uhci.c | 35 +++++++++++++++++++++++++++++++++++
sysemu.h | 4 ++++
5 files changed, 76 insertions(+), 3 deletions(-)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Qemu-devel] [rfc patch qemu 1/4] wakeup: add acpi gpe wakeup reasons
2012-07-17 12:30 [Qemu-devel] [rfc patch qemu 0/4] s3 improvements Gerd Hoffmann
@ 2012-07-17 12:30 ` Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 2/4] wakeup: make ps/2 configurable Gerd Hoffmann
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2012-07-17 12:30 UTC (permalink / raw)
To: qemu-devel, seabios; +Cc: Gerd Hoffmann
Allocate four acpi gpe bits (0x08 -> 0x0b) for s3 wakeup
configuration and notification.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/acpi.c | 26 ++++++++++++++++++++++++++
sysemu.h | 4 ++++
2 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/hw/acpi.c b/hw/acpi.c
index effc7ec..208c4af 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -262,6 +262,22 @@ static void acpi_notify_wakeup(Notifier *notifier, void *data)
ar->pm1.evt.sts |=
(ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS);
break;
+ case QEMU_WAKEUP_REASON_GPE_8:
+ ar->pm1.evt.sts |= ACPI_BITMASK_WAKE_STATUS;
+ ar->gpe.sts[1] |= (1 << 0);
+ break;
+ case QEMU_WAKEUP_REASON_GPE_9:
+ ar->pm1.evt.sts |= ACPI_BITMASK_WAKE_STATUS;
+ ar->gpe.sts[1] |= (1 << 1);
+ break;
+ case QEMU_WAKEUP_REASON_GPE_a:
+ ar->pm1.evt.sts |= ACPI_BITMASK_WAKE_STATUS;
+ ar->gpe.sts[1] |= (1 << 2);
+ break;
+ case QEMU_WAKEUP_REASON_GPE_b:
+ ar->pm1.evt.sts |= ACPI_BITMASK_WAKE_STATUS;
+ ar->gpe.sts[1] |= (1 << 3);
+ break;
case QEMU_WAKEUP_REASON_OTHER:
default:
/* ACPI_BITMASK_WAKE_STATUS should be set on resume.
@@ -426,6 +442,10 @@ void acpi_gpe_reset(ACPIREGS *ar)
{
memset(ar->gpe.sts, 0, ar->gpe.len / 2);
memset(ar->gpe.en, 0, ar->gpe.len / 2);
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_GPE_8, 0);
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_GPE_9, 0);
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_GPE_a, 0);
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_GPE_b, 0);
}
static uint8_t *acpi_gpe_ioport_get_ptr(ACPIREGS *ar, uint32_t addr)
@@ -455,6 +475,12 @@ void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val)
} else if (addr < ar->gpe.len) {
/* GPE_EN */
*cur = val;
+ if (addr == ar->gpe.len / 2 + 1) {
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_GPE_8, val & (1 << 0));
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_GPE_9, val & (1 << 1));
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_GPE_a, val & (1 << 2));
+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_GPE_b, val & (1 << 3));
+ }
} else {
abort();
}
diff --git a/sysemu.h b/sysemu.h
index 6540c79..8cd3443 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -42,6 +42,10 @@ typedef enum WakeupReason {
QEMU_WAKEUP_REASON_OTHER = 0,
QEMU_WAKEUP_REASON_RTC,
QEMU_WAKEUP_REASON_PMTIMER,
+ QEMU_WAKEUP_REASON_GPE_8,
+ QEMU_WAKEUP_REASON_GPE_9,
+ QEMU_WAKEUP_REASON_GPE_a,
+ QEMU_WAKEUP_REASON_GPE_b,
} WakeupReason;
void qemu_system_reset_request(void);
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [rfc patch qemu 2/4] wakeup: make ps/2 configurable
2012-07-17 12:30 [Qemu-devel] [rfc patch qemu 0/4] s3 improvements Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 1/4] wakeup: add acpi gpe wakeup reasons Gerd Hoffmann
@ 2012-07-17 12:30 ` Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 3/4] wakeup: make serial configurable Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 4/4] wakeup: uhci support Gerd Hoffmann
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2012-07-17 12:30 UTC (permalink / raw)
To: qemu-devel, seabios; +Cc: Gerd Hoffmann
ps/2 gets gpe bits 0x08 (keyboard) and 0x09 (mouse).
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/ps2.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/ps2.c b/hw/ps2.c
index f93cd24..a3cd124 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -155,7 +155,7 @@ static void ps2_put_keycode(void *opaque, int keycode)
{
PS2KbdState *s = opaque;
- qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_GPE_8);
/* XXX: add support for scancode set 1 */
if (!s->translate && keycode < 0xe0 && s->scancode_set > 1) {
if (keycode & 0x80) {
@@ -371,7 +371,7 @@ static void ps2_mouse_event(void *opaque,
s->mouse_buttons = buttons_state;
if (buttons_state) {
- qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_GPE_9);
}
if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [rfc patch qemu 3/4] wakeup: make serial configurable
2012-07-17 12:30 [Qemu-devel] [rfc patch qemu 0/4] s3 improvements Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 1/4] wakeup: add acpi gpe wakeup reasons Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 2/4] wakeup: make ps/2 configurable Gerd Hoffmann
@ 2012-07-17 12:30 ` Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 4/4] wakeup: uhci support Gerd Hoffmann
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2012-07-17 12:30 UTC (permalink / raw)
To: qemu-devel, seabios; +Cc: Gerd Hoffmann
serial port #1 gets gpe 0x0a. Now that the wakeup is guest-configurable
via acpi we also enable it unconditionally.
Other serial ports are unchanged: they continue to use the "other" exit
reason and are disabled unless explicitly enabled via wakeup property.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/serial.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/hw/serial.c b/hw/serial.c
index a421d1e..06f7e28 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -140,6 +140,7 @@ struct SerialState {
int baudbase;
int tsr_retry;
uint32_t wakeup;
+ WakeupReason reason;
uint64_t last_xmit_ts; /* Time when the last byte was successfully sent out of the tsr */
SerialFIFO recv_fifo;
@@ -641,7 +642,7 @@ 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);
+ qemu_system_wakeup_request(s->reason);
}
if(s->fcr & UART_FCR_FE) {
int i;
@@ -789,6 +790,13 @@ static int serial_isa_initfn(ISADevice *dev)
isa->isairq = isa_serial_irq[isa->index];
index++;
+ if (isa->iobase == 0x3f8) {
+ s->reason = QEMU_WAKEUP_REASON_GPE_a;
+ s->wakeup = 1;
+ } else {
+ s->reason = QEMU_WAKEUP_REASON_OTHER;
+ }
+
s->baudbase = 115200;
isa_init_irq(dev, &s->irq, isa->isairq);
serial_init_core(s);
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [rfc patch qemu 4/4] wakeup: uhci support
2012-07-17 12:30 [Qemu-devel] [rfc patch qemu 0/4] s3 improvements Gerd Hoffmann
` (2 preceding siblings ...)
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 3/4] wakeup: make serial configurable Gerd Hoffmann
@ 2012-07-17 12:30 ` Gerd Hoffmann
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2012-07-17 12:30 UTC (permalink / raw)
To: qemu-devel, seabios; +Cc: Gerd Hoffmann
Implement the (intel-specific) pci configuration register 0xc4, which is
a bitmask saying which ports are allowed to wakeup the system.
Also assign gpe bit 0x0b (used only in case uhci handles device 01.2).
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/hcd-uhci.c | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 8f652d2..b2da21d 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -32,6 +32,7 @@
#include "iov.h"
#include "dma.h"
#include "trace.h"
+#include "sysemu.h"
//#define DEBUG
//#define DEBUG_DUMP_DATA
@@ -129,6 +130,7 @@ struct UHCIState {
uint32_t fl_base_addr; /* frame list base address */
uint8_t sof_timing;
uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
+ uint8_t system_wakeup;
int64_t expire_time;
QEMUTimer *frame_timer;
QEMUBH *bh;
@@ -665,6 +667,22 @@ static void uhci_wakeup(USBPort *port1)
}
}
+static void uhci_wakeup_endpoint(USBBus *bus, USBEndpoint *ep)
+{
+ USBPort *port1 = ep->dev->port;
+ UHCIState *s = port1->opaque;
+
+ if (!(s->system_wakeup & (1 << port1->index))) {
+ return;
+ }
+ if (s->dev.devfn == PCI_DEVFN(1, 2)) {
+ /* piix3/4 chipset uhci controller */
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_GPE_b);
+ } else {
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
+ }
+}
+
static USBDevice *uhci_find_device(UHCIState *s, uint8_t addr)
{
USBDevice *dev;
@@ -1181,6 +1199,7 @@ static USBPortOps uhci_port_ops = {
};
static USBBusOps uhci_bus_ops = {
+ .wakeup_endpoint = uhci_wakeup_endpoint,
};
static int usb_uhci_common_initfn(PCIDevice *dev)
@@ -1242,6 +1261,17 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
return 0;
}
+static void usb_uhci_intel_write_config(PCIDevice *dev, uint32_t addr,
+ uint32_t val, int len)
+{
+ UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
+
+ pci_default_write_config(dev, addr, val, len);
+ if (addr == 0xc4) {
+ s->system_wakeup = val;
+ }
+}
+
static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
{
UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
@@ -1279,6 +1309,7 @@ static void piix3_uhci_class_init(ObjectClass *klass, void *data)
k->init = usb_uhci_common_initfn;
k->exit = usb_uhci_exit;
+ k->config_write = usb_uhci_intel_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_2;
k->revision = 0x01;
@@ -1301,6 +1332,7 @@ static void piix4_uhci_class_init(ObjectClass *klass, void *data)
k->init = usb_uhci_common_initfn;
k->exit = usb_uhci_exit;
+ k->config_write = usb_uhci_intel_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371AB_2;
k->revision = 0x01;
@@ -1344,6 +1376,7 @@ static void ich9_uhci1_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->init = usb_uhci_common_initfn;
+ k->config_write = usb_uhci_intel_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1;
k->revision = 0x03;
@@ -1365,6 +1398,7 @@ static void ich9_uhci2_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->init = usb_uhci_common_initfn;
+ k->config_write = usb_uhci_intel_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2;
k->revision = 0x03;
@@ -1386,6 +1420,7 @@ static void ich9_uhci3_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->init = usb_uhci_common_initfn;
+ k->config_write = usb_uhci_intel_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3;
k->revision = 0x03;
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-07-17 12:31 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-17 12:30 [Qemu-devel] [rfc patch qemu 0/4] s3 improvements Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 1/4] wakeup: add acpi gpe wakeup reasons Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 2/4] wakeup: make ps/2 configurable Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 3/4] wakeup: make serial configurable Gerd Hoffmann
2012-07-17 12:30 ` [Qemu-devel] [rfc patch qemu 4/4] wakeup: uhci support Gerd Hoffmann
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).