From 40d020f56226aee7c75a6c29f471c4b866765732 Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Wed, 15 Jan 2014 14:20:06 +0200 Subject: [PATCH] resume: restore piix pm config registers after resume 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 Acked-by: Michael S. Tsirkin --- src/fw/pciinit.c | 24 +++++++++++++++++++++--- src/resume.c | 2 ++ src/util.h | 1 + 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index a24b8ff..11c92ae 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); @@ -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; diff --git a/src/resume.c b/src/resume.c index d69429c..9ad2e4f 100644 --- a/src/resume.c +++ b/src/resume.c @@ -101,6 +101,8 @@ s3_resume(void) pic_setup(); smm_setup(); + pci_resume(); + s3_resume_vga(); make_bios_readonly(); 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; -- 2.39.5