[SeaBIOS] [PATCH] seabios: restore piix pm config registers after resume

Kevin O'Connor kevin at koconnor.net
Mon Jan 13 17:31:20 CET 2014


On Thu, Jan 02, 2014 at 07:00:45PM +0200, Marcel Apfelbaum wrote:
> 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 at redhat.com>
> ---
> This patch is based on Michael S. Tsirkin's patch:
> [SeaBIOS] [PATCH] seabios: call pci_init_device on resume
> If Michael agrees with it, I'll add him to signed-off section.
> 
> Notes:
>  - Without this patch the OS gets stuck because it tries repeatedly
>    to read/write to pm io space, but the
>    memory region is not enabled, so -1 is returned.
>  - After resume the OS does not actually use the pm base address
>    configured by the bios to get the IO ports, but uses
>    the value from the ACPI FADT table actually. However, as a side effect
>    of the configuration, the pm-io space is enabled by Qemu and
>    the OS can continue the the boot sequence.
>  - Bioses used for hardware like coreboot have the same init
>    sequence for piix, see enable_pm from src/southbridge/intel/i82371eb/early_pm.c.

Thanks.  SeaBIOS isn't responsible for PCI setup on CSM/coreboot, so
the patch must check for CONFIG_QEMU.

Also, I think we can simplify this a bit - how about the patch below
(untested)?

-Kevin


diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
index a24b8ff..1c90059 100644
--- a/src/fw/pciinit.c
+++ b/src/fw/pciinit.c
@@ -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);
@@ -858,3 +865,12 @@ pci_setup(void)
 
     pci_enable_default_vga();
 }
+
+void
+pci_resume(void)
+{
+    if (!CONFIG_QEMU)
+        return;
+    if (PiixPMBDF >= 0)
+        piix4_pm_config_setup(PiixPMBDF);
+}
diff --git a/src/resume.c b/src/resume.c
index d69429c..0c0e60e 100644
--- a/src/resume.c
+++ b/src/resume.c
@@ -100,6 +100,7 @@ s3_resume(void)
 
     pic_setup();
     smm_setup();
+    pci_resume();
 
     s3_resume_vga();
 
diff --git a/src/util.h b/src/util.h
index 1b7d525..b8acbfa 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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;



More information about the SeaBIOS mailing list