]> xenbits.xensource.com Git - seabios.git/commitdiff
resume: restore piix pm config registers after resume
authorMarcel Apfelbaum <marcel.a@redhat.com>
Wed, 15 Jan 2014 12:20:06 +0000 (14:20 +0200)
committerKevin O'Connor <kevin@koconnor.net>
Wed, 15 Jan 2014 16:01:58 +0000 (11:01 -0500)
On resume, the OS queries the power management event that
caused it. In order to complete this task, it executes some
reads to the piix pm io space. This all happens before the
OS has a chance to restore the PCI config space for devices,
so it is bios's responsibility to make sure the pm IO space
is configured correctly. (During suspend, the piix pm
configuration space is lost).

Note: For 'ordinary' pci devices the config space is
saved by the OS on sleep and restored on resume.

Signed-off-by: Marcel Apfelbaum <marcel.a@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
src/fw/pciinit.c
src/resume.c
src/util.h

index a24b8ff94f3a09c866258521a124f28fd3349fd1..11c92aec453fda3131bfc30816c9f7483f70d123 100644 (file)
@@ -230,10 +230,8 @@ static void apple_macio_setup(struct pci_device *pci, void *arg)
     pci_set_io_region_addr(pci, 0, 0x80800000, 0);
 }
 
-/* PIIX4 Power Management device (for ACPI) */
-static void piix4_pm_setup(struct pci_device *pci, void *arg)
+static void piix4_pm_config_setup(u16 bdf)
 {
-    u16 bdf = pci->bdf;
     // acpi sci is hardwired to 9
     pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 9);
 
@@ -241,6 +239,15 @@ static void piix4_pm_setup(struct pci_device *pci, void *arg)
     pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */
     pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1);
     pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */
+}
+
+static int PiixPmBDF = -1;
+
+/* PIIX4 Power Management device (for ACPI) */
+static void piix4_pm_setup(struct pci_device *pci, void *arg)
+{
+    PiixPmBDF = pci->bdf;
+    piix4_pm_config_setup(pci->bdf);
 
     acpi_pm1a_cnt = PORT_ACPI_PM_BASE + 0x04;
     pmtimer_setup(PORT_ACPI_PM_BASE + 0x08);
@@ -295,6 +302,17 @@ static const struct pci_device_id pci_device_tbl[] = {
     PCI_DEVICE_END,
 };
 
+void pci_resume(void)
+{
+    if (!CONFIG_QEMU) {
+        return;
+    }
+
+    if (PiixPmBDF >= 0) {
+        piix4_pm_config_setup(PiixPmBDF);
+    }
+}
+
 static void pci_bios_init_device(struct pci_device *pci)
 {
     u16 bdf = pci->bdf;
index d69429cb097cfb7f70fa5ebdd4089ae6160593cd..9ad2e4fee22264d3d1740c8e7d96b4ae60f121e4 100644 (file)
@@ -101,6 +101,8 @@ s3_resume(void)
     pic_setup();
     smm_setup();
 
+    pci_resume();
+
     s3_resume_vga();
 
     make_bios_readonly();
index 1b7d5259ef95bb354d525f6f50d123e553246954..b8acbfaa00f005f642e77a9702b3f87728ddf0d3 100644 (file)
@@ -99,6 +99,7 @@ void mtrr_setup(void);
 // fw/pciinit.c
 extern const u8 pci_irqs[4];
 void pci_setup(void);
+void pci_resume(void);
 
 // fw/pirtable.c
 extern struct pir_header *PirAddr;