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

Michael S. Tsirkin mst at redhat.com
Mon Jan 13 17:36:56 CET 2014


On Mon, Jan 13, 2014 at 11:31:20AM -0500, Kevin O'Connor wrote:
> 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)

so this does nothing unless piix4_pm_setup run but
if it did why do we need to resume anything?

> +        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