From nobody Fri Apr 19 07:52:48 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of seabios.org designates 78.46.105.101 as permitted sender) client-ip=78.46.105.101; envelope-from=seabios-bounces@seabios.org; helo=coreboot.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of seabios.org designates 78.46.105.101 as permitted sender) smtp.mailfrom=seabios-bounces@seabios.org Return-Path: Received: from coreboot.org (coreboot.org [78.46.105.101]) by mx.zohomail.com with SMTPS id 1647769615531960.0284475440643; Sun, 20 Mar 2022 02:46:55 -0700 (PDT) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTPA id B031E16E36E2; Sun, 20 Mar 2022 09:46:51 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTP id 1C09216E3671 for ; Sun, 20 Mar 2022 09:46:38 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by mailout01.t-online.de (Postfix) with SMTP id 6715345EF for ; Sun, 20 Mar 2022 10:46:37 +0100 (CET) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) with (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 encrypted) esmtp id 1nVs8w-1IrTg90; Sun, 20 Mar 2022 10:46:34 +0100 Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) id D706020060C; Sun, 20 Mar 2022 10:46:33 +0100 (CET) From: =?UTF-8?q?Volker=20R=C3=BCmelin?= To: seabios@seabios.org Date: Sun, 20 Mar 2022 10:46:32 +0100 Message-Id: <20220320094633.2239-1-vr_qemu@t-online.de> In-Reply-To: <69efc2d8-3bc5-48b8-238c-172af136d61c@t-online.de> References: <69efc2d8-3bc5-48b8-238c-172af136d61c@t-online.de> MIME-Version: 1.0 X-TOI-EXPURGATEID: 150726::1647769594-00012DCC-6E2A7167/0/0 CLEAN NORMAL X-TOI-MSGID: 6b66a69a-fb38-4bdf-9267-2920aecc871e Message-ID-Hash: YI5BQUUDPAGFQSWZB2LT6YP33UACKRIF X-Message-ID-Hash: YI5BQUUDPAGFQSWZB2LT6YP33UACKRIF X-MailFrom: volker.ruemelin@t-online.de X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-seabios.seabios.org-0; header-match-seabios.seabios.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.5rc1 Precedence: list Subject: [SeaBIOS] [PATCH 1/2] pci: refactor the pci_config_*() functions List-Id: SeaBIOS mailing list Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Authentication-Results: coreboot.org; auth=pass smtp.auth=mailman@coreboot.org smtp.mailfrom=seabios-bounces@seabios.org X-Spamd-Bar: --- X-ZM-MESSAGEID: 1647769616248100001 Split out the Standard PCI Configuration Access Mechanism pci_ioconfig_*() functions from the pci_config_*() functions. The standard PCI CAM functions will be used in the next patch. Signed-off-by: Volker R=C3=BCmelin Reviewed-by: Gerd Hoffmann --- src/hw/pci.c | 54 ++++++++++++++++++++++++++++++++++++++++------------ src/hw/pci.h | 12 +++++++++++- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/hw/pci.c b/src/hw/pci.c index 3df1dae..f13cbde 100644 --- a/src/hw/pci.c +++ b/src/hw/pci.c @@ -26,63 +26,93 @@ static u32 ioconfig_cmd(u16 bdf, u32 addr) return 0x80000000 | (bdf << 8) | (addr & 0xfc); } =20 +void pci_ioconfig_writel(u16 bdf, u32 addr, u32 val) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + outl(val, PORT_PCI_DATA); +} + void pci_config_writel(u16 bdf, u32 addr, u32 val) { if (!MODESEGMENT && mmconfig) { writel(mmconfig_addr(bdf, addr), val); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - outl(val, PORT_PCI_DATA); + pci_ioconfig_writel(bdf, addr, val); } } =20 +void pci_ioconfig_writew(u16 bdf, u32 addr, u16 val) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + outw(val, PORT_PCI_DATA + (addr & 2)); +} + void pci_config_writew(u16 bdf, u32 addr, u16 val) { if (!MODESEGMENT && mmconfig) { writew(mmconfig_addr(bdf, addr), val); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - outw(val, PORT_PCI_DATA + (addr & 2)); + pci_ioconfig_writew(bdf, addr, val); } } =20 +void pci_ioconfig_writeb(u16 bdf, u32 addr, u8 val) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + outb(val, PORT_PCI_DATA + (addr & 3)); +} + void pci_config_writeb(u16 bdf, u32 addr, u8 val) { if (!MODESEGMENT && mmconfig) { writeb(mmconfig_addr(bdf, addr), val); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - outb(val, PORT_PCI_DATA + (addr & 3)); + pci_ioconfig_writeb(bdf, addr, val); } } =20 +u32 pci_ioconfig_readl(u16 bdf, u32 addr) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + return inl(PORT_PCI_DATA); +} + u32 pci_config_readl(u16 bdf, u32 addr) { if (!MODESEGMENT && mmconfig) { return readl(mmconfig_addr(bdf, addr)); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - return inl(PORT_PCI_DATA); + return pci_ioconfig_readl(bdf, addr); } } =20 +u16 pci_ioconfig_readw(u16 bdf, u32 addr) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + return inw(PORT_PCI_DATA + (addr & 2)); +} + u16 pci_config_readw(u16 bdf, u32 addr) { if (!MODESEGMENT && mmconfig) { return readw(mmconfig_addr(bdf, addr)); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - return inw(PORT_PCI_DATA + (addr & 2)); + return pci_ioconfig_readw(bdf, addr); } } =20 +u8 pci_ioconfig_readb(u16 bdf, u32 addr) +{ + outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); + return inb(PORT_PCI_DATA + (addr & 3)); +} + u8 pci_config_readb(u16 bdf, u32 addr) { if (!MODESEGMENT && mmconfig) { return readb(mmconfig_addr(bdf, addr)); } else { - outl(ioconfig_cmd(bdf, addr), PORT_PCI_CMD); - return inb(PORT_PCI_DATA + (addr & 3)); + return pci_ioconfig_readb(bdf, addr); } } =20 diff --git a/src/hw/pci.h b/src/hw/pci.h index 01c51f7..ee6acaf 100644 --- a/src/hw/pci.h +++ b/src/hw/pci.h @@ -32,6 +32,15 @@ static inline u16 pci_bus_devfn_to_bdf(int bus, u16 devf= n) { ; BDF >=3D 0 \ ; BDF=3Dpci_next(BDF, (BUS))) =20 +// standard PCI configration access mechanism +void pci_ioconfig_writel(u16 bdf, u32 addr, u32 val); +void pci_ioconfig_writew(u16 bdf, u32 addr, u16 val); +void pci_ioconfig_writeb(u16 bdf, u32 addr, u8 val); +u32 pci_ioconfig_readl(u16 bdf, u32 addr); +u16 pci_ioconfig_readw(u16 bdf, u32 addr); +u8 pci_ioconfig_readb(u16 bdf, u32 addr); + +// PCI configuration access using either PCI CAM or PCIe ECAM void pci_config_writel(u16 bdf, u32 addr, u32 val); void pci_config_writew(u16 bdf, u32 addr, u16 val); void pci_config_writeb(u16 bdf, u32 addr, u8 val); @@ -39,9 +48,10 @@ u32 pci_config_readl(u16 bdf, u32 addr); u16 pci_config_readw(u16 bdf, u32 addr); u8 pci_config_readb(u16 bdf, u32 addr); void pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on); -void pci_enable_mmconfig(u64 addr, const char *name); u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap); int pci_next(int bdf, int bus); + +void pci_enable_mmconfig(u64 addr, const char *name); int pci_probe_host(void); void pci_reboot(void); =20 --=20 2.34.1 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org From nobody Fri Apr 19 07:52:48 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of seabios.org designates 78.46.105.101 as permitted sender) client-ip=78.46.105.101; envelope-from=seabios-bounces@seabios.org; helo=coreboot.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of seabios.org designates 78.46.105.101 as permitted sender) smtp.mailfrom=seabios-bounces@seabios.org Return-Path: Received: from coreboot.org (coreboot.org [78.46.105.101]) by mx.zohomail.com with SMTPS id 1647769631236829.733992194555; Sun, 20 Mar 2022 02:47:11 -0700 (PDT) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTPA id 2C8BF16E3CF6; Sun, 20 Mar 2022 09:47:07 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTP id B1B0916E3671 for ; Sun, 20 Mar 2022 09:46:40 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by mailout07.t-online.de (Postfix) with SMTP id 8559C8DC2 for ; Sun, 20 Mar 2022 10:46:40 +0100 (CET) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) with (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 encrypted) esmtp id 1nVs8y-2TyHrt0; Sun, 20 Mar 2022 10:46:36 +0100 Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) id D93562006CE; Sun, 20 Mar 2022 10:46:33 +0100 (CET) From: =?UTF-8?q?Volker=20R=C3=BCmelin?= To: seabios@seabios.org Date: Sun, 20 Mar 2022 10:46:33 +0100 Message-Id: <20220320094633.2239-2-vr_qemu@t-online.de> In-Reply-To: <69efc2d8-3bc5-48b8-238c-172af136d61c@t-online.de> References: <69efc2d8-3bc5-48b8-238c-172af136d61c@t-online.de> MIME-Version: 1.0 X-TOI-EXPURGATEID: 150726::1647769596-00009E39-3ED6788E/0/0 CLEAN NORMAL X-TOI-MSGID: 6530383e-f52d-41c8-9f3f-020e94d54d34 Message-ID-Hash: TCASL7WHPRVRGMRKUZRQMXY354XGOC3T X-Message-ID-Hash: TCASL7WHPRVRGMRKUZRQMXY354XGOC3T X-MailFrom: volker.ruemelin@t-online.de X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-seabios.seabios.org-0; header-match-seabios.seabios.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.5rc1 Precedence: list Subject: [SeaBIOS] [PATCH 2/2] reset: force standard PCI configuration access List-Id: SeaBIOS mailing list Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Authentication-Results: coreboot.org; auth=pass smtp.auth=mailman@coreboot.org smtp.mailfrom=seabios-bounces@seabios.org X-Spamd-Bar: --- X-ZM-MESSAGEID: 1647769632512100001 After a reset of a QEMU -machine q35 guest, the PCI Express Enhanced Configuration Mechanism is disabled and the variable mmconfig no longer matches the configuration register MCHBAR of the Q35 chipset. Until the variable mmconfig is reset to 0, all pci_config_*() functions no longer work. The variable mmconfig is located in the read-only F-segment. To reset it the pci_config_*() functions are needed, but they do not work. Replace all pci_config_*() calls with Standard PCI Configuration Mechanism pci_ioconfig_*() calls until mmconfig is reset to 0. This fixes In resume (status=3D0) In 32bit resume Attempting a hard reboot Unable to unlock ram - bridge not found and a reset loop with QEMU -accel tcg. Signed-off-by: Volker R=C3=BCmelin Reviewed-by: Gerd Hoffmann --- src/fw/shadow.c | 16 +++++++++------- src/hw/pci.c | 32 ++++++++++++++++++++++++++++++++ src/hw/pci.h | 7 +++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/fw/shadow.c b/src/fw/shadow.c index 4c627a8..0722df2 100644 --- a/src/fw/shadow.c +++ b/src/fw/shadow.c @@ -32,8 +32,8 @@ __make_bios_writable_intel(u16 bdf, u32 pam0) { // Read in current PAM settings from pci config space union pamdata_u pamdata; - pamdata.data32[0] =3D pci_config_readl(bdf, ALIGN_DOWN(pam0, 4)); - pamdata.data32[1] =3D pci_config_readl(bdf, ALIGN_DOWN(pam0, 4) + 4); + pamdata.data32[0] =3D pci_ioconfig_readl(bdf, ALIGN_DOWN(pam0, 4)); + pamdata.data32[1] =3D pci_ioconfig_readl(bdf, ALIGN_DOWN(pam0, 4) + 4); u8 *pam =3D &pamdata.data8[pam0 & 0x03]; =20 // Make ram from 0xc0000-0xf0000 writable @@ -46,8 +46,8 @@ __make_bios_writable_intel(u16 bdf, u32 pam0) pam[0] =3D 0x30; =20 // Write PAM settings back to pci config space - pci_config_writel(bdf, ALIGN_DOWN(pam0, 4), pamdata.data32[0]); - pci_config_writel(bdf, ALIGN_DOWN(pam0, 4) + 4, pamdata.data32[1]); + pci_ioconfig_writel(bdf, ALIGN_DOWN(pam0, 4), pamdata.data32[0]); + pci_ioconfig_writel(bdf, ALIGN_DOWN(pam0, 4) + 4, pamdata.data32[1]); =20 if (!ram_present) // Copy bios. @@ -59,7 +59,7 @@ __make_bios_writable_intel(u16 bdf, u32 pam0) static void make_bios_writable_intel(u16 bdf, u32 pam0) { - int reg =3D pci_config_readb(bdf, pam0); + int reg =3D pci_ioconfig_readb(bdf, pam0); if (!(reg & 0x10)) { // QEMU doesn't fully implement the piix shadow capabilities - // if ram isn't backing the bios segment when shadowing is @@ -125,8 +125,8 @@ make_bios_writable(void) // At this point, statically allocated variables can't be written, // so do this search manually. int bdf; - foreachbdf(bdf, 0) { - u32 vendev =3D pci_config_readl(bdf, PCI_VENDOR_ID); + pci_ioconfig_foreachbdf(bdf, 0) { + u32 vendev =3D pci_ioconfig_readl(bdf, PCI_VENDOR_ID); u16 vendor =3D vendev & 0xffff, device =3D vendev >> 16; if (vendor =3D=3D PCI_VENDOR_ID_INTEL && device =3D=3D PCI_DEVICE_ID_INTEL_82441) { @@ -183,10 +183,12 @@ qemu_reboot(void) apm_shutdown(); } make_bios_writable(); + pci_disable_mmconfig(); HaveRunPost =3D 3; } else { // Copy the BIOS making sure to only reset HaveRunPost at end make_bios_writable(); + pci_disable_mmconfig(); u32 cstart =3D SYMBOL(code32flat_start), cend =3D SYMBOL(code32fla= t_end); memcpy((void*)cstart, flash + cstart, hrp - cstart); memcpy((void*)hrp + 4, flash + hrp + 4, cend - (hrp + 4)); diff --git a/src/hw/pci.c b/src/hw/pci.c index f13cbde..ccf208a 100644 --- a/src/hw/pci.c +++ b/src/hw/pci.c @@ -133,6 +133,11 @@ pci_enable_mmconfig(u64 addr, const char *name) mmconfig =3D addr; } =20 +void pci_disable_mmconfig(void) +{ + mmconfig =3D 0; +} + u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap) { int i; @@ -157,6 +162,33 @@ u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap) return 0; } =20 +// Helper function for pci_ioconfig_foreachbdf() macro - return next device +int pci_ioconfig_next(int bdf, int bus) +{ + if (pci_bdf_to_fn(bdf) =3D=3D 0 + && (pci_ioconfig_readb(bdf, PCI_HEADER_TYPE) & 0x80) =3D=3D 0) + // Last found device wasn't a multi-function device - skip to + // the next device. + bdf +=3D 8; + else + bdf +=3D 1; + + for (;;) { + if (pci_bdf_to_bus(bdf) !=3D bus) + return -1; + + u16 v =3D pci_ioconfig_readw(bdf, PCI_VENDOR_ID); + if (v !=3D 0x0000 && v !=3D 0xffff) + // Device is present. + return bdf; + + if (pci_bdf_to_fn(bdf) =3D=3D 0) + bdf +=3D 8; + else + bdf +=3D 1; + } +} + // Helper function for foreachbdf() macro - return next device int pci_next(int bdf, int bus) diff --git a/src/hw/pci.h b/src/hw/pci.h index ee6acaf..ec45fca 100644 --- a/src/hw/pci.h +++ b/src/hw/pci.h @@ -27,6 +27,11 @@ static inline u16 pci_bus_devfn_to_bdf(int bus, u16 devf= n) { return (bus << 8) | devfn; } =20 +#define pci_ioconfig_foreachbdf(BDF, BUS) \ + for (BDF=3Dpci_ioconfig_next(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS)) \ + ; BDF >=3D 0 \ + ; BDF=3Dpci_ioconfig_next(BDF, (BUS))) + #define foreachbdf(BDF, BUS) \ for (BDF=3Dpci_next(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS)) \ ; BDF >=3D 0 \ @@ -39,6 +44,7 @@ void pci_ioconfig_writeb(u16 bdf, u32 addr, u8 val); u32 pci_ioconfig_readl(u16 bdf, u32 addr); u16 pci_ioconfig_readw(u16 bdf, u32 addr); u8 pci_ioconfig_readb(u16 bdf, u32 addr); +int pci_ioconfig_next(int bdf, int bus); =20 // PCI configuration access using either PCI CAM or PCIe ECAM void pci_config_writel(u16 bdf, u32 addr, u32 val); @@ -52,6 +58,7 @@ u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap); int pci_next(int bdf, int bus); =20 void pci_enable_mmconfig(u64 addr, const char *name); +void pci_disable_mmconfig(void); int pci_probe_host(void); void pci_reboot(void); =20 --=20 2.34.1 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org