From nobody Sat May 10 08:06:33 2025 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) client-ip=80.81.252.135; envelope-from=seabios-bounces@seabios.org; helo=mail.coreboot.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) smtp.mailfrom=seabios-bounces@seabios.org; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from mail.coreboot.org (mail.coreboot.org [80.81.252.135]) by mx.zohomail.com with SMTPS id 1533179429085691.8690657645594; Wed, 1 Aug 2018 20:10:29 -0700 (PDT) Received: from [127.0.0.1] (helo=ra.coreboot.org) by mail.coreboot.org with esmtp (Exim 4.86_2) (envelope-from ) id 1fl3Yg-0001Nr-Rn; Thu, 02 Aug 2018 04:41:46 +0200 Received: from mail-wr1-f65.google.com ([209.85.221.65]) by mail.coreboot.org with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.86_2) (envelope-from ) id 1fl3YQ-0001Mw-GV for seabios@seabios.org; Thu, 02 Aug 2018 04:41:44 +0200 Received: by mail-wr1-f65.google.com with SMTP id c13-v6so555413wrt.1 for ; Wed, 01 Aug 2018 19:39:36 -0700 (PDT) Received: from bloodymary.ipads-lab.se.sjtu.edu.cn ([46.243.138.172]) by smtp.gmail.com with ESMTPSA id a84-v6sm380965wmh.27.2018.08.01.19.39.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 01 Aug 2018 19:39:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=sG1b1s76nnEQsqj+ZPAz4QLWCEAZay2ilgUJ7mFLkvQ=; b=HoPVX/PNntC4ZQi5DdL+e8rms4/Xh5wlzkdncw+teWNBcBkxWVULQcE7Y/LtDhM8VI A2q8ovlTSlJKwqhNpO1k2+bmErF0060ssJuuvnNh9iifYVyCgKF6pAWsid5MEfSB8VRQ JSyYxjXsMLgnOeU7mMNRyx0F5wy3ODk52yLKwTzbItxdkSzABOtb1GI5IBL3k3HA/1FV jJW1KfcDCsVaJ3DSospgvl/FKGkh0yDzU1KdYhKLu8S8j7cZN0IhS3pqLcWfTTDtNud9 JERi3/xMCY31z89Ob7sRt2qTantGW6IwoMxGkp9MY4UR/CYl6AclDjLZBOG+MNSjHxM2 ci/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=sG1b1s76nnEQsqj+ZPAz4QLWCEAZay2ilgUJ7mFLkvQ=; b=J3LNSaU8WE5xXUewi2F1EGCx7X44gDsNQ5Ev+Ns8CrTPN1iPIB07NkPSsDOTse7vBq j6w/RvW+awF+nv0uqAwHlifb5ATUGtf+5TtE8YmSkdQyudRyg37myW53Y/JOv9DtgbNe 64x2sA897rl1h7X5y15kgaktNox4tKSSXqClcUgDxrWSylefF+DkjklcU6jYeGdRj88o EAidHBpMzfjX5T2q7wGrTi/NAKIZBdVLwQIoo1JRF8/u+kOWG1i4dy34F+DDXm4ZPNn3 gdPRGq5ArpE2KL7dHlMwGySvJGp0Es7kS/dGcO+2aXqJ0j/nsQsle9VaZ/Woo33apoQc NLew== X-Gm-Message-State: AOUpUlFeq/RepzAKutsmqURjn3lgrgb/QGkHtg7AsVbsqQyqkLyTt0s1 JD9fXZ0UZSbYz2J0V6kAJdk7BNUeB9U= X-Google-Smtp-Source: AAOMgpfDXLzdwE6l+BrR6En9/Alk7rHLYKZkeg2OBmwdmpWmnYfazhU/ermkkgPvhZoMBBRfGh8ymQ== X-Received: by 2002:adf:dbc3:: with SMTP id e3-v6mr478125wrj.217.1533177574507; Wed, 01 Aug 2018 19:39:34 -0700 (PDT) From: Zihan Yang To: seabios@seabios.org Date: Thu, 2 Aug 2018 10:39:15 +0800 Message-Id: <1533177555-19114-3-git-send-email-whois.zihan.yang@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1533177555-19114-1-git-send-email-whois.zihan.yang@gmail.com> References: <1533177555-19114-1-git-send-email-whois.zihan.yang@gmail.com> X-Spam-Score: -3.5 (---) Subject: [SeaBIOS] [RFC 2/2] pci_device: Add pci domain support X-BeenThere: seabios@seabios.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SeaBIOS mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Zihan Yang MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: seabios-bounces@seabios.org Sender: "SeaBIOS" X-Duff: Orig. Duff, Duff Lite, Duff Dry, Duff Dark, Raspberry Duff, Lady Duff, Red Duff, Tartar Control Duff X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Most part of seabios assume only PCI domain 0. This patch adds support for multiple domain in pci devices Signed-off-by: Zihan Yang --- src/fw/coreboot.c | 2 +- src/fw/csm.c | 2 +- src/fw/paravirt.c | 2 +- src/fw/pciinit.c | 191 +++++++++++++++++++++++++++++++++----------------= ---- src/hw/pci.c | 69 ++++++++++--------- src/hw/pci.h | 42 ++++++++---- src/hw/pci_ids.h | 7 +- src/hw/pcidevice.c | 8 ++- src/hw/pcidevice.h | 10 ++- 9 files changed, 206 insertions(+), 127 deletions(-) diff --git a/src/fw/coreboot.c b/src/fw/coreboot.c index 7c0954b..c955dfd 100644 --- a/src/fw/coreboot.c +++ b/src/fw/coreboot.c @@ -254,7 +254,7 @@ coreboot_platform_setup(void) { if (!CONFIG_COREBOOT) return; - pci_probe_devices(); + pci_probe_devices(0); =20 struct cb_memory *cbm =3D CBMemTable; if (!cbm) diff --git a/src/fw/csm.c b/src/fw/csm.c index 03b4bb8..e94f614 100644 --- a/src/fw/csm.c +++ b/src/fw/csm.c @@ -63,7 +63,7 @@ static void csm_maininit(struct bregs *regs) { interface_init(); - pci_probe_devices(); + pci_probe_devices(0); =20 csm_compat_table.PnPInstallationCheckSegment =3D SEG_BIOS; csm_compat_table.PnPInstallationCheckOffset =3D get_pnp_offset(); diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index 6b14542..ef4d487 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -155,7 +155,7 @@ qemu_platform_setup(void) return; =20 if (runningOnXen()) { - pci_probe_devices(); + pci_probe_devices(0); xen_hypercall_setup(); xen_biostable_setup(); return; diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index 6e6a434..71508d5 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -51,6 +51,7 @@ u64 pcimem_end =3D BUILD_PCIMEM_END; u64 pcimem64_start =3D BUILD_PCIMEM64_START; u64 pcimem64_end =3D BUILD_PCIMEM64_END; u64 pci_io_low_end =3D 0xa000; +u64 pxb_mcfg_size =3D 0; =20 struct pci_region_entry { struct pci_device *dev; @@ -405,19 +406,21 @@ static void pci_bios_init_device(struct pci_device *p= ci) =20 /* map the interrupt */ u16 bdf =3D pci->bdf; - int pin =3D pci_config_readb(bdf, PCI_INTERRUPT_PIN); + int pin =3D pci_config_readb_dom(bdf, PCI_INTERRUPT_PIN, pci->domain_n= r); if (pin !=3D 0) - pci_config_writeb(bdf, PCI_INTERRUPT_LINE, pci_slot_get_irq(pci, p= in)); + pci_config_writeb_dom(bdf, PCI_INTERRUPT_LINE, pci_slot_get_irq(pc= i, pin), + pci->domain_nr); =20 pci_init_device(pci_device_tbl, pci, NULL); =20 /* enable memory mappings */ - pci_config_maskw(bdf, PCI_COMMAND, 0, - PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SER= R); + pci_config_maskw_dom(bdf, PCI_COMMAND, 0, + PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SER= R, + pci->domain_nr); /* enable SERR# for forwarding */ if (pci->header_type & PCI_HEADER_TYPE_BRIDGE) - pci_config_maskw(bdf, PCI_BRIDGE_CONTROL, 0, - PCI_BRIDGE_CTL_SERR); + pci_config_maskw_dom(bdf, PCI_BRIDGE_CONTROL, 0, + PCI_BRIDGE_CTL_SERR, pci->domain_nr); } =20 static void pci_bios_init_devices(void) @@ -520,6 +523,10 @@ static void pxb_mem_addr_setup(struct pci_device *dev,= void *arg) * read mcfg_base and mcfg_size from it just now. Instead, we directly= add * this item to e820 */ e820_add(mcfg_base.val, mcfg_size, E820_RESERVED); + + /* Add PXBHosts so that we can can initialize them later */ + ++PXBHosts; + pxb_mcfg_size +=3D mcfg_size; } =20 static const struct pci_device_id pci_platform_tbl[] =3D { @@ -540,19 +547,21 @@ static void pci_bios_init_platform(void) } } =20 -static u8 pci_find_resource_reserve_capability(u16 bdf) +static u8 pci_find_resource_reserve_capability(u16 bdf, int domain_nr) { - if (pci_config_readw(bdf, PCI_VENDOR_ID) =3D=3D PCI_VENDOR_ID_REDHAT && - pci_config_readw(bdf, PCI_DEVICE_ID) =3D=3D - PCI_DEVICE_ID_REDHAT_ROOT_PORT) { + if (pci_config_readw_dom(bdf, PCI_VENDOR_ID, domain_nr) =3D=3D PCI_VEN= DOR_ID_REDHAT && + (pci_config_readw_dom(bdf, PCI_DEVICE_ID, domain_nr) =3D=3D + PCI_DEVICE_ID_REDHAT_ROOT_PORT || + pci_config_readw_dom(bdf, PCI_DEVICE_ID, domain_nr) =3D=3D + PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE)) { u8 cap =3D 0; do { - cap =3D pci_find_capability(bdf, PCI_CAP_ID_VNDR, cap); + cap =3D pci_find_capability_dom(bdf, PCI_CAP_ID_VNDR, cap, dom= ain_nr); } while (cap && - pci_config_readb(bdf, cap + PCI_CAP_REDHAT_TYPE_OFFSET) != =3D + pci_config_readb_dom(bdf, cap + PCI_CAP_REDHAT_TYPE_OFFSE= T, domain_nr) !=3D REDHAT_CAP_RESOURCE_RESERVE); if (cap) { - u8 cap_len =3D pci_config_readb(bdf, cap + PCI_CAP_FLAGS); + u8 cap_len =3D pci_config_readb_dom(bdf, cap + PCI_CAP_FLAGS, = domain_nr); if (cap_len < RES_RESERVE_CAP_SIZE) { dprintf(1, "PCI: QEMU resource reserve cap length %d is in= valid\n", cap_len); @@ -570,7 +579,7 @@ static u8 pci_find_resource_reserve_capability(u16 bdf) ****************************************************************/ =20 static void -pci_bios_init_bus_rec(int bus, u8 *pci_bus) +pci_bios_init_bus_rec(int bus, u8 *pci_bus, int domain_nr) { int bdf; u16 class; @@ -578,54 +587,54 @@ pci_bios_init_bus_rec(int bus, u8 *pci_bus) dprintf(1, "PCI: %s bus =3D 0x%x\n", __func__, bus); =20 /* prevent accidental access to unintended devices */ - foreachbdf(bdf, bus) { - class =3D pci_config_readw(bdf, PCI_CLASS_DEVICE); + foreachbdf_dom(bdf, bus, domain_nr) { + class =3D pci_config_readw_dom(bdf, PCI_CLASS_DEVICE, domain_nr); if (class =3D=3D PCI_CLASS_BRIDGE_PCI) { - pci_config_writeb(bdf, PCI_SECONDARY_BUS, 255); - pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 0); + pci_config_writeb_dom(bdf, PCI_SECONDARY_BUS, 255, domain_nr); + pci_config_writeb_dom(bdf, PCI_SUBORDINATE_BUS, 0, domain_nr); } } =20 - foreachbdf(bdf, bus) { - class =3D pci_config_readw(bdf, PCI_CLASS_DEVICE); + foreachbdf_dom(bdf, bus, domain_nr) { + class =3D pci_config_readw_dom(bdf, PCI_CLASS_DEVICE, domain_nr); if (class !=3D PCI_CLASS_BRIDGE_PCI) { continue; } dprintf(1, "PCI: %s bdf =3D 0x%x\n", __func__, bdf); =20 - u8 pribus =3D pci_config_readb(bdf, PCI_PRIMARY_BUS); + u8 pribus =3D pci_config_readb_dom(bdf, PCI_PRIMARY_BUS, domain_nr= ); if (pribus !=3D bus) { dprintf(1, "PCI: primary bus =3D 0x%x -> 0x%x\n", pribus, bus); - pci_config_writeb(bdf, PCI_PRIMARY_BUS, bus); + pci_config_writeb_dom(bdf, PCI_PRIMARY_BUS, bus, domain_nr); } else { dprintf(1, "PCI: primary bus =3D 0x%x\n", pribus); } =20 - u8 secbus =3D pci_config_readb(bdf, PCI_SECONDARY_BUS); + u8 secbus =3D pci_config_readb_dom(bdf, PCI_SECONDARY_BUS, domain_= nr); (*pci_bus)++; if (*pci_bus !=3D secbus) { dprintf(1, "PCI: secondary bus =3D 0x%x -> 0x%x\n", secbus, *pci_bus); secbus =3D *pci_bus; - pci_config_writeb(bdf, PCI_SECONDARY_BUS, secbus); + pci_config_writeb_dom(bdf, PCI_SECONDARY_BUS, secbus, domain_n= r); } else { dprintf(1, "PCI: secondary bus =3D 0x%x\n", secbus); } =20 /* set to max for access to all subordinate buses. later set it to accurate value */ - u8 subbus =3D pci_config_readb(bdf, PCI_SUBORDINATE_BUS); - pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 255); + u8 subbus =3D pci_config_readb_dom(bdf, PCI_SUBORDINATE_BUS, domai= n_nr); + pci_config_writeb_dom(bdf, PCI_SUBORDINATE_BUS, 255, domain_nr); =20 - pci_bios_init_bus_rec(secbus, pci_bus); + pci_bios_init_bus_rec(secbus, pci_bus, domain_nr); =20 if (subbus !=3D *pci_bus) { u8 res_bus =3D *pci_bus; - u8 cap =3D pci_find_resource_reserve_capability(bdf); + u8 cap =3D pci_find_resource_reserve_capability(bdf, domain_nr= ); =20 if (cap) { - u32 tmp_res_bus =3D pci_config_readl(bdf, - cap + RES_RESERVE_BUS_RES); + u32 tmp_res_bus =3D pci_config_readl_dom(bdf, + cap + RES_RESERVE_BUS_RES, domain_nr); if (tmp_res_bus !=3D (u32)-1) { res_bus =3D tmp_res_bus & 0xFF; if ((u8)(res_bus + secbus) < secbus || @@ -648,7 +657,7 @@ pci_bios_init_bus_rec(int bus, u8 *pci_bus) } else { dprintf(1, "PCI: subordinate bus =3D 0x%x\n", subbus); } - pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, subbus); + pci_config_writeb_dom(bdf, PCI_SUBORDINATE_BUS, subbus, domain_nr); } } =20 @@ -658,16 +667,29 @@ pci_bios_init_bus(void) u8 extraroots =3D romfile_loadint("etc/extra-pci-roots", 0); u8 pci_bus =3D 0; =20 - pci_bios_init_bus_rec(0 /* host bus */, &pci_bus); + pci_bios_init_bus_rec(0 /* host bus */, &pci_bus, 0); =20 if (extraroots) { while (pci_bus < 0xff) { pci_bus++; - pci_bios_init_bus_rec(pci_bus, &pci_bus); + pci_bios_init_bus_rec(pci_bus, &pci_bus, 0); } } } =20 +static void +pci_bios_init_pxb_bus(int domain_nr) +{ + u8 pci_bus =3D 0; + + // FIX ME! Hardcoded ports is not a good idea at all! + pci_bios_init_bus_rec(0, &pci_bus, domain_nr); + + while (pci_bus < 0xff) { + pci_bus++; + pci_bios_init_bus_rec(pci_bus, &pci_bus, domain_nr); + } +} =20 /**************************************************************** * Bus sizing @@ -675,17 +697,18 @@ pci_bios_init_bus(void) =20 static void pci_bios_get_bar(struct pci_device *pci, int bar, - int *ptype, u64 *psize, int *pis64) + int *ptype, u64 *psize, int *pis64, + int domain_nr) { u32 ofs =3D pci_bar(pci, bar); u16 bdf =3D pci->bdf; - u32 old =3D pci_config_readl(bdf, ofs); + u32 old =3D pci_config_readl_dom(bdf, ofs, domain_nr); int is64 =3D 0, type =3D PCI_REGION_TYPE_MEM; u64 mask; =20 if (bar =3D=3D PCI_ROM_SLOT) { mask =3D PCI_ROM_ADDRESS_MASK; - pci_config_writel(bdf, ofs, mask); + pci_config_writel_dom(bdf, ofs, mask, domain_nr); } else { if (old & PCI_BASE_ADDRESS_SPACE_IO) { mask =3D PCI_BASE_ADDRESS_IO_MASK; @@ -697,15 +720,15 @@ pci_bios_get_bar(struct pci_device *pci, int bar, is64 =3D ((old & PCI_BASE_ADDRESS_MEM_TYPE_MASK) =3D=3D PCI_BASE_ADDRESS_MEM_TYPE_64); } - pci_config_writel(bdf, ofs, ~0); + pci_config_writel_dom(bdf, ofs, ~0, domain_nr); } - u64 val =3D pci_config_readl(bdf, ofs); - pci_config_writel(bdf, ofs, old); + u64 val =3D pci_config_readl_dom(bdf, ofs, domain_nr); + pci_config_writel_dom(bdf, ofs, old, domain_nr); if (is64) { - u32 hold =3D pci_config_readl(bdf, ofs + 4); - pci_config_writel(bdf, ofs + 4, ~0); - u32 high =3D pci_config_readl(bdf, ofs + 4); - pci_config_writel(bdf, ofs + 4, hold); + u32 hold =3D pci_config_readl_dom(bdf, ofs + 4, domain_nr); + pci_config_writel_dom(bdf, ofs + 4, ~0, domain_nr); + u32 high =3D pci_config_readl_dom(bdf, ofs + 4, domain_nr); + pci_config_writel_dom(bdf, ofs + 4, hold, domain_nr); val |=3D ((u64)high << 32); mask |=3D ((u64)0xffffffff << 32); *psize =3D (~(val & mask)) + 1; @@ -717,15 +740,20 @@ pci_bios_get_bar(struct pci_device *pci, int bar, } =20 static int pci_bios_bridge_region_is64(struct pci_region *r, - struct pci_device *pci, int type) + struct pci_device *pci, int type, + int domain_nr) { if (type !=3D PCI_REGION_TYPE_PREFMEM) return 0; - u32 pmem =3D pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE); + u32 pmem =3D pci_config_readl_dom(pci->bdf, PCI_PREF_MEMORY_BASE, + domain_nr); if (!pmem) { - pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0xfff0fff0); - pmem =3D pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE); - pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0x0); + pci_config_writel_dom(pci->bdf, PCI_PREF_MEMORY_BASE, 0xfff0fff0, + domain_nr); + pmem =3D pci_config_readl_dom(pci->bdf, PCI_PREF_MEMORY_BASE, + domain_nr); + pci_config_writel_dom(pci->bdf, PCI_PREF_MEMORY_BASE, 0x0, + domain_nr); } if ((pmem & PCI_PREF_RANGE_TYPE_MASK) !=3D PCI_PREF_RANGE_TYPE_64) return 0; @@ -801,13 +829,15 @@ pci_region_create_entry(struct pci_bus *bus, struct p= ci_device *dev, return entry; } =20 -static int pci_bus_hotplug_support(struct pci_bus *bus, u8 pcie_cap) +static int pci_bus_hotplug_support(struct pci_bus *bus, u8 pcie_cap, + int domain_nr) { u8 shpc_cap; =20 if (pcie_cap) { - u16 pcie_flags =3D pci_config_readw(bus->bus_dev->bdf, - pcie_cap + PCI_EXP_FLAGS); + u16 pcie_flags =3D pci_config_readw_dom(bus->bus_dev->bdf, + pcie_cap + PCI_EXP_FLAGS, + domain_nr); u8 port_type =3D ((pcie_flags & PCI_EXP_FLAGS_TYPE) >> (__builtin_ffs(PCI_EXP_FLAGS_TYPE) - 1)); u8 downstream_port =3D (port_type =3D=3D PCI_EXP_TYPE_DOWNSTREAM) = || @@ -826,7 +856,8 @@ static int pci_bus_hotplug_support(struct pci_bus *bus,= u8 pcie_cap) return downstream_port && slot_implemented; } =20 - shpc_cap =3D pci_find_capability(bus->bus_dev->bdf, PCI_CAP_ID_SHPC, 0= ); + shpc_cap =3D pci_find_capability_dom(bus->bus_dev->bdf, PCI_CAP_ID_SHP= C, 0, + domain_nr); return !!shpc_cap; } =20 @@ -835,7 +866,8 @@ static int pci_bus_hotplug_support(struct pci_bus *bus,= u8 pcie_cap) * Note: disables bridge's window registers as a side effect. */ static int pci_bridge_has_region(struct pci_device *pci, - enum pci_region_type region_type) + enum pci_region_type region_type, + int domain_nr) { u8 base; =20 @@ -851,12 +883,12 @@ static int pci_bridge_has_region(struct pci_device *p= ci, return 1; } =20 - pci_config_writeb(pci->bdf, base, 0xFF); + pci_config_writeb_dom(pci->bdf, base, 0xFF, domain_nr); =20 - return pci_config_readb(pci->bdf, base) !=3D 0; + return pci_config_readb_dom(pci->bdf, base, domain_nr) !=3D 0; } =20 -static int pci_bios_check_devices(struct pci_bus *busses) +static int pci_bios_check_devices(struct pci_bus *busses, int domain_nr) { dprintf(1, "PCI: check devices\n"); =20 @@ -879,7 +911,7 @@ static int pci_bios_check_devices(struct pci_bus *busse= s) continue; int type, is64; u64 size; - pci_bios_get_bar(pci, i, &type, &size, &is64); + pci_bios_get_bar(pci, i, &type, &size, &is64, domain_nr); if (size =3D=3D 0) continue; =20 @@ -909,14 +941,14 @@ static int pci_bios_check_devices(struct pci_bus *bus= ses) parent =3D &busses[0]; int type; u16 bdf =3D s->bus_dev->bdf; - u8 pcie_cap =3D pci_find_capability(bdf, PCI_CAP_ID_EXP, 0); - u8 qemu_cap =3D pci_find_resource_reserve_capability(bdf); + u8 pcie_cap =3D pci_find_capability_dom(bdf, PCI_CAP_ID_EXP, 0, do= main_nr); + u8 qemu_cap =3D pci_find_resource_reserve_capability(bdf, domain_n= r); =20 - int hotplug_support =3D pci_bus_hotplug_support(s, pcie_cap); + int hotplug_support =3D pci_bus_hotplug_support(s, pcie_cap, domai= n_nr); for (type =3D 0; type < PCI_REGION_TYPE_COUNT; type++) { u64 align =3D (type =3D=3D PCI_REGION_TYPE_IO) ? PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN; - if (!pci_bridge_has_region(s->bus_dev, type)) + if (!pci_bridge_has_region(s->bus_dev, type, domain_nr)) continue; u64 size =3D 0; if (qemu_cap) { @@ -924,22 +956,25 @@ static int pci_bios_check_devices(struct pci_bus *bus= ses) u64 tmp_size_64; switch(type) { case PCI_REGION_TYPE_IO: - tmp_size_64 =3D (pci_config_readl(bdf, qemu_cap + RES_= RESERVE_IO) | - (u64)pci_config_readl(bdf, qemu_cap + RES_RESE= RVE_IO + 4) << 32); + tmp_size_64 =3D (pci_config_readl_dom(bdf, qemu_cap + = RES_RESERVE_IO, domain_nr) | + (u64)pci_config_readl_dom(bdf, qemu_cap + RES_= RESERVE_IO + 4, domain_nr) << 32); if (tmp_size_64 !=3D (u64)-1) { size =3D tmp_size_64; } break; case PCI_REGION_TYPE_MEM: - tmp_size =3D pci_config_readl(bdf, qemu_cap + RES_RESE= RVE_MEM); + tmp_size =3D pci_config_readl_dom(bdf, qemu_cap + RES_= RESERVE_MEM, domain_nr); if (tmp_size !=3D (u32)-1) { size =3D tmp_size; } break; case PCI_REGION_TYPE_PREFMEM: - tmp_size =3D pci_config_readl(bdf, qemu_cap + RES_RESE= RVE_PREF_MEM_32); - tmp_size_64 =3D (pci_config_readl(bdf, qemu_cap + RES_= RESERVE_PREF_MEM_64) | - (u64)pci_config_readl(bdf, qemu_cap + RES_RESE= RVE_PREF_MEM_64 + 4) << 32); + tmp_size =3D pci_config_readl_dom(bdf, qemu_cap + RES_= RESERVE_PREF_MEM_32, + domain_nr); + tmp_size_64 =3D (pci_config_readl_dom(bdf, qemu_cap + = RES_RESERVE_PREF_MEM_64, + domain_nr) | + (u64)pci_config_readl_dom(bdf, qemu_cap + RE= S_RESERVE_PREF_MEM_64 + 4, + domain_nr) << 32); if (tmp_size !=3D (u32)-1 && tmp_size_64 =3D=3D (u64)-= 1) { size =3D tmp_size; } else if (tmp_size =3D=3D (u32)-1 && tmp_size_64 !=3D= (u64)-1) { @@ -970,7 +1005,7 @@ static int pci_bios_check_devices(struct pci_bus *buss= es) size =3D ALIGN(sum, align); } int is64 =3D pci_bios_bridge_region_is64(&s->r[type], - s->bus_dev, type); + s->bus_dev, type, domain_nr); // entry->bar is -1 if the entry represents a bridge region struct pci_region_entry *entry =3D pci_region_create_entry( parent, s->bus_dev, -1, size, align, type, is64); @@ -1036,6 +1071,7 @@ static int pci_bios_init_root_regions_mem(struct pci_= bus *bus) align =3D pci_region_align(r_start); r_start->base =3D ALIGN_DOWN((r_end->base - sum), align); =20 + dprintf(1, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n\nr_start->bas= e =3D 0x%llx, pcimem_start =3D 0x%llx, pcimem_end =3D 0x%llx\n=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D\n", r_start->base, pcimem_start, pcimem_end); if ((r_start->base < pcimem_start) || (r_start->base > pcimem_end)) // Memory range requested is larger than available. @@ -1127,8 +1163,8 @@ static void pci_bios_map_devices(struct pci_bus *buss= es) r64_pref.base =3D r64_mem.base + sum_mem; r64_pref.base =3D ALIGN(r64_pref.base, align_pref); r64_pref.base =3D ALIGN(r64_pref.base, (1LL<<30)); // 1G hugepage - pcimem64_start =3D r64_mem.base; - pcimem64_end =3D r64_pref.base + sum_pref; + pcimem64_start =3D r64_mem.base + pxb_mcfg_size; + pcimem64_end =3D r64_pref.base + sum_pref + pxb_mcfg_size; pcimem64_end =3D ALIGN(pcimem64_end, (1LL<<30)); // 1G hugepage dprintf(1, "PCI: 64: %016llx - %016llx\n", pcimem64_start, pcimem6= 4_end); =20 @@ -1165,9 +1201,12 @@ pci_setup(void) return; } pci_bios_init_bus(); + /* FIXME! Hardcode is just for debugging right now */ + pci_bios_init_pxb_bus(1); =20 dprintf(1, "=3D=3D=3D PCI device probing =3D=3D=3D\n"); - pci_probe_devices(); + pci_probe_devices(0); + pci_probe_devices(1); =20 pcimem_start =3D RamSize; pci_bios_init_platform(); @@ -1179,7 +1218,7 @@ pci_setup(void) return; } memset(busses, 0, sizeof(*busses) * (MaxPCIBus + 1)); - if (pci_bios_check_devices(busses)) + if (pci_bios_check_devices(busses, 0)) return; =20 dprintf(1, "=3D=3D=3D PCI new allocation pass #2 =3D=3D=3D\n"); @@ -1187,6 +1226,14 @@ pci_setup(void) =20 pci_bios_init_devices(); =20 + /* then check pxb host busses */ + memset(busses, 0, sizeof(*busses) * (MaxPCIBus + 1)); + if (pci_bios_check_devices(busses, 1)) + return; + + //pci_bios_map_devices(busses); + //pci_bios_init_devices(); + free(busses); =20 pci_enable_default_vga(); diff --git a/src/hw/pci.c b/src/hw/pci.c index 9855bad..cc1b6ec 100644 --- a/src/hw/pci.c +++ b/src/hw/pci.c @@ -11,72 +11,75 @@ #include "util.h" // udelay #include "x86.h" // outl =20 -#define PORT_PCI_CMD 0x0cf8 -#define PORT_PCI_DATA 0x0cfc - -void pci_config_writel(u16 bdf, u32 addr, u32 val) +void pci_config_writel_dom(u16 bdf, u32 addr, u32 val, int domain_nr) { - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - outl(val, PORT_PCI_DATA); + outl(0x80000000 | (bdf << 8) | (addr & 0xfc), + domain_nr ? PORT_PXB_CMD_BASE + ((domain_nr - 1) << 3) : PORT_PCI= _CMD); + outl(val, (domain_nr ? PORT_PXB_DATA_BASE + ((domain_nr - 1) << 3) : P= ORT_PCI_DATA)); } =20 -void pci_config_writew(u16 bdf, u32 addr, u16 val) +void pci_config_writew_dom(u16 bdf, u32 addr, u16 val, int domain_nr) { - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - outw(val, PORT_PCI_DATA + (addr & 2)); + outl(0x80000000 | (bdf << 8) | (addr & 0xfc), + domain_nr =3D=3D 0 ? PORT_PCI_CMD : PORT_PXB_CMD_BASE + (domain_n= r << 3)); + outw(val, (domain_nr ? PORT_PXB_DATA_BASE + ((domain_nr - 1) << 3) : P= ORT_PCI_DATA) + (addr & 2)); } =20 -void pci_config_writeb(u16 bdf, u32 addr, u8 val) +void pci_config_writeb_dom(u16 bdf, u32 addr, u8 val, int domain_nr) { - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - outb(val, PORT_PCI_DATA + (addr & 3)); + outl(0x80000000 | (bdf << 8) | (addr & 0xfc), + domain_nr ? PORT_PXB_CMD_BASE + ((domain_nr - 1) << 3) : PORT_PCI= _CMD); + outb(val, (domain_nr ? PORT_PXB_DATA_BASE + ((domain_nr - 1) << 3) : P= ORT_PCI_DATA) + (addr & 3)); } =20 -u32 pci_config_readl(u16 bdf, u32 addr) +u32 pci_config_readl_dom(u16 bdf, u32 addr, int domain_nr) { - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - return inl(PORT_PCI_DATA); + outl(0x80000000 | (bdf << 8) | (addr & 0xfc), + domain_nr ? PORT_PXB_CMD_BASE + ((domain_nr - 1) << 3) : PORT_PCI= _CMD); + return inl((domain_nr ? PORT_PXB_DATA_BASE + ((domain_nr - 1) << 3) : = PORT_PCI_DATA)); } =20 -u16 pci_config_readw(u16 bdf, u32 addr) +u16 pci_config_readw_dom(u16 bdf, u32 addr, int domain_nr) { - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - return inw(PORT_PCI_DATA + (addr & 2)); + outl(0x80000000 | (bdf << 8) | (addr & 0xfc), + domain_nr ? PORT_PXB_CMD_BASE + ((domain_nr - 1) << 3) : PORT_PCI= _CMD); + return inw((domain_nr ? PORT_PXB_DATA_BASE + ((domain_nr - 1) << 3) : = PORT_PCI_DATA) + (addr & 2)); } =20 -u8 pci_config_readb(u16 bdf, u32 addr) +u8 pci_config_readb_dom(u16 bdf, u32 addr, int domain_nr) { - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - return inb(PORT_PCI_DATA + (addr & 3)); + outl(0x80000000 | (bdf << 8) | (addr & 0xfc), + domain_nr ? PORT_PXB_CMD_BASE + ((domain_nr - 1) << 3) : PORT_PCI= _CMD); + return inb((domain_nr ? PORT_PXB_DATA_BASE + ((domain_nr - 1) << 3) : = PORT_PCI_DATA) + (addr & 3)); } =20 void -pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on) +pci_config_maskw_dom(u16 bdf, u32 addr, u16 off, u16 on, int domain_nr) { - u16 val =3D pci_config_readw(bdf, addr); + u16 val =3D pci_config_readw_dom(bdf, addr, domain_nr); val =3D (val & ~off) | on; - pci_config_writew(bdf, addr, val); + pci_config_writew_dom(bdf, addr, val, domain_nr); } =20 -u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap) +u8 pci_find_capability_dom(u16 bdf, u8 cap_id, u8 cap, int domain_nr) { int i; - u16 status =3D pci_config_readw(bdf, PCI_STATUS); + u16 status =3D pci_config_readw_dom(bdf, PCI_STATUS, domain_nr); =20 if (!(status & PCI_STATUS_CAP_LIST)) return 0; =20 if (cap =3D=3D 0) { /* find first */ - cap =3D pci_config_readb(bdf, PCI_CAPABILITY_LIST); + cap =3D pci_config_readb_dom(bdf, PCI_CAPABILITY_LIST, domain_nr); } else { /* find next */ - cap =3D pci_config_readb(bdf, cap + PCI_CAP_LIST_NEXT); + cap =3D pci_config_readb_dom(bdf, cap + PCI_CAP_LIST_NEXT, domain_= nr); } for (i =3D 0; cap && i <=3D 0xff; i++) { - if (pci_config_readb(bdf, cap + PCI_CAP_LIST_ID) =3D=3D cap_id) + if (pci_config_readb_dom(bdf, cap + PCI_CAP_LIST_ID, domain_nr) = =3D=3D cap_id) return cap; - cap =3D pci_config_readb(bdf, cap + PCI_CAP_LIST_NEXT); + cap =3D pci_config_readb_dom(bdf, cap + PCI_CAP_LIST_NEXT, domain_= nr); } =20 return 0; @@ -84,10 +87,10 @@ u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap) =20 // Helper function for foreachbdf() macro - return next device int -pci_next(int bdf, int bus) +pci_next_dom(int bdf, int bus, int domain_nr) { if (pci_bdf_to_fn(bdf) =3D=3D 0 - && (pci_config_readb(bdf, PCI_HEADER_TYPE) & 0x80) =3D=3D 0) + && (pci_config_readb_dom(bdf, PCI_HEADER_TYPE, domain_nr) & 0x80) = =3D=3D 0) // Last found device wasn't a multi-function device - skip to // the next device. bdf +=3D 8; @@ -98,7 +101,7 @@ pci_next(int bdf, int bus) if (pci_bdf_to_bus(bdf) !=3D bus) return -1; =20 - u16 v =3D pci_config_readw(bdf, PCI_VENDOR_ID); + u16 v =3D pci_config_readw_dom(bdf, PCI_VENDOR_ID, domain_nr); if (v !=3D 0x0000 && v !=3D 0xffff) // Device is present. return bdf; diff --git a/src/hw/pci.h b/src/hw/pci.h index 2e30e28..4381563 100644 --- a/src/hw/pci.h +++ b/src/hw/pci.h @@ -3,7 +3,11 @@ =20 #include "types.h" // u32 =20 +#define PORT_PCI_CMD 0x0cf8 #define PORT_PCI_REBOOT 0x0cf9 +#define PORT_PCI_DATA 0x0cfc +#define PORT_PXB_CMD_BASE 0x1000 +#define PORT_PXB_DATA_BASE 0x1004 =20 static inline u8 pci_bdf_to_bus(u16 bdf) { return bdf >> 8; @@ -27,20 +31,34 @@ static inline u16 pci_bus_devfn_to_bdf(int bus, u16 dev= fn) { return (bus << 8) | devfn; } =20 -#define foreachbdf(BDF, BUS) \ - for (BDF=3Dpci_next(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS)) \ +/* for compatibility */ +#define foreachbdf(BDF, BUS) foreachbdf_dom(BDF, BUS, 0) + +#define foreachbdf_dom(BDF, BUS, DOMAIN) = \ + for (BDF=3Dpci_next_dom(pci_bus_devfn_to_bdf((BUS), 0)-1, (BUS), (DOMA= IN)) \ ; BDF >=3D 0 \ - ; BDF=3Dpci_next(BDF, (BUS))) + ; BDF=3Dpci_next_dom(BDF, (BUS), (DOMAIN))) =20 -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); -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); -u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap); -int pci_next(int bdf, int bus); +#define pci_config_maskw(BDF, ADDR, OFF, ON) pci_config_maskw_dom((BDF), (= ADDR), (OFF), (ON), 0) +#define pci_find_capability(BDF, CAP_ID, CAP) pci_find_capability_dom((BDF= ), (CAP_ID), (CAP), 0) +#define pci_next(BDF, BUS) pci_next_dom((BDF), (BUS), 0) + +#define pci_config_writel(BDF, ADDR, VAL) pci_config_writel_dom((BDF), (AD= DR), (VAL), 0) +#define pci_config_writew(BDF, ADDR, VAL) pci_config_writew_dom((BDF), (AD= DR), (VAL), 0) +#define pci_config_writeb(BDF, ADDR, VAL) pci_config_writeb_dom((BDF), (AD= DR), (VAL), 0) +#define pci_config_readl(BDF, ADDR) pci_config_readl_dom((BDF), (ADDR), 0) +#define pci_config_readw(BDF, ADDR) pci_config_readw_dom((BDF), (ADDR), 0) +#define pci_config_readb(BDF, ADDR) pci_config_readb_dom((BDF), (ADDR), 0) + +void pci_config_writel_dom(u16 bdf, u32 addr, u32 val, int domain_nr); +void pci_config_writew_dom(u16 bdf, u32 addr, u16 val, int domain_nr); +void pci_config_writeb_dom(u16 bdf, u32 addr, u8 val, int domain_nr); +u32 pci_config_readl_dom(u16 bdf, u32 addr, int domain_nr); +u16 pci_config_readw_dom(u16 bdf, u32 addr, int domain_nr); +u8 pci_config_readb_dom(u16 bdf, u32 addr, int domain_nr); +void pci_config_maskw_dom(u16 bdf, u32 addr, u16 off, u16 on, int domain_n= r); +u8 pci_find_capability_dom(u16 bdf, u8 cap_id, u8 cap, int domain_nr); +int pci_next_dom(int bdf, int bus, int domain_nr); int pci_probe_host(void); void pci_reboot(void); =20 diff --git a/src/hw/pci_ids.h b/src/hw/pci_ids.h index 35096ea..1d4ddf6 100644 --- a/src/hw/pci_ids.h +++ b/src/hw/pci_ids.h @@ -2263,9 +2263,10 @@ #define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600 #define PCI_DEVICE_ID_KORENIX_JETCARDF1 0x16ff =20 -#define PCI_VENDOR_ID_REDHAT 0x1b36 -#define PCI_DEVICE_ID_REDHAT_ROOT_PORT 0x000C -#define PCI_DEVICE_ID_REDHAT_PXB_HOST 0x000B +#define PCI_VENDOR_ID_REDHAT 0x1b36 +#define PCI_DEVICE_ID_REDHAT_PXB_HOST 0x000B +#define PCI_DEVICE_ID_REDHAT_ROOT_PORT 0x000C +#define PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE 0x000E =20 #define PCI_VENDOR_ID_TEKRAM 0x1de1 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 diff --git a/src/hw/pcidevice.c b/src/hw/pcidevice.c index 8853cf7..ec21ec1 100644 --- a/src/hw/pcidevice.c +++ b/src/hw/pcidevice.c @@ -15,10 +15,11 @@ =20 struct hlist_head PCIDevices VARVERIFY32INIT; int MaxPCIBus VARFSEG; +int PXBHosts VARFSEG; =20 // Find all PCI devices and populate PCIDevices linked list. void -pci_probe_devices(void) +pci_probe_devices(int domain_nr) { dprintf(3, "PCI probe\n"); struct pci_device *busdevs[256]; @@ -29,7 +30,7 @@ pci_probe_devices(void) while (bus < 0xff && (bus < MaxPCIBus || rootbuses < extraroots)) { bus++; int bdf; - foreachbdf(bdf, bus) { + foreachbdf_dom(bdf, bus, domain_nr) { // Create new pci_device struct and add to list. struct pci_device *dev =3D malloc_tmp(sizeof(*dev)); if (!dev) { @@ -56,6 +57,7 @@ pci_probe_devices(void) } =20 // Populate pci_device info. + dev->domain_nr =3D domain_nr; dev->bdf =3D bdf; dev->parent =3D parent; dev->rootbus =3D rootbus; @@ -69,7 +71,7 @@ pci_probe_devices(void) dev->header_type =3D pci_config_readb(bdf, PCI_HEADER_TYPE); u8 v =3D dev->header_type & 0x7f; if (v =3D=3D PCI_HEADER_TYPE_BRIDGE || v =3D=3D PCI_HEADER_TYP= E_CARDBUS) { - u8 secbus =3D pci_config_readb(bdf, PCI_SECONDARY_BUS); + u8 secbus =3D pci_config_readb_dom(bdf, PCI_SECONDARY_BUS,= domain_nr); dev->secondary_bus =3D secbus; if (secbus > bus && !busdevs[secbus]) busdevs[secbus] =3D dev; diff --git a/src/hw/pcidevice.h b/src/hw/pcidevice.h index 225d545..ddf60bb 100644 --- a/src/hw/pcidevice.h +++ b/src/hw/pcidevice.h @@ -5,6 +5,7 @@ #include "list.h" // hlist_node =20 struct pci_device { + u32 domain_nr; u16 bdf; u8 rootbus; struct hlist_node node; @@ -22,6 +23,7 @@ struct pci_device { }; extern struct hlist_head PCIDevices; extern int MaxPCIBus; +extern int PXBHosts; =20 static inline u32 pci_classprog(struct pci_device *pci) { return (pci->class << 8) | pci->prog_if; @@ -30,6 +32,12 @@ static inline u32 pci_classprog(struct pci_device *pci) { #define foreachpci(PCI) \ hlist_for_each_entry(PCI, &PCIDevices, node) =20 +#define foreachpci_dom(PCI, DOMAIN) \ + hlist_for_each_entry(PCI, &PCIDevices, node) { \ + if (pci->domain_nr !=3D (DOMAIN)) \ + continue; \ + } + #define PCI_ANY_ID (~0) struct pci_device_id { u32 vendid; @@ -62,7 +70,7 @@ struct pci_device_id { .vendid =3D 0, \ } =20 -void pci_probe_devices(void); +void pci_probe_devices(int domain_nr); struct pci_device *pci_find_device(u16 vendid, u16 devid); struct pci_device *pci_find_class(u16 classid); int pci_init_device(const struct pci_device_id *ids --=20 2.7.4 _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://mail.coreboot.org/mailman/listinfo/seabios